fix(server): allow ranked equipment with constant health options
This commit is contained in:
@@ -118,7 +118,9 @@ func equipmentStatContribution(rule EquipmentStatRule, option EquipmentOption, s
|
||||
}
|
||||
var ranks float32
|
||||
for i, rank := range option.Rank {
|
||||
if rank == 0 {
|
||||
// EquipmentInfo.GetEquipOptionByRank returns zero for an empty
|
||||
// RankValueN curve, even when the equipment has a rank there.
|
||||
if rank == 0 || len(rule.Ranks[i]) == 0 {
|
||||
continue
|
||||
}
|
||||
if rank < 1 || rank > len(rule.Ranks[i]) {
|
||||
|
||||
@@ -75,3 +75,20 @@ func TestEquipmentOptionContributionTruncatesRatherThanRounds(t *testing.T) {
|
||||
t.Fatalf("fraction percent=%+v err=%v", percent, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEquipmentHealthStatsAllowRankedItemsWithEmptyOptionRankCurves(t *testing.T) {
|
||||
// EquipmentInfo.GetEquipOptionByRank (0x06003145) returns zero when
|
||||
// RankValue1/2/3 is empty. Rank belongs to the equipment, not each option.
|
||||
d := &EquipmentStatDesign{Options: map[[2]uint64]EquipmentStatRule{
|
||||
{10, 1}: {Default: 10, Growth: 2, Levels: []float64{0, 1}},
|
||||
{20, 2}: {Default: 0.1, Growth: 0.01, Levels: []float64{0, 1}, Ranks: [3][]float64{nil, {0.5, 1}, nil}},
|
||||
}}
|
||||
flat, err := d.HealthContribution(EquipmentOption{GroupID: 10, ID: 1, Level: 1, Rank: [3]int{2, 3, 4}}, false)
|
||||
if err != nil || flat.Flat != 12 {
|
||||
t.Fatalf("empty rank curve contribution=%+v err=%v", flat, err)
|
||||
}
|
||||
percent, err := d.HealthContribution(EquipmentOption{GroupID: 20, ID: 2, Level: 1, Rank: [3]int{2, 2, 4}}, false)
|
||||
if err != nil || percent.Percent != 0.12 {
|
||||
t.Fatalf("mixed rank curve contribution=%+v err=%v", percent, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,3 +46,42 @@ func TestEquipmentStatContributionsUseOnlyEquippedOwnerAndAllHealthOptions(t *te
|
||||
t.Fatal("Find deadlocked calculating equipped health")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEatFoodWithRankedEquipmentAndEmptyHealthOptionRankCurves(t *testing.T) {
|
||||
food, inventory, characters := foodTestService(t, stateio.NewMemory())
|
||||
equipment := &EquipmentInventory{owned: equipmentSnapshot{Equipment: []Equipment{{
|
||||
InvenIndex: 1, UseChar: 77, Level: 1, Rank: []uint64{2, 2, 2},
|
||||
MainOption: []EquipmentOption{{GroupID: 10, ID: 1}},
|
||||
}}}}
|
||||
if err := equipment.AttachStatDesign(&gamedata.EquipmentStatDesign{Options: map[[2]uint64]gamedata.EquipmentStatRule{
|
||||
{10, 1}: {Default: 10, Growth: 2, Levels: []float64{0, 1}},
|
||||
}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := characters.AttachMaxHealth(func(c Character) (uint64, error) {
|
||||
contributions, err := equipment.StatContributions(c)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint64(gamedata.AggregateStats(gamedata.BaseStats{Health: 100}, contributions).Health), nil
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := characters.SetCurrentHealth(77, 20); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
stacks, err := inventory.GrantOnce("ranked-equipment-food", []gamedata.BattleReward{{Type: 5, ID: 105, Count: 1}})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, _, _, err := food.Handle("/EatFood", foodRequest(1, 77, 21, stacks[0])); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Base 100 + equipment 12 = 112 maximum; the 50% dish heals 56.
|
||||
if hp, err := characters.CurrentHealth(77); err != nil || hp != 76 {
|
||||
t.Fatalf("healed health=%d err=%v", hp, err)
|
||||
}
|
||||
if len(inventory.All()) != 0 {
|
||||
t.Fatal("successful recovery did not consume dish")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user