Files
bl/logic/service/fight/battle/skill/effect/EffectContainer.go
昔念 1405bf5ee9 refactor(fight): 重构战斗模块
- 移除 BattleStateMachine 和 BattleUnit 相关代码
- 新增 BattleContainer 和 DamageContext 结构体
- 重构伤害计算逻辑,使用高精度 decimal 进行计算
- 更新随机数生成器,支持基于用户和时间的种子生成
- 优化战斗信息结构,增加 OwnerID 字段
2025-08-25 12:58:08 +08:00

149 lines
3.9 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 effect
import (
"blazing/logic/service/fight/battle/node"
"sort"
"github.com/tnnmigga/enum"
)
// ========================
// 上下文:一次效果执行环境
// ========================
type EffectContext struct {
Parent string // 上下文来源(比如 "Skill"、"Buff"、"Passive"
Trigger node.EnumEffectTrigger // 当前触发的节点
Container *EffectContainer // 效果容器(通常挂在 Actor 身上)
Effect *Effect // 当前正在执行的 Effect
Available bool // 是否可用
Success bool // 是否执行成功
Done bool // 是否中止后续执行
}
// ========================
// Effect: 单个效果
// ========================
type Effect struct {
ID uint32 // 唯一标识
Trigger node.EnumEffectTrigger // 触发节点
Priority int // 执行优先级,数值越大越先执行
LifeType EnumLifeType //回合效果 是否可持续 继承到下一直精灵
Duration int // 持续回合/次0 = 即时生效,>0 = 回合数 ,负数是永久)
Stacks int // 当前层数
MaxStack int // 最大叠加层数
Handler func(ctx *EffectContext, next func()) bool // 执行逻辑,返回 true 表示继续保留 //TODO 内部判断是否切换了精灵,是否满足条件
}
// ================= LifeType =================
type EnumLifeType int
var LifeType = enum.New[struct {
TurnBased EnumLifeType `enum:"1"` // 回合数限制
CountBased EnumLifeType `enum:"2"` // 次数限制
}]()
// ========================
// 容器:存放多个效果
// ========================
type EffectContainer struct {
//GlobalEffects []*Effect // 全局常驻/回合/次数效果
Effects []*Effect //effects 实际上全局就是effect无限回合
}
// 添加效果
func (c *EffectContainer) AddEffect(e *Effect) {
// 如果已有同 ID 的效果,尝试叠加
for _, eff := range c.Effects {
if eff.ID == e.ID {
if eff.Stacks < eff.MaxStack {
eff.Stacks++
}
return
}
}
// 否则新加入
c.Effects = append(c.Effects, e)
}
// 添加全局效果
func (c *EffectContainer) AddGlobalEffects(e *Effect) {
// 如果已有同 ID 的效果,尝试叠加
for _, eff := range c.GlobalEffects {
if eff.ID == e.ID {
if eff.Stacks < eff.MaxStack {
eff.Stacks++
}
return
}
}
// 否则新加入
c.GlobalEffects = append(c.GlobalEffects, e)
}
// 触发执行
func (c *EffectContainer) Trigger(trigger node.EnumEffectTrigger, ctx *EffectContext) {
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 *EffectContainer) Tick() {
var remain []*Effect
for _, eff := range c.Effects {
if eff.Duration > 0 {
eff.Duration--
}
if eff.Duration != 0 { // 保留 (负数表示永久)
remain = append(remain, eff)
}
}
c.Effects = remain
}
// 删除
func (c *EffectContainer) removeEffect(e *Effect) {
var remain []*Effect
for _, eff := range c.Effects {
if eff != e {
remain = append(remain, eff)
}
}
c.Effects = remain
}
// 清理过期效果
func (c *EffectContainer) Cleanup() {
var alive []*Effect
for _, e := range c.Effects {
if e.Duration != 0 {
alive = append(alive, e)
}
}
c.Effects = alive //挂载到普通effect
}