From addebea4d69dd7409de2ec922b052416d53b0ebf Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 7 May 2025 16:25:10 -0400 Subject: [PATCH] Better handling of battle coords (#6787) --- include/battle_interface.h | 10 ++- src/battle_anim_mons.c | 30 +++---- src/battle_controller_player.c | 2 +- src/battle_gfx_sfx_util.c | 9 ++- src/battle_interface.c | 143 ++++++++++++++++++--------------- 5 files changed, 109 insertions(+), 85 deletions(-) diff --git a/include/battle_interface.h b/include/battle_interface.h index 600a9a956d..dc3348cfba 100644 --- a/include/battle_interface.h +++ b/include/battle_interface.h @@ -3,6 +3,14 @@ #include "battle_controllers.h" +// used for sBattlerCoords and sBattlerHealthboxCoords +enum BattleCoordTypes +{ + BATTLE_COORDS_SINGLES, + BATTLE_COORDS_DOUBLES, + BATTLE_COORDS_COUNT, +}; + enum { HP_CURRENT, @@ -100,7 +108,7 @@ enum HEALTHBOX_SAFARI_BALLS_TEXT }; -u32 WhichBattleCoords(u32 battlerId); +enum BattleCoordTypes GetBattlerCoordsIndex(u32 battler); u8 CreateBattlerHealthboxSprites(u8 battler); u8 CreateSafariPlayerHealthboxSprites(void); void SetBattleBarStruct(u8 battler, u8 healthboxSpriteId, s32 maxVal, s32 currVal, s32 receivedValue); diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c index 03f0dd8bfa..f352bc479c 100644 --- a/src/battle_anim_mons.c +++ b/src/battle_anim_mons.c @@ -34,19 +34,21 @@ static void CreateBattlerTrace(struct Task *task, u8 taskId); EWRAM_DATA static union AffineAnimCmd *sAnimTaskAffineAnim = NULL; -const struct UCoords8 sBattlerCoords[][MAX_BATTLERS_COUNT] = +const struct UCoords8 sBattlerCoords[BATTLE_COORDS_COUNT][MAX_BATTLERS_COUNT] = { - { // Single battle - { 72, 80 }, - { 176, 40 }, - { 48, 40 }, - { 112, 80 }, + [BATTLE_COORDS_SINGLES] = + { + [B_POSITION_PLAYER_LEFT] = { 72, 80 }, + [B_POSITION_OPPONENT_LEFT] = { 176, 40 }, + [B_POSITION_PLAYER_RIGHT] = { 48, 40 }, + [B_POSITION_OPPONENT_RIGHT] = { 112, 80 }, }, - { // Double battle - { 32, 80 }, - { 200, 40 }, - { 90, 88 }, - { 152, 32 }, + [BATTLE_COORDS_DOUBLES] = + { + [B_POSITION_PLAYER_LEFT] = { 32, 80 }, + [B_POSITION_OPPONENT_LEFT] = { 200, 40 }, + [B_POSITION_PLAYER_RIGHT] = { 90, 84 }, + [B_POSITION_OPPONENT_RIGHT] = { 152, 32 }, }, }; @@ -99,10 +101,10 @@ u8 GetBattlerSpriteCoord(u8 battlerId, u8 coordType) { case BATTLER_COORD_X: case BATTLER_COORD_X_2: - retVal = sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].x; + retVal = sBattlerCoords[GetBattlerCoordsIndex(battlerId)][GetBattlerPosition(battlerId)].x; break; case BATTLER_COORD_Y: - retVal = sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].y; + retVal = sBattlerCoords[GetBattlerCoordsIndex(battlerId)][GetBattlerPosition(battlerId)].y; break; case BATTLER_COORD_Y_PIC_OFFSET: case BATTLER_COORD_Y_PIC_OFFSET_DEFAULT: @@ -202,7 +204,7 @@ u8 GetBattlerSpriteFinal_Y(u8 battlerId, u16 species, bool8 a3) offset = GetBattlerYDelta(battlerId, species); offset -= GetBattlerElevation(battlerId, species); } - y = offset + sBattlerCoords[WhichBattleCoords(battlerId)][GetBattlerPosition(battlerId)].y; + y = offset + sBattlerCoords[GetBattlerCoordsIndex(battlerId)][GetBattlerPosition(battlerId)].y; if (a3) { if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index f36a2c9687..c828fd9c27 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -1446,7 +1446,7 @@ static void Task_GiveExpToMon(u8 taskId) u8 battler = gTasks[taskId].tExpTask_battler; s32 gainedExp = GetTaskExpValue(taskId); - if (WhichBattleCoords(battler) == 1 || monId != gBattlerPartyIndexes[battler]) // Give exp without moving the expbar. + if (GetBattlerCoordsIndex(battler) == BATTLE_COORDS_DOUBLES || monId != gBattlerPartyIndexes[battler]) // Give exp without moving the expbar. { struct Pokemon *mon = &gPlayerParty[monId]; u16 species = GetMonData(mon, MON_DATA_SPECIES); diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index c4b8df1d9c..7c3cdd4055 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -780,10 +780,15 @@ bool8 BattleLoadAllHealthBoxesGfx(u8 state) { if (state == 2) { - if (WhichBattleCoords(0)) + switch (GetBattlerCoordsIndex(B_POSITION_PLAYER_LEFT)) + { + default: LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[0]); - else + break; + case BATTLE_COORDS_SINGLES: LoadCompressedSpriteSheet(&sSpriteSheet_SinglesPlayerHealthbox); + break; + } } else if (state == 3) LoadCompressedSpriteSheet(&sSpriteSheets_DoublesPlayerHealthbox[1]); diff --git a/src/battle_interface.c b/src/battle_interface.c index 1a34c6c0e9..3d83b0ac28 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -634,18 +634,16 @@ static const struct WindowTemplate sHealthboxWindowTemplate = { // This function is here to cover a specific case - one player's mon in a 2 vs 1 double battle. In this scenario - display singles layout. // The same goes for a 2 vs 1 where opponent has only one pokemon. -u32 WhichBattleCoords(u32 battlerId) // 0 - singles, 1 - doubles +enum BattleCoordTypes GetBattlerCoordsIndex(u32 battler) { - if (GetBattlerPosition(battlerId) == B_POSITION_PLAYER_LEFT - && gPlayerPartyCount == 1 - && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - return 0; - else if (GetBattlerPosition(battlerId) == B_POSITION_OPPONENT_LEFT - && gEnemyPartyCount == 1 - && !(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)) - return 0; + if (GetBattlerPosition(battler) == B_POSITION_PLAYER_LEFT && gPlayerPartyCount == 1 && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) + return BATTLE_COORDS_SINGLES; + else if (GetBattlerPosition(battler) == B_POSITION_OPPONENT_LEFT && gEnemyPartyCount == 1 && !(gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)) + return BATTLE_COORDS_SINGLES; + else if (IsDoubleBattle()) + return BATTLE_COORDS_DOUBLES; else - return IsDoubleBattle(); + return BATTLE_COORDS_SINGLES; } u8 CreateBattlerHealthboxSprites(u8 battlerId) @@ -655,7 +653,10 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId) u8 healthbarSpriteId; struct Sprite *healthBarSpritePtr; - if (WhichBattleCoords(battlerId) == 0) // Singles + switch (GetBattlerCoordsIndex(battlerId)) + { + default: + case BATTLE_COORDS_SINGLES: { if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { @@ -680,35 +681,29 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId) gSprites[healthboxRightSpriteId].hOther_HealthBoxSpriteId = healthboxLeftSpriteId; gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; + break; } - else + case BATTLE_COORDS_DOUBLES: { if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(battlerId) / 2], DISPLAY_WIDTH, DISPLAY_HEIGHT, 1); healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(battlerId) / 2], DISPLAY_WIDTH, DISPLAY_HEIGHT, 1); - - gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId; - - gSprites[healthboxRightSpriteId].hOther_HealthBoxSpriteId = healthboxLeftSpriteId; - gSprites[healthboxRightSpriteId].oam.tileNum += 32; - gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; - data6 = 1; } else { healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(battlerId) / 2], DISPLAY_WIDTH, DISPLAY_HEIGHT, 1); healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(battlerId) / 2], DISPLAY_WIDTH, DISPLAY_HEIGHT, 1); - - gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId; - - gSprites[healthboxRightSpriteId].hOther_HealthBoxSpriteId = healthboxLeftSpriteId; - gSprites[healthboxRightSpriteId].oam.tileNum += 32; - gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; - data6 = 2; } + gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId; + + gSprites[healthboxRightSpriteId].hOther_HealthBoxSpriteId = healthboxLeftSpriteId; + gSprites[healthboxRightSpriteId].oam.tileNum += 32; + gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther; + break; + } } healthbarSpriteId = CreateSpriteAtEnd(&sHealthbarSpriteTemplates[gBattlerPositions[battlerId]], 140, 60, 0); @@ -873,35 +868,29 @@ void UpdateOamPriorityInAllHealthboxes(u8 priority, bool32 hideHPBoxes) } } +static const s16 sBattlerHealthboxCoords[BATTLE_COORDS_COUNT][MAX_BATTLERS_COUNT][2] = +{ + [BATTLE_COORDS_SINGLES] = + { + [B_POSITION_PLAYER_LEFT] = { 158, 88 }, + [B_POSITION_OPPONENT_LEFT] = { 44, 30 }, + }, + [BATTLE_COORDS_DOUBLES] = + { + [B_POSITION_PLAYER_LEFT] = { 159, 76 }, + [B_POSITION_PLAYER_RIGHT] = { 171, 101 }, + [B_POSITION_OPPONENT_LEFT] = { 44, 19 }, + [B_POSITION_OPPONENT_RIGHT] = { 32, 44 }, + }, +}; + void GetBattlerHealthboxCoords(u8 battler, s16 *x, s16 *y) { - *x = 0, *y = 0; + u8 position = GetBattlerPosition(battler); + enum BattleCoordTypes index = GetBattlerCoordsIndex(battler); - if (!WhichBattleCoords(battler)) - { - if (GetBattlerSide(battler) != B_SIDE_PLAYER) - *x = 44, *y = 30; - else - *x = 158, *y = 88; - } - else - { - switch (GetBattlerPosition(battler)) - { - case B_POSITION_PLAYER_LEFT: - *x = 159, *y = 76; - break; - case B_POSITION_PLAYER_RIGHT: - *x = 171, *y = 101; - break; - case B_POSITION_OPPONENT_LEFT: - *x = 44, *y = 19; - break; - case B_POSITION_OPPONENT_RIGHT: - *x = 32, *y = 44; - break; - } - } + *x = sBattlerHealthboxCoords[index][position][0]; + *y = sBattlerHealthboxCoords[index][position][1]; } void InitBattlerHealthboxCoords(u8 battler) @@ -945,10 +934,15 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl) if (GetBattlerSide(battler) == B_SIDE_PLAYER) { objVram = (void *)(OBJ_VRAM0); - if (!WhichBattleCoords(battler)) + switch (GetBattlerCoordsIndex(battler)) + { + case BATTLE_COORDS_SINGLES: objVram += spriteTileNum + 0x820; - else + break; + default: objVram += spriteTileNum + 0x420; + break; + } } else { @@ -1062,14 +1056,17 @@ static void UpdateOpponentHpTextSingles(u32 healthboxSpriteId, s16 value, u32 ma void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp) { - u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler; - if (WhichBattleCoords(battlerId)) + u32 battler = gSprites[healthboxSpriteId].hMain_Battler; + switch (GetBattlerCoordsIndex(battler)) + { + default: { UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, maxOrCurrent, currHp, maxHp); + break; } - else // Single Battle + case BATTLE_COORDS_SINGLES: { - if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Player + if (GetBattlerSide(battler) == B_SIDE_PLAYER) // Player { PrintHpOnHealthbox(healthboxSpriteId, currHp, maxHp, 2, 0xB00, 0x3A0); } @@ -1078,6 +1075,8 @@ void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp UpdateOpponentHpTextSingles(healthboxSpriteId, currHp, HP_CURRENT); UpdateOpponentHpTextSingles(healthboxSpriteId, maxHp, HP_MAX); } + break; + } } } @@ -1178,7 +1177,7 @@ void SwapHpBarsWithHpText(void) { if (gSprites[gHealthboxSpriteIds[i]].callback == SpriteCallbackDummy && GetBattlerSide(i) != B_SIDE_OPPONENT - && (WhichBattleCoords(i) || GetBattlerSide(i) != B_SIDE_PLAYER)) + && (GetBattlerCoordsIndex(i) != BATTLE_COORDS_SINGLES || GetBattlerSide(i) != B_SIDE_PLAYER)) { s32 currHp = GetMonData(GetPartyBattlerData(i), MON_DATA_HP); s32 maxHp = GetMonData(GetPartyBattlerData(i), MON_DATA_MAX_HP); @@ -1188,7 +1187,7 @@ void SwapHpBarsWithHpText(void) noBars = gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars; if (GetBattlerSide(i) == B_SIDE_PLAYER) { - if (!WhichBattleCoords(i)) + if (GetBattlerCoordsIndex(i) == BATTLE_COORDS_SINGLES) continue; if (gBattleTypeFlags & BATTLE_TYPE_SAFARI) continue; @@ -1270,7 +1269,7 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, { isOpponent = TRUE; - if (!skipPlayer || !WhichBattleCoords(battlerId)) + if (!skipPlayer || GetBattlerCoordsIndex(battlerId) == BATTLE_COORDS_SINGLES) bar_X = 104, bar_Y = 40; else bar_X = 104, bar_Y = 16; @@ -1753,10 +1752,15 @@ static void UpdateNickInHealthbox(u8 healthboxSpriteId, struct Pokemon *mon) { TextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x40 + spriteTileNum), windowTileData, 6); ptr = (void *)(OBJ_VRAM0); - if (!WhichBattleCoords(gSprites[healthboxSpriteId].data[6])) + switch (GetBattlerCoordsIndex(gSprites[healthboxSpriteId].data[6])) + { + case BATTLE_COORDS_SINGLES: ptr += spriteTileNum + 0x800; - else + break; + default: ptr += spriteTileNum + 0x400; + break; + } TextIntoHealthboxObject(ptr, windowTileData + 0xC0, 1); } else @@ -1804,10 +1808,15 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId) if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { status = GetMonData(GetPartyBattlerData(battlerId), MON_DATA_STATUS); - if (!WhichBattleCoords(battlerId)) + switch (GetBattlerCoordsIndex(battlerId)) + { + case BATTLE_COORDS_SINGLES: tileNumAdder = 0x1A; - else + break; + default: tileNumAdder = 0x12; + break; + } } else { @@ -1865,7 +1874,7 @@ static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId) FillPalette(sStatusIconColors[statusPalId], OBJ_PLTT_OFFSET + pltAdder, PLTT_SIZEOF(1)); CpuCopy16(&gPlttBufferUnfaded[OBJ_PLTT_OFFSET + pltAdder], (u16 *)OBJ_PLTT + pltAdder, PLTT_SIZEOF(1)); CpuCopy32(statusGfxPtr, (void *)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * TILE_SIZE_4BPP), 96); - if (WhichBattleCoords(battlerId) == 1 || GetBattlerSide(battlerId) == B_SIDE_OPPONENT) + if (GetBattlerCoordsIndex(battlerId) == BATTLE_COORDS_DOUBLES || GetBattlerSide(battlerId) == B_SIDE_OPPONENT) { if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) { @@ -1983,7 +1992,7 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { - u8 isDoubles = WhichBattleCoords(battlerId); + u8 isDoubles = GetBattlerCoordsIndex(battlerId) == BATTLE_COORDS_DOUBLES; if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL) UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));