Better handling of battle coords (#6787)

This commit is contained in:
Eduardo Quezada 2025-05-07 16:25:10 -04:00 committed by GitHub
parent 6a548a6034
commit addebea4d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 109 additions and 85 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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]);

View File

@ -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));