package input import ( "blazing/common/utils" "blazing/logic/service/fight/info" "fmt" "blazing/modules/blazing/model" "github.com/brunoga/deep" "github.com/tnnmigga/enum" ) // 战斗结束原因枚举 type EnumEffectType int var EffectType = enum.New[struct { Skill EnumEffectType `enum:"1000000"` //技能 NewSel EnumEffectType `enum:"2000000"` //特性 Status EnumEffectType `enum:"3000000"` //状态 Sub EnumEffectType `enum:"4000000"` //子效果 }]() var NodeM = make(map[int]Effect, 0) func InitEffect(etype EnumEffectType, id int, t Effect) { t.ID(id + int(etype)) //设置ID NodeM[id+int(etype)] = t } func Geteffect(etype EnumEffectType, id int) Effect { //todo 获取前GetEffect ret, ok := NodeM[id+int(etype)] if ok { //todo 获取前GetEffect eff := deep.MustCopy(ret) return eff //todo 获取后GetEffect } return nil } // * 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 { // 获取基础属性值 baseValue := int(c.AttackValue.Prop[id]) // 命中情况直接返回基础值(优先判断) if id >= 5 { return baseValue } // 处理id < 5的情况 if istue { return baseValue } // 计算实际值(这里可以插入后续优化的函数调用) realValue := info.CalculateRealValue(int(c.CurrentPet.Info.Prop[id]), baseValue) // todo: 插入获取后处理函数,例如: // realValue = postProcessValue(realValue, id, c) return realValue } func (c *Input) GetEffect(etype EnumEffectType, id int) Effect { var ret []Effect eid := id + int(etype) for _, v := range c.Effects { if v.ID() == eid && v.Alive() { ret = append(ret, v) } } if len(ret) > 0 { return ret[len(ret)-1] } return nil } func (c *Input) StatEffect_Exist(id int) bool { t := c.GetEffect(EffectType.Status, id) if t == nil { return false } return t.Alive() } func (c *Input) StatEffect_Exist_all() bool { for _, v := range c.Effects { if v.ID() >= int(EffectType.Status) && v.ID() < int(EffectType.Sub) && v.Alive() { return true } } return false } func (c *Input) GetCurrAttr(id int) *model.PetInfo { //todo 获取前GetEffect return c.CurrentPet.Info //todo 获取后GetEffect } // 比较两个[]int是否内容相等 func equalInts(a, b []int) bool { // 先判断长度是否相等 if len(a) != len(b) { return false } // 逐个比较元素 for i := range a { if a[i] != b[i] { return false } } return true } func (c *Input) AddEffects(e ...Effect) { for _, v := range e { // v.Alive() c.AddEffect(v) } } func (c *Input) AddEffect(e Effect) { e.Alive(true) //添加后默认激活 //todo 免疫 //TODO 先激活 fmt.Println("产生回合数", e.ID(), e.Duration()) // 如果已有同 ID 的效果,尝试叠加 for _, v := range c.Effects { if v == e { return //完全相同,跳过执行 } //如果效果相同,id相同,参数相同,就是同一个,确认是否可以叠加,正常来说本身就可以共存 //衰弱本身参数也是相同的,区别只是传入的回合数不一样和层数不一样 if v.ID() == e.ID() && //找到相同的效果id v.Alive() && //如果之前的效果还存活 equalInts(v.GetArgs(), e.GetArgs()) { //如果层数可以叠加或者是无限层数 if v.MaxStack() == 0 { v.Alive(false) //不允许叠层,取消效果 e.Duration(utils.Max(e.Duration(), v.Duration())) } else { ///e.Alive(false) //取消之前效果 if v.Stack() <= v.MaxStack() { //如果小于最大叠层,状态可以叠层 e.Stack(v.Stack() + e.Stack()) //获取到当前叠层数然后叠加 //这里直接返回,不再继续执行后续效果,因为这里是可以叠加的效果 //v.Duration(e.Duration()) //回合数覆盖 } return // c.Effects = append(c.Effects, e) //return } } } //无限叠加,比如能力提升类buff // 如果没有同 ID 的效果,直接添加 c.Effects = append(c.Effects, e) } // ForEachEffectBool 遍历所有 Effect,执行“无参数、返回 bool”的方法 // 参数 fn:接收单个 Effect,返回 bool(如 func(e Effect) bool { return e.OnBattleStart() }) // 返回值:所有 Effect 的方法返回值列表 func (c *Input) Exec(fn func(Effect) bool) bool { result := true for _, value := range c.Effects { if value.Alive() { if !fn(value) { //存在false,但是仍然要向下执行 result = false //如果是false,说明存在阻止向下执行的effect,比如免疫能力提升效果 } } } return result } func (c *Input) ExecCace(fn func(Effect) bool) bool { result := true for _, value := range c.EffectCache { if !fn(value) { //存在false,但是仍然要向下执行 result = false //如果是false,说明存在阻止向下执行的effect,比如免疫能力提升效果 } } return result } // 消除回合类效果 efftype 输入是消对方的还是自己的,false是自己,true是对方 func (c *Input) CancelTurn() { for _, value := range c.Effects { if value.Duration() > 0 { //false是自身,true是对方,反转后为真就是自己的 //slice = append(slice[:i], slice[i+1:]...) value.Alive(false) } } } // 消除全部 func (c *Input) CancelAll(in *Input) { if in == c { //消除自身 c.Effects = make([]Effect, 0) return } for _, value := range c.Effects { if value.GetInput() == in { //false是自身,true是对方,反转后为真就是自己的 //slice = append(slice[:i], slice[i+1:]...) value.Alive(false) } } }