diff --git a/logic/controller/pet_manage.go b/logic/controller/pet_manage.go index 2c5dd5a14..1aad93ff5 100644 --- a/logic/controller/pet_manage.go +++ b/logic/controller/pet_manage.go @@ -15,21 +15,18 @@ func petSetExpLimit(currentPet *playermodel.PetInfo) int64 { } simulatedPet := *currentPet - var allowedExp int64 + allowedExp := simulatedPet.NextLvExp - simulatedPet.Exp + if allowedExp < 0 { + allowedExp = 0 + } - for simulatedPet.Level < 100 { - needExp := simulatedPet.NextLvExp - simulatedPet.Exp - if needExp <= 0 { - simulatedPet.Exp = simulatedPet.NextLvExp - simulatedPet.Level++ - simulatedPet.Update(true) - continue - } - - allowedExp += needExp - simulatedPet.Exp += needExp + for simulatedPet.Level < 100 && simulatedPet.NextLvExp > 0 { simulatedPet.Level++ simulatedPet.Update(true) + if simulatedPet.Level >= 100 { + break + } + allowedExp += simulatedPet.NextLvExp } return allowedExp diff --git a/logic/service/player/pet.go b/logic/service/player/pet.go index 11d3dd9e5..c9346a781 100644 --- a/logic/service/player/pet.go +++ b/logic/service/player/pet.go @@ -39,27 +39,16 @@ func (p *Player) AddPetExp(petInfo *model.PetInfo, addExp int64) { return } originalLevel := petInfo.Level + allocatedExp := addExp p.Info.ExpPool -= addExp //减去已使用的经验 - remainingExp := addExp - for remainingExp > 0 { - needExp := petInfo.NextLvExp - petInfo.Exp - if needExp <= 0 { - petInfo.Exp = petInfo.NextLvExp - petInfo.Level++ - petInfo.Update(true) - continue - } - if remainingExp < needExp { - petInfo.Exp += remainingExp - break - } - - petInfo.Exp += needExp - remainingExp -= needExp + currentExp := petInfo.Exp + addExp + for currentExp >= petInfo.NextLvExp && petInfo.NextLvExp > 0 { petInfo.Level++ petInfo.Update(true) + currentExp -= petInfo.LvExp } + petInfo.Exp = currentExp // 重新计算面板 if originalLevel != petInfo.Level { @@ -95,6 +84,7 @@ func (p *Player) AddPetExp(petInfo *model.PetInfo, addExp int64) { var petUpdateInfo info.UpdatePropInfo copier.Copy(&petUpdateInfo, petInfo) + petUpdateInfo.Exp = uint32(allocatedExp) updateOutbound.Data = append(updateOutbound.Data, petUpdateInfo) p.SendPack(header.Pack(updateOutbound)) //准备包由各自发,因为协议不一样 diff --git a/logic/service/player/pet_test.go b/logic/service/player/pet_test.go index eaefa014a..d68af6425 100644 --- a/logic/service/player/pet_test.go +++ b/logic/service/player/pet_test.go @@ -122,3 +122,36 @@ func TestAddPetExpSmallRewardDoesNotJumpToMaxLevel(t *testing.T) { t.Fatalf("expected exp pool to decrease by %d, got %d", addExp, player.Info.ExpPool) } } + +func TestAddPetExpUsesDynamicPerLevelRequirement(t *testing.T) { + petID := firstPetIDForTest(t) + petInfo := playermodel.GenPetInfo(petID, 31, 0, 0, 20, nil, 0) + if petInfo == nil { + t.Fatalf("failed to generate test pet") + } + + initialNeed := petInfo.NextLvExp + if initialNeed <= 0 { + t.Fatalf("expected positive exp requirement, got %d", initialNeed) + } + + player := &Player{ + baseplayer: baseplayer{ + Info: &playermodel.PlayerInfo{ + ExpPool: 1_000_000, + }, + }, + } + + player.AddPetExp(petInfo, initialNeed) + + if petInfo.Level != 21 { + t.Fatalf("expected pet level to become 21, got %d", petInfo.Level) + } + if petInfo.Exp != 0 { + t.Fatalf("expected level-up to reset current level exp, got %d", petInfo.Exp) + } + if petInfo.NextLvExp == initialNeed { + t.Fatalf("expected next level exp to change after leveling, still %d", petInfo.NextLvExp) + } +} diff --git a/modules/player/model/pet.go b/modules/player/model/pet.go index ef0b47fc5..3414d3427 100644 --- a/modules/player/model/pet.go +++ b/modules/player/model/pet.go @@ -532,18 +532,20 @@ func (petinfo *PetInfo) Update(isup bool) { if evolveCount >= maxEvolveTimes { break } - // 进化完成后,统一更新经验(原逻辑保留) - petinfo.LvExp = petinfo.NextLvExp // 获取当前宠物形态的配置 basic, ok := xmlres.PetMAP[int(petinfo.ID)] // 配置不存在,直接退出循环 if !ok { break } - petinfo.NextLvExp = calculateExperience(petinfo.Level, basic.GetBasic()) if !isup { + petinfo.LvExp = calculatePreviousLevelExperience(petinfo.Level, basic.GetBasic()) + petinfo.NextLvExp = calculateExperience(petinfo.Level, basic.GetBasic()) return } + // 升级时保留上一等级需求,供经验结算使用。 + petinfo.LvExp = petinfo.NextLvExp + petinfo.NextLvExp = calculateExperience(petinfo.Level, basic.GetBasic()) // 检查是否满足进化条件 canEvolve := basic.EvolvesTo != 0 && // 有明确的进化目标 int(petinfo.Level) >= basic.EvolvingLv && // 等级达到进化要求 @@ -561,6 +563,13 @@ func (petinfo *PetInfo) Update(isup bool) { } +func calculatePreviousLevelExperience(level uint32, baseValue uint32) int64 { + if level <= 1 { + return 0 + } + return calculateExperience(level-1, baseValue) +} + // calculateExperience 计算指定等级和种族值所需的经验值 // level: 当前等级 // baseValue: 种族值