Files
bl/logic/service/fight/input/nodemanger.go
昔念 929b0c9006 refactor(fight): 重构战斗系统效果和技能逻辑
- 移除了未使用的 Effect0 基类效果
- 优化了技能施放和效果执行的逻辑
- 调整了命中和闪避的计算方式
-
2025-09-14 16:56:31 +08:00

225 lines
6.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 input
import (
"blazing/logic/service/fight/info"
"reflect"
)
type Effect interface {
OnBattleStart() bool //战斗开始
OnTurnStart(attacker, defender *Input) bool //回合开始
UseSkill(attacker, defender *Input) bool //使用技能 可以取消用技能节点
// OnSkillPP() bool //技能PP减少节点
// BeforeMultiHit() bool //多段攻击前
// BeforeHit() bool //命中前
// OnCritPreDamage() bool //暴击判定成功且伤害计算前触发
// PreDamage() bool // 技能伤害计算前触发(增伤 / 减伤等)
// OnBeforeCalculateDamage() bool // 最终伤害计算前触发
// OnDamage() bool // 造成伤害时触发
//使用技能 可以取消用技能节点
SetArgs(param []int)
IsCrit(attacker, defender *Input, skill *info.BattleSkillEntity) //是否暴击
CalculateDamage(attacker, defender *Input, skill *info.BattleSkillEntity) //击判定成功且伤害计算前触发
// Shield() bool // 护盾值变化时触发
// PostDamage() bool // 伤害结算后触发(血量扣除后)
IsHit(attacker, defender *Input, skill *info.BattleSkillEntity) //闪避率计算,,实际上是修改命中的判断
TakeHit(attacker, defender *Input, skill *info.BattleSkillEntity) //闪避率计算,,实际上是修改命中的判断
//() bool // 暴击伤害结算后触发
// 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
GetArgSize() int
Stack(int) int
MaxStack() int
GetOwner() bool // 技能属主,比如寄生和镇魂歌,属主是对方)
//GetSkill() *BattleSkillEntity //获得技能ctx
}
// ========================
// 容器:存放多个效果
// ========================
type NodeManager struct {
//GlobalEffects []*Effect // 全局常驻/回合/次数效果
Effects []Effect //effects 实际上全局就是effect无限回合
}
var NodeM = make(map[int]Effect, 0)
func InitEffect(id int, t Effect) {
NodeM[id] = t
}
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 *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) RemoveEffect(e Effect) {
var remain []Effect
for _, eff := range c.Effects {
if eff.ID() != e.ID() {
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 {
var results bool
// if len(c.Effects) == 0 {
// return true
// }
for _, effect := range c.Effects {
result := fn(effect)
if !result {
results = result //如果是false,说明存在阻止向下执行的effect比如免疫能力提升效果
}
if result {
results = true
}
}
return results
}
// 消除回合类效果 efftype 输入是消对方的还是自己的,false是自己,true是对方
func (c *NodeManager) CancelTurn(efftype bool) {
var remain []Effect
for _, eff := range c.Effects {
if eff.Duration(0) <= 0 && eff.GetOwner() == efftype { //false是自身,true是对方,反转后为真就是自己的
remain = append(remain, eff)
}
}
c.Effects = remain
}
// // 添加效果
// func (c **NodeManager) AddEffect(e Effect) {
// var fff *NodeManager
// switch t := (e.Duration(0) > 1); t { //判断是否是回合类效果
// case t: //t>0就是回合类效果了 -1和0都是非回合效果和无限效果,无法被断回合
// fff = c.Turn
// default:
// fff = c.Mark
// }
// fff.AddEffect(e)
// }
// // 删除
// func (c **NodeManager) RemoveEffect(e Effect) {
// var fff *NodeManager
// switch t := (e.Duration(0) > 1); t { //判断是否是回合类效果
// case t: //t>0就是回合类效果了 -1和0都是非回合效果和无限效果,无法被断回合
// fff = c.Turn
// default:
// fff = c.Mark
// }
// fff.RemoveEffect(e)
// }
// // ForEachEffectBool 遍历所有 Effect执行“无参数、返回 bool”的方法
// // 参数 fn接收单个 Effect返回 bool如 func(e Effect) bool { return e.OnBattleStart() }
// // 返回值:所有 Effect 的方法返回值列表
// func (c *NodeManagerE) Exec(fn func(Effect) bool) bool {
// // var results bool
// // execfun := func(nm *NodeManager) {
// // for _, effect := range nm.Effects {
// // result := fn(effect)
// // if !result {
// // results = result //如果是false,说明存在阻止向下执行的effect比如免疫能力提升效果
// // }
// // }
// // }
// results := true
// result := c.Mark.Exec(fn) //执行叠层
// if !result {
// results = result
// }
// result = c.Turn.Exec(fn) //执行回合类效果
// if !result {
// results = result
// }
// return results
// }