refactor(fight): 重构战斗流程实现并完善效果处理机制
This commit is contained in:
@@ -2,9 +2,60 @@ package fight
|
||||
|
||||
import "blazing/logic/service/fight/info"
|
||||
|
||||
func Rmain() {
|
||||
func NewBattle(i info.NoteReadyToFightInfo) {
|
||||
//调用技能产生effect参数后,创建effect实例,而非技能创建
|
||||
t := info.BattleSkillEntity{} //
|
||||
c := info.NewBattleContainer1v1(i) //创建战斗容器
|
||||
t := info.BattleSkillEntity{} //
|
||||
t.SideEffectArgs = []int{1, 2, 3}
|
||||
//先提交effecet后然后计算伤害
|
||||
|
||||
//物理和特殊,百分比和固定伤害也算,真实伤害不分类别,故直接扣血就行,不需要计算
|
||||
if t.Category() == info.Category.PHYSICAL || t.Category() == info.Category.SPECIAL {
|
||||
c.Effects.Exec(func(e info.Effect) bool {
|
||||
return e.PreDamage() //执行预处理效果
|
||||
})
|
||||
|
||||
// Apply pre-damage effects for pet sources
|
||||
// battle.applyEffects(context, EffectTrigger.PreDamage)
|
||||
// if (context.crit) {
|
||||
// battle.applyEffects(context, EffectTrigger.OnCritPreDamage) // Trigger crit pre-damage effects
|
||||
// }
|
||||
//假如说这里需要能力提升
|
||||
// c.Exec(func(e Effect) func() {
|
||||
// return e.OnBeforeAddMark()
|
||||
// })
|
||||
//添加印记前的效果如果有任何一个false,说明组织了添加效果
|
||||
//这里能力提升
|
||||
// c.Exec(func(e Effect) bool {
|
||||
// return e.OnAnyMarkAdded()
|
||||
// })
|
||||
|
||||
// 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 // 被拦截
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package effect
|
||||
import (
|
||||
"blazing/logic/service/fight/battle/node"
|
||||
"blazing/logic/service/fight/info"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
/**
|
||||
@@ -13,21 +15,19 @@ type Effect1 struct {
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
info.NodeM.AddEffect(&Effect1{})
|
||||
}
|
||||
|
||||
// 重写EFFectID
|
||||
func (this *Effect1) ID() int {
|
||||
this.EffectNode.ParamSize(0) //设置参数个数
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
// 重写POST_DAMAGE ,伤害结束后触发回血
|
||||
func (this *Effect1) PostDamage() bool {
|
||||
//获取技能+PET上下文,然后修改
|
||||
//但是这里会产生循环依赖问题
|
||||
|
||||
off := this.GetSkill().DamageValue.Div(decimal.NewFromInt(2)) //伤害的一半
|
||||
this.GetOwnerPet().Hp += uint32(off.IntPart()) //这里是effect在对方挂载,故回血给自己回血
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -64,8 +64,34 @@ func (this *EffectNode) ParamSize(t int) int {
|
||||
return this.paramSize
|
||||
|
||||
}
|
||||
func (this *EffectNode) GetSkill(t int) *info.BattleSkillEntity {
|
||||
pet, _ := this.ctx.Value(info.BattleSkillEntityCtx).(*info.BattleSkillEntity)
|
||||
func (this *EffectNode) GetSkill() *info.BattleSkillEntity {
|
||||
pet, ok := this.ctx.Value(info.BattleSkillEntityCtx).(*info.BattleSkillEntity)
|
||||
|
||||
if !ok { //effect不一定来自技能,也有特性 能量珠 boss effect
|
||||
return nil
|
||||
}
|
||||
return pet
|
||||
|
||||
}
|
||||
|
||||
// 获取对方精灵
|
||||
func (this *EffectNode) GetBattle() *info.BattleContainer1V1 {
|
||||
pet, _ := this.ctx.Value(info.BattleContainerCtx).(*info.BattleContainer1V1)
|
||||
|
||||
return pet
|
||||
|
||||
}
|
||||
|
||||
// 获取自身精灵
|
||||
func (this *EffectNode) GetOwnerPet() *info.BattlePetEntity {
|
||||
pet, _ := this.ctx.Value(info.Pet_O_Ctx).(*info.BattlePetEntity)
|
||||
|
||||
return pet
|
||||
|
||||
}
|
||||
|
||||
func (this *EffectNode) GetTargetPet() *info.BattlePetEntity {
|
||||
pet, _ := this.ctx.Value(info.Pet_T_Ctx).(*info.BattlePetEntity)
|
||||
|
||||
return pet
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ var PlayerOperations = enum.New[struct {
|
||||
|
||||
type BattleAction struct {
|
||||
Priority EnumPlayerOperation //优先级本质上是action的itoa
|
||||
ctx context.Context
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Compare 比较两个1v1战斗动作的执行优先级(核心逻辑)
|
||||
@@ -48,8 +48,8 @@ func (c *BattleAction) Compare(a *BattleAction) *BattleAction {
|
||||
} else if p2 < 0 {
|
||||
return c
|
||||
}
|
||||
peto, _ := a.ctx.Value(BattlePetEntityCtx).(*BattlePetEntity)
|
||||
pett, _ := a.ctx.Value(BattlePetEntityCtx).(*BattlePetEntity)
|
||||
peto, _ := a.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)
|
||||
pett, _ := a.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)
|
||||
|
||||
p2 = int(peto.UnitAttributes[AttrType.Speed].Value()) - int(pett.UnitAttributes[AttrType.Speed].Value()) // 假设 Use1v1SkillAction 有 SkillPriority() 方法
|
||||
if p2 > 0 {
|
||||
|
||||
@@ -4,10 +4,13 @@ import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const Input_ctx = "player"
|
||||
|
||||
type BattleInputSourceEntity struct {
|
||||
FightUserInfo
|
||||
ctx context.Context //输入源的上下文
|
||||
effects NodeManager //挂载effect
|
||||
FightUserInfo //用户信息
|
||||
PetEntities []*BattlePetEntity //宠物信息
|
||||
ctx context.Context //输入源的上下文
|
||||
|
||||
}
|
||||
|
||||
// 新建一个宠物
|
||||
@@ -17,7 +20,7 @@ func (u *BattleInputSourceEntity) NewBattlePetEntity(ctx context.Context) {
|
||||
|
||||
ret.UnitAttributes = make(map[EnumAttrType]*Attribute)
|
||||
//todo 待实现精灵特性+加成的封装
|
||||
ctx = context.WithValue(ctx, "player", &ret) //添加用户到上下文
|
||||
ctx = context.WithValue(ctx, Input_ctx, &ret) //添加用户到上下文
|
||||
ret.ctx = ctx
|
||||
|
||||
}
|
||||
@@ -26,7 +29,7 @@ func (u *BattleInputSourceEntity) NewBattleAction(ctx context.Context, actiontyp
|
||||
ret := BattleAction{
|
||||
Priority: actiontype,
|
||||
}
|
||||
ctx = context.WithValue(ctx, "player", &ret) //添加用户到上下文
|
||||
ctx = context.WithValue(ctx, Input_ctx, &ret) //添加用户到上下文
|
||||
ret.ctx = ctx
|
||||
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ import (
|
||||
// 战斗属性类型
|
||||
type EnumAttrType int
|
||||
|
||||
const BattlePetEntityCtx = "battle_pet_entity_ctx"
|
||||
// 精灵
|
||||
const Pet_O_Ctx = "PET_O"
|
||||
const Pet_T_Ctx = "PET_T"
|
||||
|
||||
var AttrType = enum.New[struct {
|
||||
Attack EnumAttrType `enum:"1"` //`enum:"攻击"`
|
||||
|
||||
@@ -44,6 +44,7 @@ type BattleSkillEntity struct {
|
||||
DamageZone map[EnumCategory]map[EnumsZoneType]map[EnumsZoneType][]float64 // 三维map 伤害类型-》增还是减-》加还是乘-》值
|
||||
isCritical bool //技能是否暴击
|
||||
ATTACK_COUNT_ZONE int //攻击次数
|
||||
DamageValue decimal.Decimal // 伤害值
|
||||
// 技能类型属性
|
||||
//SkillType EnumCategory // 技能类型(物理/特殊/状态)
|
||||
|
||||
@@ -252,7 +253,7 @@ func (s *BattleSkillEntity) PutDamageZone(e EnumCategory, dtype EnumsZoneType, v
|
||||
|
||||
}
|
||||
func (s *BattleSkillEntity) Pet() (*BattlePetEntity, bool) {
|
||||
pet, ok := s.ctx.Value(BattlePetEntityCtx).(*BattlePetEntity)
|
||||
pet, ok := s.ctx.Value(Pet_O_Ctx).(*BattlePetEntity)
|
||||
|
||||
return pet, ok
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ type BattleContext struct {
|
||||
Round int //回合数
|
||||
BattleMode EnumBattleMode //战斗模式
|
||||
opposite []BattleInputSourceEntity //不同阵营
|
||||
Effects NodeManager //挂载effect
|
||||
}
|
||||
|
||||
// 执行下一回合
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
type BattleContainer1V1 struct {
|
||||
BattleContext
|
||||
ownerid uint32 // 房主ID
|
||||
Ownerid uint32 // 房主ID
|
||||
FirstPerson uint32 //先手方ID
|
||||
|
||||
}
|
||||
@@ -33,13 +33,15 @@ func NewBattleContainer1v1(i NoteReadyToFightInfo) *BattleContainer1V1 {
|
||||
|
||||
ret.same = append(ret.same, BattleInputSourceEntity{
|
||||
FightUserInfo: i.OurInfo,
|
||||
//todo 待初始化精灵实体
|
||||
|
||||
}) //添加战斗实体
|
||||
ret.opposite = append(ret.same, BattleInputSourceEntity{
|
||||
FightUserInfo: i.OpponentInfo,
|
||||
})
|
||||
ret.ownerid = i.OwnerID //房主ID
|
||||
ret.Ownerid = i.OwnerID //房主ID
|
||||
|
||||
ret.Rand = random.NewRandomXS128WithTwoSeeds(uint64(ret.ownerid), uint64(time.Now().Unix()))
|
||||
ret.Rand = random.NewRandomXS128WithTwoSeeds(uint64(ret.Ownerid), uint64(time.Now().Unix()))
|
||||
ctx := context.Background()
|
||||
context.WithValue(ctx, BattleContainerCtx, &ret) //传入容器的上下文
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package info
|
||||
|
||||
|
||||
|
||||
type Effect interface {
|
||||
PreBattleStart() bool //战斗开始前
|
||||
OnBattleStart() bool //战斗开始
|
||||
@@ -78,6 +76,7 @@ type Effect interface {
|
||||
|
||||
Stack(int) int
|
||||
MaxStack() int
|
||||
//GetSkill() *BattleSkillEntity //获得技能ctx
|
||||
}
|
||||
|
||||
// ========================
|
||||
@@ -110,54 +109,6 @@ func (c *NodeManager) AddEffect(e Effect) {
|
||||
c.Effects = append(c.Effects, e)
|
||||
}
|
||||
|
||||
// 触发执行
|
||||
func (c *NodeManager) Trigger() {
|
||||
|
||||
PreBattleStart := c.Exec(func(e Effect) bool {
|
||||
return e.PreBattleStart()
|
||||
}) //回合开始
|
||||
|
||||
if PreBattleStart { //说明上一步骤没有阻止执行
|
||||
|
||||
}
|
||||
//假如说这里需要能力提升
|
||||
// c.Exec(func(e Effect) func() {
|
||||
// return e.OnBeforeAddMark()
|
||||
// })
|
||||
//添加印记前的效果如果有任何一个false,说明组织了添加效果
|
||||
//这里能力提升
|
||||
// c.Exec(func(e Effect) bool {
|
||||
// return e.OnAnyMarkAdded()
|
||||
// })
|
||||
|
||||
// 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
|
||||
|
||||
@@ -13,19 +13,19 @@ var (
|
||||
mu sync.Mutex // 保护标志位的互斥锁
|
||||
)
|
||||
|
||||
// 当A完成后调用的函数
|
||||
// 当A 战斗准备完成
|
||||
func onAFinished() {
|
||||
fmt.Println("A已完成,触发onAFinished")
|
||||
checkBothFinished() // 检查是否两者都完成
|
||||
}
|
||||
|
||||
// 当B完成后调用的函数
|
||||
// 当B 战斗准备完成
|
||||
func onBFinished() {
|
||||
fmt.Println("B已完成,触发onBFinished")
|
||||
checkBothFinished() // 检查是否两者都完成
|
||||
}
|
||||
|
||||
// 当A和B都完成后调用的函数
|
||||
// 当A和B都 这时候给双方回复开始战斗包
|
||||
func onBothFinished() {
|
||||
fmt.Println("A和B都已完成,触发onBothFinished")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user