package fight import ( "blazing/cool" "blazing/logic/service/common" "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "context" "github.com/jinzhu/copier" ) // Compare 比较两个1v1战斗动作的执行优先级(核心逻辑) func (*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.Logger.Debug(context.Background(), " 战斗chan已关闭") return } if f.Info.Status != info.BattleMode.FIGHT_WITH_NPC && res == info.BattleOverReason.PlayerEscape { 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.Logger.Debug(context.Background(), " 战斗chan已关闭") return } //todo 待实现无法切精灵的情况 ret := &action.ActiveSwitchAction{ BaseAction: action.NewBaseAction(c.GetInfo().UserID), Cid: id, } f.actionChan <- ret } // 玩家使用技能 func (f *FightC) UseSkill(c common.PlayerI, id uint32) { if f.closefight { cool.Logger.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 } t, ok := f.GetInputByPlayer(c, false).CurrentPet.Skills[id] if ok { ret.SkillEntity = t } f.actionChan <- ret } // 玩家使用技能 func (f *FightC) Capture(c common.PlayerI, id uint32) { if f.closefight { cool.Logger.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.Logger.Debug(context.Background(), " 战斗chan已关闭") return } f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: itemid, CacthTime: cacthid} } // ReadyFight 处理玩家战斗准备逻辑,当满足条件时启动战斗循环 func (f *FightC) ReadyFight(c common.PlayerI) { f.Broadcast(func(ff *input.Input) { ff.Player.SendPackCmd(2404, &info.S2C_2404{UserID: c.GetInfo().UserID}) }) // 2. 标记当前玩家已准备完成 input := f.GetInputByPlayer(c, false) input.Finished = true if f.checkBothPlayersReady(c) { f.startBattle(f.FightStartOutboundInfo) } } // buildFightStartInfo 构建战斗开始时需要发送给双方的信息 func (f *FightC) buildFightStartInfo() info.FightStartOutboundInfo { var startInfo info.FightStartOutboundInfo // 复制双方初始宠物信息(取列表第一个宠物) if len(f.ReadyInfo.OurPetList) > 0 { _ = copier.Copy(&startInfo.Info1, &f.ReadyInfo.OurPetList[0]) startInfo.Info1.UserID = f.ReadyInfo.OurInfo.UserID } if len(f.ReadyInfo.OpponentPetList) > 0 { _ = copier.Copy(&startInfo.Info2, &f.ReadyInfo.OpponentPetList[0]) startInfo.Info2.UserID = f.ReadyInfo.OpponentInfo.UserID } return startInfo } // checkBothPlayersReady 检查PVP战斗中双方是否都已准备完成 // 参数c为当前准备的玩家,返回true表示双方均准备完成 func (f *FightC) checkBothPlayersReady(currentPlayer common.PlayerI) bool { // 这里的第二个参数true含义需结合业务确认(推测为"检查对手"),建议用常量替代 opponentInput := f.GetInputByPlayer(currentPlayer, true) return opponentInput.Finished } // startBattle 启动战斗核心逻辑:提交战斗循环任务并通知双方 func (f *FightC) startBattle(startInfo info.FightStartOutboundInfo) { f.startl.Do(func() { // 提交战斗循环到战斗池(处理战斗池容量问题) // if err := Fightpool.Invoke(f); err != nil { // log.Panic(context.Background(), "战斗循环提交失败", "error", err) // } go f.battleLoop() f.Broadcast(func(ff *input.Input) { // 通知双方玩家准备完成,即将开始战斗 ff.Player.SendPackCmd(2504, &startInfo) }) }) } // var Fightpool *ants.PoolWithFuncGeneric[*FightC] // func init() { // Fightpool, _ = ants.NewPoolWithFuncGeneric(-1, func(f *FightC) { // f.battleLoop() // }, ants.WithPanicHandler(func(a any) { // cool.Logger.Debug(context.Background(), "战斗池发生panic", "error", a) // }), // ) // //defer p.Release() // }