fix: recover battle damage from statistics
This commit is contained in:
1 parent
1ed0fb73f9
commit
5120219ae2
2 files changed
+82
-3
No files matched your search
@@ -90,15 +90,46 @@ func BattleReportFromStatistics(stt *goproto.BattleStatistics, battleID uint32,
|
|||||||
Monsters: make([]*BattleMonsterReport, 0, len(stt.MonsterList)),
|
Monsters: make([]*BattleMonsterReport, 0, len(stt.MonsterList)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The 4.6.53 schema exposes OKFALMGFHMA entries with avatar_id and damage,
|
||||||
|
// but the enclosing message and several fields remain obfuscated. Treating
|
||||||
|
// these as per-avatar damage records is an inference that still needs a raw
|
||||||
|
// Client capture; use them only when the clear aggregate is zero.
|
||||||
|
damageByAvatar := make(map[uint32]float64)
|
||||||
|
var damageEventTotal float64
|
||||||
|
for _, event := range stt.OKFALMGFHMA {
|
||||||
|
if event == nil || event.AvatarId == 0 || event.Damage <= 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
damageByAvatar[event.AvatarId] += event.Damage
|
||||||
|
damageEventTotal += event.Damage
|
||||||
|
}
|
||||||
|
|
||||||
var teamDmg, teamHeal, teamShield float64
|
var teamDmg, teamHeal, teamShield float64
|
||||||
for _, a := range stt.BattleAvatarList {
|
for _, a := range stt.BattleAvatarList {
|
||||||
if a == nil {
|
if a == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
teamDmg += a.TotalDamage
|
damage := a.TotalDamage
|
||||||
|
if damage == 0 {
|
||||||
|
damage = damageByAvatar[a.Id]
|
||||||
|
}
|
||||||
|
teamDmg += damage
|
||||||
teamHeal += a.TotalHeal
|
teamHeal += a.TotalHeal
|
||||||
teamShield += a.TotalShield
|
teamShield += a.TotalShield
|
||||||
}
|
}
|
||||||
|
// If neither avatar aggregate source contains damage, enemy damage-taken
|
||||||
|
// stats still provide a reliable team total. They cannot identify which
|
||||||
|
// avatar dealt each hit, so per-avatar shares remain unavailable in that case.
|
||||||
|
if teamDmg == 0 && damageEventTotal > 0 {
|
||||||
|
teamDmg = damageEventTotal
|
||||||
|
}
|
||||||
|
if teamDmg == 0 {
|
||||||
|
for _, m := range stt.MonsterList {
|
||||||
|
if m != nil && m.TotalDamageTaken > 0 {
|
||||||
|
teamDmg += m.TotalDamageTaken
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
report.TeamTotalDamage = teamDmg
|
report.TeamTotalDamage = teamDmg
|
||||||
report.TeamTotalHeal = teamHeal
|
report.TeamTotalHeal = teamHeal
|
||||||
report.TeamTotalShield = teamShield
|
report.TeamTotalShield = teamShield
|
||||||
@@ -107,15 +138,19 @@ func BattleReportFromStatistics(stt *goproto.BattleStatistics, battleID uint32,
|
|||||||
if a == nil {
|
if a == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
damage := a.TotalDamage
|
||||||
|
if damage == 0 {
|
||||||
|
damage = damageByAvatar[a.Id]
|
||||||
|
}
|
||||||
var dmgPercent float64
|
var dmgPercent float64
|
||||||
if teamDmg > 0 {
|
if teamDmg > 0 {
|
||||||
dmgPercent = (a.TotalDamage / teamDmg) * 100.0
|
dmgPercent = (damage / teamDmg) * 100.0
|
||||||
}
|
}
|
||||||
ar := &BattleAvatarReport{
|
ar := &BattleAvatarReport{
|
||||||
AvatarID: a.Id,
|
AvatarID: a.Id,
|
||||||
AvatarLevel: a.AvatarLevel,
|
AvatarLevel: a.AvatarLevel,
|
||||||
AvatarRank: a.AvatarRank,
|
AvatarRank: a.AvatarRank,
|
||||||
TotalDamage: a.TotalDamage,
|
TotalDamage: damage,
|
||||||
DamagePercent: dmgPercent,
|
DamagePercent: dmgPercent,
|
||||||
TotalDamageTaken: a.TotalDamageTaken,
|
TotalDamageTaken: a.TotalDamageTaken,
|
||||||
TotalHeal: a.TotalHeal,
|
TotalHeal: a.TotalHeal,
|
||||||
|
|||||||
@@ -101,3 +101,47 @@ func TestBattleReportSerialization(t *testing.T) {
|
|||||||
t.Fatal("expected error after clearing report, got nil")
|
t.Fatal("expected error after clearing report, got nil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBattleReportUsesAvatarDamageEventsWhenAvatarTotalsAreZero(t *testing.T) {
|
||||||
|
stt := &goproto.BattleStatistics{
|
||||||
|
BattleAvatarList: []*goproto.AvatarBattleInfo{
|
||||||
|
{Id: 1503},
|
||||||
|
{Id: 1511},
|
||||||
|
},
|
||||||
|
OKFALMGFHMA: []*goproto.HDKEPPDIDIH{
|
||||||
|
{AvatarId: 1503, Damage: 720},
|
||||||
|
{AvatarId: 1503, Damage: 180},
|
||||||
|
{AvatarId: 1511, Damage: 100},
|
||||||
|
},
|
||||||
|
MonsterList: []*goproto.MonsterBattleInfo{{TotalDamageTaken: 1000}},
|
||||||
|
}
|
||||||
|
|
||||||
|
report := BattleReportFromStatistics(stt, 1, 1052106, "WIN")
|
||||||
|
if report.TeamTotalDamage != 1000 {
|
||||||
|
t.Fatalf("expected event-derived team damage 1000, got %f", report.TeamTotalDamage)
|
||||||
|
}
|
||||||
|
if report.Avatars[0].TotalDamage != 900 || report.Avatars[0].DamagePercent != 90 {
|
||||||
|
t.Fatalf("unexpected avatar 1503 report: %+v", report.Avatars[0])
|
||||||
|
}
|
||||||
|
if report.Avatars[1].TotalDamage != 100 || report.Avatars[1].DamagePercent != 10 {
|
||||||
|
t.Fatalf("unexpected avatar 1511 report: %+v", report.Avatars[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBattleReportFallsBackToMonsterDamageTakenForTeamTotal(t *testing.T) {
|
||||||
|
stt := &goproto.BattleStatistics{
|
||||||
|
BattleAvatarList: []*goproto.AvatarBattleInfo{{Id: 1503}},
|
||||||
|
MonsterList: []*goproto.MonsterBattleInfo{
|
||||||
|
{TotalDamageTaken: 250},
|
||||||
|
{TotalDamageTaken: 750},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
report := BattleReportFromStatistics(stt, 1, 1052106, "WIN")
|
||||||
|
if report.TeamTotalDamage != 1000 {
|
||||||
|
t.Fatalf("expected monster-derived team damage 1000, got %f", report.TeamTotalDamage)
|
||||||
|
}
|
||||||
|
if report.Avatars[0].DamagePercent != 0 {
|
||||||
|
t.Fatalf("cannot infer avatar share from monster totals, got %f", report.Avatars[0].DamagePercent)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user