From a86782b1ea365e71cee63e1f76222d55c5e6cdbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Fri, 14 Nov 2025 23:09:16 +0800 Subject: [PATCH] =?UTF-8?q?```text=20refactor(fight):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E6=88=98=E6=96=97=E5=87=86=E5=A4=87=E9=80=BB=E8=BE=91=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=88=98=E6=96=97=E5=90=AF=E5=8A=A8=E6=B5=81?= =?UTF-8?q?=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 ReadyFight 方法拆分为多个职责清晰的子方法: - buildFightStartInfo: 构建战斗初始信息 - checkBothPlayersReady: 检查PVP双方是否就绪 - handleNPCFightSpecial: 处理NPC战斗特殊逻辑(如可捕捉标记) - startBattle: 统一启动战斗流程 同时修复部分逻辑顺序问题,增强代码可读性和扩展性。 feat(fight): 新增精灵王挑战协议支持 增加 StartPetWarInboundInfo 结构体用于接收精灵王挑战请求, 为后续实现相关功能提供基础。 fix(effect): 修正多个技能效果数值引用错误 - effect_37: 技能威力计算使用正确参数索引 - effect_50: 固定减伤比例调整为除以2 - effect_65: 正确比较技能分类类型 - effect_68: 致死保护改为锁定剩余1点生命值 - effect_77: 回复目标由敌方改为己方 - effect_93: 固定伤害值直接取参数 refactor(effect): 移除冗余效果类文件 删除 effect_133.go 和 effect_90.go 文件,其功能已被统一条件伤害和倍率系统取代; 移除 effect_74.go、effect_75.go 中重复的状态随机施加逻辑。 refactor(effect): 更新能力操作枚举命名一致性 重命名 AbilityOpType 枚举项名称,去除前缀,提升语义清晰度: - AbilityOpStealStrengthen → StealStrengthen - AbilityOpReverse → Reverse - AbilityOpBounceWeaken → BounceWeaken chore(fight): 完善 BattlePetEntity 属性初始化逻辑 在创建 BattlePetEntity 时即设置 PType,避免后续多次查询 PetMAP; 移除 Type() 方法中的冗余配置查找逻辑。 fix(skill): 确保必中技能不参与命中率计算 在 AttackTimeC 方法中添加 return 防止必中技能继续执行命中率公式计算。 refactor(fight): 调整战斗回合结束逻辑 进入新回合时允许玩家更换精灵,并提前跳出循环防止多余处理。 style(effect): 更正拼写及变量命名风格 修改 BaseSataus.Switch 方法签名中的参数命名; 更正 Effect58 中 can 字段首字母大写; --- logic/controller/fight.go | 205 ------------------ logic/controller/fight_base.go | 72 ++++++ logic/controller/fight_boss.go | 114 ++++++++++ logic/controller/fight_pvp_king.go | 16 ++ logic/controller/fight_pvp_withplayer.go | 41 ++++ logic/service/fight/action.go | 122 +++++++---- logic/service/fight/cmd.go | 6 +- logic/service/fight/effect/effect_37.go | 2 +- logic/service/fight/effect/effect_49.go | 4 +- logic/service/fight/effect/effect_50.go | 2 +- logic/service/fight/effect/effect_52.go | 48 ++++ .../effect/{effect_90.go => effect_53_90.go} | 2 +- logic/service/fight/effect/effect_58.go | 6 +- logic/service/fight/effect/effect_65.go | 2 +- logic/service/fight/effect/effect_68.go | 16 +- logic/service/fight/effect/effect_71.go | 31 ++- logic/service/fight/effect/effect_73.go | 2 +- logic/service/fight/effect/effect_74.go | 58 ----- logic/service/fight/effect/effect_74_75.go | 81 +++++++ logic/service/fight/effect/effect_75.go | 58 ----- logic/service/fight/effect/effect_77.go | 2 +- logic/service/fight/effect/effect_93.go | 2 +- ...o => effect_EffectConditionalAddDamage.go} | 66 +++--- logic/service/fight/effect/effect_prop.go | 10 +- logic/service/fight/effect/effect_status.go | 6 +- logic/service/fight/fightc.go | 6 +- logic/service/fight/info/BattlePetEntity.go | 25 +-- logic/service/fight/info/BattleSkillEntity.go | 1 + logic/service/fight/info/battle.go | 6 +- logic/service/fight/info/info.go | 1 + logic/service/fight/input/fight.go | 143 ------------ logic/service/fight/input/prop.go | 173 +++++++++++++++ logic/service/player/fight.go | 142 ++++++------ logic/service/space/space.go | 13 -- 34 files changed, 808 insertions(+), 676 deletions(-) delete mode 100644 logic/controller/fight.go create mode 100644 logic/controller/fight_base.go create mode 100644 logic/controller/fight_boss.go create mode 100644 logic/controller/fight_pvp_king.go create mode 100644 logic/controller/fight_pvp_withplayer.go create mode 100644 logic/service/fight/effect/effect_52.go rename logic/service/fight/effect/{effect_90.go => effect_53_90.go} (85%) delete mode 100644 logic/service/fight/effect/effect_74.go create mode 100644 logic/service/fight/effect/effect_74_75.go delete mode 100644 logic/service/fight/effect/effect_75.go rename logic/service/fight/effect/{effect_133.go => effect_EffectConditionalAddDamage.go} (57%) create mode 100644 logic/service/fight/input/prop.go diff --git a/logic/controller/fight.go b/logic/controller/fight.go deleted file mode 100644 index 72e1c00b3..000000000 --- a/logic/controller/fight.go +++ /dev/null @@ -1,205 +0,0 @@ -package controller - -import ( - "blazing/common/data/xmlres" - "blazing/common/socket/errorcode" - - "blazing/logic/service/fight" - "blazing/logic/service/fight/info" - "blazing/logic/service/player" - "blazing/modules/blazing/model" - - "github.com/gogf/gf/v2/util/gconv" -) - -// 挑战地图boss -func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if !c.CanFight() { - return nil, errorcode.ErrorCodes.ErrPokemonNotEligible - } - - var petid int - var mo *model.PetInfo - moinfo := &model.PlayerInfo{} - - if c.Info.MapID == 515 && data.BossId == 0 { //说明是新手,随机生成 - switch c.Info.PetList[0].ID { - - case 1: - petid = 4 - - case 7: - petid = 1 - - case 4: - petid = 7 - } - - mo = c.GenPetInfo( - int(petid), 24, //24个体 - -1, - 0, //野怪没特性 - 0, - 50) - moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName - moinfo.PetList = append(moinfo.PetList, *mo) - } else { - - mdata, ok := xmlres.MonsterMap[int(c.Info.MapID)] - if !ok { - return nil, errorcode.ErrorCodes.ErrPokemonNotExists - } - if len(mdata.Bosses) == 0 { - return nil, errorcode.ErrorCodes.ErrPokemonNotExists - } - for _, bc := range mdata.Bosses { - if bc.Id == nil { - return nil, errorcode.ErrorCodes.ErrPokemonNotExists - - } - if uint32(*bc.Id) == data.BossId { - for _, bm := range bc.BossMon { - mo = c.GenPetInfo( - gconv.Int(bm.MonID), 24, //24个体 - -1, - 0, //野怪没特性 - 0, - bm.Lv) - - // mo.Level = uint32(bm.Lv) - mo.CalculatePetPane() - mo.Hp = uint32(bm.Hp) - mo.MaxHp = uint32(bm.Hp) - moinfo.PetList = append(moinfo.PetList, *mo) - - } - moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName - break - } - - } - - } - - ai := player.NewAI_player(moinfo) - fight.NewFight(info.BattleMode.MULTI_MODE, info.BattleStatus.FIGHT_WITH_BOSS, c, ai) - - return nil, -1 -} - -// 战斗野怪 -func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if !c.CanFight() { - return nil, errorcode.ErrorCodes.ErrPokemonNotEligible - } - refpet := c.OgreInfo.Data[data.Number] - if refpet.Id == 0 { - - return nil, errorcode.ErrorCodes.ErrPokemonNotExists - } - mo := c.GenPetInfo( - int(refpet.Id), -1, - -1, - 0, //野怪没特性 - int(refpet.Shiny), - int(refpet.Lv)) - - moinfo := &model.PlayerInfo{} - moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName - moinfo.PetList = append(moinfo.PetList, *mo) - ai := player.NewAI_player(moinfo) - - fight.NewFight(info.BattleMode.MULTI_MODE, info.BattleStatus.FIGHT_WITH_NPC, c, ai) - - return nil, -1 -} - -// 准备战斗 -func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - - c.FightC.ReadyFight(c) - return nil, -1 -} - -// 接收战斗或者取消战斗的包 -func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - - if ok, p1 := c.AgreeBattle(data.UserID, data.Flag, data.Mode); ok { - fight.NewFight(data.Mode, info.BattleStatus.FIGHT_WITH_PLAYER, c, p1) ///开始对战,房主方以及被邀请方 - } - return nil, -1 -} - -// 邀请其他人进行战斗 -func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if !c.CanFight() { - return nil, errorcode.ErrorCodes.ErrPokemonNotEligible - } - - c.InvitePlayerToBattle(&info.PVPinfo{PlayerID: data.UserID, Mode: data.Mode}) - - return nil, 0 -} - -// 取消和他人战斗 -func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCancelInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - c.CancelBattle() - - return nil, 0 -} - -// 使用技能包 -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)) - } - - return nil, 0 -} - -// 战斗逃跑 -func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { - if c.FightC == nil { - - return nil, 0 - } - if !c.FightC.CanEscape() { - - return nil, 0 - } - c.FightC.Over(c, info.BattleOverReason.PlayerEscape) - return nil, 0 -} - -// 切换精灵 -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) - } - return nil, -1 -} - -// 切换精灵 -func (h Controller) Capture(data *fight.CatchMonsterInboundInfo, c *player.Player) (result *info.CatchMonsterOutboundInfo, err errorcode.ErrorCode) { - - 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)) - } - - 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) - } - - return nil, -1 -} diff --git a/logic/controller/fight_base.go b/logic/controller/fight_base.go new file mode 100644 index 000000000..af5b35315 --- /dev/null +++ b/logic/controller/fight_base.go @@ -0,0 +1,72 @@ +package controller + +import ( + "blazing/common/socket/errorcode" + + "blazing/logic/service/fight" + "blazing/logic/service/fight/info" + "blazing/logic/service/player" +) + +// 准备战斗 +func (h Controller) OnReadyToFight(data *fight.ReadyToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + + 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)) + } + + return nil, 0 +} + +// 战斗逃跑 +func (h Controller) Escape(data *fight.EscapeFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + if c.FightC == nil { + + return nil, 0 + } + if !c.FightC.CanEscape() { + + return nil, 0 + } + c.FightC.Over(c, info.BattleOverReason.PlayerEscape) + return nil, 0 +} + +// 切换精灵 +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) + } + return nil, -1 +} + +// 切换精灵 +func (h Controller) Capture(data *fight.CatchMonsterInboundInfo, c *player.Player) (result *info.CatchMonsterOutboundInfo, err errorcode.ErrorCode) { + + 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)) + } + + 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) + } + + return nil, -1 +} diff --git a/logic/controller/fight_boss.go b/logic/controller/fight_boss.go new file mode 100644 index 000000000..b1624a5df --- /dev/null +++ b/logic/controller/fight_boss.go @@ -0,0 +1,114 @@ +package controller + +import ( + "blazing/common/data/xmlres" + "blazing/common/socket/errorcode" + "blazing/logic/service/fight" + "blazing/logic/service/fight/info" + "blazing/logic/service/player" + "blazing/modules/blazing/model" + + "github.com/gogf/gf/v2/util/gconv" +) + +// 挑战地图boss +func (h Controller) PlayerFightBoss(data *fight.ChallengeBossInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + if !c.CanFight() { + return nil, errorcode.ErrorCodes.ErrPokemonNotEligible + } + + var petid int + var mo *model.PetInfo + moinfo := &model.PlayerInfo{} + + if c.Info.MapID == 515 && data.BossId == 0 { //说明是新手,随机生成 + switch c.Info.PetList[0].ID { + + case 1: + petid = 4 + + case 7: + petid = 1 + + case 4: + petid = 7 + } + + mo = c.GenPetInfo( + int(petid), 24, //24个体 + -1, + 0, //野怪没特性 + 0, + 50) + moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName + moinfo.PetList = append(moinfo.PetList, *mo) + } else { + + mdata, ok := xmlres.MonsterMap[int(c.Info.MapID)] + if !ok { + return nil, errorcode.ErrorCodes.ErrPokemonNotExists + } + if len(mdata.Bosses) == 0 { + return nil, errorcode.ErrorCodes.ErrPokemonNotExists + } + for _, bc := range mdata.Bosses { + if bc.Id == nil { + return nil, errorcode.ErrorCodes.ErrPokemonNotExists + + } + if uint32(*bc.Id) == data.BossId { + for _, bm := range bc.BossMon { + mo = c.GenPetInfo( + gconv.Int(bm.MonID), 24, //24个体 + -1, + 0, //野怪没特性 + 0, + bm.Lv) + + // mo.Level = uint32(bm.Lv) + mo.CalculatePetPane() + mo.Hp = uint32(bm.Hp) + mo.MaxHp = uint32(bm.Hp) + moinfo.PetList = append(moinfo.PetList, *mo) + + } + moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName + break + } + + } + + } + + ai := player.NewAI_player(moinfo) + fight.NewFight(info.BattleMode.MULTI_MODE, info.BattleStatus.FIGHT_WITH_BOSS, c, ai) + + return nil, -1 +} + +// 战斗野怪 +func (h Controller) OnPlayerFightNpcMonster(data *fight.FightNpcMonsterInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + if !c.CanFight() { + return nil, errorcode.ErrorCodes.ErrPokemonNotEligible + } + refpet := c.OgreInfo.Data[data.Number] + if refpet.Id == 0 { + + return nil, errorcode.ErrorCodes.ErrPokemonNotExists + } + mo := c.GenPetInfo( + int(refpet.Id), -1, + -1, + 0, //野怪没特性 + int(refpet.Shiny), + int(refpet.Lv)) + + moinfo := &model.PlayerInfo{} + moinfo.Nick = xmlres.PetMAP[int(mo.ID)].DefName + moinfo.PetList = append(moinfo.PetList, *mo) + ai := player.NewAI_player(moinfo) + + fight.NewFight(info.BattleMode.MULTI_MODE, info.BattleStatus.FIGHT_WITH_NPC, c, ai) + + return nil, -1 +} diff --git a/logic/controller/fight_pvp_king.go b/logic/controller/fight_pvp_king.go new file mode 100644 index 000000000..03fce6a60 --- /dev/null +++ b/logic/controller/fight_pvp_king.go @@ -0,0 +1,16 @@ +package controller + +import ( + "blazing/common/socket/errorcode" + "blazing/logic/service/fight" + "blazing/logic/service/player" +) + +//精灵王之战 + +func (h Controller) PvpKingFight(data *fight.StartPetWarInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + if !c.CanFight() { + return nil, errorcode.ErrorCodes.ErrPokemonNotEligible + } + return +} diff --git a/logic/controller/fight_pvp_withplayer.go b/logic/controller/fight_pvp_withplayer.go new file mode 100644 index 000000000..bf847cde6 --- /dev/null +++ b/logic/controller/fight_pvp_withplayer.go @@ -0,0 +1,41 @@ +package controller + +import ( + "blazing/common/socket/errorcode" + "blazing/logic/service/fight" + "blazing/logic/service/fight/info" + "blazing/logic/service/player" +) + +// 接收战斗或者取消战斗的包 +func (h Controller) OnPlayerHandleFightInvite(data *fight.HandleFightInviteInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + + if ok, p1 := c.AgreeBattle(data.UserID, data.Flag, data.Mode); ok { + fight.NewFight(data.Mode, info.BattleStatus.FIGHT_WITH_PLAYER, p1, c) ///开始对战,房主方以及被邀请方 + } + return nil, -1 +} + +// 邀请其他人进行战斗 +func (h Controller) OnPlayerInviteOtherFight(data *fight.InviteToFightInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + if !c.CanFight() { + return nil, errorcode.ErrorCodes.ErrPokemonNotEligible + } + + //进入邀请,以及确认对战模式 + + c.PVPinfo = &info.PVPinfo{PlayerID: data.UserID, + Mode: data.Mode, + Status: info.BattleStatus.FIGHT_WITH_PLAYER} + + c.InvitePlayerToBattle() + + return nil, 0 +} + +// 取消和他人战斗 +func (h Controller) OnPlayerCanceledOtherInviteFight(data *fight.InviteFightCancelInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { + c.CancelBattle() + + return nil, 0 +} diff --git a/logic/service/fight/action.go b/logic/service/fight/action.go index 56ae2975b..9940b70b8 100644 --- a/logic/service/fight/action.go +++ b/logic/service/fight/action.go @@ -9,6 +9,7 @@ import ( "blazing/logic/service/fight/input" "blazing/logic/service/player" "context" + "log" "github.com/gogf/gf/v2/util/gconv" "github.com/jinzhu/copier" @@ -136,57 +137,92 @@ func (f *FightC) UseItem(c common.PlayerI, cacthid, itemid uint32) { f.actionChan <- &action.UseItemAction{BaseAction: action.NewBaseAction(c.GetInfo().UserID), ItemID: itemid, CacthTime: cacthid} } -// 战斗准备 +// ReadyFight 处理玩家战斗准备逻辑,当满足条件时启动战斗循环 func (f *FightC) ReadyFight(c common.PlayerI) { + // 1. 构建战斗开始信息(整理双方初始宠物信息) + fightStartInfo := f.buildFightStartInfo() - rett := info.FightStartOutboundInfo{} + // 2. 标记当前玩家已准备完成 + input := f.GetInputByPlayer(c, false) + input.Finished = true - 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 + // 3. 根据战斗类型判断是否满足战斗启动条件,满足则启动 switch f.Info.Status { - case info.BattleStatus.FIGHT_WITH_PLAYER: //pvp - - if f.GetInputByPlayer(c, true).Finished { - rrsult() + case info.BattleStatus.FIGHT_WITH_PLAYER: // PVP战斗:需双方都准备完成 + if f.checkBothPlayersReady(c) { + f.startBattle(fightStartInfo) } - 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() + case info.BattleStatus.FIGHT_WITH_BOSS: // BOSS战:单方准备完成即可启动 + f.startBattle(fightStartInfo) + case info.BattleStatus.FIGHT_WITH_NPC: // NPC/野怪战斗:处理捕捉相关逻辑后启动 + f.handleNPCFightSpecial(&fightStartInfo) + f.startBattle(fightStartInfo) } } +// buildFightStartInfo 构建战斗开始时需要发送给双方的信息 +func (f *FightC) buildFightStartInfo() info.FightStartOutboundInfo { + var startInfo info.FightStartOutboundInfo + + // 复制双方初始宠物信息(取列表第一个宠物) + if len(f.Info.OurPetList) > 0 { + _ = copier.Copy(&startInfo.Info1, &f.Info.OurPetList[0]) + startInfo.Info1.UserID = f.Info.OurInfo.UserID + } + if len(f.Info.OpponentPetList) > 0 { + _ = copier.Copy(&startInfo.Info2, &f.Info.OpponentPetList[0]) + startInfo.Info2.UserID = f.Info.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 +} + +// handleNPCFightSpecial 处理NPC战斗的特殊逻辑(如可捕捉标记) +func (f *FightC) handleNPCFightSpecial(startInfo *info.FightStartOutboundInfo) { + // 检查野怪是否可捕捉(根据宠物ID获取捕捉率) + if len(f.Info.OpponentPetList) == 0 { + return + } + npcPetID := int(f.Info.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对手允许被捕捉(类型断言确保安全) + if oppAI, ok := f.Opp.Player.(*player.AI_player); ok { + oppAI.CanCapture = true + } + } +} + +// startBattle 启动战斗核心逻辑:提交战斗循环任务并通知双方 +func (f *FightC) startBattle(startInfo info.FightStartOutboundInfo) { + // 提交战斗循环到战斗池(处理战斗池容量问题) + if err := Fightpool.Submit(f.battleLoop); err != nil { + log.Panic(context.Background(), "战斗循环提交失败", "error", err) + } + + // 通知双方玩家准备完成,即将开始战斗 + f.Our.Player.SendReadyToFightInfo(startInfo) + f.Opp.Player.SendReadyToFightInfo(startInfo) + + // 标记战斗已启动(原注释逻辑) + // f.running = true +} + var Fightpool *ants.Pool func init() { diff --git a/logic/service/fight/cmd.go b/logic/service/fight/cmd.go index c48427ad3..c761f6807 100644 --- a/logic/service/fight/cmd.go +++ b/logic/service/fight/cmd.go @@ -30,6 +30,11 @@ type EscapeFightInboundInfo struct { Head player.TomeeHeader `cmd:"2410" struc:"[0]pad"` } +// 精灵王 +type StartPetWarInboundInfo struct { + Head player.TomeeHeader `cmd:"2431" struc:"[0]pad"` +} + // HandleFightInviteInboundInfo 处理战斗邀请的入站消息 type HandleFightInviteInboundInfo struct { @@ -45,7 +50,6 @@ type InviteToFightInboundInfo struct { UserID uint32 `codec:"true"` // Mode 战斗类型 1 = 1v1 2 = 6v6 - Mode info.EnumBattleMode `codec:"true"` } type InviteFightCancelInboundInfo struct { diff --git a/logic/service/fight/effect/effect_37.go b/logic/service/fight/effect/effect_37.go index 5e2265609..801ff4d56 100644 --- a/logic/service/fight/effect/effect_37.go +++ b/logic/service/fight/effect/effect_37.go @@ -17,7 +17,7 @@ func (e *Effect37) Skill_Hit() bool { cmphp := e.GetInput().CurrentPet.GetMaxHP().Div(decimal.NewFromInt(int64(e.Args()[0]))) if e.GetInput().CurrentPet.GetHP().Cmp(cmphp) == -1 { - e.Ctx().SkillEntity.Power *= e.Args()[0] + e.Ctx().SkillEntity.Power *= e.Args()[1] } return true } diff --git a/logic/service/fight/effect/effect_49.go b/logic/service/fight/effect/effect_49.go index 648ed1e70..d13c65570 100644 --- a/logic/service/fight/effect/effect_49.go +++ b/logic/service/fight/effect/effect_49.go @@ -8,7 +8,7 @@ import ( "github.com/shopspring/decimal" ) -// "可完全抵挡n次攻击伤害 百分百减伤 ,后面还有锁伤 +// 可以抵挡n点伤害 // ---- Effect49 ---- type Effect49 struct { node.EffectNode @@ -37,9 +37,7 @@ func (e *Effect49) Damage_SUB_ex(t *info.DamageZone) bool { } func (e *Effect49) SetArgs(t *input.Input, a ...int) { - //e.CanStack(-1)//后续的不会顶掉这个效果 e.EffectNode.SetArgs(t, a...) - //e.Duration(-1) //次数类,无限回合 } diff --git a/logic/service/fight/effect/effect_50.go b/logic/service/fight/effect/effect_50.go index dcb0b533f..3fbe1d2d4 100644 --- a/logic/service/fight/effect/effect_50.go +++ b/logic/service/fight/effect/effect_50.go @@ -29,7 +29,7 @@ func (e *Effect50) Damage_DIV_ex(t *info.DamageZone) bool { //fmt.Println("Effect50_o", t.Damage) if t.Type == info.DamageType.Red { - t.Damage = t.Damage.Div(decimal.NewFromInt(int64(e.Args()[1]))) + t.Damage = t.Damage.Div(decimal.NewFromInt(2)) } //fmt.Println("Effect50_n", t.Damage) diff --git a/logic/service/fight/effect/effect_52.go b/logic/service/fight/effect/effect_52.go new file mode 100644 index 000000000..f6abcbc35 --- /dev/null +++ b/logic/service/fight/effect/effect_52.go @@ -0,0 +1,48 @@ +package effect + +import ( + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +/** + * n回合若本方先手攻击: 使得技能miss (但MustHit有效) + */ + +func init() { + t := &Effect52{ + EffectNode: node.EffectNode{}, + } + // t.Duration(-1) //设置成无限回合,到回合数就停止 + input.InitEffect(input.EffectType.Skill, 52, t) + +} + +type Effect52 struct { + node.EffectNode +} + +// 默认添加回合 +func (e *Effect52) SetArgs(t *input.Input, a ...int) { + + e.EffectNode.SetArgs(t, a...) + e.EffectNode.Duration(e.EffectNode.SideEffectArgs[0]) + +} + +func (e *Effect52) Skill_Hit_ex() bool { + + //fmt.Println(e.Ctx().SkillEntity) + if e.Ctx().SkillEntity == nil { + return true + } + + if !e.Input.FightC.IsFirst(e.Ctx().Our.Player) { + return true + } + if e.Ctx().SkillEntity.AttackTime == 1 { + e.Ctx().SkillEntity.AttackTime = 0 + } + + return true +} diff --git a/logic/service/fight/effect/effect_90.go b/logic/service/fight/effect/effect_53_90.go similarity index 85% rename from logic/service/fight/effect/effect_90.go rename to logic/service/fight/effect/effect_53_90.go index e8338c011..25fe29f3f 100644 --- a/logic/service/fight/effect/effect_90.go +++ b/logic/service/fight/effect/effect_53_90.go @@ -28,7 +28,7 @@ func (e *Effect90) Damage_Mul(t *info.DamageZone) bool { if t.Type == info.DamageType.Red { - e.Ctx().Our.DamageZone.Damage = e.Ctx().Our.DamageZone.Damage.Mul(decimal.NewFromInt(int64(e.SideEffectArgs[1]))) + t.Damage = t.Damage.Mul(decimal.NewFromInt(int64(e.SideEffectArgs[1]))) } diff --git a/logic/service/fight/effect/effect_58.go b/logic/service/fight/effect/effect_58.go index a72825c04..d52df36e9 100644 --- a/logic/service/fight/effect/effect_58.go +++ b/logic/service/fight/effect/effect_58.go @@ -18,14 +18,14 @@ func init() { type Effect58 struct { node.EffectNode - can bool + Can bool } func (e *Effect58) OnSkill() bool { if !e.Hit() { return true } - e.can = true + e.Can = true return true } @@ -34,7 +34,7 @@ func (e *Effect58) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool { if !e.Hit() { return true } - if !e.can { + if !e.Can { return true } //fmt.Println(e.Ctx().SkillEntity) diff --git a/logic/service/fight/effect/effect_65.go b/logic/service/fight/effect/effect_65.go index 37660b936..5f9ff5e27 100644 --- a/logic/service/fight/effect/effect_65.go +++ b/logic/service/fight/effect/effect_65.go @@ -26,7 +26,7 @@ func (e *Effect65) Skill_Hit() bool { return true } - if e.Ctx().SkillEntity.Category() != info.EnumCategory(e.Args()[1]) { + if info.EnumCategory(e.Ctx().SkillEntity.Move.Type) != info.EnumCategory(e.Args()[1]) { return true } //技能威力=【165-65*【当前体力百分比】】,任意体力百分比对应的威力浮动范围∈[-10,+10] diff --git a/logic/service/fight/effect/effect_68.go b/logic/service/fight/effect/effect_68.go index eb9cd450a..af8bf97e7 100644 --- a/logic/service/fight/effect/effect_68.go +++ b/logic/service/fight/effect/effect_68.go @@ -4,6 +4,8 @@ import ( "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "blazing/logic/service/fight/node" + + "github.com/shopspring/decimal" ) // 1回合内,受到致死攻击时则余下1点体力 @@ -13,7 +15,7 @@ type Effect68 struct { StatusID int } -func (e *Effect68) Skill_Use_ex() bool { +func (e *Effect68) Damage_Lock_ex(t *info.DamageZone) bool { if !e.Hit() { return true } @@ -26,19 +28,13 @@ func (e *Effect68) Skill_Use_ex() bool { //fmt.Println("Effect68_o", t.Damage) //伤害溢出 - if e.Ctx().Opp.DamageZone.Damage.Cmp(e.Ctx().Our.CurrentPet.GetHP()) == 1 { - e.Ctx().Our.CurrentPet.Info.Hp = 1 - + if t.Type == info.DamageType.Red && t.Damage.Cmp(e.Ctx().Our.CurrentPet.GetHP()) == 1 { + //e.Ctx().Our.CurrentPet.Info.Hp = 1 + t.Damage = e.Ctx().Our.CurrentPet.GetHP().Sub(decimal.NewFromInt(1)) } //fmt.Println("Effect68_n", t.Damage) return true } -func (e *Effect68) SetArgs(t *input.Input, a ...int) { - - e.EffectNode.SetArgs(t, a...) - e.EffectNode.Duration(e.EffectNode.SideEffectArgs[1]) - -} // ---- 注册所有效果 ---- func init() { diff --git a/logic/service/fight/effect/effect_71.go b/logic/service/fight/effect/effect_71.go index ac5c8f2fc..1de21177d 100644 --- a/logic/service/fight/effect/effect_71.go +++ b/logic/service/fight/effect/effect_71.go @@ -1,6 +1,7 @@ package effect import ( + "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" "blazing/logic/service/fight/node" @@ -18,7 +19,7 @@ type Effect71 struct { func init() { - input.InitEffect(input.EffectType.Skill, 59, &Effect71{}) + input.InitEffect(input.EffectType.Skill, 71, &Effect71{}) } func (e *Effect71) SetArgs(t *input.Input, a ...int) { @@ -50,13 +51,29 @@ func (e *Effect71) Switch(in *input.Input, at info.AttackValue, oldpet *info.Bat if in != e.Ctx().Our { return true } + t := &Effect71_sub{} + t.Duration(2) + t.ID(e.ID() + int(input.EffectType.Sub)) + e.Ctx().Our.AddEffect(e.Ctx().Our, t) - t := input.Geteffect(input.EffectType.Skill, 58) - if t != nil { - e.SetArgs(e.Ctx().Our, 2) - e.Ctx().Our.AddEffect(e.Ctx().Our, e) - - } e.Alive(false) return true } + +type Effect71_sub struct { + node.EffectNode +} + +func (e *Effect71_sub) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool { + + //fmt.Println(e.Ctx().SkillEntity) + if e.Ctx().SkillEntity == nil { + return true + } + if e.Ctx().SkillEntity.Category() == info.Category.STATUS { + return true + } + e.Ctx().SkillEntity.CritRate = 16 + + return true +} diff --git a/logic/service/fight/effect/effect_73.go b/logic/service/fight/effect/effect_73.go index f9f861c6d..9faab8953 100644 --- a/logic/service/fight/effect/effect_73.go +++ b/logic/service/fight/effect/effect_73.go @@ -43,7 +43,7 @@ func (e *Effect73) Skill_Use_ex() bool { e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ Type: info.DamageType.Fixed, - Damage: e.Ctx().Opp.DamageZone.Damage.Div(decimal.NewFromInt(2)), + Damage: e.Ctx().Opp.DamageZone.Damage.Mul(decimal.NewFromInt(2)), }) return true diff --git a/logic/service/fight/effect/effect_74.go b/logic/service/fight/effect/effect_74.go deleted file mode 100644 index 0e223dc7c..000000000 --- a/logic/service/fight/effect/effect_74.go +++ /dev/null @@ -1,58 +0,0 @@ -package effect - -import ( - "blazing/logic/service/fight/info" - "blazing/logic/service/fight/input" - "blazing/logic/service/fight/node" -) - -/** - * 10%中毒、10%烧伤、10%冻伤(剩下70%无效果) - */ -type Effect74 struct { - node.EffectNode -} - -func init() { - ret := &Effect74{} - - input.InitEffect(input.EffectType.Skill, 74, ret) - -} - -// 命中之后 -func (e *Effect74) OnSkill() bool { - if !e.Hit() { - return true - } - Status := info.PetStatus.NULL - - // 生成0-99的随机数(共100种可能) - switch t := e.Input.FightC.GetRand().Int31n(100); { - case t < 10: // 0-9(10个数,占10%) - Status = info.PetStatus.Poisoned - case t < 20: // 10-19(10个数,占10%) - // 触发睡眠效果 - Status = info.PetStatus.Burned - case t < 30: // 20-29(10个数,占10%) - // 触发害怕效果 - Status = info.PetStatus.Frozen - default: // 30-99(70个数,占70%) - // 无效果 - - } - if Status == info.PetStatus.NULL { - return true - } - // 获取状态效果 - eff := input.Geteffect(input.EffectType.Status, int(Status)) - if eff == nil { - return true - } - duration := int(e.Input.FightC.GetRand().Int31n(2)) // 默认随机 2~3 回合 - duration++ - eff.Duration(duration) - eff.SetArgs(e.Ctx().Our) //输入参数是对方 - e.Ctx().Opp.AddEffect(e.Ctx().Our, eff) - return true -} diff --git a/logic/service/fight/effect/effect_74_75.go b/logic/service/fight/effect/effect_74_75.go new file mode 100644 index 000000000..a947fdac6 --- /dev/null +++ b/logic/service/fight/effect/effect_74_75.go @@ -0,0 +1,81 @@ +package effect + +import ( + "blazing/logic/service/fight/info" + "blazing/logic/service/fight/input" + "blazing/logic/service/fight/node" +) + +// 定义状态区间配置:包含概率上限(0-100)和对应的状态 +type statusRange struct { + upper int // 概率区间上限(例如10表示0-9区间) + status info.EnumPetStatus // 该区间触发的状态 +} + +// 通用随机状态效果结构体 +type EffectRandomStatus struct { + node.EffectNode + ranges []statusRange // 当前效果的状态概率配置 +} + +// 工厂函数:创建通用随机状态效果实例(接收状态配置) +func newEffectRandomStatus(ranges []statusRange) *EffectRandomStatus { + return &EffectRandomStatus{ + ranges: ranges, + } +} + +// 通用逻辑:命中后按概率随机触发状态 +func (e *EffectRandomStatus) OnSkill() bool { + if !e.Hit() { + return true + } + + // 生成0-99的随机数(100种可能) + randVal := int(e.Input.FightC.GetRand().Int31n(100)) + targetStatus := info.PetStatus.NULL + + // 根据配置匹配对应的状态 + for _, r := range e.ranges { + if randVal < r.upper { + targetStatus = r.status + break + } + } + + // 未匹配到任何状态(概率外情况) + if targetStatus == info.PetStatus.NULL { + return true + } + + // 获取状态效果并设置参数 + eff := input.Geteffect(input.EffectType.Status, int(targetStatus)) + if eff == nil { + return true + } + + // 持续时间:随机2-3回合(与原逻辑一致) + duration := int(e.Input.FightC.GetRand().Int31n(2)) + 2 + eff.Duration(duration) + eff.SetArgs(e.Ctx().Our) + e.Ctx().Opp.AddEffect(e.Ctx().Our, eff) + + return true +} + +// 初始化:注册Effect74和Effect75(通过不同配置区分) +func init() { + // Effect74:10%中毒、10%烧伤、10%冻伤(70%无效果) + input.InitEffect(input.EffectType.Skill, 74, newEffectRandomStatus([]statusRange{ + {upper: 10, status: info.PetStatus.Poisoned}, // 0-9:中毒 + {upper: 20, status: info.PetStatus.Burned}, // 10-19:烧伤 + {upper: 30, status: info.PetStatus.Frozen}, // 20-29:冻伤 + })) + + // Effect75:10%麻痹、10%睡眠、10%害怕(70%无效果) + input.InitEffect(input.EffectType.Skill, 75, newEffectRandomStatus([]statusRange{ + {upper: 10, status: info.PetStatus.Paralysis}, // 0-9:麻痹 + {upper: 20, status: info.PetStatus.Sleep}, // 10-19:睡眠 + {upper: 30, status: info.PetStatus.Fear}, // 20-29:害怕 + })) +} diff --git a/logic/service/fight/effect/effect_75.go b/logic/service/fight/effect/effect_75.go deleted file mode 100644 index 19c2659d1..000000000 --- a/logic/service/fight/effect/effect_75.go +++ /dev/null @@ -1,58 +0,0 @@ -package effect - -import ( - "blazing/logic/service/fight/info" - "blazing/logic/service/fight/input" - "blazing/logic/service/fight/node" -) - -/** - * 10%麻痹、10%睡眠、10%害怕(剩下70%无效果) - */ -type Effect75 struct { - node.EffectNode -} - -func init() { - ret := &Effect75{} - - input.InitEffect(input.EffectType.Skill, 75, ret) - -} - -// 命中之后 -func (e *Effect75) OnSkill() bool { - if !e.Hit() { - return true - } - Status := info.PetStatus.NULL - - // 生成0-99的随机数(共100种可能) - switch t := e.Input.FightC.GetRand().Int31n(100); { - case t < 10: // 0-9(10个数,占10%) - Status = info.PetStatus.Paralysis - case t < 20: // 10-19(10个数,占10%) - // 触发睡眠效果 - Status = info.PetStatus.Sleep - case t < 30: // 20-29(10个数,占10%) - // 触发害怕效果 - Status = info.PetStatus.Fear - default: // 30-99(70个数,占70%) - // 无效果 - - } - if Status == info.PetStatus.NULL { - return true - } - // 获取状态效果 - eff := input.Geteffect(input.EffectType.Status, int(Status)) - if eff == nil { - return true - } - duration := int(e.Input.FightC.GetRand().Int31n(2)) // 默认随机 2~3 回合 - duration++ - eff.Duration(duration) - eff.SetArgs(e.Ctx().Our) //输入参数是对方 - e.Ctx().Opp.AddEffect(e.Ctx().Our, eff) - return true -} diff --git a/logic/service/fight/effect/effect_77.go b/logic/service/fight/effect/effect_77.go index 1f9a52932..960dfe08c 100644 --- a/logic/service/fight/effect/effect_77.go +++ b/logic/service/fight/effect/effect_77.go @@ -34,6 +34,6 @@ func (e *Effect77) OnSkill() bool { if !e.Hit() { return true } - e.Ctx().Opp.Heal(e.Ctx().Our, &action.SelectSkillAction{}, decimal.NewFromInt(int64(e.Args()[0]))) + e.Ctx().Our.Heal(e.Ctx().Our, &action.SelectSkillAction{}, decimal.NewFromInt(int64(e.Args()[1]))) return true } diff --git a/logic/service/fight/effect/effect_93.go b/logic/service/fight/effect/effect_93.go index f49cd8f1b..5803cad55 100644 --- a/logic/service/fight/effect/effect_93.go +++ b/logic/service/fight/effect/effect_93.go @@ -34,7 +34,7 @@ func (e *Effect93) OnSkill() bool { } e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ Type: info.DamageType.Fixed, - Damage: decimal.NewFromInt(int64(e.Ctx().Opp.CurrentPet.Info.Hp)).Div(decimal.NewFromInt(int64(e.SideEffectArgs[0]))), + Damage: decimal.NewFromInt(int64(e.SideEffectArgs[0])), }) return true } diff --git a/logic/service/fight/effect/effect_133.go b/logic/service/fight/effect/effect_EffectConditionalAddDamage.go similarity index 57% rename from logic/service/fight/effect/effect_133.go rename to logic/service/fight/effect/effect_EffectConditionalAddDamage.go index ff093809c..a5ea6c1c0 100644 --- a/logic/service/fight/effect/effect_133.go +++ b/logic/service/fight/effect/effect_EffectConditionalAddDamage.go @@ -11,19 +11,20 @@ import ( // ----------------------------------------------------------- // 通用效果:满足特定条件时,附加n点固定伤害 // ----------------------------------------------------------- + // 条件回调函数:判断对方是否满足触发条件(返回true则触发伤害) type conditionFunc func(e *EffectConditionalAddDamage) bool +// 全局映射:关联效果ID与对应的条件函数 +var conditionMap = make(map[int]conditionFunc) + type EffectConditionalAddDamage struct { - node.EffectNode - condition conditionFunc // 差异化:判断触发条件的函数 + node.EffectNode // 仅继承基础效果节点,不嵌入条件函数 } -// 工厂函数:创建"条件附加伤害"效果实例,传入条件判断函数 -func newEffectConditionalAddDamage(cond conditionFunc) *EffectConditionalAddDamage { - return &EffectConditionalAddDamage{ - condition: cond, - } +// 工厂函数:创建"条件附加伤害"效果实例(无需传入函数) +func newEffectConditionalAddDamage() *EffectConditionalAddDamage { + return &EffectConditionalAddDamage{} } // 初始化:批量注册所有"条件附加伤害"类效果 @@ -33,19 +34,20 @@ func init() { // 批量注册:绑定效果ID与对应的条件函数(可扩展) func registerConditionalAddDamageEffects() { - // 效果ID与条件函数的映射: - // 133: 对方烧伤时附加伤害;134:对方冻伤时附加伤害;135:对方是X属性时附加伤害;136:对方处于异常状态时附加伤害 + // 效果ID与条件函数的映射 effectMap := map[int]conditionFunc{ - 133: conditionIsBurned, // Effect133:对方烧伤时 - 141: conditionIsFrozen, // 新增:对方冻伤时 - 135: conditionIsAbnormal, // 新增:对方是X属性时(示例,需根据实际属性枚举调整) - 130: conditionIsTypeX, // 新增:对方处于任意异常状态时 - 167: conditionprop, //167 若对手处于能力下降状态则附加n点伤害 + 130: conditionIsTypeX, // 对方是X属性时 + 133: conditionIsBurned, // 对方烧伤时 + 141: conditionIsFrozen, // 对方冻伤时 + + 162: conditionIsAbnormal, // 对方处于任意异常状态时 + 167: conditionPropDown, // 对方处于能力下降状态时 } - // 循环注册所有效果 + // 注册到全局映射,并初始化效果 for effectID, cond := range effectMap { - input.InitEffect(input.EffectType.Skill, effectID, newEffectConditionalAddDamage(cond)) + conditionMap[effectID] = cond + input.InitEffect(input.EffectType.Skill, effectID, newEffectConditionalAddDamage()) } } @@ -58,12 +60,18 @@ func (e *EffectConditionalAddDamage) OnSkill() bool { return true } - // 2. 检查是否满足触发条件(调用差异化的条件函数) - if !e.condition(e) { + // 2. 获取当前效果ID对应的条件函数 + cond, ok := conditionMap[e.ID()-int(input.EffectType.Skill)] + if !ok { + return true // 无对应条件函数,不触发 + } + + // 3. 检查是否满足触发条件 + if !cond(e) { return true } - // 3. 附加固定伤害(伤害值从SideEffectArgs[0]获取,与原Effect133一致) + // 4. 附加固定伤害(从SideEffectArgs[0]获取伤害值) damageValue := decimal.NewFromInt(int64(e.SideEffectArgs[0])) e.Ctx().Opp.Damage(e.Ctx().Our, &info.DamageZone{ Type: info.DamageType.Fixed, @@ -77,37 +85,33 @@ func (e *EffectConditionalAddDamage) OnSkill() bool { // 差异化条件函数的实现(对应不同效果的判断逻辑) // ----------------------------------------------------------- -// conditionIsBurned:判断对方是否处于烧伤状态(对应原Effect133) +// conditionIsBurned:判断对方是否处于烧伤状态 func conditionIsBurned(e *EffectConditionalAddDamage) bool { return e.Ctx().Opp.StatEffect_Exist(info.PetStatus.Burned) } -// conditionIsFrozen:判断对方是否处于冻伤状态(新增效果) +// conditionIsFrozen:判断对方是否处于冻伤状态 func conditionIsFrozen(e *EffectConditionalAddDamage) bool { return e.Ctx().Opp.StatEffect_Exist(info.PetStatus.Frozen) } -// conditionIsTypeX:判断对方是否为X属性(示例,需根据实际属性枚举调整) -// 假设属性枚举为info.PetType,X属性为info.PetType.X +// conditionIsTypeX:判断对方是否为X属性(需根据实际属性枚举调整) func conditionIsTypeX(e *EffectConditionalAddDamage) bool { - return e.Ctx().Opp.CurrentPet.Gender == e.Args()[0] + // 示例:假设Args[0]为目标属性值,判断对方属性是否匹配 + return e.Ctx().Opp.CurrentPet.PType == e.Args()[0] } -// conditionIsAbnormal:判断对方是否处于任意异常状态(新增效果) -// 假设异常状态包含烧伤、冻伤、麻痹等,通过检查是否存在任意异常状态实现 +// conditionIsAbnormal:判断对方是否处于任意异常状态 func conditionIsAbnormal(e *EffectConditionalAddDamage) bool { return e.Ctx().Opp.StatEffect_Exist_all() - } -func conditionprop(e *EffectConditionalAddDamage) bool { +// conditionPropDown:判断对方是否处于能力下降状态 +func conditionPropDown(e *EffectConditionalAddDamage) bool { for _, v := range e.Ctx().Opp.Prop { - if v < 0 { return true } - } return false - } diff --git a/logic/service/fight/effect/effect_prop.go b/logic/service/fight/effect/effect_prop.go index 10f0234b6..47b23d020 100644 --- a/logic/service/fight/effect/effect_prop.go +++ b/logic/service/fight/effect/effect_prop.go @@ -57,11 +57,11 @@ func init() { level int8 opType info.EnumAbilityOpType }{ - {3, false, -1, info.AbilityOpType.RESET}, // 解除自身能力下降状态 - {33, true, 1, info.AbilityOpType.RESET}, // 消除对手能力提升状态 - {63, false, 0, info.AbilityOpType.AbilityOpBounceWeaken}, // 将能力下降反馈给对手 - {85, false, -1, info.AbilityOpType.AbilityOpStealStrengthen}, // 将对手提升效果转移到自己 - {143, true, 1, info.AbilityOpType.AbilityOpReverse}, // 反转对手能力提升为下降 + {3, false, -1, info.AbilityOpType.RESET}, // 解除自身能力下降状态 + {33, true, 1, info.AbilityOpType.RESET}, // 消除对手能力提升状态 + {63, false, 0, info.AbilityOpType.BounceWeaken}, // 将能力下降反馈给对手 + {85, false, -1, info.AbilityOpType.StealStrengthen}, // 将对手提升效果转移到自己 + {143, true, 1, info.AbilityOpType.Reverse}, // 反转对手能力提升为下降 } for _, e := range effects { diff --git a/logic/service/fight/effect/effect_status.go b/logic/service/fight/effect/effect_status.go index ad8eb7213..16f644262 100644 --- a/logic/service/fight/effect/effect_status.go +++ b/logic/service/fight/effect/effect_status.go @@ -16,10 +16,10 @@ type BaseSataus struct { } // /重写切换事件 -func (e *BaseSataus) Switch(*input.Input, info.AttackValue, *info.BattlePetEntity) bool { +func (e *BaseSataus) Switch(in *input.Input, _ info.AttackValue, _ *info.BattlePetEntity) bool { //状态如果是我方切换,那么就消除掉状态效果 - if e.Input == e.Ctx().Our { + if in == e.Ctx().Our { //下场,执行消回合效果 // e.ctx.Our.CancelAll() ///我放下场 @@ -91,7 +91,7 @@ type DrainedHP struct { func (e *DrainedHP) Skill_Hit_Pre(a, b *action.SelectSkillAction) bool { - if gconv.Int(e.Input.CurrentPet.Type) == 1 { + if gconv.Int(e.Ctx().Our.CurrentPet.Type) == 1 { return true } e.DrainHP.Skill_Hit_Pre(a, b) //先调用父类扣血 diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index 5521aead6..b8b40bd7f 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -45,9 +45,9 @@ func (f *FightC) processSkillAttack(attacker, defender *input.Input, a *info.Ski //技能miss+效果生效 这里属于强制改命中效果,但是正常来说,技能miss掉后效果也应该失效 //技能失效+效果失效 // 记录技能信息 + attacker.SkillID = uint32(a.ID) //获取技能ID + if attacker.AttackTime > 0 { //如果命中 - if attacker.AttackTime > 0 { //如果命中 - attacker.SkillID = uint32(a.ID) //获取技能ID attacker.CalculateCrit(defender, a) //暴击计算 attacker.IsCritical = a.Crit @@ -323,6 +323,8 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { f.closefight = true // break } + attacker.CanChange = true + break } if defender.CurrentPet.Info.Hp == 0 { diff --git a/logic/service/fight/info/BattlePetEntity.go b/logic/service/fight/info/BattlePetEntity.go index 2858dd921..2c37220b2 100644 --- a/logic/service/fight/info/BattlePetEntity.go +++ b/logic/service/fight/info/BattlePetEntity.go @@ -49,6 +49,15 @@ func CreateBattlePetEntity(info *model.PetInfo, rand *rand.Rand) *BattlePetEntit } + ret.PType = 8 + for _, v := range xmlres.PetMAP { + if v.ID == int(ret.Info.ID) { + ret.PType = v.Type + + break + } + } + return ret } @@ -89,22 +98,6 @@ func (u *BattlePetEntity) GetMaxHP() decimal.Decimal { } func (u *BattlePetEntity) Type() *element.ElementCombination { // 1. 遍历宠物配置,查找对应元素类型ID - found := false - if u.PType == 0 { - - for _, v := range xmlres.PetMAP { - if v.ID == int(u.Info.ID) { - u.PType = v.Type - - found = true - break - } - } - } - // 2. 未找到配置时,默认使用"普通(8)" - if !found { - u.PType = 8 - } // 3. 从预加载的组合池中获取实例(无需创建,直接读取) combo, err := element.Calculator.GetCombination(u.PType) diff --git a/logic/service/fight/info/BattleSkillEntity.go b/logic/service/fight/info/BattleSkillEntity.go index 560c589ca..406de024a 100644 --- a/logic/service/fight/info/BattleSkillEntity.go +++ b/logic/service/fight/info/BattleSkillEntity.go @@ -154,6 +154,7 @@ func (s *SkillEntity) AttackTimeC(level int) { if s.MustHit != 0 { s.AttackTime = 2 + return } a := int64(s.GetAccuracy(level)) diff --git a/logic/service/fight/info/battle.go b/logic/service/fight/info/battle.go index 07d2c358b..3dc8dd96d 100644 --- a/logic/service/fight/info/battle.go +++ b/logic/service/fight/info/battle.go @@ -96,8 +96,8 @@ var AbilityOpType = enum.New[struct { COPY EnumAbilityOpType `enum:"3"` // 复制强化/弱化 RESET EnumAbilityOpType `enum:"4"` // 能力重置 - AbilityOpStealStrengthen EnumAbilityOpType `enum:"6"` // 吸取强化 - AbilityOpReverse EnumAbilityOpType `enum:"7"` // 反转强化/弱化 + StealStrengthen EnumAbilityOpType `enum:"6"` // 吸取强化 + Reverse EnumAbilityOpType `enum:"7"` // 反转强化/弱化 - AbilityOpBounceWeaken EnumAbilityOpType `enum:"10"` // 弹弱(反弹弱化效果) + BounceWeaken EnumAbilityOpType `enum:"10"` // 弹弱(反弹弱化效果) }]() diff --git a/logic/service/fight/info/info.go b/logic/service/fight/info/info.go index 0cc96a92c..89a4e0053 100644 --- a/logic/service/fight/info/info.go +++ b/logic/service/fight/info/info.go @@ -46,6 +46,7 @@ type S2C_NOTE_HANDLE_FIGHT_INVITE struct { type PVPinfo struct { PlayerID uint32 Mode EnumBattleMode + Status EnumBattleMode } // FightPetInfo 战斗精灵信息结构体,FightPetInfo类 diff --git a/logic/service/fight/input/fight.go b/logic/service/fight/input/fight.go index 8828eb37d..c60ad3014 100644 --- a/logic/service/fight/input/fight.go +++ b/logic/service/fight/input/fight.go @@ -6,7 +6,6 @@ import ( "blazing/common/utils" "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" - "fmt" "math/rand" "github.com/shopspring/decimal" @@ -186,148 +185,6 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) { } -// 攻击,防御,特供,特防,速度,命中 -// 施加方,类型,等级,操作类别,是否成功 -func (our *Input) SetProp(in *Input, prop, level int8, ptype info.EnumAbilityOpType) (ret bool) { - //in.Our = our //设置属性的角色是我方 - canuseskill := our.Exec(func(t Effect) bool { //这个是能否使用技能 - //结算状态 - return t.Prop_Befer(in, prop, level, ptype) //返回本身结算,如果false,说明不能使用技能了 - - }) - if !canuseskill { - - return false - } - var newValue int8 - abfunc := func(prop, level int8, ptype info.EnumAbilityOpType) (ret bool) { - - switch ptype { - case info.AbilityOpType.ADD: - newValue = utils.Min(our.AttackValue.Prop[prop]+int8(level), 6) - - if newValue > our.AttackValue.Prop[prop] { - fmt.Println("属性值会增加") - return true - } else { - fmt.Println("属性值不会增加") - return false - } - - case info.AbilityOpType.SUB: - newValue = utils.Max(our.AttackValue.Prop[prop]+int8(level), -6) - if newValue < our.AttackValue.Prop[prop] { - fmt.Println("属性值会减少") - return true - } else { - fmt.Println("属性值不会增加") - return false - } - - case info.AbilityOpType.RESET: - if level > 0 && our.AttackValue.Prop[prop] > 0 { //消强 - newValue = 0 - return true - - } - if level < 0 && our.AttackValue.Prop[prop] < 0 { //解弱 - newValue = 0 - return true - } - - } - - return false - } - switch ptype { - - case info.AbilityOpType.AbilityOpStealStrengthen: - - temp := our.Opp.AttackValue.Prop[prop] - - if temp <= 0 { //对方没有强化 - return false - } - if abfunc(prop, temp, info.AbilityOpType.ADD) { //把对面的强化等级添加自身 - our.AttackValue.Prop[prop] = newValue //成功把 强化更新 - our.Opp.SetProp(our, prop, 1, info.AbilityOpType.RESET) //吸取后消除对面强化 - - } - - case info.AbilityOpType.AbilityOpReverse: - temp := our.AttackValue.Prop[prop] - - switch { - - case level > 0: //反转强化 - if temp <= 0 { //没有强化 - return false - } - if abfunc(prop, temp*2, info.AbilityOpType.SUB) { - our.AttackValue.Prop[prop] = newValue - if temp == -our.AttackValue.Prop[prop] { //成功到对应弱化 - - return true - } else { - return true - - } - - } else { //自身免弱或已到-6 - - return false - } - default: //反转弱化 - if temp >= 0 { //没有弱化 - return false - } - if abfunc(prop, -temp*2, info.AbilityOpType.ADD) { - our.AttackValue.Prop[prop] = newValue - if temp == -our.AttackValue.Prop[prop] { //成功到对应强化 - - return true - } else { - return true - - } - - } else { //自身免弱或已到-6 - - return false - } - } - - case info.AbilityOpType.AbilityOpBounceWeaken: - temp := our.AttackValue.Prop[prop] - if temp >= 0 { //没有弱化 - return false - } - - if our.Opp.SetProp(our, prop, temp, info.AbilityOpType.SUB) { - - our.SetProp(our, prop, -1, info.AbilityOpType.RESET) //消除自身弱化 - return true - } - case info.AbilityOpType.COPY: - temp := our.Opp.AttackValue.Prop[prop] - if temp >= 0 { - our.SetProp(our, prop, temp, info.AbilityOpType.ADD) - } else { - our.SetProp(our, prop, -temp, info.AbilityOpType.SUB) - } - - default: //增加减少重置 - - if abfunc(prop, level, ptype) { - // 执行赋值 - our.AttackValue.Prop[prop] = newValue - return true - } - - } - - return false -} func (our *Input) GetAction(opp *Input) { // 获取己方当前宠物和对方当前宠物 selfPet := our.FightC.GetCurrPET(our.Player) diff --git a/logic/service/fight/input/prop.go b/logic/service/fight/input/prop.go new file mode 100644 index 000000000..cad811b54 --- /dev/null +++ b/logic/service/fight/input/prop.go @@ -0,0 +1,173 @@ +package input + +import ( + "blazing/common/utils" + "blazing/logic/service/fight/info" + "fmt" +) + +// SetProp 处理属性操作(提升/下降/消除/偷取等) +// our:当前执行操作的主体(操作发起方) +// target:输入源(操作的源头输入对象,可能是我方或对方) +// prop:属性类型 +// level:操作幅度(强化/弱化的程度) +// opType:操作类型(明确区分提升/下降/消除等) +func (our *Input) SetProp(target *Input, prop int8, level int8, opType info.EnumAbilityOpType) bool { + // 前置检查:输入源是否允许该操作(基于输入源的状态) + if !our.checkPreCondition(target, prop, level, opType) { + return false + } + + // 根据操作类型处理(明确区分不同操作的逻辑) + switch opType { + case info.AbilityOpType.ADD: // 能力提升(强化):仅正向增加,不处理负数 + return our.handleStrengthen(target, prop, level) + case info.AbilityOpType.SUB: // 能力下降(弱化):仅负向减少,不处理正数 + return our.handleWeaken(target, prop, level) + case info.AbilityOpType.RESET: // 能力消除(重置):清除强化或弱化,恢复0 + return our.handleReset(target, prop, level) + case info.AbilityOpType.StealStrengthen: // 偷取强化:从对方输入源偷取到自身 + return our.handleStealStrengthen(target, prop) + case info.AbilityOpType.Reverse: // 反转:强化转弱化,弱化转强化 + return our.handleReverse(target, prop, level) + case info.AbilityOpType.BounceWeaken: // 反弹弱化:将输入源的弱化反弹给对方 + return our.handleBounceWeaken(target, prop) + case info.AbilityOpType.COPY: // 复制:复制对方属性到输入源 + return our.handleCopy(target, prop) + default: + return false + } +} + +// checkPreCondition 检查输入源是否允许操作(基于输入源的状态) +func (our *Input) checkPreCondition(inputSource *Input, prop, level int8, opType info.EnumAbilityOpType) bool { + return our.Exec(func(e Effect) bool { + // 检查输入源是否允许该操作(e.Prop_Befer的参数是输入源) + return e.Prop_Befer(inputSource, prop, level, opType) + }) +} + +// ------------------------------ +// 1. 能力提升(强化):仅处理正向增加,上限6 +// ------------------------------ +func (our *Input) handleStrengthen(inputSource *Input, prop, level int8) bool { + if level <= 0 { + fmt.Printf("强化失败:幅度必须为正数(level=%d)\n", level) + return false + } + current := inputSource.AttackValue.Prop[prop] + newVal := utils.Min(current+level, 6) // 强化上限6 + if newVal == current { + fmt.Printf("属性[%d]强化无变化(当前%d,已达上限6)\n", prop, current) + return false + } + inputSource.AttackValue.Prop[prop] = newVal + fmt.Printf("属性[%d]强化:%d → %d(+%d)\n", prop, current, newVal, level) + return true +} + +// ------------------------------ +// 2. 能力下降(弱化):仅处理负向减少,下限-6 +// ------------------------------ +func (our *Input) handleWeaken(inputSource *Input, prop, level int8) bool { + if level >= 0 { + fmt.Printf("弱化失败:幅度必须为负数(level=%d)\n", level) + return false + } + current := inputSource.AttackValue.Prop[prop] + newVal := utils.Max(current+level, -6) // 弱化下限-6 + if newVal == current { + fmt.Printf("属性[%d]弱化无变化(当前%d,已达下限-6)\n", prop, current) + return false + } + inputSource.AttackValue.Prop[prop] = newVal + fmt.Printf("属性[%d]弱化:%d → %d(%d)\n", prop, current, newVal, level) + return true +} + +// ------------------------------ +// 3. 能力消除(重置):仅清除对应状态(强化/弱化),不影响正常状态 +// ------------------------------ +func (our *Input) handleReset(inputSource *Input, prop, level int8) bool { + current := inputSource.AttackValue.Prop[prop] + // 规则:level>0清除强化(current>0),level<0清除弱化(current<0),不处理正常状态(current=0) + if (level > 0 && current <= 0) || (level < 0 && current >= 0) { + fmt.Printf("重置失败:属性[%d]当前状态(%d)与操作(level=%d)不匹配\n", prop, current, level) + return false + } + inputSource.AttackValue.Prop[prop] = 0 + fmt.Printf("属性[%d]重置:%d → 0(level=%d)\n", prop, current, level) + return true +} + +// ------------------------------ +// 4. 偷取强化:从对方输入源偷取强化到自身输入源 +// ------------------------------ +func (our *Input) handleStealStrengthen(inputSource *Input, prop int8) bool { + // 对方输入源的强化值(必须为正) + oppProp := our.Opp.AttackValue.Prop[prop] + if oppProp <= 0 { + fmt.Printf("偷取失败:对方属性[%d]无强化(%d)\n", prop, oppProp) + return false + } + // 自身输入源增加偷取的强化值 + if !our.handleStrengthen(inputSource, prop, oppProp) { + return false + } + // 清除对方输入源的强化(用level>0重置) + our.Opp.SetProp(our.Opp, prop, 1, info.AbilityOpType.RESET) + return true +} + +// ------------------------------ +// 5. 反转:输入源的强化转弱化,或弱化转强化 +// ------------------------------ +func (our *Input) handleReverse(inputSource *Input, prop, level int8) bool { + current := inputSource.AttackValue.Prop[prop] + switch { + case level > 0 && current > 0: // 强化转弱化(幅度为当前强化值的2倍) + // 例:当前+2 → 弱化-4(level>0指定强化转弱化) + return our.handleWeaken(inputSource, prop, -current*2) + case level < 0 && current < 0: // 弱化转强化(幅度为当前弱化值的2倍) + // 例:当前-2 → 强化+4(level<0指定弱化转强化) + return our.handleStrengthen(inputSource, prop, -current*2) + default: + fmt.Printf("反转失败:当前值(%d)与操作方向(level=%d)不匹配\n", current, level) + return false + } +} + +// ------------------------------ +// 6. 反弹弱化:将输入源的弱化反弹给对方,同时清除输入源的弱化 +// ------------------------------ +func (our *Input) handleBounceWeaken(inputSource *Input, prop int8) bool { + // 输入源的弱化值(必须为负) + currentWeak := inputSource.AttackValue.Prop[prop] + if currentWeak >= 0 { + fmt.Printf("反弹失败:输入源属性[%d]无弱化(%d)\n", prop, currentWeak) + return false + } + // 反弹给对方:对方输入源承受相同弱化(用弱化操作) + if !our.Opp.SetProp(our.Opp, prop, currentWeak, info.AbilityOpType.SUB) { + return false + } + // 清除输入源的弱化(用level<0重置) + return our.handleReset(inputSource, prop, -1) +} + +// ------------------------------ +// 7. 复制:将对方属性复制到输入源(强化/弱化均复制) +// ------------------------------ +func (our *Input) handleCopy(inputSource *Input, prop int8) bool { + oppProp := our.Opp.AttackValue.Prop[prop] + if oppProp == 0 { + fmt.Printf("复制无变化:对方属性[%d]为0\n", prop) + return true // 无变化也算成功 + } + // 根据对方属性类型选择强化/弱化操作 + if oppProp > 0 { + return our.handleStrengthen(inputSource, prop, oppProp) // 复制强化 + } else { + return our.handleWeaken(inputSource, prop, oppProp) // 复制弱化(oppProp是负数) + } +} diff --git a/logic/service/player/fight.go b/logic/service/player/fight.go index fd44749a5..1fca5a0d5 100644 --- a/logic/service/player/fight.go +++ b/logic/service/player/fight.go @@ -3,14 +3,16 @@ package player import ( "blazing/logic/service/common" "blazing/logic/service/fight/info" + "blazing/logic/service/space" ) // 邀请玩家加入战斗 邀请者,被邀请者,邀请模式 -func (lw *Player) InvitePlayerToBattle(pinfo *info.PVPinfo) { - lw.PVPinfo = pinfo - Mainplayer.Range(func(key uint32, value *Player) bool { +func (lw *Player) InvitePlayerToBattle() { + pinfo := lw.PVPinfo + space.GetSpace(lw.Info.MapID).User.IterCb(func(key uint32, v common.PlayerI) { - if key == uint32(pinfo.PlayerID) { + value := v.(*Player) + if key == uint32(pinfo.PlayerID) { //说明这里是针对玩家邀请的 value.HavePVPinfo = append([]*Player{lw}, value.HavePVPinfo...) t1 := NewTomeeHeader(2501, value.Info.UserID) @@ -20,10 +22,9 @@ func (lw *Player) InvitePlayerToBattle(pinfo *info.PVPinfo) { Mode: pinfo.Mode, } value.SendPack(t1.Pack(&t)) - return false + return } - return true }) } @@ -31,24 +32,6 @@ func (lw *Player) InvitePlayerToBattle(pinfo *info.PVPinfo) { // 取消对战邀请 func (lw *Player) CancelBattle() { - if lw.PVPinfo == nil { - return - } - Mainplayer.Range(func(key uint32, value *Player) bool { - - if key == uint32(lw.PVPinfo.PlayerID) { - for idx, v := range value.HavePVPinfo { - if v != nil && v.GetInfo().UserID == lw.PVPinfo.PlayerID { - value.HavePVPinfo = append(value.HavePVPinfo[:idx], value.HavePVPinfo[idx+1:]...) - } - } - - return false - } - - return true - }) - lw.PVPinfo = nil } @@ -59,51 +42,80 @@ func (p *Player) SendLoadPercent(b info.LoadPercentOutboundInfo) { } // 同意对战 +// AgreeBattle 处理战斗邀请响应(同意/拒绝) +// 参数: +// +// userid:邀请者ID +// flag:0-拒绝,1-同意 +// mode:战斗模式 +// +// 返回: +// +// bool:是否成功(仅同意且符合条件时为true) +// common.PlayerI:对应的邀请者玩家(成功时有效) func (lw *Player) AgreeBattle(userid, flag uint32, mode info.EnumBattleMode) (bool, common.PlayerI) { + // 处理完毕后清空收到的邀请列表(原defer逻辑保留) + defer func() { + lw.HavePVPinfo = make([]*Player, 0) + }() - defer func(p *Player) { - p.HavePVPinfo = make([]*Player, 0) - - }(lw) //删除对方的邀请信息 - - for _, v := range lw.HavePVPinfo { - if v == nil || v.Info.UserID != userid || v.PVPinfo == nil { - continue - - } - t1 := NewTomeeHeader(2502, v.Info.UserID) - ret := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{ - UserID: lw.Info.UserID, - Nick: lw.Info.Nick, - } - - if flag == 0 { //拒绝对战 - - v.SendPack(t1.Pack(ret)) - return false, nil - } - if !lw.IsLogin { //玩家未登录 - ret.Result = 4 - v.SendPack(t1.Pack(ret)) - return false, nil - } - if v.Info.UserID == userid && v.PVPinfo.Mode == mode { //成功找到,同意对战 - if lw.CanFight() &&v.CanFight(){ - ret.Result = 1 - - v.SendPack(t1.Pack(ret)) - return true, v - - } else { - ret.Result = 3 - v.SendPack(t1.Pack(ret)) - return false, nil - } - + // 遍历收到的邀请,寻找目标邀请者 + var inviter *Player + for _, p := range lw.HavePVPinfo { + if p == nil || p.Info.UserID != userid { + continue // 跳过空指针或非目标邀请者 } + inviter = p + break // 找到目标后退出循环 + } + // 未找到对应的邀请者(如邀请已过期、不存在) + if inviter == nil { return false, nil + } - } //如果对方掉线 - return false, nil + // 构建响应消息(统一创建,避免重复代码) + respHeader := NewTomeeHeader(2502, inviter.Info.UserID) + resp := &info.S2C_NOTE_HANDLE_FIGHT_INVITE{ + UserID: lw.Info.UserID, + Nick: lw.Info.Nick, + } + + // 检查邀请者的邀请是否有效(对方已取消邀请) + if inviter.PVPinfo == nil { + resp.Result = 4 // 邀请已取消 + inviter.SendPack(respHeader.Pack(resp)) + return false, nil + } + + // 检查战斗模式是否匹配 + if inviter.PVPinfo.Mode != mode { + return false, nil // 模式不匹配,不响应(或根据业务加错误码) + } + + // 处理拒绝逻辑 + if flag == 0 { + resp.Result = 0 // 拒绝邀请 + inviter.SendPack(respHeader.Pack(resp)) + return false, nil + } + + // 处理同意逻辑:检查自身状态 + if !lw.IsLogin { + resp.Result = 4 // 玩家未登录(复用原错误码) + inviter.SendPack(respHeader.Pack(resp)) + return false, nil + } + + // 检查双方是否可战斗 + if !lw.CanFight() || !inviter.CanFight() { + resp.Result = 3 // 不可战斗(如正在战斗中) + inviter.SendPack(respHeader.Pack(resp)) + return false, nil + } + + // 所有条件满足,同意战斗 + resp.Result = 1 // 成功同意 + inviter.SendPack(respHeader.Pack(resp)) + return true, inviter } diff --git a/logic/service/space/space.go b/logic/service/space/space.go index b382a6f2b..347227929 100644 --- a/logic/service/space/space.go +++ b/logic/service/space/space.go @@ -27,19 +27,6 @@ func NewSpace() *Space { } } -// // Range 遍历所有玩家并执行回调函数 -// // 读操作使用RLock,遍历过程中不会阻塞其他读操作 -// func (m *Space) Range(f func(playerID uint32, player common.PlayerI) bool) { -// m.mu.RLock() -// defer m.mu.RUnlock() -// for id, player := range m.User { -// // 若回调返回false,则停止遍历 -// if !f(id, player) { -// break -// } -// } -// } - // 获取星球 func GetSpace(id uint32) *Space {