Files
bl/logic/service/fight/action.go
昔念 6ba9c3549c feat(fight): 优化精灵切换逻辑与技能效果处理
- 修改 `ChangePet` 方法,记录初始攻击值并在切换时正确传递
- 简化多个 effect 的初始化方式,移除冗余的 `EffectNode` 字段
- 增强 Effect58 和 Effect67 的逻辑判断,增加空指针检查和类型判断
- 引入 decimal 包用于精确血量计算
- 统一 `Switch` 接口参数,增强状态类和节点类的兼容性
- 修正部分技能效果的触发条件和持续时间设置
- 调整回合结束逻辑,注释掉原有后手增益机制
2025-11-13 23:06:55 +08:00

196 lines
4.7 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 fight
import (
"blazing/common/data/xmlres"
"blazing/cool"
"blazing/logic/service/common"
"blazing/logic/service/fight/action"
"blazing/logic/service/fight/info"
"blazing/logic/service/fight/input"
"blazing/logic/service/player"
"context"
"github.com/gogf/gf/v2/util/gconv"
"github.com/jinzhu/copier"
"github.com/panjf2000/ants/v2"
)
// Compare 比较两个1v1战斗动作的执行优先级核心逻辑
func (f *FightC) Compare(a, b action.BattleActionI) (action.BattleActionI, action.BattleActionI) {
// 动作本身的优先级比较
p1 := b.Priority() - a.Priority()
if p1 > 0 { // 对手优先级更高
return b, a
} else if p1 < 0 {
return a, b
}
return a, b // 速度相同时,发起方优先
}
// 玩家逃跑/无响应/掉线
func (f *FightC) Over(c common.PlayerI, res info.EnumBattleOverReason) {
if f.closefight {
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
return
}
// case *action.EscapeAction:
// f.FightOverInfo.WinnerId = b2.GetPlayerID() //对方胜利
// f.FightOverInfo.Reason = a.Reason
// f.closefight = true
// ret := &action.EscapeAction{
// BaseAction: action.NewBaseAction(c.GetInfo().UserID),
// Reason: res,
// }
f.overl.Do(func() {
f.Reason = res
f.WinnerId = f.GetInputByPlayer(c, true).UserID
close(f.quit)
})
}
// 切换精灵 主动和被驱逐
func (f *FightC) ChangePet(c common.PlayerI, id uint32) {
if f.closefight {
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
return
}
selfinput := f.GetInputByPlayer(c, false)
InitAttackValue := *selfinput.AttackValue
oldpet := selfinput.CurrentPet
ret := &action.ActiveSwitchAction{
BaseAction: action.NewBaseAction(c.GetInfo().UserID),
}
selfinput.CurrentPet, ret.Reason = selfinput.GetPet(id)
f.Switch = append(f.Switch, ret)
selfinput.InitAttackValue() //切换精灵消除能力提升
//这时候精灵已经切换过了,可以直接给新精灵加效果
f.Broadcast(func(ff *input.Input) {
ff.Exec(func(t input.Effect) bool {
t.Switch(selfinput, InitAttackValue, oldpet)
return true
})
})
f.Broadcast(func(ff *input.Input) { //先给自身广播
if ff.Player.GetInfo().UserID == c.GetInfo().UserID {
ff.Player.SendChangePet(ret.Reason)
}
})
f.actionChan <- ret
}
// 玩家使用技能
func (f *FightC) UseSkill(c common.PlayerI, id int32) {
if f.closefight {
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
return
}
ret := &action.SelectSkillAction{
BaseAction: action.NewBaseAction(c.GetInfo().UserID),
}
if f.GetInputByPlayer(c, false).CurrentPet == nil {
return
}
if f.GetInputByPlayer(c, false).CurrentPet.Info.Hp <= 0 {
return
}
for _, v := range f.GetInputByPlayer(c, false).CurrentPet.Skills {
if v != nil && v.ID == int(id) {
ret.SkillEntity = v
break
}
}
f.actionChan <- ret
}
// 玩家使用技能
func (f *FightC) Capture(c common.PlayerI, id uint32) {
if f.closefight {
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
return
}
f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: id}
}
func (f *FightC) UseItem(c common.PlayerI, cacthid, itemid uint32) {
if f.closefight {
cool.Loger.Debug(context.Background(), " 战斗chan已关闭")
return
}
f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: itemid, CacthTime: cacthid}
}
// 战斗准备
func (f *FightC) ReadyFight(c common.PlayerI) {
rett := info.FightStartOutboundInfo{}
copier.Copy(&rett.Info1, &f.Info.OurPetList[0]) // 复制自己的信息
copier.Copy(&rett.Info2, &f.Info.OpponentPetList[0])
rett.Info1.UserID = f.Info.OurInfo.UserID //
rett.Info2.UserID = f.Info.OpponentInfo.UserID
rrsult := func() { //传回函数
// i := Fightpool.Free()
// if i <= 0 {
// Fightpool.Tune(Fightpool.Cap() + 1)
// cool.Loger.Error(context.Background(), "Fightpool is full")
// }
rr := Fightpool.Submit(f.battleLoop)
if rr != nil {
panic(rr)
}
f.Our.Player.SendReadyToFightInfo(rett)
f.Opp.Player.SendReadyToFightInfo(rett)
//f.runing = true
//然后开始战斗循环
}
f.GetInputByPlayer(c, false).Finished = true
switch f.Info.Status {
case info.BattleStatus.FIGHT_WITH_PLAYER: //pvp
if f.GetInputByPlayer(c, true).Finished {
rrsult()
}
case info.BattleStatus.FIGHT_WITH_BOSS: // 6v6
rrsult()
case info.BattleStatus.FIGHT_WITH_NPC: // 野怪战斗
if gconv.Int(xmlres.PetMAP[int(f.Info.OpponentPetList[0].ID)].CatchRate) > 0 {
rett.Info2.Catchable = 1
t, _ := f.Opp.Player.(*player.AI_player)
t.CanCapture = true
}
rrsult()
}
}
var Fightpool *ants.Pool
func init() {
Fightpool, _ = ants.NewPool(-1)
//defer p.Release()
}