feat(currency_wars): complete systems, settlement Rank SS, damage report, camera and recovery fixes
This commit is contained in:
1 parent
c008243f11
commit
0995055296
78 files changed
+33840
-9525
No files matched your search
@@ -0,0 +1,617 @@
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gac-hkrpg-go/internal/common"
|
||||
pb "gac-hkrpg-go/protocol/proto"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestCurrencyWarsTalentsHandlers(t *testing.T) {
|
||||
origPersistent, _ := os.ReadFile("persistent")
|
||||
if origPersistent != nil {
|
||||
t.Cleanup(func() {
|
||||
_ = os.WriteFile("persistent", origPersistent, 0644)
|
||||
})
|
||||
}
|
||||
|
||||
session := &Session{Token: 12345}
|
||||
catalog, err := common.LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
t.Fatalf("load catalog: %v", err)
|
||||
}
|
||||
data, rev, err := readCurrencyWarsData(catalog)
|
||||
if err != nil || data == nil {
|
||||
data, err = newCurrencyWarsData(catalog)
|
||||
if err != nil {
|
||||
t.Fatalf("new data: %v", err)
|
||||
}
|
||||
rev = 0
|
||||
}
|
||||
session.currencyWarsRevision = rev
|
||||
if err := session.saveCurrencyWarsData(data, catalog); err != nil {
|
||||
t.Fatalf("save initial data: %v", err)
|
||||
}
|
||||
|
||||
// 1. Enable Permanent Talent
|
||||
permReq := &pb.GridFightPermanentTalentEnableCsReq{CKHCLKOALKE: 101}
|
||||
permCmdID, ok := pb.CmdIDByName["GridFightPermanentTalentEnableCsReq"]
|
||||
if !ok || typedHandlers[uint16(permCmdID)] == nil {
|
||||
t.Fatal("handler GridFightPermanentTalentEnable not registered")
|
||||
}
|
||||
rawPerm, err := proto.Marshal(permReq)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal permReq: %v", err)
|
||||
}
|
||||
if err := typedHandlers[uint16(permCmdID)](session, rawPerm); err != nil {
|
||||
t.Fatalf("call GridFightPermanentTalentEnable: %v", err)
|
||||
}
|
||||
|
||||
saved, _, err := readCurrencyWarsData(catalog)
|
||||
if err != nil || saved == nil {
|
||||
t.Fatalf("read saved data: %v", err)
|
||||
}
|
||||
if saved.LFLCDNGALME == nil || saved.LFLCDNGALME.PKELAIPIHMF == nil || saved.LFLCDNGALME.PKELAIPIHMF.MHFHLBHFIBC == nil {
|
||||
t.Fatal("permanent talent container missing")
|
||||
}
|
||||
found := false
|
||||
for _, id := range saved.LFLCDNGALME.PKELAIPIHMF.MHFHLBHFIBC.BDGMNPIJDDL {
|
||||
if id == 101 {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Errorf("permanent talent 101 was not persisted: %v", saved.LFLCDNGALME.PKELAIPIHMF.MHFHLBHFIBC.BDGMNPIJDDL)
|
||||
}
|
||||
|
||||
// 2. Enable Season Talent
|
||||
seasonReq := &pb.GridFightSeasonTalentEnableCsReq{CKHCLKOALKE: 202}
|
||||
seasonCmdID, ok := pb.CmdIDByName["GridFightSeasonTalentEnableCsReq"]
|
||||
if !ok || typedHandlers[uint16(seasonCmdID)] == nil {
|
||||
t.Fatal("handler GridFightSeasonTalentEnable not registered")
|
||||
}
|
||||
rawSeason, err := proto.Marshal(seasonReq)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal seasonReq: %v", err)
|
||||
}
|
||||
if err := typedHandlers[uint16(seasonCmdID)](session, rawSeason); err != nil {
|
||||
t.Fatalf("call GridFightSeasonTalentEnable: %v", err)
|
||||
}
|
||||
|
||||
saved, _, _ = readCurrencyWarsData(catalog)
|
||||
if saved.LFLCDNGALME == nil || saved.LFLCDNGALME.HFPEJIDDDJG == nil || saved.LFLCDNGALME.HFPEJIDDDJG.MHFHLBHFIBC == nil {
|
||||
t.Fatal("season talent container missing")
|
||||
}
|
||||
foundSeason := false
|
||||
for _, id := range saved.LFLCDNGALME.HFPEJIDDDJG.MHFHLBHFIBC.BDGMNPIJDDL {
|
||||
if id == 202 {
|
||||
foundSeason = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundSeason {
|
||||
t.Errorf("season talent 202 was not persisted: %v", saved.LFLCDNGALME.HFPEJIDDDJG.MHFHLBHFIBC.BDGMNPIJDDL)
|
||||
}
|
||||
|
||||
// 3. Reset Talents
|
||||
resetCmdID, ok := pb.CmdIDByName["GridFightPermanentTalentResetCsReq"]
|
||||
if ok && typedHandlers[uint16(resetCmdID)] != nil {
|
||||
rawReset, _ := proto.Marshal(&pb.GridFightPermanentTalentResetCsReq{})
|
||||
_ = typedHandlers[uint16(resetCmdID)](session, rawReset)
|
||||
}
|
||||
saved, _, _ = readCurrencyWarsData(catalog)
|
||||
if len(saved.LFLCDNGALME.PKELAIPIHMF.MHFHLBHFIBC.BDGMNPIJDDL) != 0 {
|
||||
t.Errorf("expected permanent talents to be empty after reset, got %v", saved.LFLCDNGALME.PKELAIPIHMF.MHFHLBHFIBC.BDGMNPIJDDL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyWarsArchiveHandlers(t *testing.T) {
|
||||
record := &pb.OEDHMAHDECC{
|
||||
Reason: pb.PEIJNEFOCHI_PEIJNEFOCHI_JOJPGBCECLN,
|
||||
IsOverlock: false,
|
||||
}
|
||||
entry := cwRecordArchive(record, 2, 1)
|
||||
if entry == nil || entry.BAAGDILLLME == 0 {
|
||||
t.Fatal("archive record failed")
|
||||
}
|
||||
|
||||
session := &Session{Token: 54321}
|
||||
|
||||
// Toggle Favour
|
||||
favourReq := &pb.FavourArchiveCsReq{BAAGDILLLME: entry.BAAGDILLLME, IECKKCHJMLP: true}
|
||||
favourCmdID, ok := pb.CmdIDByName["FavourArchiveCsReq"]
|
||||
if !ok || typedHandlers[uint16(favourCmdID)] == nil {
|
||||
t.Fatal("FavourArchive handler missing")
|
||||
}
|
||||
rawFavour, err := proto.Marshal(favourReq)
|
||||
if err != nil {
|
||||
t.Fatalf("marshal favourReq: %v", err)
|
||||
}
|
||||
if err := typedHandlers[uint16(favourCmdID)](session, rawFavour); err != nil {
|
||||
t.Fatalf("call FavourArchive: %v", err)
|
||||
}
|
||||
|
||||
foundFavour := false
|
||||
globalCWArchive.mu.RLock()
|
||||
for _, e := range globalCWArchive.entries {
|
||||
if e.BAAGDILLLME == entry.BAAGDILLLME && e.IECKKCHJMLP {
|
||||
foundFavour = true
|
||||
break
|
||||
}
|
||||
}
|
||||
globalCWArchive.mu.RUnlock()
|
||||
if !foundFavour {
|
||||
t.Errorf("expected archive %d to be favoured", entry.BAAGDILLLME)
|
||||
}
|
||||
|
||||
// Get Archive
|
||||
getArchiveCmdID, ok := pb.CmdIDByName["GridFightGetArchiveCsReq"]
|
||||
if !ok || typedHandlers[uint16(getArchiveCmdID)] == nil {
|
||||
t.Fatal("GridFightGetArchive handler missing")
|
||||
}
|
||||
rawGetArchive, _ := proto.Marshal(&pb.GridFightGetArchiveCsReq{Type: pb.MLJIILDNDPL_MLJIILDNDPL_FAGECPGMPEH})
|
||||
if err := typedHandlers[uint16(getArchiveCmdID)](session, rawGetArchive); err != nil {
|
||||
t.Fatalf("call GridFightGetArchive: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyWarsCalculateBoardTraits(t *testing.T) {
|
||||
catalog, err := common.LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
t.Fatalf("load catalog: %v", err)
|
||||
}
|
||||
// Role 100402 (Welt) in Season 2 has TraitList: [ 100502, 200302 ]
|
||||
run := &pb.MPIMAEMCEFH{
|
||||
NAGDJGMMCBE: []*pb.GridFightGameInfo{
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_EJIPINIKNCK{
|
||||
EJIPINIKNCK: &pb.HKFECLCHBFJ{
|
||||
GridGameRoleList: []*pb.CDEAABODKCP{
|
||||
{Id: 100402, RoleStar: 1, Pos: 1, UniqueId: 101},
|
||||
{Id: 100402, RoleStar: 1, Pos: 2, UniqueId: 102},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
traits := cwCalculateBoardTraits(catalog, run)
|
||||
if len(traits) == 0 {
|
||||
t.Fatal("expected computed traits for deployed roles")
|
||||
}
|
||||
foundTrait := false
|
||||
for _, tr := range traits {
|
||||
if tr.TraitId == 100502 || tr.TraitId == 200302 {
|
||||
foundTrait = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundTrait {
|
||||
t.Errorf("expected Welt traits to be computed, got %v", traits)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyWarsOrbDropsAndClaim(t *testing.T) {
|
||||
origPersistent, _ := os.ReadFile("persistent")
|
||||
if origPersistent != nil {
|
||||
t.Cleanup(func() {
|
||||
_ = os.WriteFile("persistent", origPersistent, 0644)
|
||||
})
|
||||
}
|
||||
|
||||
catalog, err := common.LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
t.Fatalf("load catalog: %v", err)
|
||||
}
|
||||
|
||||
// 1. Test cwRollNodeOrbs for various stages in Route 2801
|
||||
// 1-1: 900 -> 4 rolls
|
||||
orbs1_1, err := cwRollNodeOrbs(catalog, nil, 2801, 1, 1, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("cwRollNodeOrbs 1-1: %v", err)
|
||||
}
|
||||
if len(orbs1_1) != 4 {
|
||||
t.Errorf("expected 4 orbs from 1-1, got %d", len(orbs1_1))
|
||||
}
|
||||
|
||||
// Progress 50% on 1-1: (4*50 + 99)/100 = 2 orbs
|
||||
orbs1_1_half, err := cwRollNodeOrbs(catalog, nil, 2801, 1, 1, 50)
|
||||
if err != nil {
|
||||
t.Fatalf("cwRollNodeOrbs 1-1 half: %v", err)
|
||||
}
|
||||
if len(orbs1_1_half) != 2 {
|
||||
t.Errorf("expected 2 orbs from 1-1 at 50%% progress, got %d", len(orbs1_1_half))
|
||||
}
|
||||
|
||||
// 1-5 (monster 902 in route 2801): 8 rolls
|
||||
orbs1_5, err := cwRollNodeOrbs(catalog, nil, 2801, 1, 5, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("cwRollNodeOrbs 1-5: %v", err)
|
||||
}
|
||||
if len(orbs1_5) != 8 {
|
||||
t.Errorf("expected 8 orbs from 1-5, got %d", len(orbs1_5))
|
||||
}
|
||||
|
||||
// 2-4 (monster 903): 10 rolls
|
||||
orbs2_4, err := cwRollNodeOrbs(catalog, nil, 2801, 2, 4, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("cwRollNodeOrbs 2-4: %v", err)
|
||||
}
|
||||
if len(orbs2_4) != 10 {
|
||||
t.Errorf("expected 10 orbs from 2-4, got %d", len(orbs2_4))
|
||||
}
|
||||
|
||||
// 3-4 (monster 904): 6 rolls
|
||||
orbs3_4, err := cwRollNodeOrbs(catalog, nil, 2801, 3, 4, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("cwRollNodeOrbs 3-4: %v", err)
|
||||
}
|
||||
if len(orbs3_4) != 6 {
|
||||
t.Errorf("expected 6 orbs from 3-4, got %d", len(orbs3_4))
|
||||
}
|
||||
|
||||
// Non-combat / Supply node (1-3): 0 orbs
|
||||
orbs1_3, err := cwRollNodeOrbs(catalog, nil, 2801, 1, 3, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("cwRollNodeOrbs 1-3: %v", err)
|
||||
}
|
||||
if len(orbs1_3) != 0 {
|
||||
t.Errorf("expected 0 orbs from supply node 1-3, got %d", len(orbs1_3))
|
||||
}
|
||||
|
||||
// 2. Test cwUseOrbs with Orb 305 and multiple orbs
|
||||
session := &Session{Token: 99887}
|
||||
orbBag := &pb.DBONCGFHHDN{
|
||||
MDKGCIKOMLI: []*pb.IBPDPCOGDEP{
|
||||
{UniqueId: 5001, LDBNOMPCOKK: 102},
|
||||
{UniqueId: 5002, LDBNOMPCOKK: 103},
|
||||
{UniqueId: 5003, LDBNOMPCOKK: 305},
|
||||
},
|
||||
}
|
||||
data, err := newCurrencyWarsData(catalog)
|
||||
if err != nil {
|
||||
t.Fatalf("new data: %v", err)
|
||||
}
|
||||
testRun := &pb.MPIMAEMCEFH{
|
||||
UniqueId: 99887,
|
||||
LJNGPCKPJLF: catalog.ActiveSeasonID,
|
||||
DivisionId: data.LFLCDNGALME.HFPEJIDDDJG.DivisionId,
|
||||
NAGDJGMMCBE: []*pb.GridFightGameInfo{
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_KLCPAAHDPJF{
|
||||
KLCPAAHDPJF: &pb.BEEFLEJAOCN{
|
||||
DCAHJELNJNP: 1,
|
||||
SectionId: 1,
|
||||
EMOHLJHPOPC: 2801,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_FAOCFBOFCJP{
|
||||
FAOCFBOFCJP: &pb.NIHNGPKHEPC{
|
||||
Gold: 100,
|
||||
MICEOJBAKGN: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_EJIPINIKNCK{
|
||||
EJIPINIKNCK: &pb.HKFECLCHBFJ{},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_GCKLIONKMJC{
|
||||
GCKLIONKMJC: &pb.CONONEALNOF{},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_EBHDIOGALIE{
|
||||
EBHDIOGALIE: &pb.POCJDMMANBM{},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_DBAGKJNPDOL{
|
||||
DBAGKJNPDOL: orbBag,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
data.DHFOFLFCLAH = testRun
|
||||
_, rev, _ := readCurrencyWarsData(catalog)
|
||||
session.currencyWarsRevision = rev
|
||||
if err := session.saveCurrencyWarsData(data, catalog); err != nil {
|
||||
t.Fatalf("save initial data with orbs: %v", err)
|
||||
}
|
||||
|
||||
// Claim all orbs
|
||||
useReq := &pb.IKMOCJBMGOJ{IsGetAll: true}
|
||||
if err := cwUseOrbs(session, useReq); err != nil {
|
||||
t.Fatalf("cwUseOrbs with IsGetAll: %v", err)
|
||||
}
|
||||
|
||||
// Verify bag in saved data is now empty
|
||||
saved, _, err := readCurrencyWarsData(catalog)
|
||||
if err != nil || saved == nil || saved.DHFOFLFCLAH == nil {
|
||||
t.Fatalf("read saved data: %v", err)
|
||||
}
|
||||
var savedBag *pb.DBONCGFHHDN
|
||||
for _, c := range saved.DHFOFLFCLAH.NAGDJGMMCBE {
|
||||
if b := c.GetDBAGKJNPDOL(); b != nil {
|
||||
savedBag = b
|
||||
break
|
||||
}
|
||||
}
|
||||
if savedBag != nil && len(savedBag.MDKGCIKOMLI) != 0 {
|
||||
t.Errorf("expected 0 orbs left in bag, got %d", len(savedBag.MDKGCIKOMLI))
|
||||
}
|
||||
|
||||
// 3. Test idempotency: clicking already consumed or ghost orbs must NOT return error (avoids 6900 error toast)
|
||||
ghostReq := &pb.IKMOCJBMGOJ{CBMGDBJHLHO: []uint32{5001, 5002, 5003}}
|
||||
if err := cwUseOrbs(session, ghostReq); err != nil {
|
||||
t.Fatalf("cwUseOrbs on already consumed orbs returned error: %v", err)
|
||||
}
|
||||
|
||||
// Calling IsGetAll when bag is already empty must also succeed cleanly
|
||||
if err := cwUseOrbs(session, &pb.IKMOCJBMGOJ{IsGetAll: true}); err != nil {
|
||||
t.Fatalf("cwUseOrbs with IsGetAll on empty bag returned error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyWarsTerminalSettlementLogic(t *testing.T) {
|
||||
catalog, err := common.LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
t.Fatalf("load catalog: %v", err)
|
||||
}
|
||||
run := &pb.MPIMAEMCEFH{
|
||||
UniqueId: 999,
|
||||
LJNGPCKPJLF: catalog.ActiveSeasonID,
|
||||
DivisionId: 1,
|
||||
NAGDJGMMCBE: []*pb.GridFightGameInfo{
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_KLCPAAHDPJF{
|
||||
KLCPAAHDPJF: &pb.BEEFLEJAOCN{
|
||||
DCAHJELNJNP: 3,
|
||||
SectionId: 5,
|
||||
EMOHLJHPOPC: 2801,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_FAOCFBOFCJP{
|
||||
FAOCFBOFCJP: &pb.NIHNGPKHEPC{
|
||||
Gold: 500,
|
||||
GridFightLineupHp: 100,
|
||||
PPKKHHNEOHB: 100,
|
||||
GDAKCOICIDA: 7,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_EJIPINIKNCK{
|
||||
EJIPINIKNCK: &pb.HKFECLCHBFJ{
|
||||
GridGameRoleList: []*pb.CDEAABODKCP{
|
||||
{Id: 1001, UniqueId: 1, Pos: 1, RoleStar: 3},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
keepWin, settle, err := currencyWarsTerminalSettlement(catalog, nil, run, pb.PEIJNEFOCHI_PEIJNEFOCHI_JOJPGBCECLN, true, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("currencyWarsTerminalSettlement failed: %v", err)
|
||||
}
|
||||
if keepWin == nil || settle == nil {
|
||||
t.Fatal("expected non-nil keepWin and settle notifications")
|
||||
}
|
||||
if settle.BFLLJJBHLDF == nil || settle.BFLLJJBHLDF.Reason != pb.PEIJNEFOCHI_PEIJNEFOCHI_JOJPGBCECLN {
|
||||
t.Errorf("expected victory reason in settlement, got %v", settle.BFLLJJBHLDF)
|
||||
}
|
||||
if settle.BFLLJJBHLDF.NDLIKNEKDLL.DCAHJELNJNP != 3 || settle.BFLLJJBHLDF.NDLIKNEKDLL.SectionId != 5 {
|
||||
t.Errorf("expected 3-5 stage in settlement, got %d-%d", settle.BFLLJJBHLDF.NDLIKNEKDLL.DCAHJELNJNP, settle.BFLLJJBHLDF.NDLIKNEKDLL.SectionId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyWarsBonfireSelectHeal(t *testing.T) {
|
||||
origPersistent, _ := os.ReadFile("persistent")
|
||||
if origPersistent != nil {
|
||||
t.Cleanup(func() {
|
||||
_ = os.WriteFile("persistent", origPersistent, 0644)
|
||||
})
|
||||
}
|
||||
catalog, err := common.LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
t.Fatalf("load catalog: %v", err)
|
||||
}
|
||||
offer := &pb.NCEPOLNLNKH{
|
||||
Phase: cwBonfireChoosing,
|
||||
EIFICNFGGHI: 10,
|
||||
AHJJJNBOMPG: 2,
|
||||
DANCNIMJOLE: 3,
|
||||
KFNMIEMBJGD: []*pb.MHCOIBONODA{
|
||||
{EventId: 10200601, HAFOKMHCGFM: 1},
|
||||
},
|
||||
}
|
||||
run := &pb.MPIMAEMCEFH{
|
||||
UniqueId: 101,
|
||||
LJNGPCKPJLF: catalog.ActiveSeasonID,
|
||||
DivisionId: 1,
|
||||
FMIGOKIDKJL: &pb.CHCHAJIANIM{
|
||||
QueuePosition: 795,
|
||||
FGLIODAJFML: &pb.CHCHAJIANIM_IIDBLCFAAPC{
|
||||
IIDBLCFAAPC: offer,
|
||||
},
|
||||
},
|
||||
NAGDJGMMCBE: []*pb.GridFightGameInfo{
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_KLCPAAHDPJF{
|
||||
KLCPAAHDPJF: &pb.BEEFLEJAOCN{
|
||||
DCAHJELNJNP: 1,
|
||||
SectionId: 5,
|
||||
EMOHLJHPOPC: 2801,
|
||||
BossInfo: &pb.KGMCLFHAJNJ{NCGHKPEMPDP: []*pb.AHKDPCIIELA{{MonsterId: 1004016, RoleStar: 1, LOGHLGKIFEN: 1}}},
|
||||
HEKMEJLMGFF: []*pb.LHNCMINFONJ{{LOGHLGKIFEN: 1}},
|
||||
OOMMIIKPHBC: []*pb.BCCIJHPLJOJ{
|
||||
{DCAHJELNJNP: 1, SectionId: 6, DisplayValue: &pb.OHMDHKGAEMM{StageId: 70000009}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_FAOCFBOFCJP{
|
||||
FAOCFBOFCJP: &pb.NIHNGPKHEPC{
|
||||
Gold: 50,
|
||||
GridFightLineupHp: 60,
|
||||
PPKKHHNEOHB: 100,
|
||||
EHNJDIDABHD: 1,
|
||||
NDAINFLOLPJ: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_EJIPINIKNCK{
|
||||
EJIPINIKNCK: &pb.HKFECLCHBFJ{},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_EBHDIOGALIE{
|
||||
EBHDIOGALIE: &pb.POCJDMMANBM{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
// 1. Test Select Heal HP
|
||||
healReq := &pb.CAMIICJDOBO{
|
||||
FFBBOFAGGDI: &pb.CAMIICJDOBO_NCGOOEMOBIC{
|
||||
NCGOOEMOBIC: &pb.MLAENDOFBCK{
|
||||
FFBBOFAGGDI: &pb.MLAENDOFBCK_LGAJNMNOAEM{
|
||||
LGAJNMNOAEM: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
notify, _, err := cwSelectBonfire(catalog, run, healReq)
|
||||
if err != nil {
|
||||
t.Fatalf("cwSelectBonfire heal failed: %v", err)
|
||||
}
|
||||
if notify == nil {
|
||||
t.Fatal("expected notify from heal")
|
||||
}
|
||||
if offer.Phase != cwBonfireSelected {
|
||||
t.Errorf("expected phase %v, got %v", cwBonfireSelected, offer.Phase)
|
||||
}
|
||||
player, _, _ := cwComponents(run)
|
||||
if player.GridFightLineupHp != 80 {
|
||||
t.Errorf("expected 80 HP after heal, got %d", player.GridFightLineupHp)
|
||||
}
|
||||
|
||||
// 2. Test Take Bonfire rewards and advance node
|
||||
takeReq := &pb.CAMIICJDOBO{
|
||||
FFBBOFAGGDI: &pb.CAMIICJDOBO_ECDACDNDHGO{
|
||||
ECDACDNDHGO: &pb.EFIEAIJBHIB{},
|
||||
},
|
||||
}
|
||||
takeNotify, _, err := cwSelectBonfire(catalog, run, takeReq)
|
||||
if err != nil {
|
||||
t.Fatalf("cwSelectBonfire take failed: %v", err)
|
||||
}
|
||||
if takeNotify == nil {
|
||||
t.Fatal("expected notify from take")
|
||||
}
|
||||
stage, _ := cwStage(run)
|
||||
if stage.SectionId != 6 {
|
||||
t.Errorf("expected node advance to section 6, got %d", stage.SectionId)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintSaveRoles(t *testing.T) {
|
||||
catalog, err := common.LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
t.Fatalf("catalog: %v", err)
|
||||
}
|
||||
data, _, err := readCurrencyWarsData(catalog)
|
||||
if err != nil || data == nil || data.DHFOFLFCLAH == nil {
|
||||
t.Skip("no active run in persistent snapshot")
|
||||
}
|
||||
run := data.DHFOFLFCLAH
|
||||
_, team, _ := cwComponents(run)
|
||||
if team == nil {
|
||||
t.Fatal("team nil")
|
||||
}
|
||||
for _, r := range team.GridGameRoleList {
|
||||
v, _ := catalog.CapturedRoleVariant(r.Id, r.RoleStar)
|
||||
t.Logf("Role ID=%d Star=%d Pos=%d AvatarID=%d BABNHPDGNGB=%v Props=%v ValInit=%v", r.Id, r.RoleStar, r.Pos, v.Config.AvatarID, r.BABNHPDGNGB, r.ConvertPropertyToFixpoint, r.GridFightValueInitComponent)
|
||||
}
|
||||
runtime, _ := cwBonfireRuntime(catalog, run)
|
||||
if runtime != nil {
|
||||
t.Logf("Runtime rules: %v", runtime.Rules)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCurrencyWarsGrantRandomOrb(t *testing.T) {
|
||||
catalog, err := common.LoadCurrencyWarsCatalog()
|
||||
if err != nil {
|
||||
t.Fatalf("load catalog: %v", err)
|
||||
}
|
||||
run := &pb.MPIMAEMCEFH{
|
||||
UniqueId: 999,
|
||||
NAGDJGMMCBE: []*pb.GridFightGameInfo{
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_DBAGKJNPDOL{
|
||||
DBAGKJNPDOL: &pb.DBONCGFHHDN{},
|
||||
},
|
||||
},
|
||||
{
|
||||
LEOIAOFBBFA: &pb.GridFightGameInfo_FAOCFBOFCJP{
|
||||
FAOCFBOFCJP: &pb.NIHNGPKHEPC{
|
||||
Gold: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cmd := common.CurrencyWarsCommand{
|
||||
Field: "orb",
|
||||
Value: 0,
|
||||
Quantity: 3,
|
||||
}
|
||||
notify, err := cwApplyCommand(catalog, run, cmd)
|
||||
if err != nil {
|
||||
t.Fatalf("cwApplyCommand random orb: %v", err)
|
||||
}
|
||||
if notify == nil || len(notify.GCPNIHHBGGD) == 0 {
|
||||
t.Fatal("expected notify with update bundle")
|
||||
}
|
||||
if len(notify.GCPNIHHBGGD[0].JKPJFKCBIEM) != 3 {
|
||||
t.Fatalf("expected 3 notify items, got %d", len(notify.GCPNIHHBGGD[0].JKPJFKCBIEM))
|
||||
}
|
||||
var bag *pb.DBONCGFHHDN
|
||||
for _, c := range run.NAGDJGMMCBE {
|
||||
if b := c.GetDBAGKJNPDOL(); b != nil {
|
||||
bag = b
|
||||
break
|
||||
}
|
||||
}
|
||||
if bag == nil || len(bag.MDKGCIKOMLI) != 3 {
|
||||
t.Fatalf("expected 3 orbs in bag, got %v", bag)
|
||||
}
|
||||
// Verify that all granted orbs have valid, implemented IDs
|
||||
recipes, err := common.LoadCurrencyWarsOrbRecipes()
|
||||
if err != nil {
|
||||
t.Fatalf("load recipes: %v", err)
|
||||
}
|
||||
implemented := make(map[uint32]bool)
|
||||
for _, r := range recipes.Recipes {
|
||||
if r.Status == "Implemented" && r.Engine == "Orb" {
|
||||
implemented[r.ID] = true
|
||||
}
|
||||
}
|
||||
for i, orb := range bag.MDKGCIKOMLI {
|
||||
if !implemented[orb.LDBNOMPCOKK] {
|
||||
t.Errorf("orb[%d] id %d is not an implemented orb", i, orb.LDBNOMPCOKK)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user