diff --git a/logic/service/fight/battle/node/manger.go b/logic/service/fight/battle/node/manger.go new file mode 100644 index 00000000..ba63dbe5 --- /dev/null +++ b/logic/service/fight/battle/node/manger.go @@ -0,0 +1,101 @@ +package node + +// ======================== +// 容器:存放多个效果 +// ======================== +type NodeManager struct { + //GlobalEffects []*Effect // 全局常驻/回合/次数效果 + Effects []Effect //effects 实际上全局就是effect无限回合 +} + +// 添加效果 +func (c *NodeManager) AddEffect(e Effect) { + // 如果已有同 ID 的效果,尝试叠加 + for _, eff := range c.Effects { + if eff.ID() == e.ID() { + if eff.Stack(0) < eff.MaxStack() { //如果小于最大叠层 + eff.Stack(eff.Stack(0)) //获取到当前叠层数然后叠加 + } else { + + //这里,说明是延续回合效果 + + eff.Duration(eff.Duration(0)) + } + return + } + } + // 否则新加入 + c.Effects = append(c.Effects, e) +} + +// 触发执行 +func (c *NodeManager) Trigger() { + + turnStartResults := c.Exec(func(e Effect) bool { + return e.OnTurnStart() + }) //回合开始 + + // var candidates []*Effect + // for _, eff := range c.Effects { + // if eff.Trigger == trigger { + // candidates = append(candidates, eff) + // } + // } + + // // 按优先级排序 + // sort.SliceStable(candidates, func(i, j int) bool { + // return candidates[i].Priority > candidates[j].Priority + // }) + + // // 执行 + // for _, eff := range candidates { + // ctx.Effect = eff + // keep := eff.Apply(ctx) + + // if !keep { + // // 持续回合结束 / 返回 false 的 effect 删除 + // c.removeEffect(eff) + // } + + // if ctx.Done { + // break // 被拦截 + // } + // } +} + +// 每回合结束时调用,用于处理持续时间 +func (c *NodeManager) Tick() { + var remain []Effect + for _, eff := range c.Effects { + if eff.Duration(0) > 0 { + eff.Duration(eff.Duration(0) - 1) //回合数减1 + } + if eff.Duration(0) != 0 { // 保留 (负数表示永久) + remain = append(remain, eff) + } + } + c.Effects = remain +} + +// 删除 +func (c *NodeManager) removeEffect(e Effect) { + var remain []Effect + for _, eff := range c.Effects { + if eff != e { + remain = append(remain, eff) + } + } + c.Effects = remain +} + +// ForEachEffectBool 遍历所有 Effect,执行“无参数、返回 bool”的方法 +// 参数 fn:接收单个 Effect,返回 bool(如 func(e Effect) bool { return e.OnBattleStart() }) +// 返回值:所有 Effect 的方法返回值列表 +func (c *NodeManager) Exec(fn func(Effect) bool) []bool { + + results := make([]bool, 0, len(c.Effects)) + for _, effect := range c.Effects { + results = append(results, fn(effect)) + } + return results +} diff --git a/logic/service/fight/battle/node/node.go b/logic/service/fight/battle/node/node.go new file mode 100644 index 00000000..f4befb9c --- /dev/null +++ b/logic/service/fight/battle/node/node.go @@ -0,0 +1,95 @@ +package node + +import "context" + +type Effect interface { + OnBattleStart() bool + OnBattleEnd() bool + BeforeEffect() bool + AfterEffect() bool + OnSwitch() bool + OnTurnStart() bool + ID() int + + Stack(int) int + MaxStack() int + + Duration(int) int +} + +///基础节点 +type Node struct { + //Turn int // 当前回合数 ,回合数其实从战斗的上下文中获取 + //本质上ctx还要传入战斗双方数据来判断是否是本精灵切换 + ctx context.Context //节点上下文 + duration int // 持续回合/次(0 = 即时生效,>0 = 回合数 ,负数是永久) + stacks int // 当前层数 + + maxStack int // 最大叠加层数 ,正常都是不允许叠加的,除了衰弱特殊效果 + //LifeType EnumLifeType //回合效果 是否可持续 继承到下一直精灵 ,这个用重写事件来实现 + + // Parent string // 上下文来源(比如 "Skill"、"Buff"、"Passive") + // Trigger node.EnumEffectTrigger // 当前触发的节点 + // Container *EffectContainer // 效果容器(通常挂在 Actor 身上) + // Effect *Effect // 当前正在执行的 Effect + // Available bool // 是否可用 + // Success bool // 是否执行成功 + // Done bool // 是否中止后续执行 +} + +func (this *Node) ID() int { + + return 0 + +} +func (this *Node) Stacks(t int) int { + if t != 0 { + this.stacks = t + } + + return this.stacks + +} +func (this *Node) MaxStacks() int { + + return this.maxStack + +} +func (this *Node) Duration(t int) int { + + return this.duration + +} + +//返回false阻止继续运行 +//回合开始 +func (this *Node) OnBattleStart() bool { + + return true + +} + +//回合结束 + +func (this *Node) OnBattleEnd() bool { + return true + +} + +//技能效果前 +func (this *Node) BeforeEffect() bool { + return true + +} + +//技能效果前 +func (this *Node) AfterEffect() bool { + return true + +} + +//精灵切换时 +func (this *Node) OnSwitch() bool { + return true + +}