```
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful

feat(fight): 添加旧组队协议支持并优化战斗系统

- 实现了旧组队协议相关功能,包括GroupReadyFightFinish、GroupUseSkill、
  GroupUseItem、GroupChangePet和GroupEscape方法
- 新增组队战斗相关的入站信息结构体定义
- 实现了组队BOSS战斗逻辑,添加groupBossSlotLimit常量
- 重构宠物技能设置逻辑,调整金币消耗时机
- 优化战斗循环逻辑,添加对无行动槽位的处理
- 改进AI行动逻辑,增加多位置目标选择机制
- 完善捕获系统上下文处理,修复空指针问题
- 添加战斗状态更新和数据同步机制

fix(pet-skill): 修复宠物技能设置中的金币扣除逻辑错误

- 将金币扣除逻辑移到验证之后
- 修正宠物技能数量限制检查的顺序
- 防止重复添加已有技能的情况

refactor(fight): 重构战斗系统代码结构

- 分离新旧组队协议的战斗创建逻辑
- 优化战斗输入验证和处理流程
- 改进战斗循环中的错误处理机制
```
This commit is contained in:
昔念
2026-04-09 02:14:09 +08:00
parent 3b35789b47
commit 487ee0e726
10 changed files with 796 additions and 130 deletions

View File

@@ -43,7 +43,8 @@ func (h Controller) GroupUseSkill(data *GroupUseSkillInboundInfo, c *player.Play
targetRelation = fight.SkillTargetAlly
}
h.dispatchFightActionEnvelope(c, fight.NewSkillActionEnvelope(data.SkillId, int(data.ActorIndex), int(data.TargetPos), targetRelation, 0))
return nil, 0
c.SendPackCmd(7558, nil)
return nil, -1
}
func (h Controller) GroupUseItem(data *GroupUseItemInboundInfo, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {

View File

@@ -75,54 +75,13 @@ func startMapBossFight(
ourPets := p.GetPetInfo(100)
oppPets := ai.GetPetInfo(0)
if mapNode != nil && mapNode.IsGroupBoss != 0 {
ourSlots := buildGroupBossPetSlots(ourPets, groupBossSlotLimit)
oppSlots := buildGroupBossPetSlots(oppPets, groupBossSlotLimit)
if len(ourSlots) > 0 && len(oppSlots) > 0 {
return fight.NewLegacyGroupFightSingleControllerN(p, ai, ourSlots, oppSlots, fn)
if len(ourPets) > 0 && len(oppPets) > 0 {
return fight.NewLegacyGroupFightSingleController(p, ai, ourPets, oppPets, groupBossSlotLimit, fn)
}
}
return fight.NewFight(p, ai, ourPets, oppPets, fn)
}
func buildGroupBossPetSlots(pets []model.PetInfo, slotLimit int) [][]model.PetInfo {
if len(pets) == 0 {
return nil
}
slots := make([][]model.PetInfo, 0, slotLimit)
for _, pet := range pets {
if pet.Hp == 0 {
continue
}
if slotLimit <= 0 {
slotLimit = 3
}
if len(slots) < slotLimit {
slots = append(slots, []model.PetInfo{pet})
continue
}
break
}
if len(slots) == 0 {
return nil
}
var idx int = 0
for _, pet := range pets[len(slots):] {
if pet.Hp == 0 {
continue
}
for step := 0; step < len(slots); step++ {
slotIdx := (idx + step) % len(slots)
if len(slots[slotIdx]) < 6 {
slots[slotIdx] = append(slots[slotIdx], pet)
idx = (slotIdx + 1) % len(slots)
break
}
}
}
return slots
}
// OnPlayerFightNpcMonster 战斗野怪
func (Controller) OnPlayerFightNpcMonster(req *FightNpcMonsterInboundInfo, p *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
if err = p.CanFight(); err != 0 {

View File

@@ -64,6 +64,7 @@ func (h *Controller) SwitchFlying(data *SwitchFlyingInboundInfo, c *player.Playe
// PlayerPetCure 处理控制器请求。
func (h *Controller) PlayerPetCure(data *PetCureInboundInfo, c *player.Player) (result *nono.PetCureOutboundEmpty, err errorcode.ErrorCode) { //这个时候player应该是空的
_ = data
result = &nono.PetCureOutboundEmpty{}
if c.IsArenaHealLocked() {
return result, errorcode.ErrorCodes.ErrChampionCannotHeal
}
@@ -73,6 +74,9 @@ func (h *Controller) PlayerPetCure(data *PetCureInboundInfo, c *player.Player) (
for i := range c.Info.PetList {
c.Info.PetList[i].Cure()
}
for i := range c.Info.BackupPetList {
c.Info.BackupPetList[i].Cure()
}
c.Info.Coins -= nonoPetCureCost
return
}