#include "global.h" #include "battle_records.h" #include "constants/game_stat.h" #include "link.h" #include "menu.h" #include "overworld.h" #include "string_util.h" #include "strings2.h" #include "trainer_card.h" struct DebugStruct1 { u16 var0; u8 var1[10]; }; extern struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4]; extern u8 gBattleOutcome; #if DEBUG const struct DebugStruct1 gUnknown_Debug_4245CC[] = { { 1, _("NUMBER1") }, { 2, DTR("ナンバー2", "NUMBER2") }, { 3, DTR("ナンバー3", "NUMBER3") }, { 4, DTR("ナンバー4", "NUMBER4") }, { 5, DTR("ナンバー5", "NUMBER5") }, { 6, DTR("ナンバー6", "NUMBER6") }, { 7, DTR("ナンバー7", "NUMBER7") }, }; const struct {u8 totalPoints; u8 nextTurnSpriteId;} gUnknown_Debug_8424620[] = { { 1, 1 }, { 2, 1 }, { 3, 1 }, }; #endif static void InitLinkBattleRecord(struct LinkBattleRecord *record) { CpuFill16(0, record, sizeof(struct LinkBattleRecord)); record->name[0] = 0xFF; record->trainerId = 0; record->wins = 0; record->losses = 0; record->draws = 0; } static void InitLinkBattleRecords_(struct LinkBattleRecord *records) { int i; for (i = 0; i < 5; i++) { InitLinkBattleRecord(records + i); } SetGameStat(GAME_STAT_LINK_BATTLE_WINS, 0); SetGameStat(GAME_STAT_LINK_BATTLE_LOSSES, 0); SetGameStat(GAME_STAT_LINK_BATTLE_DRAWS, 0); } static int GetLinkBattleRecordTotalBattles(struct LinkBattleRecord *record) { return record->wins + record->losses + record->draws; } static int FindLinkBattleRecord(struct LinkBattleRecord *records, const u8 *name, u16 trainerId) { int i; for (i = 0; i < 5; i++) { memcpy(gStringVar1, records[i].name, 7); gStringVar1[7] = EOS; if (!StringCompareWithoutExtCtrlCodes(gStringVar1, name) && records[i].trainerId == trainerId) return i; } return 5; } static void SortLinkBattleRecords(struct LinkBattleRecord *records) { int i, j; for (i = 4; i > 0; i--) { for (j = i - 1; j >= 0; j--) { int totalBattlesI = GetLinkBattleRecordTotalBattles(records + i); int totalBattlesJ = GetLinkBattleRecordTotalBattles(records + j); if (totalBattlesI > totalBattlesJ) { struct LinkBattleRecord temp = *(records + i); *(records + i) = *(records + j); *(records + j) = temp; } } } } static void UpdateLinkBattleRecord(struct LinkBattleRecord *record, int battleOutcome) { switch (battleOutcome) { case 1: record->wins++; if (record->wins > 9999) record->wins = 9999; break; case 2: record->losses++; if (record->losses > 9999) record->losses = 9999; break; case 3: record->draws++; if (record->draws > 9999) record->draws = 9999; break; } } static void UpdateLinkBattleGameStats(int battleOutcome) { u8 stat; switch (battleOutcome) { case 1: stat = GAME_STAT_LINK_BATTLE_WINS; break; case 2: stat = GAME_STAT_LINK_BATTLE_LOSSES; break; case 3: stat = GAME_STAT_LINK_BATTLE_DRAWS; break; default: return; } if (GetGameStat(stat) < 9999) IncrementGameStat(stat); } static void UpdateLinkBattleRecords_(struct LinkBattleRecord *records, const u8 *name, u16 trainerId, int battleOutcome, u8 language) { int index; UpdateLinkBattleGameStats(battleOutcome); SortLinkBattleRecords(records); index = FindLinkBattleRecord(records, name, trainerId); if (index == 5) { index = 4; InitLinkBattleRecord(records + index); if (language == LANGUAGE_JAPANESE) { records[index].name[0] = EXT_CTRL_CODE_BEGIN; records[index].name[1] = 0x15; StringCopyN(records[index].name + 2, name, 5); } else { StringCopyN(records[index].name, name, 7); } // needed block to match { struct LinkBattleRecord *record = records + index; record->trainerId = trainerId; } } UpdateLinkBattleRecord(records + index, battleOutcome); SortLinkBattleRecords(records); } void InitLinkBattleRecords(void) { InitLinkBattleRecords_(gSaveBlock1.linkBattleRecords); } static void IncTrainerCardWins(int id) { u16 *wins = &gTrainerCards[id].linkBattleWins; (*wins)++; if (*wins > 9999) *wins = 9999; } static void IncTrainerCardLosses(int id) { u16 *losses = &gTrainerCards[id].linkBattleLosses; (*losses)++; if (*losses > 9999) *losses = 9999; } static void UpdateTrainerCardWinsLosses(int id) { switch (gBattleOutcome) { case 1: IncTrainerCardWins(id ^ 1); IncTrainerCardLosses(id); break; case 2: IncTrainerCardLosses(id ^ 1); IncTrainerCardWins(id); break; } } void UpdateLinkBattleRecords(int id) { UpdateTrainerCardWinsLosses(id); UpdateLinkBattleRecords_( gSaveBlock1.linkBattleRecords, gTrainerCards[id].playerName, gTrainerCards[id].trainerId, gBattleOutcome, gLinkPlayers[gLinkPlayerObjectEvents[id].linkPlayerId].language); } #if DEBUG void debug_sub_81257E0(void) { u32 i; InitLinkBattleRecords(); for (i = 0; i < 3; i++) { u32 id = gUnknown_Debug_8424620[i].totalPoints - 1; UpdateLinkBattleRecords_( gSaveBlock1.linkBattleRecords, gUnknown_Debug_4245CC[id].var1, gUnknown_Debug_4245CC[id].var0, gUnknown_Debug_8424620[i].nextTurnSpriteId, gLinkPlayers[gLinkPlayerObjectEvents[id].linkPlayerId].language); } } #endif static void PrintLinkBattleWinsLossesDraws(struct LinkBattleRecord *records) { ConvertIntToDecimalStringN_DigitWidth6(gStringVar1, GetGameStat(GAME_STAT_LINK_BATTLE_WINS), STR_CONV_MODE_RIGHT_ALIGN, 4); ConvertIntToDecimalStringN_DigitWidth6(gStringVar2, GetGameStat(GAME_STAT_LINK_BATTLE_LOSSES), STR_CONV_MODE_RIGHT_ALIGN, 4); ConvertIntToDecimalStringN_DigitWidth6(gStringVar3, GetGameStat(GAME_STAT_LINK_BATTLE_DRAWS), STR_CONV_MODE_RIGHT_ALIGN, 4); Menu_PrintText(gOtherText_WinRecord, 3, 3); } static void PrintLinkBattleRecord(struct LinkBattleRecord *record, u8 y) { if (!record->wins && !record->losses && !record->draws) { u8 buffer[16]; buffer[0] = EXT_CTRL_CODE_BEGIN; buffer[1] = 0x14; buffer[2] = 6; buffer[3] = EXT_CTRL_CODE_BEGIN; buffer[4] = 0x11; buffer[5] = 1; StringCopy(buffer + 6, gOtherText_SevenDashes); Menu_PrintText(buffer, 3, y); StringCopy(buffer + 6, gOtherText_FourDashes); Menu_PrintText(buffer, 11, y); Menu_PrintText(buffer, 17, y); Menu_PrintText(buffer, 23, y); } else { StringFillWithTerminator(gStringVar1, 8); StringCopyN(gStringVar1, record->name, 7); Menu_PrintText(gStringVar1, 3, y); gStringVar1[0] = EXT_CTRL_CODE_BEGIN; gStringVar1[1] = 0x14; gStringVar1[2] = 6; ConvertIntToDecimalStringN(gStringVar1 + 3, record->wins, STR_CONV_MODE_RIGHT_ALIGN, 4); Menu_PrintText(gStringVar1, 11, y); ConvertIntToDecimalStringN(gStringVar1 + 3, record->losses, STR_CONV_MODE_RIGHT_ALIGN, 4); Menu_PrintText(gStringVar1, 17, y); ConvertIntToDecimalStringN(gStringVar1 + 3, record->draws, STR_CONV_MODE_RIGHT_ALIGN, 4); Menu_PrintText(gStringVar1, 23, y); } } void ShowLinkBattleRecords(void) { s32 i; Menu_DrawStdWindowFrame(1, 0, 28, 18); MenuPrint_Centered(gOtherText_BattleResults, 0, 1, 240); PrintLinkBattleWinsLossesDraws(gSaveBlock1.linkBattleRecords); #if ENGLISH Menu_PrintText(gOtherText_WinLoseDraw, 12, 6); #elif GERMAN Menu_PrintTextPixelCoords(gOtherText_WinLoseDraw, 88, 48, 1); #endif for (i = 0; i < 5; i++) { PrintLinkBattleRecord(&gSaveBlock1.linkBattleRecords[i], 6 + (i + 1) * 2); } } static bool32 sub_8110494(u8 level) { struct BattleTowerData *battleTower = &gSaveBlock2.battleTower; switch (battleTower->var_4AE[level]) { case 0: return FALSE; case 1: return FALSE; case 2: return TRUE; case 4: return FALSE; case 3: return TRUE; case 5: return FALSE; case 6: return TRUE; default: return FALSE; } } static void PrintWinStreak(const u8 *str, u16 streak, u8 left, u8 top) { Menu_PrintText(str, left, top); if (streak > 9999) streak = 9999; AlignInt1InMenuWindow(gStringVar1, streak, 24, 1); Menu_PrintText(gOtherText_WinStreak, left + 7, top); } static void PrintRecordWinStreak(u8 level, u8 left, u8 top) { struct BattleTowerData *battleTower = &gSaveBlock2.battleTower; u16 winStreak = battleTower->recordWinStreaks[level]; PrintWinStreak(gOtherText_Record, winStreak, left, top); } static u16 GetLastWinStreak(u8 level) { u16 winStreak = gSaveBlock2.battleTower.currentWinStreaks[level]; if (winStreak > 9999) winStreak = 9999; return winStreak; } static void PrintLastWinStreak(u8 level, u8 left, u8 top) { u16 winStreak = GetLastWinStreak(level); if (sub_8110494(level) == TRUE) PrintWinStreak(gOtherText_Current, winStreak, left, top); else PrintWinStreak(gOtherText_Prev, winStreak, left, top); } void ShowBattleTowerRecords(void) { u16 i; Menu_DrawStdWindowFrame(3, 1, 27, 17); MenuPrint_Centered(gOtherText_BattleTowerResults, 3, 2, 0xC8); Menu_PrintText(gOtherText_Lv50, 5, 6); Menu_PrintText(gOtherText_Lv100, 5, 12); for (i = 5; i < 26; i++) { sub_8071F60(CHAR_HYPHEN, i, 10); } PrintLastWinStreak(0, 10, 6); PrintRecordWinStreak(0, 10, 8); PrintLastWinStreak(1, 10, 12); PrintRecordWinStreak(1, 10, 14); }