feat(currency_wars): complete systems, settlement Rank SS, damage report, camera and recovery fixes

This commit is contained in:
CAtlas0784 committed 2026-10-31 20:47:36 +07:00
1 parent c008243f11
commit 0995055296
78 files changed
+33840 -9525

No files matched your search

+138
View File
@@ -5,6 +5,7 @@ import (
"testing"
goproto "gac-hkrpg-go/protocol/proto"
"google.golang.org/protobuf/proto"
)
func TestBattleReportUsesActualBattleSlots(t *testing.T) {
@@ -234,3 +235,140 @@ func TestBattleReportDoesNotReplaceStandardDamageWithSupplementalAggregate(t *te
t.Fatalf("supplemental data replaced standard damage: %+v", report)
}
}
func TestCurrencyWarsBattleReportWithMoreThanFourAvatars(t *testing.T) {
// Simulated CW battle: 4 front row avatars + 4 back row avatars = 8 avatars on board.
stt := &goproto.BattleStatistics{
TotalBattleTurns: 15,
RoundCnt: 1,
CostTime: 30.0,
BattleAvatarList: []*goproto.AvatarBattleInfo{
{Id: 1213, TotalDamage: 0},
{Id: 1308, TotalDamage: 0},
{Id: 1511, TotalDamage: 0},
{Id: 1513, TotalDamage: 0},
},
APAGMJNECCN: &goproto.MGMJOPHJCNL{
DOGMMGLBJIJ: []*goproto.CPNCAPLOIHI{
{RoleId: 121302, Damage: 100000},
{RoleId: 130802, Damage: 50000},
{RoleId: 151102, Damage: 10000},
{RoleId: 151302, Damage: 40000},
{RoleId: 604202, Damage: 20000},
{RoleId: 150302, Damage: 30000},
{RoleId: 800902, Damage: 15000},
{RoleId: 150502, Damage: 35000},
},
},
}
report := BattleReportFromStatistics(stt, 101, 80211, "WIN")
if !report.IsCurrencyWars {
t.Fatal("expected IsCurrencyWars to be true")
}
if report.TeamTotalDamage != 300000 {
t.Fatalf("expected team total damage 300000, got %f", report.TeamTotalDamage)
}
battleContext := &goproto.SceneBattleInfo{
BattleId: 101,
StageId: 80211,
BattleAvatarList: []*goproto.BattleAvatar{
{Id: 1213, Level: 80, Rank: 2, Index: 0},
{Id: 1308, Level: 80, Rank: 1, Index: 1},
{Id: 1511, Level: 80, Rank: 0, Index: 2},
{Id: 1513, Level: 80, Rank: 1, Index: 3},
},
EIGMKOJOEEI: &goproto.OJCBOMCCPDB{
OPHONCKPNMG: []*goproto.BattleAvatar{
{Id: 6042, Level: 80, Rank: 1, Index: 0},
{Id: 1503, Level: 80, Rank: 0, Index: 1},
{Id: 8009, Level: 80, Rank: 6, Index: 2},
{Id: 1505, Level: 80, Rank: 0, Index: 3},
},
GridGameRoleList: []*goproto.BJGJBNJDLIK{
{RoleId: 121302, AvatarId: 1213, Pos: 1, RoleStar: 3},
{RoleId: 130802, AvatarId: 1308, Pos: 2, RoleStar: 2},
{RoleId: 151102, AvatarId: 1511, Pos: 3, RoleStar: 1},
{RoleId: 151302, AvatarId: 1513, Pos: 4, RoleStar: 2},
{RoleId: 604202, AvatarId: 6042, Pos: 5, RoleStar: 1},
{RoleId: 150302, AvatarId: 1503, Pos: 6, RoleStar: 2},
{RoleId: 800902, AvatarId: 8009, Pos: 7, RoleStar: 2},
{RoleId: 150502, AvatarId: 1505, Pos: 8, RoleStar: 3},
},
},
}
ApplyBattleReportContext(report, battleContext)
if len(report.Avatars) != 8 {
t.Fatalf("expected 8 avatars in CW battle report, got %d", len(report.Avatars))
}
expectedDamages := map[uint32]float64{
1213: 100000,
1308: 50000,
1511: 10000,
1513: 40000,
6042: 20000,
1503: 30000,
8009: 15000,
1505: 35000,
}
var totalPercent float64
for i, a := range report.Avatars {
if a.Slot == nil || *a.Slot != uint32(i+1) {
t.Fatalf("avatar %d slot expected %d, got %v", a.AvatarID, i+1, a.Slot)
}
expectedDmg := expectedDamages[a.AvatarID]
if a.TotalDamage != expectedDmg {
t.Fatalf("avatar %d damage expected %f, got %f", a.AvatarID, expectedDmg, a.TotalDamage)
}
totalPercent += a.DamagePercent
}
if totalPercent < 99.9 || totalPercent > 100.1 {
t.Fatalf("expected total percent ~100%%, got %f", totalPercent)
}
// Verify star rank
if report.Avatars[0].AvatarRank != 3 {
t.Fatalf("expected Dan Heng IL rank (star) to be 3, got %d", report.Avatars[0].AvatarRank)
}
}
func TestRealCapturedBattleResult(t *testing.T) {
path := "../../battle_diagnostics/20261031T050254.858914500Z_result_4462dff22ebf/battle_result.bin"
wire, err := os.ReadFile(path)
if err != nil {
t.Skip("real captured battle result not found on disk")
}
var req goproto.PVEBattleResultCsReq
if err := proto.Unmarshal(wire, &req); err != nil {
t.Fatal(err)
}
report := BattleReportFromStatistics(req.Stt, req.BattleId, req.StageId, "WIN")
if !report.IsCurrencyWars {
t.Fatal("expected IsCurrencyWars = true")
}
if len(report.CurrencyWarsRoleDamages) != 9 {
t.Fatalf("expected 9 role damages, got %d", len(report.CurrencyWarsRoleDamages))
}
if report.TeamTotalDamage < 115000000 {
t.Fatalf("expected team total damage > 115M, got %f", report.TeamTotalDamage)
}
battleWire, err := os.ReadFile("../../battle_diagnostics/20261031T050532.034020800Z_86babfb031c1/battle_last.bin")
if err == nil {
var battle goproto.SceneBattleInfo
if err := proto.Unmarshal(battleWire, &battle); err == nil {
ApplyBattleReportContext(report, &battle)
if len(report.Avatars) != 9 {
t.Fatalf("expected 9 avatars after applying CW battle context, got %d", len(report.Avatars))
}
// Write to battle_report.json in root so current dashboard reflects this real battle
_ = SaveBattleReport(report)
}
}
}