```
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful

feat(fight): 添加效果工厂模式支持以解决闭包变量捕获问题

- 新增initskillFactory函数用于注册效果工厂
- 修改技能效果注册逻辑从直接实例化改为工厂模式
- 解决循环中闭包捕获变量导致的潜在问题

feat(fight): 实现对手输入获取逻辑优化回合处理

- 添加roundOpponentInput方法获取对手输入
- 重构enterturn方法中的先后手逻辑
- 确保攻击方和被攻击
This commit is contained in:
昔念
2026-04-12 22:44:13 +08:00
parent 82bb99d141
commit e1a994ba11
6 changed files with 87 additions and 8 deletions

View File

@@ -5,3 +5,7 @@ import "blazing/logic/service/fight/input"
func initskill(id int, e input.Effect) {
input.InitEffect(input.EffectType.Skill, id, e)
}
func initskillFactory(id int, factory func() input.Effect) {
input.InitEffectFactory(input.EffectType.Skill, id, factory)
}

View File

@@ -158,7 +158,10 @@ func registerSelfDamageSkillHitEffects() {
}
for effectID, handler := range handlers {
initskill(effectID, newSkillHitRegistrarEffect(handler))
currentHandler := handler
initskillFactory(effectID, func() input.Effect {
return newSkillHitRegistrarEffect(currentHandler)
})
}
}
@@ -223,7 +226,10 @@ func registerSelfDamageOnSkillEffects() {
}
for effectID, handler := range handlers {
initskill(effectID, newOnSkillRegistrarEffect(handler))
currentHandler := handler
initskillFactory(effectID, func() input.Effect {
return newOnSkillRegistrarEffect(currentHandler)
})
}
}
@@ -305,7 +311,10 @@ func registerSelfDamageSkillUseEffects() {
}
for effectID, handler := range handlers {
initskill(effectID, newSkillUseRegistrarEffect(handler))
currentHandler := handler
initskillFactory(effectID, func() input.Effect {
return newSkillUseRegistrarEffect(currentHandler)
})
}
}
@@ -339,7 +348,10 @@ func registerSelfDamageComparePreOnSkillEffects() {
}
for effectID, effect := range effects {
initskill(effectID, effect)
currentEffect := effect
initskillFactory(effectID, func() input.Effect {
return newComparePreOnSkillRegistrarEffect(currentEffect.comparePreHandler, currentEffect.onSkillHandler)
})
}
}

View File

@@ -198,6 +198,18 @@ func (f *FightC) buildNoteUseSkillOutboundInfo() info.NoteUseSkillOutboundInfo {
return result
}
func (f *FightC) roundOpponentInput(attacker *input.Input) *input.Input {
if attacker == nil {
return nil
}
for _, opponent := range attacker.OpponentSlots() {
if opponent != nil {
return opponent
}
}
return nil
}
// enterturn 处理战斗回合逻辑
// 回合有先手方和后手方,同时有攻击方和被攻击方
func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction) {
@@ -245,9 +257,11 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction)
f.First, _ = f.getSkillParticipants(firstAttack)
f.Second, _ = f.getSkillParticipants(secondAttack)
case firstAttack != nil:
f.First, f.Second = f.getSkillParticipants(firstAttack)
f.First, _ = f.getSkillParticipants(firstAttack)
f.Second = f.roundOpponentInput(f.First)
case secondAttack != nil:
f.First, f.Second = f.getSkillParticipants(secondAttack)
f.First, _ = f.getSkillParticipants(secondAttack)
f.Second = f.roundOpponentInput(f.First)
}
if f.First == nil {
f.First = f.primaryOur()
@@ -332,7 +346,6 @@ func (f *FightC) enterturn(firstAttack, secondAttack *action.SelectSkillAction)
}
//先手权不一定出手
} else {
f.setActionAttackValue(currentAction)

View File

@@ -32,6 +32,7 @@ var EffectType = enum.New[struct {
}]()
var NodeM = make(map[int64]Effect, 0)
var NodeFactoryM = make(map[int64]func() Effect, 0)
func InitEffect(etype EnumEffectType, id int, t Effect) {
pr := EffectIDCombiner{}
@@ -41,6 +42,13 @@ func InitEffect(etype EnumEffectType, id int, t Effect) {
NodeM[pr.EffectID()] = t
}
func InitEffectFactory(etype EnumEffectType, id int, factory func() Effect) {
pr := EffectIDCombiner{}
pr.Combine(etype, 0, gconv.Uint16(id))
NodeFactoryM[pr.EffectID()] = factory
}
func GeteffectIDs(etype EnumEffectType) []uint32 {
var ret []uint32 = make([]uint32, 0)
@@ -60,6 +68,19 @@ func geteffect[T int | byte | uint16](etype EnumEffectType, id T) Effect {
pr := EffectIDCombiner{}
pr.Combine(etype, 0, gconv.Uint16(id))
if factory, ok := NodeFactoryM[pr.EffectID()]; ok {
eff := factory()
if eff == nil {
return nil
}
eff.ID(pr)
if etype == EffectType.Status {
eff.CanStack(true)
eff.Duration(grand.N(1, 2))
}
return eff
}
//todo 获取前GetEffect
ret, ok := NodeM[pr.EffectID()]
if ok {