diff --git a/include/battle_interface.h b/include/battle_interface.h index 90184d75a..f8f5c9d19 100644 --- a/include/battle_interface.h +++ b/include/battle_interface.h @@ -6,7 +6,8 @@ enum { HP_CURRENT, - HP_MAX + HP_MAX, + HP_BOTH }; enum @@ -83,7 +84,7 @@ void DestoryHealthboxSprite(u8 healthboxSpriteId); void DummyBattleInterfaceFunc(u8 healthboxSpriteId, bool8 isDoubleBattleBankOnly); void UpdateOamPriorityInAllHealthboxes(u8 priority, bool32 hideHpBoxes); void InitBattlerHealthboxCoords(u8 battler); -void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent); +void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp); void SwapHpBarsWithHpText(void); void ChangeMegaTriggerSprite(u8 spriteId, u8 animId); void CreateMegaTriggerSprite(u8 battlerId, u8 palId); diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index 833925550..26ee356c3 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -392,7 +392,7 @@ static void CompleteOnHealthbarDone(void) if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else { diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c index 6a0ecb297..4afa2cb18 100644 --- a/src/battle_controller_link_partner.c +++ b/src/battle_controller_link_partner.c @@ -278,7 +278,7 @@ static void CompleteOnHealthbarDone(void) if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else { diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index a503c1c7a..760fbf320 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -410,7 +410,7 @@ static void CompleteOnHealthbarDone(void) SetHealthboxSpriteVisible(gHealthboxSpriteIds[gActiveBattler]); if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else OpponentBufferExecCompleted(); @@ -1588,9 +1588,9 @@ static void OpponentHandleChooseMove(void) gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - } + } if (ShouldUseZMove(gActiveBattler, gBattlerTarget, chosenMove)) - QueueZMove(gActiveBattler, chosenMove); + QueueZMove(gActiveBattler, chosenMove); if (CanMegaEvolve(gActiveBattler)) // If opponent can mega evolve, do it. BtlController_EmitTwoReturnValues(BUFFER_B, 10, (chosenMoveId) | (RET_MEGA_EVOLUTION) | (gBattlerTarget << 8)); else @@ -1617,7 +1617,7 @@ static void OpponentHandleChooseMove(void) do { target = GetBattlerAtPosition(Random() & 2); } while (!CanTargetBattler(gActiveBattler, target, move)); - + #if B_WILD_NATURAL_ENEMIES == TRUE // Don't bother to loop through table if the move can't attack ally if (!(gBattleMoves[move].target & MOVE_TARGET_BOTH)) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 819541495..ea3bf2915 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -248,7 +248,7 @@ static void HandleInputChooseAction(void) { PlaySE(SE_SELECT); TryHideLastUsedBall(); - + switch (gActionSelectionCursor[gActiveBattler]) { case 0: // Top left @@ -614,17 +614,17 @@ static void HandleInputChooseMove(void) { moveTarget = GetBattlerMoveTargetType(gActiveBattler, moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]); } - + if (gBattleStruct->zmove.viewing) { u16 chosenMove = moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]; - + QueueZMove(gActiveBattler, chosenMove); gBattleStruct->zmove.viewing = FALSE; if (gBattleMoves[moveInfo->moves[gMoveSelectionCursor[gActiveBattler]]].split != SPLIT_STATUS) moveTarget = MOVE_TARGET_SELECTED; //damaging z moves always have selected target } - + if (moveTarget & MOVE_TARGET_USER) gMultiUsePlayerCursor = gActiveBattler; else @@ -660,7 +660,7 @@ static void HandleInputChooseMove(void) u32 i = 0; for (i = 0; i < gBattlersCount; i++) TryShowAsTarget(i); - + canSelectTarget = 3; } else if (moveTarget & (MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) @@ -673,7 +673,7 @@ static void HandleInputChooseMove(void) } } } - + switch (canSelectTarget) { case 0: @@ -1346,7 +1346,7 @@ static void CompleteOnHealthbarDone(void) if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else { @@ -2858,7 +2858,7 @@ static void PlayerHandleChooseMove(void) else { struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[gActiveBattler][4]); - + InitMoveSelectionsVarsAndStrings(); gBattleStruct->mega.playerSelect = FALSE; if (!IsMegaTriggerSpriteActive()) @@ -2867,7 +2867,7 @@ static void PlayerHandleChooseMove(void) CreateMegaTriggerSprite(gActiveBattler, 0); if (!IsZMoveTriggerSpriteActive()) gBattleStruct->zmove.triggerSpriteId = 0xFF; - + GetUsableZMoves(gActiveBattler, moveInfo->moves); gBattleStruct->zmove.viable = IsZMoveUsable(gActiveBattler, gMoveSelectionCursor[gActiveBattler]); CreateZMoveTriggerSprite(gActiveBattler, gBattleStruct->zmove.viable); @@ -2952,7 +2952,7 @@ static void PlayerHandleHealthBarUpdate(void) u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], 0, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP); } gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index a868d09c0..f29bd1b87 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -292,7 +292,7 @@ static void CompleteOnHealthbarDone(void) if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else { @@ -1528,7 +1528,7 @@ static void PlayerPartnerHandleChooseMove(void) if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); } - + if (ShouldUseZMove(gActiveBattler, gBattlerTarget, moveInfo->moves[chosenMoveId])) QueueZMove(gActiveBattler, moveInfo->moves[chosenMoveId]); diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index 3f5e1cf7f..14efa76c2 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -376,7 +376,7 @@ static void CompleteOnHealthbarDone(void) if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else { diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index b02f171f9..0d531db92 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -351,7 +351,7 @@ static void CompleteOnHealthbarDone(void) if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else { @@ -1481,7 +1481,7 @@ static void RecordedPlayerHandleHealthBarUpdate(void) u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], 0, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP); } gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c index 9728376df..0b480a23a 100644 --- a/src/battle_controller_wally.c +++ b/src/battle_controller_wally.c @@ -352,7 +352,7 @@ static void CompleteOnHealthbarDone(void) if (hpValue != -1) { - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], hpValue, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, hpValue, gBattleMons[gActiveBattler].maxHP); } else { @@ -1277,7 +1277,7 @@ static void WallyHandleHealthBarUpdate(void) u32 maxHP = GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_MAX_HP); SetBattleBarStruct(gActiveBattler, gHealthboxSpriteIds[gActiveBattler], maxHP, 0, hpVal); - UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], 0, HP_CURRENT); + UpdateHpTextInHealthbox(gHealthboxSpriteIds[gActiveBattler], HP_CURRENT, 0, maxHP); } gBattlerControllerFuncs[gActiveBattler] = CompleteOnHealthbarDone; diff --git a/src/battle_interface.c b/src/battle_interface.c index 828e2f8ed..545808fb5 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -161,7 +161,7 @@ static const u8 *GetHealthboxElementGfxPtr(u8); static u8 *AddTextPrinterAndCreateWindowOnHealthbox(const u8 *, u32, u32, u32, u32 *); static void RemoveWindowOnHealthbox(u32 windowId); -static void UpdateHpTextInHealthboxInDoubles(u8, s16, u8); +static void UpdateHpTextInHealthboxInDoubles(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp); static void UpdateStatusIconInHealthbox(u8); static void TextIntoHealthboxObject(void *, u8 *, s32); @@ -1125,173 +1125,149 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl) RemoveWindowOnHealthbox(windowId); } -void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent) +static void PrintHpOnHealthbox(u32 spriteId, s16 currHp, s16 maxHp, u32 bgColor, u32 rightTile, u32 leftTile) { - u32 windowId, spriteTileNum, battler; u8 *windowTileData; - u8 text[32]; - void *objVram; + u32 windowId, tilesCount, x, healthboxTileNum; + u8 text[28], *txtPtr; + void *objVram = (void *)(OBJ_VRAM0) + gSprites[spriteId].oam.tileNum * TILE_SIZE_4BPP; - battler = gSprites[healthboxSpriteId].hMain_Battler; - if (GetBattlerSide(battler) == B_SIDE_PLAYER && !WhichBattleCoords(battler)) - { - spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP; - if (maxOrCurrent != HP_CURRENT) // singles, max - { - ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3); - windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, 2, &windowId); - objVram = (void *)(OBJ_VRAM0); - objVram += spriteTileNum + 0xB40; - HpTextIntoHealthboxObject(objVram, windowTileData, 2); - RemoveWindowOnHealthbox(windowId); - } - else // singles, current - { - ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3); - text[3] = CHAR_SLASH; - text[4] = EOS; - windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 4, 5, 2, &windowId); - objVram = (void *)(OBJ_VRAM0); - objVram += spriteTileNum + 0x3E0; - HpTextIntoHealthboxObject(objVram, windowTileData, 1); - objVram = (void *)(OBJ_VRAM0); - objVram += spriteTileNum + 0xB00; - HpTextIntoHealthboxObject(objVram, windowTileData + 0x20, 2); - RemoveWindowOnHealthbox(windowId); - } - } + // To fit 4 digit HP values we need to modify a bit the way hp is printed on Healthbox. + // 6 chars can fit on the right healthbox, the rest goes to the left one + txtPtr = ConvertIntToDecimalStringN(text, currHp, STR_CONV_MODE_RIGHT_ALIGN, 4); + *txtPtr++ = CHAR_SLASH; + txtPtr = ConvertIntToDecimalStringN(txtPtr, maxHp, STR_CONV_MODE_LEFT_ALIGN, 4); + // Print last 6 chars on the right window + windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(txtPtr - 6, 0, 5, bgColor, &windowId); + HpTextIntoHealthboxObject(objVram + rightTile, windowTileData, 4); + RemoveWindowOnHealthbox(windowId); + // Print the rest of the chars on the left window + txtPtr[-6] = EOS; + // if max hp is 3 digits print on block closer to the right window, if 4 digits print further from the right window + if (maxHp >= 1000) + x = 9, tilesCount = 3; else - { - memcpy(text, sEmptyWhiteText_GrayHighlight, sizeof(sEmptyWhiteText_GrayHighlight)); - if (IsDoubleBattle() == TRUE) - { - UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, value, maxOrCurrent); - } - else if (gBattleSpritesDataPtr->battlerData[battler].hpNumbersNoBars) // don't print text if only bars are visible - { - u32 var; - u8 i; + x = 6, tilesCount = 2, leftTile += 0x20; + windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, x, 5, bgColor, &windowId); + HpTextIntoHealthboxObject(objVram + leftTile, windowTileData, tilesCount); + RemoveWindowOnHealthbox(windowId); +} - if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER) +// Note: this is only possible to trigger via debug, it was an unused GF function. +static void UpdateOpponentHpTextDoubles(u32 healthboxSpriteId, u32 barSpriteId, s16 value, u8 maxOrCurrent) +{ + u8 text[32], *txtPtr; + u32 i, var; + u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler; + + if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible + { + memcpy(text, sEmptyWhiteText_TransparentHighlight, sizeof(sEmptyWhiteText_TransparentHighlight)); + if (maxOrCurrent == HP_CURRENT) + var = 0; + else + var = 4; + + txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3); + if (!maxOrCurrent) + StringCopy(txtPtr, gText_Slash); + RenderTextHandleBold(gMonSpritesGfxPtr->barFontGfx, FONT_BOLD, text); + + for (i = var; i < var + 3; i++) + { + if (i < 3) { - if (maxOrCurrent == HP_CURRENT) - var = 29; - else - var = 89; + CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32], + (void *)((OBJ_VRAM0) + 32 * (1 + gSprites[barSpriteId].oam.tileNum + i)), + 0x20); } else { - if (maxOrCurrent == HP_CURRENT) - var = 21; - else - var = 49; + CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32], + (void *)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[barSpriteId].oam.tileNum)), + 0x20); } + } - ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_LEADING_ZEROS, 3); - RenderTextHandleBold(gMonSpritesGfxPtr->barFontGfx, FONT_BOLD, text); - - for (i = 0; i < 3; i++) - { - CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[i * 64 + 32], - (void *)((OBJ_VRAM0) + TILE_SIZE_4BPP * (gSprites[healthboxSpriteId].oam.tileNum + var + i)), - 0x20); - } + if (maxOrCurrent == HP_CURRENT) + { + CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224], + (void *)((OBJ_VRAM0) + ((gSprites[barSpriteId].oam.tileNum + 4) * TILE_SIZE_4BPP)), + 0x20); + CpuFill32(0, (void *)((OBJ_VRAM0) + (gSprites[barSpriteId].oam.tileNum * TILE_SIZE_4BPP)), 0x20); } } } -static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent) +// Same with this one. +static void UpdateOpponentHpTextSingles(u32 healthboxSpriteId, s16 value, u32 maxOrCurrent) { - u32 windowId, spriteTileNum; - u8 *windowTileData; u8 text[32]; - void *objVram; + u32 var, i; + u32 battler = gSprites[healthboxSpriteId].hMain_Battler; + + memcpy(text, sEmptyWhiteText_GrayHighlight, sizeof(sEmptyWhiteText_GrayHighlight)); + if (gBattleSpritesDataPtr->battlerData[battler].hpNumbersNoBars) // don't print text if only bars are visible + { + if (maxOrCurrent == HP_CURRENT) + var = 21; + else + var = 49; + + ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_LEADING_ZEROS, 3); + RenderTextHandleBold(gMonSpritesGfxPtr->barFontGfx, FONT_BOLD, text); + + for (i = 0; i < 3; i++) + { + CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[i * 64 + 32], + (void *)((OBJ_VRAM0) + TILE_SIZE_4BPP * (gSprites[healthboxSpriteId].oam.tileNum + var + i)), + 0x20); + } + } +} + +void UpdateHpTextInHealthbox(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp) +{ + u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler; + if (WhichBattleCoords(battlerId)) + { + UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, maxOrCurrent, currHp, maxHp); + } + else // Single Battle + { + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Player + { + PrintHpOnHealthbox(healthboxSpriteId, currHp, maxHp, 2, 0xB00, 0x3A0); + } + else // Opponent + { + UpdateOpponentHpTextSingles(healthboxSpriteId, currHp, HP_CURRENT); + UpdateOpponentHpTextSingles(healthboxSpriteId, maxHp, HP_MAX); + } + } +} + +static void UpdateHpTextInHealthboxInDoubles(u32 healthboxSpriteId, u32 maxOrCurrent, s16 currHp, s16 maxHp) +{ + u32 barSpriteId = gSprites[healthboxSpriteId].data[5]; if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER) { if (gBattleSpritesDataPtr->battlerData[gSprites[healthboxSpriteId].data[6]].hpNumbersNoBars) // don't print text if only bars are visible { - spriteTileNum = gSprites[gSprites[healthboxSpriteId].data[5]].oam.tileNum * TILE_SIZE_4BPP; - objVram = (void *)(OBJ_VRAM0) + spriteTileNum; - - if (maxOrCurrent != HP_CURRENT) // doubles, max hp - { - ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3); - windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, 0, &windowId); - HpTextIntoHealthboxObject((void *)(OBJ_VRAM0) + spriteTileNum + 0xC0, windowTileData, 2); - RemoveWindowOnHealthbox(windowId); - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_FRAME_END), + PrintHpOnHealthbox(barSpriteId, currHp, maxHp, 0, 0x80, 0x20); + // Clears the end of the healthbar gfx. + CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_FRAME_END), (void *)(OBJ_VRAM0 + 0x680) + (gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP), 0x20); - } - else - { - ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3); - text[3] = CHAR_SLASH; - text[4] = EOS; - windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 4, 5, 0, &windowId); - FillHealthboxObject(objVram, 0, 3); // Erases HP bar leftover. - HpTextIntoHealthboxObject((void *)(OBJ_VRAM0 + 0x60) + spriteTileNum, windowTileData, 3); - RemoveWindowOnHealthbox(windowId); - } + // Erases HP bar leftover. + FillHealthboxObject((void *)(OBJ_VRAM0) + (gSprites[barSpriteId].oam.tileNum * TILE_SIZE_4BPP), 0, 2); } } - else + else // Opponent { - u8 battlerId; - - memcpy(text, sEmptyWhiteText_TransparentHighlight, sizeof(sEmptyWhiteText_TransparentHighlight)); - battlerId = gSprites[healthboxSpriteId].hMain_Battler; - - if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible - { - u8 var = 4; - u8 r7; - u8 *txtPtr; - u8 i; - - if (maxOrCurrent == HP_CURRENT) - var = 0; - - r7 = gSprites[healthboxSpriteId].data[5]; - txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3); - if (!maxOrCurrent) - StringCopy(txtPtr, gText_Slash); - RenderTextHandleBold(gMonSpritesGfxPtr->barFontGfx, FONT_BOLD, text); - - for (i = var; i < var + 3; i++) - { - if (i < 3) - { - CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32], - (void *)((OBJ_VRAM0) + 32 * (1 + gSprites[r7].oam.tileNum + i)), - 0x20); - } - else - { - CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32], - (void *)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[r7].oam.tileNum)), - 0x20); - } - } - - if (maxOrCurrent == HP_CURRENT) - { - CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224], - (void *)((OBJ_VRAM0) + ((gSprites[r7].oam.tileNum + 4) * TILE_SIZE_4BPP)), - 0x20); - CpuFill32(0, (void *)((OBJ_VRAM0) + (gSprites[r7].oam.tileNum * TILE_SIZE_4BPP)), 0x20); - } - else - { - if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Impossible to reach part, because the battlerId is from the opponent's side. - { - CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_FRAME_END), - (void *)(OBJ_VRAM0) + ((gSprites[healthboxSpriteId].oam.tileNum + 52) * TILE_SIZE_4BPP), - 0x20); - } - } - } + UpdateOpponentHpTextDoubles(healthboxSpriteId, barSpriteId, maxHp, HP_MAX); + UpdateOpponentHpTextDoubles(healthboxSpriteId, barSpriteId, currHp, HP_CURRENT); } } @@ -1362,8 +1338,7 @@ static void PrintSafariMonInfo(u8 healthboxSpriteId, struct Pokemon *mon) void SwapHpBarsWithHpText(void) { - s32 i; - u8 healthBarSpriteId; + u32 healthBarSpriteId, i; for (i = 0; i < gBattlersCount; i++) { @@ -1371,6 +1346,8 @@ void SwapHpBarsWithHpText(void) && GetBattlerSide(i) != B_SIDE_OPPONENT && (WhichBattleCoords(i) || GetBattlerSide(i) != B_SIDE_PLAYER)) { + s32 currHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP); + s32 maxHp = GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP); bool8 noBars; gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars ^= 1; @@ -1387,8 +1364,7 @@ void SwapHpBarsWithHpText(void) healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId; CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * TILE_SIZE_4BPP), 0x100); - UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT); - UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX); + UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], HP_BOTH, currHp, maxHp); } else // text to bars { @@ -1411,8 +1387,7 @@ void SwapHpBarsWithHpText(void) healthBarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId; CpuFill32(0, (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 0x100); - UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT); - UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX); + UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], HP_BOTH, currHp, maxHp); } } else // text to bars @@ -2368,28 +2343,31 @@ static void UpdateLeftNoOfBallsTextOnHealthbox(u8 healthboxSpriteId) void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId) { - s32 maxHp, currHp; - u8 battlerId = gSprites[healthboxSpriteId].hMain_Battler; + u32 battlerId = gSprites[healthboxSpriteId].hMain_Battler; + s32 maxHp = GetMonData(mon, MON_DATA_MAX_HP); + s32 currHp = GetMonData(mon, MON_DATA_HP); - if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER) + if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) { - u8 isDoubles; + u8 isDoubles = WhichBattleCoords(battlerId); if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL) UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL)); - if (elementId == HEALTHBOX_CURRENT_HP || elementId == HEALTHBOX_ALL) - UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_HP), HP_CURRENT); - if (elementId == HEALTHBOX_MAX_HP || elementId == HEALTHBOX_ALL) - UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_MAX_HP), HP_MAX); + + if (elementId == HEALTHBOX_ALL) + UpdateHpTextInHealthbox(healthboxSpriteId, HP_BOTH, currHp, maxHp); + else if (elementId == HEALTHBOX_MAX_HP) + UpdateHpTextInHealthbox(healthboxSpriteId, HP_MAX, currHp, maxHp); + else if (elementId == HEALTHBOX_CURRENT_HP) + UpdateHpTextInHealthbox(healthboxSpriteId, HP_CURRENT, currHp, maxHp); + if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL) { LoadBattleBarGfx(0); - maxHp = GetMonData(mon, MON_DATA_MAX_HP); - currHp = GetMonData(mon, MON_DATA_HP); SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0); MoveBattleBar(battlerId, healthboxSpriteId, HEALTH_BAR, 0); } - isDoubles = WhichBattleCoords(battlerId); + if (!isDoubles && (elementId == HEALTHBOX_EXP_BAR || elementId == HEALTHBOX_ALL)) { u16 species; @@ -2420,15 +2398,18 @@ void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elem { if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL) UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL)); - if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars && (elementId == HEALTHBOX_CURRENT_HP || elementId == HEALTHBOX_ALL)) - UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_HP), HP_CURRENT); - if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars && (elementId == HEALTHBOX_MAX_HP || elementId == HEALTHBOX_ALL)) - UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_MAX_HP), HP_MAX); + if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) + { + if (elementId == HEALTHBOX_ALL) + UpdateHpTextInHealthbox(healthboxSpriteId, HP_BOTH, currHp, maxHp); + else if (elementId == HEALTHBOX_MAX_HP) + UpdateHpTextInHealthbox(healthboxSpriteId, HP_MAX, currHp, maxHp); + else if (elementId == HEALTHBOX_CURRENT_HP) + UpdateHpTextInHealthbox(healthboxSpriteId, HP_CURRENT, currHp, maxHp); + } if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL) { LoadBattleBarGfx(0); - maxHp = GetMonData(mon, MON_DATA_MAX_HP); - currHp = GetMonData(mon, MON_DATA_HP); SetBattleBarStruct(battlerId, healthboxSpriteId, maxHp, currHp, 0); MoveBattleBar(battlerId, healthboxSpriteId, HEALTH_BAR, 0); } diff --git a/src/party_menu.c b/src/party_menu.c index b2e6ea68d..c859acef5 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -270,7 +270,7 @@ static u8 CanMonLearnTMTutor(struct Pokemon *, u16, u8); static void DisplayPartyPokemonBarDetail(u8, const u8 *, u8, const u8 *); static void DisplayPartyPokemonLevel(u8, struct PartyMenuBox *); static void DisplayPartyPokemonGender(u8, u16, u8 *, struct PartyMenuBox *); -static void DisplayPartyPokemonHP(u16, struct PartyMenuBox *); +static void DisplayPartyPokemonHP(u16 hp, u16 maxHp, struct PartyMenuBox *menuBox); static void DisplayPartyPokemonMaxHP(u16, struct PartyMenuBox *); static void DisplayPartyPokemonHPBar(u16, u16, struct PartyMenuBox *); static void CreatePartyMonIconSpriteParameterized(u16, u32, struct PartyMenuBox *, u8); @@ -1032,7 +1032,7 @@ static void DisplayPartyPokemonDataForMultiBattle(u8 slot) DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, menuBox->infoRects->dimensions); DisplayPartyPokemonLevel(gMultiPartnerParty[actualSlot].level, menuBox); DisplayPartyPokemonGender(gMultiPartnerParty[actualSlot].gender, gMultiPartnerParty[actualSlot].species, gMultiPartnerParty[actualSlot].nickname, menuBox); - DisplayPartyPokemonHP(gMultiPartnerParty[actualSlot].hp, menuBox); + DisplayPartyPokemonHP(gMultiPartnerParty[actualSlot].hp, gMultiPartnerParty[actualSlot].maxhp, menuBox); DisplayPartyPokemonMaxHP(gMultiPartnerParty[actualSlot].maxhp, menuBox); DisplayPartyPokemonHPBar(gMultiPartnerParty[actualSlot].hp, gMultiPartnerParty[actualSlot].maxhp, menuBox); } @@ -2359,18 +2359,31 @@ static void DisplayPartyPokemonHPCheck(struct Pokemon *mon, struct PartyMenuBox if (c != 0) menuBox->infoRects->blitFunc(menuBox->windowId, menuBox->infoRects->dimensions[12] >> 3, (menuBox->infoRects->dimensions[13] >> 3) + 1, menuBox->infoRects->dimensions[14] >> 3, menuBox->infoRects->dimensions[15] >> 3, FALSE); if (c != 2) - DisplayPartyPokemonHP(GetMonData(mon, MON_DATA_HP), menuBox); + DisplayPartyPokemonHP(GetMonData(mon, MON_DATA_HP), GetMonData(mon, MON_DATA_MAX_HP), menuBox); } } -static void DisplayPartyPokemonHP(u16 hp, struct PartyMenuBox *menuBox) +static void DisplayParty4DigitsHP(struct PartyMenuBox *menuBox, const u8 *str, const u8 *origAlings, u32 toSub) { - u8 *strOut = ConvertIntToDecimalStringN(gStringVar1, hp, STR_CONV_MODE_RIGHT_ALIGN, 3); + u8 newAligns[4]; + + memcpy(newAligns, origAlings, sizeof(newAligns)); + newAligns[0] -= toSub; // x, so that the hp fits + DisplayPartyPokemonBarDetail(menuBox->windowId, str, 0, newAligns); +} + +static void DisplayPartyPokemonHP(u16 hp, u16 maxhp, struct PartyMenuBox *menuBox) +{ + bool32 fourDigits = (maxhp >= 1000); + u8 *strOut = ConvertIntToDecimalStringN(gStringVar1, hp, STR_CONV_MODE_RIGHT_ALIGN, fourDigits ? 4 : 3); strOut[0] = CHAR_SLASH; strOut[1] = EOS; - DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[12]); + if (fourDigits) + DisplayParty4DigitsHP(menuBox, gStringVar1, &menuBox->infoRects->dimensions[12], 10); + else + DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[12]); } static void DisplayPartyPokemonMaxHPCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox, u8 c) @@ -2386,10 +2399,16 @@ static void DisplayPartyPokemonMaxHPCheck(struct Pokemon *mon, struct PartyMenuB static void DisplayPartyPokemonMaxHP(u16 maxhp, struct PartyMenuBox *menuBox) { - ConvertIntToDecimalStringN(gStringVar2, maxhp, STR_CONV_MODE_RIGHT_ALIGN, 3); + bool32 fourDigits = (maxhp >= 1000); + + ConvertIntToDecimalStringN(gStringVar2, maxhp, STR_CONV_MODE_RIGHT_ALIGN, fourDigits ? 4 : 3); StringCopy(gStringVar1, gText_Slash); StringAppend(gStringVar1, gStringVar2); - DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[16]); + + if (fourDigits) + DisplayParty4DigitsHP(menuBox, gStringVar1, &menuBox->infoRects->dimensions[16], 5); + else + DisplayPartyPokemonBarDetail(menuBox->windowId, gStringVar1, 0, &menuBox->infoRects->dimensions[16]); } static void DisplayPartyPokemonHPBarCheck(struct Pokemon *mon, struct PartyMenuBox *menuBox)