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

feat(fight_boss): 优化BOSS战斗奖励逻辑并修复宠物等级突破100级限制

重构了handleMapBossFightRewards函数,将奖励逻辑分离到独立的处理函数中,
增加了shouldGrantBossWinBonus条件判断,确保只有满足条件时才发放胜利奖励。

同时修复了宠物等级系统,允许宠物等级突破100级限制但面板属性仍保持100级上限,
改进了经验获取和面板更新逻辑。

fix(item_use): 添加全能性格转化剂使用验证

添加了UniversalNatureItemID常量定义,增加对道具ID和性格配置的有效性验证,
确保只有正确的道具和性格类型才能被使用。

refactor(fight): 统一战斗结束原因处理逻辑

引入normalizeFightOverReason函数来标准化战斗结束原因,
统一了不同模块中的战斗结果映射逻辑,提高了代码一致性。

perf(pet): 优化宠物升级和经验计算性能

移除了等级100的硬性限制,在保证面板属性不超限的前提下允许宠物等级继续增长,
优化了经验分配和面板重新计算的逻辑流程。
```
This commit is contained in:
昔念
2026-04-14 00:43:32 +08:00
parent b953e7831a
commit 43b0bc2dec
4 changed files with 35 additions and 10 deletions

View File

@@ -35,11 +35,16 @@ func (h Controller) GetUserItemList(data *ItemListInboundInfo, c *player.Player)
// c: 当前玩家对象 // c: 当前玩家对象
// 返回: 使用后的宠物信息和错误码 // 返回: 使用后的宠物信息和错误码
func (h Controller) UsePetItemOutOfFight(data *C2S_USE_PET_ITEM_OUT_OF_FIGHT, c *player.Player) (result *item.S2C_USE_PET_ITEM_OUT_OF_FIGHT, err errorcode.ErrorCode) { func (h Controller) UsePetItemOutOfFight(data *C2S_USE_PET_ITEM_OUT_OF_FIGHT, c *player.Player) (result *item.S2C_USE_PET_ITEM_OUT_OF_FIGHT, err errorcode.ErrorCode) {
_, currentPet, found := c.FindPet(data.CatchTime) slot, found := c.FindPetBagSlot(data.CatchTime)
if !found { if !found {
return nil, errorcode.ErrorCodes.Err10401 return nil, errorcode.ErrorCodes.Err10401
} }
currentPet := slot.PetInfoPtr()
if currentPet == nil {
return nil, errorcode.ErrorCodes.Err10401
}
itemID := uint32(data.ItemID) itemID := uint32(data.ItemID)
if c.Service.Item.CheakItem(itemID) == 0 { if c.Service.Item.CheakItem(itemID) == 0 {
return nil, errorcode.ErrorCodes.ErrInsufficientItems return nil, errorcode.ErrorCodes.ErrInsufficientItems
@@ -184,11 +189,16 @@ func (h Controller) handleRegularPetItem(itemID uint32, currentPet *model.PetInf
// c: 当前玩家对象 // c: 当前玩家对象
// 返回: 无数据和错误码 // 返回: 无数据和错误码
func (h Controller) ResetNature(data *C2S_PET_RESET_NATURE, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) { func (h Controller) ResetNature(data *C2S_PET_RESET_NATURE, c *player.Player) (result *fight.NullOutboundInfo, err errorcode.ErrorCode) {
_, currentPet, found := c.FindPet(data.CatchTime) slot, found := c.FindPetBagSlot(data.CatchTime)
if !found { if !found {
return nil, errorcode.ErrorCodes.Err10401 return nil, errorcode.ErrorCodes.Err10401
} }
currentPet := slot.PetInfoPtr()
if currentPet == nil {
return nil, errorcode.ErrorCodes.Err10401
}
if data.ItemId != UniversalNatureItemID { if data.ItemId != UniversalNatureItemID {
return nil, errorcode.ErrorCodes.ErrItemUnusable return nil, errorcode.ErrorCodes.ErrItemUnusable
} }

View File

@@ -13,10 +13,11 @@ func (h Controller) GetPetInfo(
data *GetPetInfoInboundInfo, data *GetPetInfoInboundInfo,
player *player.Player) (result *model.PetInfo, player *player.Player) (result *model.PetInfo,
err errorcode.ErrorCode) { err errorcode.ErrorCode) {
_, petInfo, found := player.FindPet(data.CatchTime) if slot, found := player.FindPetBagSlot(data.CatchTime); found {
if found { if petInfo := slot.PetInfoPtr(); petInfo != nil {
result = petInfo result = petInfo
return result, 0 return result, 0
}
} }
ret := player.Service.Pet.PetInfoOneByCatchTime(data.CatchTime) ret := player.Service.Pet.PetInfoOneByCatchTime(data.CatchTime)
@@ -73,7 +74,6 @@ func (h Controller) PlayerShowPet(
Flag: data.Flag, Flag: data.Flag,
} }
_, currentPet, ok := player.FindPet(data.CatchTime)
if data.Flag == 0 { if data.Flag == 0 {
player.SetPetDisplay(0, nil) player.SetPetDisplay(0, nil)
player.GetSpace().RefreshUserInfo(player) player.GetSpace().RefreshUserInfo(player)
@@ -81,10 +81,16 @@ func (h Controller) PlayerShowPet(
return return
} }
slot, ok := player.FindPetBagSlot(data.CatchTime)
if !ok { if !ok {
return nil, errorcode.ErrorCodes.ErrPokemonNotExists return nil, errorcode.ErrorCodes.ErrPokemonNotExists
} }
currentPet := slot.PetInfoPtr()
if currentPet == nil {
return nil, errorcode.ErrorCodes.ErrPokemonNotExists
}
player.SetPetDisplay(data.Flag, currentPet) player.SetPetDisplay(data.Flag, currentPet)
player.GetSpace().RefreshUserInfo(player) player.GetSpace().RefreshUserInfo(player)
result = buildPetShowOutboundInfo(data.Head.UserID, data.Flag, currentPet) result = buildPetShowOutboundInfo(data.Head.UserID, data.Flag, currentPet)

View File

@@ -32,9 +32,11 @@ func (h Controller) PetOneCure(
return result, errorcode.ErrorCodes.ErrChampionCannotHeal return result, errorcode.ErrorCodes.ErrChampionCannotHeal
} }
_, currentPet, ok := player.FindPet(data.CatchTime) if slot, ok := player.FindPetBagSlot(data.CatchTime); ok {
if ok { currentPet := slot.PetInfoPtr()
defer currentPet.Cure() if currentPet != nil {
defer currentPet.Cure()
}
} }
return &pet.PetOneCureOutboundInfo{ return &pet.PetOneCureOutboundInfo{

View File

@@ -25,6 +25,13 @@ func (slot PetBagSlot) PetInfo() model.PetInfo {
return slot.info return slot.info
} }
func (slot PetBagSlot) PetInfoPtr() *model.PetInfo {
if !slot.IsValid() {
return nil
}
return &(*slot.list)[slot.index]
}
func (slot PetBagSlot) IsMainBag() bool { func (slot PetBagSlot) IsMainBag() bool {
return slot.main return slot.main
} }