Files
bl/logic/service/fight/input/nodemanger.go

255 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package input
import (
"blazing/logic/service/fight/info"
"blazing/modules/blazing/model"
"reflect"
"github.com/mohae/deepcopy"
)
type Effect interface {
OnBattleStart() bool //战斗开始
OnTurnStart(opp *Input) bool //回合开始
UseSkill(opp *Input) bool //使用技能 可以取消用技能节点
// OnSkillPP() bool //技能PP减少节点
// BeforeMultiHit() bool //多段攻击前
// BeforeHit() bool //命中前
// OnCritPreDamage() bool //暴击判定成功且伤害计算前触发
// PreDamage() bool // 技能伤害计算前触发(增伤 / 减伤等)
// OnBeforeCalculateDamage() bool // 最终伤害计算前触发
// OnDamage() bool // 造成伤害时触发
//使用技能 可以取消用技能节点
SetInput(input *Input)
AfterAttr() //在获取属性前,比如重写对方属性AfterAttr
BeferAttr() //在获取属性后,比如视为对方属性
SetArgs(param []int)
IsCrit(opp *Input, skill *info.SkillEntity) //是否暴击
CalculateDamage(opp *Input, skill *info.SkillEntity) //击判定成功且伤害计算前触发
OnBeforeCalculateDamage(opp *Input, skill *info.SkillEntity) // 最终伤害计算前触发
// Shield() bool // 护盾值变化时触发
// PostDamage() bool // 伤害结算后触发(血量扣除后)
IsHit(opp *Input, skill *info.SkillEntity) //闪避率计算,,实际上是修改命中的判断
TakeHit(opp *Input, skill *info.SkillEntity) //闪避率计算,,实际上是修改命中的判断
//() bool // 暴击伤害结算后触发
OnSkill(opp *Input, skill *info.SkillEntity) //闪避率计算,,实际上是修改命中的判断
// OnHit() bool // 技能命中时触发
// OnMiss() bool // 技能未命中时触发
// AfterAttacked() bool // 被攻击后触发(受击判定)
// SetOwner(bool)
// OnDefeat() bool // 精灵被击败时触发
// TurnEnd() bool // 回合结束
// // 堆叠Stack相关触发
// OnStackBefore() bool // 堆叠效果前触发
// OnStack() bool // 堆叠效果触发
// OnBeforeConsumeStack() bool // 消耗堆叠前触发
// OnConsumeStack() bool // 消耗堆叠时触发
// // 治疗相关触发
// OnBeforeHeal() bool // 治疗前触发
// OnHeal() bool // 治疗生效时触发
// // // 怒气Rage相关触发
// // BeforeRageGain EnumEffectTrigger enum:"37" // 增怒前触发
// // OnRageGain EnumEffectTrigger enum:"38" // 增怒时触发
// // BeforeRageLoss EnumEffectTrigger enum:"39" // 减怒前触发
// // OnRageLoss EnumEffectTrigger enum:"40" // 减怒时触发
// // 精灵切换相关触发
// OnSwitchIn() bool // 精灵出战 / 上场时触发
// OnSwitchOut() bool // 精灵下场时触发
// OnOwnerSwitchIn() bool // 所属玩家精灵出战时触发
// OnOwnerSwitchOut() bool // 所属玩家精灵下场时触发
// PreBattleEnd() bool //战斗结束前
// OnBattleEnd() bool //战斗结束
//回合数,然后次数另外维护
Duration(...int) int
ID() int
Alive() bool
Stack(...int) int
GetMaxStack() int
NotALive()
GetOwner() bool // 技能属主,比如寄生和镇魂歌,属主是对方)
//GetSkill() *BattleSkillEntity //获得技能ctx
}
var NodeM = make(map[int]Effect, 0)
func InitSkillEffect(id int, t Effect) {
NodeM[id+1000000] = t
}
func Geteffect(id int) (Effect, bool) {
//todo 获取前GetEffect
ret, ok := NodeM[id]
if ok {
eff := deepcopy.Copy(ret).(Effect)
return eff, ok
}
return nil, false
//todo 获取后GetEffect
}
func InitPropEffect(id int, t Effect) {
NodeM[id+2000000] = t
}
// * battle_lv: atk(0), def(1), sp_atk(2), sp_def(3), spd(4), accuracy(5)
// 是否需要真实提升
func (c *Input) GetProp(id int, istue bool) int {
//todo 插入获取前
t, ok := NodeM[id+2000000]
if ok {
if id < 5 {
if istue {
return t.Stack()
}
return info.CalculateRealValue(int(c.CurrentPet.Info.Prop[id]), t.Stack())
}
//命中就直接返回
return t.Stack()
}
//todo 插入获取后函数
return 0
}
func InitDamageEffect(id int, t Effect) {
NodeM[id+4000000] = t
}
// 1为红伤
func (c *Input) GetDamageEffect(id int) Effect {
ret, ok := Geteffect(id + 1000000)
if ok {
//todo 获取前GetEffect
return ret
//todo 获取后GetEffect
}
return nil
}
func InitStatusEffect(id int, t Effect) {
NodeM[id+3000000] = t
}
func (c *Input) GetStatusEffect(id int) (Effect, bool) {
ret, ok := Geteffect(id + 3000000)
if ok {
//todo 获取前GetEffect
return ret, true
//todo 获取后GetEffect
}
return nil, false
}
func (c *Input) GetCurrAttr(id int) *model.PetInfo {
//todo 获取前GetEffect
return c.CurrentPet.Info
//todo 获取后GetEffect
}
func getTypeName(v interface{}) string {
// 获取类型信息
t := reflect.TypeOf(v)
// 如果是指针类型,需要先获取其指向的元素类型
if t.Kind() == reflect.Ptr {
t = t.Elem()
}
// 如果是结构体类型,返回其名称
if t.Kind() == reflect.Struct {
return t.Name()
}
// 非结构体类型返回空或对应的类型名
return t.Kind().String()
}
func (c *Input) AddEffect(e Effect) {
e.SetInput(c)
// 如果已有同 ID 的效果,尝试叠加
for _, eff := range c.Effects {
if eff.ID() == e.ID() {
//设置输入源
if eff.Stack() < eff.GetMaxStack() { //如果小于最大叠层
eff.Stack(eff.Stack()) //获取到当前叠层数然后叠加
} else {
//这里,说明是延续回合效果
eff.Duration(eff.Duration())
}
return
}
}
// 否则新加入
c.Effects = append(c.Effects, e)
}
// 删除
func (c *Input) RemoveEffect(e Effect) {
slice := c.Effects
for i := 0; i < len(slice); {
if slice[i].ID() == e.ID() {
slice = append(slice[:i], slice[i+1:]...)
} else {
i++
}
}
c.Effects = slice
}
// ForEachEffectBool 遍历所有 Effect执行“无参数、返回 bool”的方法
// 参数 fn接收单个 Effect返回 bool如 func(e Effect) bool { return e.OnBattleStart() }
// 返回值:所有 Effect 的方法返回值列表
func (c *Input) Exec(fn func(Effect) bool) bool {
for _, effect := range c.Effects {
if effect.Alive() {
result := fn(effect)
if !result {
return result //如果是false,说明存在阻止向下执行的effect比如免疫能力提升效果
}
}
}
return true
}
// 消除回合类效果 efftype 输入是消对方的还是自己的,false是自己,true是对方
func (c *Input) CancelTurn(efftype bool) {
slice := c.Effects
for i := 0; i < len(slice); {
if slice[i].Duration() > 0 { //false是自身,true是对方,反转后为真就是自己的
slice = append(slice[:i], slice[i+1:]...)
} else {
i++
}
}
c.Effects = slice
}