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

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

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

fix(item
This commit is contained in:
昔念
2026-04-14 00:38:50 +08:00
parent 62d93f65e7
commit b953e7831a
9 changed files with 110 additions and 161 deletions

View File

@@ -27,33 +27,24 @@ func (p *Player) AddPetExp(petInfo *model.PetInfo, addExp int64) {
if petInfo == nil || addExp <= 0 {
return
}
if petInfo.Level >= 100 {
petInfo.Level = 100
petInfo.Exp = 0
if petInfo.Level > 100 {
currentHP := petInfo.Hp
petInfo.Update(false)
petInfo.CalculatePetPane(100)
if petInfo.Hp > petInfo.MaxHp {
petInfo.Hp = petInfo.MaxHp
}
return
petInfo.Hp = utils.Min(currentHP, petInfo.MaxHp)
}
addExp = utils.Min(addExp, p.Info.ExpPool)
originalLevel := petInfo.Level
exp := int64(petInfo.Exp) + addExp
p.Info.ExpPool -= addExp //减去已使用的经验
gainedExp := exp //已获得的经验
for petInfo.Level < 100 && exp >= int64(petInfo.NextLvExp) {
for exp >= int64(petInfo.NextLvExp) {
petInfo.Level++
exp -= int64(petInfo.LvExp)
petInfo.Update(true)
}
if petInfo.Level >= 100 {
p.Info.ExpPool += exp // 超出100级上限的经验退回经验池
gainedExp -= exp
exp = 0
}
petInfo.Exp = (exp)
// 重新计算面板
if originalLevel != petInfo.Level {

View File

@@ -17,12 +17,16 @@ func firstPetIDForTest(t *testing.T) int {
return 0
}
func TestAddPetExpStopsAtLevel100(t *testing.T) {
func TestAddPetExpAllowsLevelBeyond100WhilePanelStaysCapped(t *testing.T) {
petID := firstPetIDForTest(t)
petInfo := playermodel.GenPetInfo(petID, 31, 0, 0, 99, nil, 0)
petInfo := playermodel.GenPetInfo(petID, 31, 0, 0, 100, nil, 0)
expectedPanel := playermodel.GenPetInfo(petID, 31, 0, 0, 100, nil, 0)
if petInfo == nil {
t.Fatalf("failed to generate test pet")
}
if expectedPanel == nil {
t.Fatalf("failed to generate expected test pet")
}
player := &Player{
baseplayer: baseplayer{
@@ -34,21 +38,29 @@ func TestAddPetExpStopsAtLevel100(t *testing.T) {
player.AddPetExp(petInfo, petInfo.NextLvExp+10_000)
if petInfo.Level != 100 {
t.Fatalf("expected pet level to stop at 100, got %d", petInfo.Level)
if petInfo.Level <= 100 {
t.Fatalf("expected pet level to continue beyond 100, got %d", petInfo.Level)
}
if petInfo.Exp != 0 {
t.Fatalf("expected pet exp to reset at level cap, got %d", petInfo.Exp)
if petInfo.MaxHp != expectedPanel.MaxHp {
t.Fatalf("expected max hp to stay capped at 100-level panel, got %d want %d", petInfo.MaxHp, expectedPanel.MaxHp)
}
if petInfo.Prop != expectedPanel.Prop {
t.Fatalf("expected props to stay capped at 100-level panel, got %+v want %+v", petInfo.Prop, expectedPanel.Prop)
}
}
func TestAddPetExpDoesNotConsumePoolAboveLevel100(t *testing.T) {
func TestAddPetExpRecalculatesPanelForLevelAbove100(t *testing.T) {
petID := firstPetIDForTest(t)
petInfo := playermodel.GenPetInfo(petID, 31, 0, 0, 100, nil, 0)
expectedPanel := playermodel.GenPetInfo(petID, 31, 0, 0, 100, nil, 0)
if petInfo == nil {
t.Fatalf("failed to generate test pet")
}
if expectedPanel == nil {
t.Fatalf("failed to generate expected test pet")
}
petInfo.Level = 101
petInfo.Exp = 7
petInfo.MaxHp = 1
petInfo.Hp = 999999
@@ -62,19 +74,16 @@ func TestAddPetExpDoesNotConsumePoolAboveLevel100(t *testing.T) {
player.AddPetExp(petInfo, 12_345)
if petInfo.Level != 100 {
t.Fatalf("expected level to be normalized to 100, got %d", petInfo.Level)
if petInfo.Level < 101 {
t.Fatalf("expected level above 100 to be preserved, got %d", petInfo.Level)
}
if player.Info.ExpPool != 50_000 {
t.Fatalf("expected exp pool to remain unchanged, got %d", player.Info.ExpPool)
}
if petInfo.Exp != 0 {
t.Fatalf("expected exp to reset after normalization, got %d", petInfo.Exp)
}
if petInfo.MaxHp <= 1 {
t.Fatalf("expected pet panel to be recalculated, got max hp %d", petInfo.MaxHp)
if petInfo.MaxHp != expectedPanel.MaxHp {
t.Fatalf("expected max hp to be recalculated using level 100 cap, got %d want %d", petInfo.MaxHp, expectedPanel.MaxHp)
}
if petInfo.Hp != petInfo.MaxHp {
t.Fatalf("expected hp to be clamped to recalculated max hp, got hp=%d maxHp=%d", petInfo.Hp, petInfo.MaxHp)
}
if player.Info.ExpPool != 50_000-12_345 {
t.Fatalf("expected exp pool to be consumed normally, got %d", player.Info.ExpPool)
}
}