From 39dc79f7067a23c2a4b9f61507ec18a7e8b28f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=98=94=E5=BF=B5?= <1@72wo.cn> Date: Tue, 16 Dec 2025 02:50:10 +0800 Subject: [PATCH] =?UTF-8?q?```=20feat(xml):=20=E6=B7=BB=E5=8A=A0=E8=BF=9B?= =?UTF-8?q?=E5=8C=96=E9=85=8D=E7=BD=AE=E6=98=A0=E5=B0=84=E5=B9=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=94=99=E8=AF=AF=E7=A0=81=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 `common/data/xmlres/file.go` 中添加 EVOLVMAP 用于加载进化配置 - 更新多个控制器中的金币不足错误码,统一使用骄阳余额不足错误码 `ErrSunDouInsufficient10016` - 修改战斗逻辑中 AI 动作触发机制,并优化战斗流程 - 增加对融合材料合法性的校验 - 调整战斗动作通道缓冲区大小以提升并发处理能力 - 更新 XML 配置 --- common/data/xmlres/evllve.go | 22 +++++++++++++ common/data/xmlres/file.go | 4 +++ common/socket/errorcode/error.go | 4 +-- logic/controller/nono.go | 3 +- logic/controller/pet_elo.go | 1 + logic/controller/pet_fusion.go | 8 +++-- logic/controller/pet_skill.go | 2 +- logic/controller/room_buy.go | 2 +- logic/controller/user_action.go | 4 +-- logic/service/fight/action.go | 3 +- logic/service/fight/fightc.go | 32 ++++++++----------- logic/service/fight/input/fight.go | 8 ++--- logic/service/fight/loop.go | 29 +++++++++-------- .../service/pet_fusion_material_service.go | 4 +++ ...t.core.config.xml.EggsXMLInfo_xmlClass.bin | 10 ++++++ public/config/地图配置野怪.xml | 12 ++++++- .../进化仓.xml} | 0 17 files changed, 101 insertions(+), 47 deletions(-) create mode 100644 common/data/xmlres/evllve.go create mode 100644 logic/controller/pet_elo.go create mode 100644 public/config/72_com.robot.core.config.xml.EggsXMLInfo_xmlClass.bin rename public/{binaryData/199_com.robot.core.config.xml.EvolveXMLInfo_xmlcls.bin => config/进化仓.xml} (100%) diff --git a/common/data/xmlres/evllve.go b/common/data/xmlres/evllve.go new file mode 100644 index 000000000..e29c6d2c4 --- /dev/null +++ b/common/data/xmlres/evllve.go @@ -0,0 +1,22 @@ +package xmlres + +import "github.com/ECUST-XX/xml" + +// CondEvolves 根节点结构体 +type CondEvolves struct { + XMLName xml.Name `xml:"CondEvolves"` + Evolves []Evolve `xml:"Evolve"` +} + +// Evolve 进化配置结构体 +type Evolve struct { + ID int `xml:"ID,attr"` // 进化ID(属性) + Branches []Branch `xml:"Branch"` // 进化分支列表 +} + +// Branch 进化分支结构体 +type Branch struct { + MonTo int `xml:"MonTo,attr"` // 进化目标精灵ID + EvolvItem int `xml:"EvolvItem,attr,omitempty"` // 进化道具ID(可选) + EvolvItemCount int `xml:"EvolvItemCount,attr,omitempty"` // 进化道具数量(可选) +} diff --git a/common/data/xmlres/file.go b/common/data/xmlres/file.go index 7480ef3bd..96dd9dbe3 100644 --- a/common/data/xmlres/file.go +++ b/common/data/xmlres/file.go @@ -54,6 +54,7 @@ var ( SkillTypeMap map[int]SkillType RelationsMap map[int]Relation GoldProductMap = make(map[int]GoldProductItem, 0) + EVOLVMAP map[int]Evolve ) func Initfile() { @@ -70,7 +71,10 @@ func Initfile() { return m.ID }) + EVOLVMAP = utils.ToMap[Evolve, int](getXml[CondEvolves](path+"进化仓.xml").Evolves, func(m Evolve) int { + return m.ID + }) //TalkConfig = getXml[TalkRoot](path + "talk.xml") MonsterMap = utils.ToMap(getXml[MonsterRoot](path+"地图配置野怪.xml").Maps, func(m TMapConfig) int { diff --git a/common/socket/errorcode/error.go b/common/socket/errorcode/error.go index ac0f491d1..751d74b05 100644 --- a/common/socket/errorcode/error.go +++ b/common/socket/errorcode/error.go @@ -349,8 +349,8 @@ var ErrorCodes = enum.New[struct { ErrPokemonReleasing ErrorCode `enum:"103017"` // 你今天已经领了10次礼物了,不能再领了! ErrDailyGiftsLimit10 ErrorCode `enum:"15007"` - // 你的XIN豆余额不足 - ErrXinDouInsufficient10016 ErrorCode `enum:"10016"` + // 你的骄阳余额不足 + ErrSunDouInsufficient10016 ErrorCode `enum:"10016"` // 你还没有开通超能NoNo,无法使用相关服务。 ErrNoSuperNoNo ErrorCode `enum:"10041"` // 没有完成任务不能领奖品 diff --git a/logic/controller/nono.go b/logic/controller/nono.go index 46b8653be..811e8e6a1 100644 --- a/logic/controller/nono.go +++ b/logic/controller/nono.go @@ -8,7 +8,6 @@ import ( "github.com/jinzhu/copier" ) - func (h *Controller) NonoFollowOrHome(data *nono.NonoFollowOrHomeInInfo, c *player.Player) (result *nono.NonoFollowOutInfo, err errorcode.ErrorCode) { //这个时候player应该是空的 c.Info.NONO.Flag = data.Flag result = &nono.NonoFollowOutInfo{ @@ -56,7 +55,7 @@ func (h *Controller) PlayerPetCure(data *nono.PetCureInboundInfo, c *player.Play return result, errorcode.ErrorCodes.ErrChampionCannotHeal } if !c.UseCoins(50) { - return result, errorcode.ErrorCodes.ErrSystemBusy + return result, errorcode.ErrorCodes.ErrSunDouInsufficient10016 } for i := 0; i < len(c.Info.PetList); i++ { c.Info.PetList[i].Cure() diff --git a/logic/controller/pet_elo.go b/logic/controller/pet_elo.go new file mode 100644 index 000000000..b0b429f89 --- /dev/null +++ b/logic/controller/pet_elo.go @@ -0,0 +1 @@ +package controller diff --git a/logic/controller/pet_fusion.go b/logic/controller/pet_fusion.go index 35f014f8c..1cd91c7c4 100644 --- a/logic/controller/pet_fusion.go +++ b/logic/controller/pet_fusion.go @@ -13,7 +13,7 @@ import ( func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result *pet.PetFusionInfo, err errorcode.ErrorCode) { if !c.UseCoins(1000) { - return result, errorcode.ErrorCodes.ErrSystemBusy + return result, errorcode.ErrorCodes.ErrSunDouInsufficient10016 } // g.Dump(c.Info.PetList) @@ -49,10 +49,14 @@ func (h Controller) PetFusion(data *pet.C2S_PetFusion, c *player.Player) (result if resid == 0 { //todo失败降低等级 + + return &pet.PetFusionInfo{}, 0 + } + effect := int(service.PetFusionMaterialServiceIns.Data(data.Item1)) + if effect == 0 { return &pet.PetFusionInfo{}, 0 } - effect := int(service.PetFusionMaterialServiceIns.Data(data.Item1)) dv1 := alpacadecimal.NewFromInt(2).Div(alpacadecimal.NewFromInt(3)).Mul(alpacadecimal.NewFromInt(int64(Mcatchpetinfo.Dv))) dv2 := alpacadecimal.NewFromInt(1).Div(alpacadecimal.NewFromInt(3)).Mul(alpacadecimal.NewFromInt(int64(Auxpetinfo.Dv))) dv := dv1.Add(dv2).Add(alpacadecimal.NewFromInt(1)).IntPart() diff --git a/logic/controller/pet_skill.go b/logic/controller/pet_skill.go index 32bbab6f7..0b17609e6 100644 --- a/logic/controller/pet_skill.go +++ b/logic/controller/pet_skill.go @@ -12,7 +12,7 @@ import ( func (h Controller) SetPetSkill(data *pet.ChangeSkillInfo, c *player.Player) (result *pet.ChangeSkillOutInfo, err errorcode.ErrorCode) { if !c.UseCoins(100) { - return result, errorcode.ErrorCodes.ErrSystemBusy + return result, errorcode.ErrorCodes.ErrSunDouInsufficient10016 } c.Info.Coins -= 50 _, onpet, ok := c.FindPet(data.CatchTime) diff --git a/logic/controller/room_buy.go b/logic/controller/room_buy.go index f38f430fd..004d22337 100644 --- a/logic/controller/room_buy.go +++ b/logic/controller/room_buy.go @@ -15,7 +15,7 @@ func (h Controller) BUY_FITMENT(data *room.C2S_BUY_FITMENT, c *player.Player) (r used := xmlres.ItemsMAP[int(data.ID)].Price * int(data.Count) if !c.UseCoins(uint32(used)) { - return nil, errorcode.ErrorCodes.ErrPurchaseFailed + return nil, errorcode.ErrorCodes.ErrSunDouInsufficient10016 } c.Service.Room.Add(data.ID, data.Count) diff --git a/logic/controller/user_action.go b/logic/controller/user_action.go index f773f79f1..f6eb0a6e2 100644 --- a/logic/controller/user_action.go +++ b/logic/controller/user_action.go @@ -38,7 +38,7 @@ func (h Controller) Chat(data *user.ChatInboundInfo, c *player.Player) (result * func (h Controller) ChangePlayerColor(data *user.ChangeColorInboundInfo, c *player.Player) (result *user.ChangeColorOutboundInfo, err errorcode.ErrorCode) { if !c.UseCoins(200) { //如果花不了200,直接返回 - return + return nil, errorcode.ErrorCodes.ErrSunDouInsufficient10016 } c.Info.Coins -= 50 c.Info.Color = data.Color @@ -55,7 +55,7 @@ func (h Controller) ChangePlayerColor(data *user.ChangeColorInboundInfo, c *play } func (h Controller) ChangePlayerDoodle(data *user.ChangeDoodleInboundInfo, c *player.Player) (result *user.ChangeDoodleOutboundInfo, err errorcode.ErrorCode) { if !c.UseCoins(200) { //如果花不了200,直接返回 - return + return nil, errorcode.ErrorCodes.ErrSunDouInsufficient10016 } c.Info.Coins -= 50 c.Info.Texture = data.Id diff --git a/logic/service/fight/action.go b/logic/service/fight/action.go index d3b00bf9b..0a785595a 100644 --- a/logic/service/fight/action.go +++ b/logic/service/fight/action.go @@ -64,7 +64,7 @@ func (f *FightC) ChangePet(c common.PlayerI, id uint32) { BaseAction: action.NewBaseAction(c.GetInfo().UserID), Cid: id, } - + println("切精灵", c.GetInfo().UserID, id) f.actionChan <- ret } @@ -77,6 +77,7 @@ func (f *FightC) UseSkill(c common.PlayerI, id uint32) { ret := &action.SelectSkillAction{ BaseAction: action.NewBaseAction(c.GetInfo().UserID), } + println("使用技能", c.GetInfo().UserID, id) if f.GetInputByPlayer(c, false).CurrentPet == nil { return } diff --git a/logic/service/fight/fightc.go b/logic/service/fight/fightc.go index 41b796b47..50cb81eab 100644 --- a/logic/service/fight/fightc.go +++ b/logic/service/fight/fightc.go @@ -6,7 +6,6 @@ import ( "blazing/logic/service/fight/action" "blazing/logic/service/fight/info" "blazing/logic/service/fight/input" - "blazing/logic/service/player" "blazing/modules/blazing/model" "fmt" "reflect" @@ -339,14 +338,6 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { f.closefight = true // break - } else { - if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC { - if _, ok := defender.Player.(*player.AI_player); ok { - defender.GetAction(f.Our) - //panic("AI自动技能") - } - - } } //attacker.CanAction = true @@ -373,16 +364,8 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { f.closefight = true - } else { - if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC { - if _, ok := defender.Player.(*player.AI_player); ok { - defender.GetAction(f.Our) - //panic("AI自动技能") - } - - } } - break + //break } } @@ -408,6 +391,8 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { if ff.Player.GetInfo().UserID != v.Reason.UserId { + println("切精灵", v.Reason.UserId, v.Reason.ID) + ff.Player.SendPackCmd(2407, &v.Reason) } @@ -419,7 +404,18 @@ func (f *FightC) enterturn(fattack, sattack *action.SelectSkillAction) { return } f.Broadcast(func(ff *input.Input) { + ff.Player.SendPackCmd(2505, &ret) ff.CanChange = 0 }) + println("回合结束") + if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC { + if f.Opp.CurrentPet.Info.Hp <= 0 { + println("回合结束开始执行NPC动作") + f.Opp.GetAction() + //panic("AI自动技能") + } + + } + } diff --git a/logic/service/fight/input/fight.go b/logic/service/fight/input/fight.go index d7ce857b6..c14833734 100644 --- a/logic/service/fight/input/fight.go +++ b/logic/service/fight/input/fight.go @@ -189,7 +189,7 @@ func (our *Input) Damage(in *Input, sub *info.DamageZone) { } -func (our *Input) GetAction(opp *Input) { +func (our *Input) GetAction() { next := our.Exec(func(t Effect) bool { @@ -205,7 +205,7 @@ func (our *Input) GetAction(opp *Input) { for _, v := range our.AllPet { if v.Info.Hp > 0 { our.FightC.ChangePet(our.Player, v.Info.CatchTime) - our.GetAction(our.Opp) + return } @@ -237,7 +237,7 @@ func (our *Input) GetAction(opp *Input) { continue } // 计算技能对对方的伤害(假设CalculatePower返回伤害值,或需从技能中获取) - damage := our.CalculatePower(opp, s) + damage := our.CalculatePower(our.Opp, s) if !s.CanUse() { continue @@ -245,7 +245,7 @@ func (our *Input) GetAction(opp *Input) { allSkills = append(allSkills, skillWithDamage{SkillEntity: s, damage: damage}) // 判断是否能秒杀(伤害 >= 对方当前生命值) - if uint32(damage.IntPart()) >= opp.CurrentPet.Info.Hp { // 假设oppPet.HP为对方当前剩余生命值 + if uint32(damage.IntPart()) >= our.Opp.CurrentPet.Info.Hp { // 假设oppPet.HP为对方当前剩余生命值 killableSkills = append(killableSkills, struct { *info.SkillEntity damage alpacadecimal.Decimal diff --git a/logic/service/fight/loop.go b/logic/service/fight/loop.go index 3672d5eeb..2c45dce3b 100644 --- a/logic/service/fight/loop.go +++ b/logic/service/fight/loop.go @@ -20,22 +20,25 @@ import ( func (f *FightC) battleLoop() { - f.actionChan = make(chan action.BattleActionI, 2) + f.actionChan = make(chan action.BattleActionI, 10) //fmt.Println("战斗开始精灵", f.Our.Player.GetInfo().PetList[0].CatchTime) ourID := f.Our.Player.GetInfo().UserID oppID := f.Opp.Player.GetInfo().UserID + //fmt.Println("开始收集玩家动作", waitr) for !f.closefight { f.Round++ //fmt.Printf("—— 第 %d 回合开始 ——\n", f.Round) + // AI自动技能 actions := f.collectPlayerActions(ourID, oppID) if f.closefight { break } + println("进入回合") f.resolveRound(actions[ourID], actions[oppID]) } @@ -111,7 +114,7 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat actions := make(map[uint32]action.BattleActionI) waitr := time.Duration(f.waittime)*time.Millisecond*10 + 60*time.Second - //fmt.Println("开始收集玩家动作", waitr) + timeout := time.After(waitr) for len(actions) < 2 { @@ -133,12 +136,10 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat if pid != ourID && pid != oppID { continue } - - // // 避免重复提交 - // if _, exists := actions[pid]; exists { - // fmt.Printf("玩家%d 已经提交过动作,忽略重复\n", pid) - // continue - // } + if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC && pid != 0 { + f.Opp.GetAction() + println("开始执行NPC动作") + } selfinput := f.GetInputByAction(paction, false) if ret, ok := paction.(*action.ActiveSwitchAction); ok { //正常结束可以切换,以及死切后还能再切一次 @@ -170,7 +171,14 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat }) }) if selfinput.CanChange == 2 { + selfinput.CanChange = 0 + if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC && pid == 0 { + f.Switch = make(map[uint32]*action.ActiveSwitchAction) + f.Our.Player.SendPackCmd(2407, &ret.Reason) + f.Opp.GetAction() + println("开始执行NPC死切动作") + } continue } } @@ -188,11 +196,6 @@ func (f *FightC) collectPlayerActions(ourID, oppID uint32) map[uint32]action.Bat // selfinput.CanChange-- // } } - // AI自动技能 - if pid != 0 && (f.Info.Status == info.BattleMode.FIGHT_WITH_NPC) { - f.GetInputByAction(paction, true).GetAction(f.Our) - //panic("AI自动技能") - } actions[pid] = paction //fmt.Println("玩家执行动作:", pid, paction.Priority()) diff --git a/modules/blazing/service/pet_fusion_material_service.go b/modules/blazing/service/pet_fusion_material_service.go index e59806b8e..c4b5ccf22 100644 --- a/modules/blazing/service/pet_fusion_material_service.go +++ b/modules/blazing/service/pet_fusion_material_service.go @@ -38,6 +38,10 @@ func (s *PetFusionMaterialService) Data(Material1 [4]uint32) uint32 { fusions := service.DictInfoServiceS.GetData("fusion") for _, v := range Material1 { + if v < 10000 { + //使用过小的道具 + return 0 + } _, ok := fusions[v] if !ok { //todo使用了非法材料 diff --git a/public/config/72_com.robot.core.config.xml.EggsXMLInfo_xmlClass.bin b/public/config/72_com.robot.core.config.xml.EggsXMLInfo_xmlClass.bin new file mode 100644 index 000000000..d93bab56f --- /dev/null +++ b/public/config/72_com.robot.core.config.xml.EggsXMLInfo_xmlClass.bin @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/config/地图配置野怪.xml b/public/config/地图配置野怪.xml index b5fc3f3f7..59db034b7 100644 --- a/public/config/地图配置野怪.xml +++ b/public/config/地图配置野怪.xml @@ -443,6 +443,16 @@ eg: + + + + + + + @@ -4449,7 +4459,7 @@ eg: - + diff --git a/public/binaryData/199_com.robot.core.config.xml.EvolveXMLInfo_xmlcls.bin b/public/config/进化仓.xml similarity index 100% rename from public/binaryData/199_com.robot.core.config.xml.EvolveXMLInfo_xmlcls.bin rename to public/config/进化仓.xml