diff --git a/logic/controller/fight_base.go b/logic/controller/fight_base.go index 44a1e4633..7e53007c6 100644 --- a/logic/controller/fight_base.go +++ b/logic/controller/fight_base.go @@ -11,27 +11,34 @@ import ( // 准备战斗 func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - + if c.FightC == nil { + return nil, errorcode.ErrorCodes.ErrBattleEnded + } c.FightC.ReadyFight(c) return nil, -1 } // 使用技能包 func (h Controller) UseSkill(data *fight.UseSkillInInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if c.FightC != nil { - c.FightC.UseSkill(c, int32(data.SkillId)) + if c.FightC == nil { + return nil, errorcode.ErrorCodes.ErrBattleEnded } - + c.FightC.UseSkill(c, int32(data.SkillId)) return nil, 0 } // 战斗逃跑 func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if atomic.LoadUint32(&c.Fightinfo.Status) == 0 { + + if c.FightC == nil { + return nil, errorcode.ErrorCodes.ErrBattleEnded + } + + if atomic.LoadUint32(&c.Fightinfo.Mode) == 0 { return nil, errorcode.ErrorCodes.ErrBattleNotStarted //,没开始对战 } - if atomic.LoadUint32(&c.Fightinfo.Status) == 1 { //用户对战不能逃跑 + if atomic.LoadUint32(&c.Fightinfo.Mode) == 1 { //用户对战不能逃跑 return nil, errorcode.ErrorCodes.ErrCannotFleePlayerBattle } @@ -41,33 +48,39 @@ func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) // 切换精灵 func (h Controller) ChangePet(data *fight.ChangePetInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if c.FightC != nil { - c.FightC.ChangePet(c, data.CatchTime) + if c.FightC == nil { + return nil, errorcode.ErrorCodes.ErrBattleEnded } + + c.FightC.ChangePet(c, data.CatchTime) return nil, -1 } // 切换精灵 func (h Controller) Capture(data *fight.CatchMonsterInboundInfo, c *player.Player) (result *info.CatchMonsterOutboundInfo, err errorcode.ErrorCode) { - + if c.FightC == nil { + return nil, errorcode.ErrorCodes.ErrBattleEnded + } c.FightC.Capture(c, data.CapsuleId) return nil, -1 } // 加载进度 func (h Controller) LoadPercent(data *fight.LoadPercentInboundInfo, c *player.Player) (result *info.LoadPercentOutboundInfo, err errorcode.ErrorCode) { - if c.FightC != nil { - - c.FightC.LoadPercent(c, int32(data.Percent)) + if c.FightC == nil { + return nil, errorcode.ErrorCodes.ErrBattleEnded } + c.FightC.LoadPercent(c, int32(data.Percent)) return nil, -1 } func (h Controller) UsePetItemInboundInfo(data *fight.UsePetItemInboundInfo, c *player.Player) (result *info.UsePetIteminfo, err errorcode.ErrorCode) { - if c.FightC != nil { - c.FightC.UseItem(c, data.CatchTime, data.ItemId) + if c.FightC == nil { + return nil, errorcode.ErrorCodes.ErrBattleEnded } + c.FightC.UseItem(c, data.CatchTime, data.ItemId) + return nil, -1 } diff --git a/logic/controller/fight_boss.go b/logic/controller/fight_boss.go index d6344c05c..c6edaee3c 100644 --- a/logic/controller/fight_boss.go +++ b/logic/controller/fight_boss.go @@ -3,6 +3,7 @@ package controller import ( "blazing/common/data/xmlres" "blazing/common/socket/errorcode" + "fmt" "math/rand" "strings" @@ -97,17 +98,23 @@ func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *pla } - c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_BOSS + c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC c.Fightinfo.Mode = info.BattleMode.MULTI_MODE ai := player.NewAI_player(moinfo) //给予打过一次的奖励 - event := c.Done.SPT(c.Info.MapID, data.BossId, 1, func() { - + event := c.Done.SPT(c.Info.MapID, data.BossId, 1, func() bool { + fmt.Println("触发事件", "第一次奖励") + return true + }) + event1 := c.Done.SPT(c.Info.MapID, data.BossId, 2, func() bool { + fmt.Println("触发事件", "第二次奖励") + return true }) fight.NewFight(c, ai, func(foi *info.FightOverInfo) { - c.Done.Exec(model.MilestoneMode.BOSS, []uint32{data.BossId}) + c.Done.Exec(model.MilestoneMode.BOSS, []uint32{c.Info.MapID, data.BossId}) event.Cancel() //取消事件 + event1.Cancel() }) @@ -133,9 +140,10 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName moinfo.PetList = append(moinfo.PetList, *mo) ai := player.NewAI_player(moinfo) + ai.CanCapture = handleNPCFightSpecial(mo.ID) - c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_NPC - c.Fightinfo.Mode = info.BattleMode.MULTI_MODE + c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC //打野怪 + c.Fightinfo.Mode = info.BattleMode.MULTI_MODE //多人模式 fight.NewFight(c, ai, func(foi *info.FightOverInfo) { @@ -143,3 +151,15 @@ func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundIn return nil, -1 } +func handleNPCFightSpecial(petid uint32) int { + + npcPetID := int(petid) + petCfg, ok := xmlres.PetMAP[npcPetID] + if !ok { + // log.Error(context.Background(), "NPC宠物配置不存在", "petID", npcPetID) + return 0 + } + + catchRate := gconv.Int(petCfg.CatchRate) + return catchRate +} diff --git a/logic/controller/fight_leitai.go b/logic/controller/fight_leitai.go index f220fa2bb..81a8ed03f 100644 --- a/logic/controller/fight_leitai.go +++ b/logic/controller/fight_leitai.go @@ -17,6 +17,10 @@ import ( // 都需要通过2419包广播更新擂台状态 func (h Controller) ARENA_SET_OWENR(data *fight.ARENA_SET_OWENR, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + if !c.CanFight() { + return nil, errorcode.ErrorCodes.ErrPokemonNotEligible + } + c.Fightinfo.Mode = 0 //取消队列匹配 if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 0, 1) { c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID @@ -42,14 +46,28 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P if !c.CanFight() { return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon } + + if c.Info.UserID == c.GetSpace().Owner.UserID { + return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon + } //原子操作,修改擂台状态 if atomic.CompareAndSwapUint32(&c.GetSpace().Owner.Flag, 1, 2) { //成功发起擂台挑战后才修改我放状态 c.Fightinfo.Mode = info.BattleMode.SINGLE_MODE - c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER + c.Fightinfo.Status = info.BattleMode.FIGHT_ARENA _, err = fight.NewFight(c, c.GetSpace().ARENA_Player, func(foi *info.FightOverInfo) { //我方邀请擂主挑战,我方先手 + if foi.Reason != 0 && foi.WinnerId == c.GetInfo().UserID { //异常退出 + c.GetSpace().ARENA_Player = nil + c.GetSpace().Owner.Reset() + + c.GetSpace().Broadcast(c, 2419, &c.GetSpace().Owner) + c.SendPackCmd(2419, &c.GetSpace().Owner) + + } + //todo 擂主输了,那就直接让他放弃擂台 + }) ///开始对战,房主方以及被邀请方 if err <= 0 { //发起战斗成功 @@ -58,10 +76,10 @@ func (h Controller) ARENA_FIGHT_OWENR(data *fight.ARENA_FIGHT_OWENR, c *player.P //c.SendPackCmd(2419, &c.GetSpace().Owner) } else { //发起失败,改回1 - c.GetSpace().Owner.HostWins = 0 //连胜重置 - c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID - c.GetSpace().Owner.Nick = c.GetInfo().Nick - c.GetSpace().ARENA_Player = c //添加用户 + // c.GetSpace().Owner.HostWins = 0 //连胜重置 + // c.GetSpace().Owner.UserID = c.GetInfo().UserID //添加用户ID + // c.GetSpace().Owner.Nick = c.GetInfo().Nick + // c.GetSpace().ARENA_Player = c //添加用户 atomic.StoreUint32(&c.GetSpace().Owner.Flag, 1) } diff --git a/logic/controller/fight_pvp_king.go b/logic/controller/fight_pvp_king.go index ecc55d2be..63be84894 100644 --- a/logic/controller/fight_pvp_king.go +++ b/logic/controller/fight_pvp_king.go @@ -14,10 +14,10 @@ import ( func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { c.Fightinfo.Mode = info.BattleMode.PET_MELEE - c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER + c.Fightinfo.Status = info.BattleMode.PET_MELEE err = c.JoinFight(func(p common.PlayerI) bool { - fight.NewFight(p, c, func(foi *info.FightOverInfo) { + _, err = fight.NewFight(p, c, func(foi *info.FightOverInfo) { if foi.Reason == 0 { //我放获胜 if foi.WinnerId == c.GetInfo().UserID { @@ -29,6 +29,10 @@ func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Play } }) ///开始对战,房主方以及被邀请方 + if err > 0 { //说明有报错 + + return false + } return true }) @@ -37,7 +41,7 @@ func (h Controller) PET_MELEE(data *fight.StartPetWarInboundInfo, c *player.Play } func (h Controller) PET_King(data *fight.PetKingJoinInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - c.Fightinfo.Status = info.BattleStatus.FIGHT_WITH_PLAYER + c.Fightinfo.Status = info.BattleMode.PET_TOPLEVEL switch data.Type { case 5: diff --git a/logic/controller/fight_pvp_withplayer.go b/logic/controller/fight_pvp_withplayer.go index b44138e92..e0ccbf6d5 100644 --- a/logic/controller/fight_pvp_withplayer.go +++ b/logic/controller/fight_pvp_withplayer.go @@ -12,28 +12,32 @@ import ( // 接收战斗或者取消战斗的包 func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - - if !atomic.CompareAndSwapUint32(&c.Fightinfo.Status, 0, 1) { //邀请前提是自己没在战斗 + if c.GetSpace().Owner.UserID == c.Info.UserID { + return nil, errorcode.ErrorCodes.ErrSystemError + } + if c.GetSpace().Owner.UserID == data.UserID { + return nil, errorcode.ErrorCodes.ErrSystemError + } + if !atomic.CompareAndSwapUint32(&c.Fightinfo.Mode, 0, data.Mode) { //邀请前提是自己没在战斗 return nil, errorcode.ErrorCodes.ErrInBattle } - //c.Fightinfo.PlayerID = c.Info.UserID - c.Fightinfo.Mode = data.Mode - c.Fightinfo.Status = 1 - c.Fightinfo.Type = 0 + + //c.Fightinfo.Status = info.BattleMode.FIGHT_WITH_NPC + resp := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{ UserID: c.Info.UserID, Nick: c.Info.Nick, } for _, v := range c.HavePVPinfo { - if v.GetInfo().UserID == data.UserID { + if v.GetInfo().UserID == data.UserID && v.Getfightinfo().Mode == data.Mode { resp.Result = data.Flag // 检查邀请者的邀请是否有效(对方已取消邀请) if v.Getfightinfo().Status == 0 { resp.Result = 4 // 邀请已取消 v.SendPackCmd(2502, &resp) - atomic.StoreUint32(&c.Fightinfo.Status, 0) + atomic.StoreUint32(&c.Fightinfo.Mode, 0) return } @@ -47,7 +51,7 @@ func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInbou } else { resp.Result = 3 v.SendPackCmd(2502, &resp) - atomic.StoreUint32(&c.Fightinfo.Status, 0) + atomic.StoreUint32(&c.Fightinfo.Mode, 0) return } @@ -59,7 +63,15 @@ func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInbou // 邀请其他人进行战斗 func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - + if c.GetSpace().Owner.UserID == c.Info.UserID { + return nil, errorcode.ErrorCodes.ErrSystemError + } + if c.GetSpace().Owner.ChallengerID == c.Info.UserID { + return nil, errorcode.ErrorCodes.ErrSystemError + } + if c.GetSpace().Owner.UserID == data.UserID { + return nil, errorcode.ErrorCodes.ErrSystemError + } // c.Fightinfo.PlayerID = data.UserID c.Fightinfo.Mode = data.Mode c.Fightinfo.Status = 1 @@ -76,6 +88,6 @@ func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInf // 取消队列 func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCancelInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - atomic.StoreUint32(&c.Fightinfo.Status, 0) //设置状态为0 + atomic.StoreUint32(&c.Fightinfo.Mode, 0) //设置状态为0 return } diff --git a/logic/controller/pet.go b/logic/controller/pet.go index 2eb52380a..b471f4aa9 100644 --- a/logic/controller/pet.go +++ b/logic/controller/pet.go @@ -23,6 +23,7 @@ func (h *Controller) GetPetInfo( result = &pet.OutInfo{ PetInfo: pi, } + return result, 0 } } diff --git a/logic/service/fight/action.go b/logic/service/fight/action.go index 6295ffe4d..0f18ee451 100644 --- a/logic/service/fight/action.go +++ b/logic/service/fight/action.go @@ -1,17 +1,16 @@ 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" "log" - "github.com/gogf/gf/v2/util/gconv" "github.com/jinzhu/copier" "github.com/panjf2000/ants/v2" ) @@ -148,15 +147,20 @@ func (f *FightC) ReadyFight(c common.PlayerI) { // 3. 根据战斗类型判断是否满足战斗启动条件,满足则启动 switch f.Info.Status { - case info.BattleStatus.FIGHT_WITH_PLAYER: // PVP战斗:需双方都准备完成 + + case info.BattleMode.FIGHT_WITH_NPC: // NPC/野怪战斗:处理捕捉相关逻辑后启动 + //f.handleNPCFightSpecial(&fightStartInfo) + + if f.Opp.Player.(*player.AI_player).CanCapture > 0 { + f.Opp.CanCapture = f.Opp.Player.(*player.AI_player).CanCapture + fightStartInfo.Info2.Catchable = 1 //可以捕捉就置1 + } + f.startBattle(fightStartInfo) + default: // PVP战斗:需双方都准备完成 if f.checkBothPlayersReady(c) { f.startBattle(fightStartInfo) } - case info.BattleStatus.FIGHT_WITH_BOSS: // BOSS战:单方准备完成即可启动 - f.startBattle(fightStartInfo) - case info.BattleStatus.FIGHT_WITH_NPC: // NPC/野怪战斗:处理捕捉相关逻辑后启动 - f.handleNPCFightSpecial(&fightStartInfo) - f.startBattle(fightStartInfo) + } } @@ -185,28 +189,6 @@ func (f *FightC) checkBothPlayersReady(currentPlayer common.PlayerI) bool { return opponentInput.Finished } -// handleNPCFightSpecial 处理NPC战斗的特殊逻辑(如可捕捉标记) -func (f *FightC) handleNPCFightSpecial(startInfo *info.FightStartOutboundInfo) { - // 检查野怪是否可捕捉(根据宠物ID获取捕捉率) - if len(f.ReadyInfo.OpponentPetList) == 0 { - return - } - npcPetID := int(f.ReadyInfo.OpponentPetList[0].ID) - petCfg, ok := xmlres.PetMAP[npcPetID] - if !ok { - // log.Error(context.Background(), "NPC宠物配置不存在", "petID", npcPetID) - return - } - - catchRate := gconv.Int(petCfg.CatchRate) - if catchRate > 0 { - startInfo.Info2.Catchable = 1 // 标记为可捕捉 - // 标记AI对手允许被捕捉(类型断言确保安全) - f.Opp.CanCapture = true - - } -} - // startBattle 启动战斗核心逻辑:提交战斗循环任务并通知双方 func (f *FightC) startBattle(startInfo info.FightStartOutboundInfo) { diff --git a/logic/service/fight/info/battle.go b/logic/service/fight/info/battle.go index 7b2b447a3..b49c8e46c 100644 --- a/logic/service/fight/info/battle.go +++ b/logic/service/fight/info/battle.go @@ -24,18 +24,44 @@ import ( // 战斗模式 +// BattleMode 战斗模式(对应AS中的战斗类型常量) var BattleMode = enum.New[struct { - PET_MELEE uint32 `enum:"3"` //乱斗模式 - SINGLE_MODE uint32 `enum:"1"` // 单人模式 - MULTI_MODE uint32 `enum:"2"` // 多人模式 -}]() -var BattleStatus = enum.New[struct { - // 原ActionScript中的常量映射 - - FIGHT_WITH_NPC uint32 `enum:"3"` // 与NPC战斗 - FIGHT_WITH_BOSS uint32 `enum:"2"` // 与BOSS战斗 - FIGHT_WITH_PLAYER uint32 `enum:"1"` // 与玩家战斗(PVP) - Null uint32 `enum:"0"` + // 基础模式 + FIGHT_WITH_NPC uint32 `enum:"0"` //NPC模式 + SINGLE_MODE uint32 `enum:"1"` // 单人模式 + MULTI_MODE uint32 `enum:"2"` // 多人模式 + PET_MELEE uint32 `enum:"3"` // 宠物乱斗模式 + DARK_FIGHT uint32 `enum:"4"` // 暗黑战斗 + PET_TOPLEVEL uint32 `enum:"5"` // 宠物顶级战 + PET_ELEMENT_FIGHT uint32 `enum:"6"` // 宠物元素战斗(修正原拼写错误:ELMENT → ELEMENT) + FIGHT_DEMON_SPACE uint32 `enum:"7"` // 魔域战斗 + BATTLE_LAB uint32 `enum:"8"` // 战斗实验室 + LUCKY_BATTLE uint32 `enum:"9"` // 幸运战斗 + FIGHT_ARENA uint32 `enum:"10"` // 竞技场战斗 + CORE_FIGHT uint32 `enum:"11"` // 核心战斗 + IMAGE_FIGHT uint32 `enum:"12"` // 镜像战斗 + TOP_WAR_BEYOND uint32 `enum:"13"` // 巅峰之战·超越 + HIGHER_FIGHT uint32 `enum:"14"` // 高阶战斗 + GOLDEN_PALACE_FIGHT uint32 `enum:"15"` // 金殿战斗 + FANTASY_PET_MELEE uint32 `enum:"16"` // 梦幻宠物乱斗 + REFRACTIVE_MAGIC uint32 `enum:"17"` // 折射魔法战 + PET_MELEE_FIGHT_BOSS uint32 `enum:"18"` // 宠物乱斗·打BOSS + PET_TRY_FIGHT uint32 `enum:"19"` // 宠物试玩战斗 + PET_TOPLEVEL_NEW uint32 `enum:"20"` // 宠物顶级战(新版) + CATCH_LENNY_GAME uint32 `enum:"21"` // 捕捉莱尼小游戏 + PEAK_JIHAD_FREE uint32 `enum:"22"` // 巅峰圣战·自由战 + PEAK_JIHAD_3V3 uint32 `enum:"23"` // 巅峰圣战·3V3 + GOBLINKING_BATTLE uint32 `enum:"24"` // 哥布林王战斗 + DOOM_FIGHT uint32 `enum:"25"` // 末日战斗 + SHOW_ROUND uint32 `enum:"26"` // 展示回合(试玩/演示) + PEAK_JIHAD_6V6 uint32 `enum:"27"` // 巅峰圣战·6V6 + PEAK_JIHAD_FREE_PLAN uint32 `enum:"28"` // 巅峰圣战·自由战(计划版) + PEAK_JIHAD_6V6_JJ uint32 `enum:"29"` // 巅峰圣战·6V6(竞技版) + WIZARDKING_BIGFIGHT uint32 `enum:"30"` // 法老王大战 + QINGLONG_COMPLETE_FIGHT uint32 `enum:"83"` // 青龙全套战斗(修正原拼写:COMPLELETE → COMPLETE) + PEAK_JIHAD_FIGHT_WITH_FIGURE uint32 `enum:"87"` // 巅峰圣战·角色对战 + PEAK_JIHAD_BIG_MELEE uint32 `enum:"88"` // 巅峰圣战·大乱斗 + PEAK_JIHAD_LIMIT_AC uint32 `enum:"999"` // 巅峰圣战·限AC(账号类型限制) }]() // 玩家离线数据 diff --git a/logic/service/fight/info/info.go b/logic/service/fight/info/info.go index a6380b62f..c7ef60a65 100644 --- a/logic/service/fight/info/info.go +++ b/logic/service/fight/info/info.go @@ -45,11 +45,10 @@ type S2C_NOTE_HANDLE_FIGHT_INVITE struct { } type Fightinfo struct { ///PlayerID uint32 - // 战斗模式 1 = 1v1 2 = 6v6 3大乱斗 + // 战斗模式 1 = 1v1 2 = 6v6 3大乱斗 0 什么都不做 Mode uint32 - Type uint32 //战斗类型 + //Type uint32 //战斗类型 - //0无战斗,1PVP,2,BOOS,3PVE Status uint32 } diff --git a/logic/service/fight/input.go b/logic/service/fight/input.go index f6d813b0a..cb6b1541c 100644 --- a/logic/service/fight/input.go +++ b/logic/service/fight/input.go @@ -105,10 +105,6 @@ func (f *FightC) LoadPercent(c common.PlayerI, percent int32) { } func (f *FightC) initplayer(c common.PlayerI) (*input.Input, errorcode.ErrorCode) { - if len(c.GetInfo().PetList) == 0 { - return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon - - } if !c.CanFight() { return nil, errorcode.ErrorCodes.ErrNoEligiblePokemon @@ -221,12 +217,12 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err f.ReadyInfo.OurInfo, f.ReadyInfo.OurPetList = initfightready(f.Our) f.ReadyInfo.OpponentInfo, f.ReadyInfo.OpponentPetList = initfightready(f.Opp) + var loadtime time.Duration = 120 * time.Second + //说明是PVE + if f.Info.Mode == info.BattleMode.FIGHT_WITH_NPC { - switch f.Info.Mode { - case info.BattleStatus.FIGHT_WITH_PLAYER: - - default: f.Opp.Finished = true //PVE 默认boss数据直接加载完成 + loadtime = 60 * time.Second } f.Broadcast(func(ff *input.Input) { @@ -240,16 +236,7 @@ func NewFight(p1, p2 common.PlayerI, fn func(*info.FightOverInfo)) (*FightC, err }) - var t time.Duration - // 60秒后判断战斗是否开始 - switch f.Info.Mode { - case info.BattleMode.PET_MELEE: - t = 120 * time.Second - - default: - t = 60 * time.Second - } - cool.Cron.AfterFunc(t, func() { + cool.Cron.AfterFunc(loadtime, func() { if !f.Our.Finished || !f.Opp.Finished { //如果有任一没有加载完成 f.closefight = true //阻止继续添加action f.Reason = info.BattleOverReason.PlayerOVerTime diff --git a/logic/service/fight/input/input.go b/logic/service/fight/input/input.go index 134a3e554..60373c44b 100644 --- a/logic/service/fight/input/input.go +++ b/logic/service/fight/input/input.go @@ -18,7 +18,7 @@ type Input struct { AllPet []*info.BattlePetEntity Player common.PlayerI Opp *Input - CanCapture bool + CanCapture int Finished bool //是否加载完成 *info.AttackValue FightC common.FightI diff --git a/logic/service/fight/loop.go b/logic/service/fight/loop.go index 739e29000..f13c738b1 100644 --- a/logic/service/fight/loop.go +++ b/logic/service/fight/loop.go @@ -125,8 +125,7 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat } // AI自动技能 - if pid != 0 && (f.Info.Status == info.BattleStatus.FIGHT_WITH_BOSS || - f.Info.Status == info.BattleStatus.FIGHT_WITH_NPC) { + if pid != 0 && (f.Info.Status == info.BattleMode.FIGHT_WITH_NPC) { f.GetInputByAction(paction, true).GetAction(f.Our) //panic("AI自动技能") } @@ -223,7 +222,8 @@ func (f *FightC) handleItemAction(a *action.UseItemAction) { switch { case gconv.Int(item.Bonus) != 0: - if f.Opp.CanCapture { //可以捕捉 + if f.Opp.CanCapture > 0 { //可以捕捉 + f.Opp.CurrentPet.CatchRate = f.Opp.CanCapture ok, res := f.Our.Capture(f.Opp.CurrentPet, a.ItemID, -1) our := f.Our.Player.(*player.Player) if ok { diff --git a/logic/service/player/ai.go b/logic/service/player/ai.go index 48ba6f8b5..de5ad8074 100644 --- a/logic/service/player/ai.go +++ b/logic/service/player/ai.go @@ -8,8 +8,8 @@ import ( type AI_player struct { baseplayer - petinfo []model.PetInfo //精灵信息 - + petinfo []model.PetInfo //精灵信息 + CanCapture int } func (p *AI_player) Getfightinfo() info.Fightinfo { diff --git a/logic/service/player/done.go b/logic/service/player/done.go index 265b01cb6..9682793cc 100644 --- a/logic/service/player/done.go +++ b/logic/service/player/done.go @@ -24,7 +24,8 @@ func NewDone(P *Player) Done { // MAPID 地图ID // BOSSID 地图BOSSID // 注册胜利次数 -func (d *Done) SPT(mapid, bossid, count uint32, fn func()) *bus.Listener[*model.MilestoneEX] { +// 监听器返回奖励是否发送完成,完成就done +func (d *Done) SPT(mapid, bossid, count uint32, fn func() bool) *bus.Listener[*model.MilestoneEX] { return d.Topic.Sub(func(v *model.MilestoneEX) { if v.DoneType == model.MilestoneMode.BOSS && EqualBasicSlice(v.Args, []uint32{mapid, bossid}) && v.Count == count { @@ -34,8 +35,11 @@ func (d *Done) SPT(mapid, bossid, count uint32, fn func()) *bus.Listener[*model. return v1 == count }) if !ok { //说明没有触发过 - v.Results = append(v.Results, count) //把本次的记录添加 - fn() + + if fn() { + v.Results = append(v.Results, count) //把本次的记录添加 + } + } } diff --git a/logic/service/player/fight.go b/logic/service/player/fight.go index bd67be6bf..097d14a84 100644 --- a/logic/service/player/fight.go +++ b/logic/service/player/fight.go @@ -4,13 +4,20 @@ import ( "blazing/common/socket/errorcode" "blazing/logic/service/common" "blazing/logic/service/fight/info" + "sync/atomic" ) func (p *Player) JoinFight(fn func(p common.PlayerI) bool) errorcode.ErrorCode { + //加入队列前就开始判断一次 if !p.CanFight() { + return errorcode.ErrorCodes.ErrNoEligiblePokemon } + if p.GetSpace().Owner.UserID == p.Info.UserID { + return errorcode.ErrorCodes.ErrSystemError + } + //修复发包进入,如果此时是擂台主 p.GetSpace().User.Range(func(key uint32, v common.PlayerI) bool { @@ -24,7 +31,11 @@ func (p *Player) JoinFight(fn func(p common.PlayerI) bool) errorcode.ErrorCode { ttt := fn(v) if ttt { + atomic.StoreUint32(&v.(*Player).Fightinfo.Mode, 0) + atomic.StoreUint32(&p.Fightinfo.Mode, 0) + } + // lw = value return ttt //如果发起成功就停止,否则继续遍历队列 } diff --git a/logic/service/player/player.go b/logic/service/player/player.go index ef3ccdf52..a4703eba5 100644 --- a/logic/service/player/player.go +++ b/logic/service/player/player.go @@ -103,8 +103,6 @@ func (p *Player) Getfightinfo() info.Fightinfo { return p.Fightinfo } func (p *Player) QuitFight() { - //将战斗标记设置为0 这里的标记是 - atomic.StoreUint32(&p.Fightinfo.Status, 0) p.FightC = nil @@ -116,11 +114,14 @@ func (p *Player) GetSpace() *space.Space { // 0无战斗,1PVP,2,BOOS,3PVE func (p *Player) CanFight() bool { - // if atomic.CompareAndSwapUint32(&p.Fightinfo.Status, 0, staus) { //先判断是否竞态条件被挑战 + if len(p.Info.PetList) == 0 { + atomic.StoreUint32(&p.Fightinfo.Mode, 0) + return false - //成功,继续判断 + } if p.FightC != nil { + atomic.StoreUint32(&p.Fightinfo.Mode, 0) return false } @@ -133,7 +134,7 @@ func (p *Player) CanFight() bool { } } // 遍历完所有宠物,都没有血量大于0的,才不能战斗 - + atomic.StoreUint32(&p.Fightinfo.Mode, 0) return false // } diff --git a/modules/blazing/model/done.go b/modules/blazing/model/done.go index de5715eda..9993226a7 100644 --- a/modules/blazing/model/done.go +++ b/modules/blazing/model/done.go @@ -9,8 +9,9 @@ import ( type EnumMilestone int var MilestoneMode = enum.New[struct { - BOSS EnumMilestone //boss类 - ITEM EnumMilestone //物品类 + BOSS EnumMilestone //boss类 地图ID->BOSSID + ITEM EnumMilestone //物品类 物品ID 使用精灵 + Fight EnumMilestone //挑战类 对战模式->对战类型->1是赢,0是总局数 }]() // 里程碑数据结构,与DoneEvent对应,记录单条里程碑的详细信息 @@ -29,7 +30,7 @@ type Milestone struct { *cool.Model PlayerID uint64 `gorm:"not null;index:idx_milestone_by_player_id;comment:'所属玩家ID'" json:"player_id"` DoneType EnumMilestone `gorm:"not null;comment:'里程碑类型'" json:"done_type"` - Args string `gorm:"type:jsonb;not null;comment:'里程碑ID'" json:"args"` + Args string `gorm:"type:text;not null;comment:'里程碑ID'" json:"args"` // 注:不单独设置"里程碑ID",通过 PlayerID + DoneType + IDs 组合唯一标识一个里程碑(更灵活) Results string `gorm:"type:jsonb;not null;comment:'里程碑参数'" json:"results"` Count uint32 `gorm:"not null;comment:'里程碑完成次数'" json:"count"` @@ -38,7 +39,7 @@ type Milestone struct { // MilestoneEX 里程碑扩展结构体,用于业务层解析后的数据操作 type MilestoneEX struct { Milestone - Args []uint32 `json:"args"` // 解析后的里程碑详细数据 + Args []uint32 // 解析后的里程碑详细数据 Results []uint32 `json:"results"` // 解析后的里程碑详细数据 } diff --git a/modules/blazing/service/done.go b/modules/blazing/service/done.go index 55e37ae92..0b1607ee9 100644 --- a/modules/blazing/service/done.go +++ b/modules/blazing/service/done.go @@ -3,6 +3,9 @@ package service import ( "blazing/cool" "blazing/modules/blazing/model" + "strings" + + "github.com/gogf/gf/v2/util/gconv" ) type DoneService struct { @@ -10,15 +13,27 @@ type DoneService struct { } func (s *DoneService) Exec(data model.EnumMilestone, id []uint32, fn func(*model.MilestoneEX) bool) { - - m := s.GModel(s.Model).Where("done_type", data).Where("args", id) - var tt model.MilestoneEX + arss := strings.Join(gconv.Strings(id), "-") + m := s.GModel(s.Model).Where("done_type", data).Where("args", arss) + var tt *model.MilestoneEX m.Scan(&tt) - ook := fn(&tt) + if tt == nil { + tt = &model.MilestoneEX{ + Milestone: model.Milestone{ + DoneType: data, + Args: strings.Join(gconv.Strings(id), "-"), + Count: 1, + }, + } + } + + tt.Args = id + ook := fn(tt) if !ook { //不需要保存 return } tt.PlayerID = uint64(s.userid) + tt.Milestone.Args = strings.Join(gconv.Strings(id), "-") _, err := m.Save(tt) if err != nil {