2017-10-16 18:12:27 +02:00
# include "global.h"
2019-10-10 16:18:48 +02:00
# include "malloc.h"
2017-10-16 18:12:27 +02:00
# include "battle.h"
# include "pokemon.h"
2017-10-19 15:28:41 +02:00
# include "battle_controllers.h"
2017-10-16 18:12:27 +02:00
# include "battle_interface.h"
2020-11-26 15:56:18 -05:00
# include "battle_z_move.h"
2018-10-21 02:24:57 -05:00
# include "graphics.h"
2017-10-16 18:12:27 +02:00
# include "sprite.h"
2017-10-18 00:00:46 +02:00
# include "window.h"
# include "string_util.h"
# include "text.h"
2017-10-18 21:42:00 +02:00
# include "sound.h"
# include "decompress.h"
# include "task.h"
# include "util.h"
# include "gpu_regs.h"
# include "battle_message.h"
2017-10-18 23:05:14 +02:00
# include "pokedex.h"
# include "palette.h"
# include "international_string_util.h"
# include "safari_zone.h"
2017-10-20 19:24:46 +02:00
# include "battle_anim.h"
2019-04-04 23:53:06 +02:00
# include "data.h"
# include "pokemon_summary_screen.h"
2021-11-06 11:41:47 -04:00
# include "strings.h"
2021-11-27 21:38:26 -08:00
# include "battle_debug.h"
# include "item.h"
2021-06-25 13:37:59 -06:00
# include "item_icon.h"
# include "item_use.h"
2021-11-06 11:41:47 -04:00
# include "constants/battle_anim.h"
# include "constants/rgb.h"
# include "constants/songs.h"
2021-11-27 21:38:26 -08:00
# include "constants/battle_config.h"
2021-09-23 12:03:01 -04:00
# include "constants/items.h"
2017-10-16 18:12:27 +02:00
2017-10-19 18:25:48 +02:00
enum
2019-02-16 23:33:00 -05:00
{ // Corresponds to gHealthboxElementsGfxTable (and the tables after it) in graphics.c
2019-02-23 20:01:48 -05:00
// These are indexes into the tables, which are filled with 8x8 square pixel data.
HEALTHBOX_GFX_0 , //hp bar [black section]
HEALTHBOX_GFX_1 , //hp bar "H"
HEALTHBOX_GFX_2 , //hp bar "P"
HEALTHBOX_GFX_HP_BAR_GREEN , //hp bar [0 pixels]
HEALTHBOX_GFX_4 , //hp bar [1 pixels]
HEALTHBOX_GFX_5 , //hp bar [2 pixels]
HEALTHBOX_GFX_6 , //hp bar [3 pixels]
HEALTHBOX_GFX_7 , //hp bar [4 pixels]
HEALTHBOX_GFX_8 , //hp bar [5 pixels]
HEALTHBOX_GFX_9 , //hp bar [6 pixels]
HEALTHBOX_GFX_10 , //hp bar [7 pixels]
HEALTHBOX_GFX_11 , //hp bar [8 pixels]
HEALTHBOX_GFX_12 , //exp bar [0 pixels]
HEALTHBOX_GFX_13 , //exp bar [1 pixels]
HEALTHBOX_GFX_14 , //exp bar [2 pixels]
HEALTHBOX_GFX_15 , //exp bar [3 pixels]
HEALTHBOX_GFX_16 , //exp bar [4 pixels]
HEALTHBOX_GFX_17 , //exp bar [5 pixels]
HEALTHBOX_GFX_18 , //exp bar [6 pixels]
HEALTHBOX_GFX_19 , //exp bar [7 pixels]
HEALTHBOX_GFX_20 , //exp bar [8 pixels]
HEALTHBOX_GFX_STATUS_PSN_BATTLER0 , //status psn "(P"
HEALTHBOX_GFX_22 , //status psn "SN"
HEALTHBOX_GFX_23 , //status psn "|)""
HEALTHBOX_GFX_STATUS_PRZ_BATTLER0 , //status prz
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_25 ,
HEALTHBOX_GFX_26 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER0 , //status slp
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_28 ,
HEALTHBOX_GFX_29 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER0 , //status frz
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_31 ,
HEALTHBOX_GFX_32 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER0 , //status brn
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_34 ,
HEALTHBOX_GFX_35 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_36 , //misc [Black section]
HEALTHBOX_GFX_37 , //misc [Black section]
HEALTHBOX_GFX_38 , //misc [Black section]
HEALTHBOX_GFX_39 , //misc [Blank Health Window?]
HEALTHBOX_GFX_40 , //misc [Blank Health Window?]
HEALTHBOX_GFX_41 , //misc [Blank Health Window?]
HEALTHBOX_GFX_42 , //misc [Blank Health Window?]
HEALTHBOX_GFX_43 , //misc [Top of Health Window?]
HEALTHBOX_GFX_44 , //misc [Top of Health Window?]
HEALTHBOX_GFX_45 , //misc [Top of Health Window?]
HEALTHBOX_GFX_46 , //misc [Blank Health Window?]
HEALTHBOX_GFX_HP_BAR_YELLOW , //hp bar yellow [0 pixels]
HEALTHBOX_GFX_48 , //hp bar yellow [1 pixels]
HEALTHBOX_GFX_49 , //hp bar yellow [2 pixels]
HEALTHBOX_GFX_50 , //hp bar yellow [3 pixels]
HEALTHBOX_GFX_51 , //hp bar yellow [4 pixels]
HEALTHBOX_GFX_52 , //hp bar yellow [5 pixels]
HEALTHBOX_GFX_53 , //hp bar yellow [6 pixels]
HEALTHBOX_GFX_54 , //hp bar yellow [7 pixels]
HEALTHBOX_GFX_55 , //hp bar yellow [8 pixels]
HEALTHBOX_GFX_HP_BAR_RED , //hp bar red [0 pixels]
HEALTHBOX_GFX_57 , //hp bar red [1 pixels]
HEALTHBOX_GFX_58 , //hp bar red [2 pixels]
HEALTHBOX_GFX_59 , //hp bar red [3 pixels]
HEALTHBOX_GFX_60 , //hp bar red [4 pixels]
HEALTHBOX_GFX_61 , //hp bar red [5 pixels]
HEALTHBOX_GFX_62 , //hp bar red [6 pixels]
HEALTHBOX_GFX_63 , //hp bar red [7 pixels]
HEALTHBOX_GFX_64 , //hp bar red [8 pixels]
HEALTHBOX_GFX_65 , //hp bar frame end
2021-09-06 17:39:21 -04:00
HEALTHBOX_GFX_STATUS_BALL , // Full
HEALTHBOX_GFX_STATUS_BALL_EMPTY ,
HEALTHBOX_GFX_STATUS_BALL_FAINTED ,
HEALTHBOX_GFX_STATUS_BALL_STATUSED ,
HEALTHBOX_GFX_STATUS_BALL_CAUGHT ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_PSN_BATTLER1 , //status2 "PSN"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_72 ,
HEALTHBOX_GFX_73 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_PRZ_BATTLER1 , //status2 "PRZ"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_75 ,
HEALTHBOX_GFX_76 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER1 , //status2 "SLP"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_78 ,
HEALTHBOX_GFX_79 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER1 , //status2 "FRZ"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_81 ,
HEALTHBOX_GFX_82 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER1 , //status2 "BRN"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_84 ,
HEALTHBOX_GFX_85 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_PSN_BATTLER2 , //status3 "PSN"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_87 ,
HEALTHBOX_GFX_88 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_PRZ_BATTLER2 , //status3 "PRZ"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_90 ,
HEALTHBOX_GFX_91 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER2 , //status3 "SLP"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_93 ,
HEALTHBOX_GFX_94 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER2 , //status3 "FRZ"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_96 ,
HEALTHBOX_GFX_97 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER2 , //status3 "BRN"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_99 ,
HEALTHBOX_GFX_100 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_PSN_BATTLER3 , //status4 "PSN"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_102 ,
HEALTHBOX_GFX_103 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_PRZ_BATTLER3 , //status4 "PRZ"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_105 ,
HEALTHBOX_GFX_106 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER3 , //status4 "SLP"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_108 ,
HEALTHBOX_GFX_109 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER3 , //status4 "FRZ"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_111 ,
HEALTHBOX_GFX_112 ,
2019-02-23 20:01:48 -05:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER3 , //status4 "BRN"
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_114 ,
HEALTHBOX_GFX_115 ,
2021-09-06 11:40:40 -04:00
HEALTHBOX_GFX_FRAME_END ,
HEALTHBOX_GFX_FRAME_END_BAR ,
2017-10-19 18:25:48 +02:00
} ;
2022-05-21 15:21:50 -04:00
static const u8 * GetHealthboxElementGfxPtr ( u8 ) ;
2022-07-29 10:17:58 -04:00
static u8 * AddTextPrinterAndCreateWindowOnHealthbox ( const u8 * , u32 , u32 , u32 , u32 * ) ;
2017-10-19 15:28:41 +02:00
static void RemoveWindowOnHealthbox ( u32 windowId ) ;
2022-08-25 16:40:56 +02:00
static void UpdateHpTextInHealthboxInDoubles ( u32 healthboxSpriteId , u32 maxOrCurrent , s16 currHp , s16 maxHp ) ;
2022-05-21 15:21:50 -04:00
static void UpdateStatusIconInHealthbox ( u8 ) ;
2017-10-19 15:28:41 +02:00
2022-05-21 15:21:50 -04:00
static void TextIntoHealthboxObject ( void * , u8 * , s32 ) ;
static void SafariTextIntoHealthboxObject ( void * , u8 * , u32 ) ;
static void HpTextIntoHealthboxObject ( void * , u8 * , u32 ) ;
static void FillHealthboxObject ( void * , u32 , u32 ) ;
2017-10-19 15:28:41 +02:00
2022-05-21 15:21:50 -04:00
static void Task_HidePartyStatusSummary_BattleStart_1 ( u8 ) ;
static void Task_HidePartyStatusSummary_BattleStart_2 ( u8 ) ;
static void Task_HidePartyStatusSummary_DuringBattle ( u8 ) ;
2017-10-19 15:28:41 +02:00
2022-05-21 15:21:50 -04:00
static void SpriteCB_HealthBoxOther ( struct Sprite * ) ;
static void SpriteCB_HealthBar ( struct Sprite * ) ;
static void SpriteCB_StatusSummaryBar_Enter ( struct Sprite * ) ;
static void SpriteCB_StatusSummaryBar_Exit ( struct Sprite * ) ;
static void SpriteCB_StatusSummaryBalls_Enter ( struct Sprite * ) ;
static void SpriteCB_StatusSummaryBalls_Exit ( struct Sprite * ) ;
static void SpriteCB_StatusSummaryBalls_OnSwitchout ( struct Sprite * ) ;
2017-10-19 15:28:41 +02:00
2022-07-15 12:58:46 -04:00
static void SpriteCb_MegaTrigger ( struct Sprite * ) ;
static void SpriteCb_MegaIndicator ( struct Sprite * ) ;
2018-09-17 22:40:49 +02:00
2022-05-21 15:21:50 -04:00
static u8 GetStatusIconForBattlerId ( u8 , u8 ) ;
static s32 CalcNewBarValue ( s32 , s32 , s32 , s32 * , u8 , u16 ) ;
static u8 GetScaledExpFraction ( s32 , s32 , s32 , u8 ) ;
static void MoveBattleBarGraphically ( u8 , u8 ) ;
static u8 CalcBarFilledPixels ( s32 , s32 , s32 , s32 * , u8 * , u8 ) ;
2017-10-16 18:12:27 +02:00
2022-07-15 12:58:46 -04:00
static void SpriteCb_AbilityPopUp ( struct Sprite * ) ;
static void Task_FreeAbilityPopUpGfx ( u8 ) ;
2017-10-16 18:12:27 +02:00
2022-07-15 12:58:46 -04:00
static void SpriteCB_LastUsedBall ( struct Sprite * ) ;
static void SpriteCB_LastUsedBallWin ( struct Sprite * ) ;
2021-06-25 13:37:59 -06:00
2021-11-06 11:41:47 -04:00
static const struct OamData sOamData_64x32 =
2017-10-16 18:12:27 +02:00
{
. y = 0 ,
2019-12-04 15:25:13 -05:00
. affineMode = ST_OAM_AFFINE_OFF ,
. objMode = ST_OAM_OBJ_NORMAL ,
2022-07-29 21:27:39 -04:00
. mosaic = FALSE ,
2019-12-04 15:25:13 -05:00
. bpp = ST_OAM_4BPP ,
2019-03-11 03:12:15 -04:00
. shape = SPRITE_SHAPE ( 64 x32 ) ,
2017-10-16 18:12:27 +02:00
. x = 0 ,
. matrixNum = 0 ,
2019-03-11 03:12:15 -04:00
. size = SPRITE_SIZE ( 64 x32 ) ,
2017-10-16 18:12:27 +02:00
. tileNum = 0 ,
. priority = 1 ,
. paletteNum = 0 ,
. affineParam = 0 ,
} ;
2017-10-19 18:25:48 +02:00
static const struct SpriteTemplate sHealthboxPlayerSpriteTemplates [ 2 ] =
2017-10-16 18:12:27 +02:00
{
{
2017-10-19 18:25:48 +02:00
. tileTag = TAG_HEALTHBOX_PLAYER1_TILE ,
. paletteTag = TAG_HEALTHBOX_PAL ,
2021-11-06 11:41:47 -04:00
. oam = & sOamData_64x32 ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCallbackDummy
} ,
{
2017-10-19 18:25:48 +02:00
. tileTag = TAG_HEALTHBOX_PLAYER2_TILE ,
. paletteTag = TAG_HEALTHBOX_PAL ,
2021-11-06 11:41:47 -04:00
. oam = & sOamData_64x32 ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCallbackDummy
}
} ;
2017-10-19 18:25:48 +02:00
static const struct SpriteTemplate sHealthboxOpponentSpriteTemplates [ 2 ] =
2017-10-16 18:12:27 +02:00
{
{
2017-10-19 18:25:48 +02:00
. tileTag = TAG_HEALTHBOX_OPPONENT1_TILE ,
. paletteTag = TAG_HEALTHBOX_PAL ,
2021-11-06 11:41:47 -04:00
. oam = & sOamData_64x32 ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCallbackDummy
} ,
{
2017-10-19 18:25:48 +02:00
. tileTag = TAG_HEALTHBOX_OPPONENT2_TILE ,
. paletteTag = TAG_HEALTHBOX_PAL ,
2021-11-06 11:41:47 -04:00
. oam = & sOamData_64x32 ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCallbackDummy
}
} ;
2017-10-19 18:25:48 +02:00
static const struct SpriteTemplate sHealthboxSafariSpriteTemplate =
2017-10-16 18:12:27 +02:00
{
2017-10-19 18:25:48 +02:00
. tileTag = TAG_HEALTHBOX_SAFARI_TILE ,
. paletteTag = TAG_HEALTHBOX_PAL ,
2021-11-06 11:41:47 -04:00
. oam = & sOamData_64x32 ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCallbackDummy
} ;
2018-06-19 00:43:15 +02:00
static const struct OamData sOamData_Healthbar =
2017-10-16 18:12:27 +02:00
{
. y = 0 ,
2019-12-04 15:25:13 -05:00
. affineMode = ST_OAM_AFFINE_OFF ,
. objMode = ST_OAM_OBJ_NORMAL ,
2022-07-29 21:27:39 -04:00
. mosaic = FALSE ,
2019-12-04 15:25:13 -05:00
. bpp = ST_OAM_4BPP ,
2019-03-11 03:12:15 -04:00
. shape = SPRITE_SHAPE ( 32 x8 ) ,
2017-10-16 18:12:27 +02:00
. x = 0 ,
. matrixNum = 0 ,
2019-03-11 03:12:15 -04:00
. size = SPRITE_SIZE ( 32 x8 ) ,
2017-10-16 18:12:27 +02:00
. tileNum = 0 ,
. priority = 1 ,
. paletteNum = 0 ,
. affineParam = 0 ,
} ;
2018-06-19 00:43:15 +02:00
static const struct SpriteTemplate sHealthbarSpriteTemplates [ MAX_BATTLERS_COUNT ] =
2017-10-16 18:12:27 +02:00
{
{
2018-06-19 00:43:15 +02:00
. tileTag = TAG_HEALTHBAR_PLAYER1_TILE ,
. paletteTag = TAG_HEALTHBAR_PAL ,
. oam = & sOamData_Healthbar ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2018-06-19 00:43:15 +02:00
. callback = SpriteCB_HealthBar
2017-10-16 18:12:27 +02:00
} ,
{
2018-06-19 00:43:15 +02:00
. tileTag = TAG_HEALTHBAR_OPPONENT1_TILE ,
. paletteTag = TAG_HEALTHBAR_PAL ,
. oam = & sOamData_Healthbar ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2018-06-19 00:43:15 +02:00
. callback = SpriteCB_HealthBar
2017-10-16 18:12:27 +02:00
} ,
{
2018-06-19 00:43:15 +02:00
. tileTag = TAG_HEALTHBAR_PLAYER2_TILE ,
. paletteTag = TAG_HEALTHBAR_PAL ,
. oam = & sOamData_Healthbar ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2018-06-19 00:43:15 +02:00
. callback = SpriteCB_HealthBar
2017-10-16 18:12:27 +02:00
} ,
{
2018-06-19 00:43:15 +02:00
. tileTag = TAG_HEALTHBAR_OPPONENT2_TILE ,
. paletteTag = TAG_HEALTHBAR_PAL ,
. oam = & sOamData_Healthbar ,
2017-10-16 18:12:27 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2018-06-19 00:43:15 +02:00
. callback = SpriteCB_HealthBar
2017-10-16 18:12:27 +02:00
}
} ;
2022-09-17 13:33:10 -04:00
/* v-- Origin
[ 0 + ] [ 1 ] 64 x8
*/
2021-11-06 11:41:47 -04:00
static const struct Subsprite sHealthBar_Subsprites_Player [ ] =
2017-10-19 15:28:41 +02:00
{
2019-12-04 21:00:45 -05:00
{
2022-09-17 13:33:10 -04:00
. x = - 16 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 0 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2019-12-09 08:16:18 +01:00
. x = 16 ,
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 4 ,
2019-12-04 21:00:45 -05:00
. priority = 1
}
2017-10-19 15:28:41 +02:00
} ;
2022-09-17 13:33:10 -04:00
/* v-- Origin
2022-09-17 14:34:20 -04:00
[ ] [ 0 + ] [ 1 ] 8 x8 + 64 x8
2022-09-17 13:33:10 -04:00
2 ^ ^ - - - Note 8 px space
*/
2021-11-06 11:41:47 -04:00
static const struct Subsprite sHealthBar_Subsprites_Opponent [ ] =
2017-10-19 15:28:41 +02:00
{
2019-12-04 21:00:45 -05:00
{
2022-09-17 13:33:10 -04:00
. x = - 16 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 0 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2019-12-09 08:16:18 +01:00
. x = 16 ,
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 4 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2022-09-17 13:33:10 -04:00
. x = - 32 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 8 x8 ) ,
. size = SPRITE_SIZE ( 8 x8 ) ,
. tileOffset = 8 ,
2019-12-04 21:00:45 -05:00
. priority = 1
}
2017-10-19 15:28:41 +02:00
} ;
2021-11-06 11:41:47 -04:00
static const struct SubspriteTable sHealthBar_SubspriteTables [ ] =
2017-10-19 15:28:41 +02:00
{
2021-11-06 11:41:47 -04:00
[ B_SIDE_PLAYER ] = { ARRAY_COUNT ( sHealthBar_Subsprites_Player ) , sHealthBar_Subsprites_Player } ,
[ B_SIDE_OPPONENT ] = { ARRAY_COUNT ( sHealthBar_Subsprites_Opponent ) , sHealthBar_Subsprites_Opponent }
2017-10-19 15:28:41 +02:00
} ;
2022-09-17 14:34:20 -04:00
/* v-- Origin
[ 0 ] [ 1 ] [ 2 ] [ 3 ] 128 x8
*/
2021-11-06 11:41:47 -04:00
static const struct Subsprite sStatusSummaryBar_Subsprites_Enter [ ] =
2017-10-19 15:28:41 +02:00
{
2019-12-04 21:00:45 -05:00
{
2022-09-17 14:34:20 -04:00
. x = 32 * - 3 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 0 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2022-09-17 14:34:20 -04:00
. x = 32 * - 2 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 4 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2022-09-17 14:34:20 -04:00
. x = 32 * - 1 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 8 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2019-12-09 08:16:18 +01:00
. x = 0 ,
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 12 ,
2019-12-04 21:00:45 -05:00
. priority = 1
}
2017-10-19 15:28:41 +02:00
} ;
2022-09-17 14:34:20 -04:00
/* v-- Origin
[ 0 ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] 192 x8
^ - - uses same tiles - - ^
*/
2021-11-06 11:41:47 -04:00
static const struct Subsprite sStatusSummaryBar_Subsprites_Exit [ ] =
2017-10-19 15:28:41 +02:00
{
2019-12-04 21:00:45 -05:00
{
2022-09-17 14:34:20 -04:00
. x = 32 * - 3 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 0 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2022-09-17 14:34:20 -04:00
. x = 32 * - 2 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 4 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2022-09-17 14:34:20 -04:00
. x = 32 * - 1 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 8 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2021-11-06 11:41:47 -04:00
. x = 32 * 0 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 8 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2021-11-06 11:41:47 -04:00
. x = 32 * 1 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 8 ,
2019-12-04 21:00:45 -05:00
. priority = 1
} ,
{
2021-11-06 11:41:47 -04:00
. x = 32 * 2 ,
2019-12-09 08:16:18 +01:00
. y = 0 ,
. shape = SPRITE_SHAPE ( 32 x8 ) ,
. size = SPRITE_SIZE ( 32 x8 ) ,
. tileOffset = 12 ,
2019-12-04 21:00:45 -05:00
. priority = 1
}
2017-10-19 15:28:41 +02:00
} ;
2021-11-06 11:41:47 -04:00
static const struct SubspriteTable sStatusSummaryBar_SubspriteTable_Enter [ ] =
2017-10-19 15:28:41 +02:00
{
2021-11-06 11:41:47 -04:00
{ ARRAY_COUNT ( sStatusSummaryBar_Subsprites_Enter ) , sStatusSummaryBar_Subsprites_Enter }
2017-10-19 15:28:41 +02:00
} ;
2021-11-06 11:41:47 -04:00
static const struct SubspriteTable sStatusSummaryBar_SubspriteTable_Exit [ ] =
2017-10-19 15:28:41 +02:00
{
2021-11-06 11:41:47 -04:00
{ ARRAY_COUNT ( sStatusSummaryBar_Subsprites_Exit ) , sStatusSummaryBar_Subsprites_Exit }
2017-10-19 15:28:41 +02:00
} ;
2017-10-19 18:25:48 +02:00
static const struct CompressedSpriteSheet sStatusSummaryBarSpriteSheet =
2017-10-19 15:28:41 +02:00
{
2017-10-19 18:25:48 +02:00
gBattleInterface_BallStatusBarGfx , 0x200 , TAG_STATUS_SUMMARY_BAR_TILE
2017-10-19 15:28:41 +02:00
} ;
2017-10-19 18:25:48 +02:00
static const struct SpritePalette sStatusSummaryBarSpritePal =
2017-10-19 15:28:41 +02:00
{
2017-10-19 18:25:48 +02:00
gBattleInterface_BallStatusBarPal , TAG_STATUS_SUMMARY_BAR_PAL
2017-10-19 15:28:41 +02:00
} ;
2017-10-19 18:25:48 +02:00
static const struct SpritePalette sStatusSummaryBallsSpritePal =
2017-10-19 15:28:41 +02:00
{
2017-10-19 18:25:48 +02:00
gBattleInterface_BallDisplayPal , TAG_STATUS_SUMMARY_BALLS_PAL
2017-10-19 15:28:41 +02:00
} ;
2017-10-19 18:25:48 +02:00
static const struct SpriteSheet sStatusSummaryBallsSpriteSheet =
2017-10-19 15:28:41 +02:00
{
2021-09-06 17:39:21 -04:00
& gHealthboxElementsGfxTable [ HEALTHBOX_GFX_STATUS_BALL ] , 0x80 , TAG_STATUS_SUMMARY_BALLS_TILE
2017-10-19 15:28:41 +02:00
} ;
2017-10-20 19:24:46 +02:00
static const struct OamData sOamData_StatusSummaryBalls =
2017-10-19 15:28:41 +02:00
{
. y = 0 ,
2019-12-04 15:25:13 -05:00
. affineMode = ST_OAM_AFFINE_OFF ,
. objMode = ST_OAM_OBJ_NORMAL ,
2022-07-29 21:27:39 -04:00
. mosaic = FALSE ,
2019-12-04 15:25:13 -05:00
. bpp = ST_OAM_4BPP ,
2019-03-11 03:12:15 -04:00
. shape = SPRITE_SHAPE ( 8 x8 ) ,
2017-10-19 15:28:41 +02:00
. x = 0 ,
. matrixNum = 0 ,
2019-03-11 03:12:15 -04:00
. size = SPRITE_SIZE ( 8 x8 ) ,
2017-10-19 15:28:41 +02:00
. tileNum = 0 ,
. priority = 1 ,
. paletteNum = 0 ,
. affineParam = 0 ,
} ;
2017-10-19 18:25:48 +02:00
static const struct SpriteTemplate sStatusSummaryBarSpriteTemplates [ 2 ] =
2017-10-19 15:28:41 +02:00
{
2021-11-06 11:41:47 -04:00
{ // Player
2017-10-19 18:25:48 +02:00
. tileTag = TAG_STATUS_SUMMARY_BAR_TILE ,
. paletteTag = TAG_STATUS_SUMMARY_BAR_PAL ,
2021-11-06 11:41:47 -04:00
. oam = & sOamData_64x32 ,
2017-10-19 15:28:41 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2021-11-06 11:41:47 -04:00
. callback = SpriteCB_StatusSummaryBar_Enter
2017-10-19 15:28:41 +02:00
} ,
2021-11-06 11:41:47 -04:00
{ // Opponent
2017-10-19 18:25:48 +02:00
. tileTag = TAG_STATUS_SUMMARY_BAR_TILE ,
. paletteTag = TAG_STATUS_SUMMARY_BAR_PAL ,
2021-11-06 11:41:47 -04:00
. oam = & sOamData_64x32 ,
2017-10-19 15:28:41 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2021-11-06 11:41:47 -04:00
. callback = SpriteCB_StatusSummaryBar_Enter
2017-10-19 15:28:41 +02:00
}
} ;
2017-10-19 18:25:48 +02:00
static const struct SpriteTemplate sStatusSummaryBallsSpriteTemplates [ 2 ] =
2017-10-19 15:28:41 +02:00
{
{
2017-10-19 18:25:48 +02:00
. tileTag = TAG_STATUS_SUMMARY_BALLS_TILE ,
. paletteTag = TAG_STATUS_SUMMARY_BALLS_PAL ,
2017-10-20 19:24:46 +02:00
. oam = & sOamData_StatusSummaryBalls ,
2017-10-19 15:28:41 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2021-11-06 11:41:47 -04:00
. callback = SpriteCB_StatusSummaryBalls_Enter
2017-10-19 15:28:41 +02:00
} ,
{
2017-10-19 18:25:48 +02:00
. tileTag = TAG_STATUS_SUMMARY_BALLS_TILE ,
. paletteTag = TAG_STATUS_SUMMARY_BALLS_PAL ,
2017-10-20 19:24:46 +02:00
. oam = & sOamData_StatusSummaryBalls ,
2017-10-19 15:28:41 +02:00
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2021-11-06 11:41:47 -04:00
. callback = SpriteCB_StatusSummaryBalls_Enter
2017-10-19 15:28:41 +02:00
}
} ;
2021-10-30 16:47:37 -04:00
static const u8 sEmptyWhiteText_GrayHighlight [ ] = __ ( " {COLOR WHITE}{HIGHLIGHT DARK_GRAY} " ) ;
static const u8 sEmptyWhiteText_TransparentHighlight [ ] = __ ( " {COLOR WHITE}{HIGHLIGHT TRANSPARENT} " ) ;
2017-10-19 15:28:41 +02:00
enum
{
PAL_STATUS_PSN ,
PAL_STATUS_PAR ,
PAL_STATUS_SLP ,
PAL_STATUS_FRZ ,
PAL_STATUS_BRN
} ;
2018-01-29 14:36:13 +01:00
static const u16 sStatusIconColors [ ] =
2017-10-19 15:28:41 +02:00
{
2018-12-05 22:31:01 +08:00
[ PAL_STATUS_PSN ] = RGB ( 24 , 12 , 24 ) ,
[ PAL_STATUS_PAR ] = RGB ( 23 , 23 , 3 ) ,
[ PAL_STATUS_SLP ] = RGB ( 20 , 20 , 17 ) ,
[ PAL_STATUS_FRZ ] = RGB ( 17 , 22 , 28 ) ,
[ PAL_STATUS_BRN ] = RGB ( 28 , 14 , 10 ) ,
2017-10-19 15:28:41 +02:00
} ;
2021-11-06 11:41:47 -04:00
static const struct WindowTemplate sHealthboxWindowTemplate = {
. bg = 0 ,
. tilemapLeft = 0 ,
. tilemapTop = 0 ,
. width = 8 ,
. height = 2 ,
. paletteNum = 0 ,
. baseBlock = 0
} ;
2017-10-19 15:28:41 +02:00
2018-09-17 22:40:49 +02:00
static const u8 sMegaTriggerGfx [ ] = INCBIN_U8 ( " graphics/battle_interface/mega_trigger.4bpp " ) ;
2018-09-20 20:59:00 +02:00
static const u16 sMegaTriggerPal [ ] = INCBIN_U16 ( " graphics/battle_interface/mega_trigger.gbapal " ) ;
2017-10-19 15:28:41 +02:00
2018-09-17 22:40:49 +02:00
static const struct SpriteSheet sSpriteSheet_MegaTrigger =
2017-10-16 18:12:27 +02:00
{
2018-09-17 22:40:49 +02:00
sMegaTriggerGfx , sizeof ( sMegaTriggerGfx ) , TAG_MEGA_TRIGGER_TILE
} ;
2018-09-20 20:59:00 +02:00
static const struct SpritePalette sSpritePalette_MegaTrigger =
2017-10-16 18:12:27 +02:00
{
2018-09-20 20:59:00 +02:00
sMegaTriggerPal , TAG_MEGA_TRIGGER_PAL
2018-09-17 22:40:49 +02:00
} ;
2017-10-16 18:12:27 +02:00
2018-09-17 22:40:49 +02:00
static const struct OamData sOamData_MegaTrigger =
{
. y = 0 ,
. affineMode = 0 ,
. objMode = 0 ,
. mosaic = 0 ,
. bpp = 0 ,
. shape = ST_OAM_SQUARE ,
. x = 0 ,
. matrixNum = 0 ,
. size = 2 ,
. tileNum = 0 ,
2018-09-20 20:59:00 +02:00
. priority = 1 ,
2018-09-17 22:40:49 +02:00
. paletteNum = 0 ,
. affineParam = 0 ,
} ;
2017-10-16 18:12:27 +02:00
2018-09-20 20:59:00 +02:00
static const union AnimCmd sSpriteAnim_MegaTriggerOff [ ] =
{
ANIMCMD_FRAME ( 0 , 0 ) ,
ANIMCMD_END
} ;
2017-10-16 18:12:27 +02:00
2018-09-20 20:59:00 +02:00
static const union AnimCmd sSpriteAnim_MegaTriggerOn [ ] =
{
ANIMCMD_FRAME ( 16 , 0 ) ,
ANIMCMD_END
} ;
2017-10-16 18:12:27 +02:00
2018-09-20 20:59:00 +02:00
static const union AnimCmd * const sSpriteAnimTable_MegaTrigger [ ] =
{
sSpriteAnim_MegaTriggerOff ,
sSpriteAnim_MegaTriggerOn ,
} ;
2017-10-16 18:12:27 +02:00
2018-09-17 22:40:49 +02:00
static const struct SpriteTemplate sSpriteTemplate_MegaTrigger =
2017-10-16 18:12:27 +02:00
{
2018-09-17 22:40:49 +02:00
. tileTag = TAG_MEGA_TRIGGER_TILE ,
2018-09-20 20:59:00 +02:00
. paletteTag = TAG_MEGA_TRIGGER_PAL ,
2018-09-17 22:40:49 +02:00
. oam = & sOamData_MegaTrigger ,
2018-09-20 20:59:00 +02:00
. anims = sSpriteAnimTable_MegaTrigger ,
2018-09-17 22:40:49 +02:00
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCb_MegaTrigger
} ;
2019-05-02 23:10:01 +02:00
static const u8 sMegaIndicatorGfx [ ] = INCBIN_U8 ( " graphics/battle_interface/mega_indicator.4bpp " ) ;
static const u16 sMegaIndicatorPal [ ] = INCBIN_U16 ( " graphics/battle_interface/mega_indicator.gbapal " ) ;
static const struct SpriteSheet sSpriteSheet_MegaIndicator =
{
sMegaIndicatorGfx , sizeof ( sMegaIndicatorGfx ) , TAG_MEGA_INDICATOR_TILE
} ;
static const struct SpritePalette sSpritePalette_MegaIndicator =
{
sMegaIndicatorPal , TAG_MEGA_INDICATOR_PAL
} ;
2021-08-25 03:35:21 -03:00
static const u8 sAlphaIndicatorGfx [ ] = INCBIN_U8 ( " graphics/battle_interface/alpha_indicator.4bpp " ) ;
static const u16 sAlphaIndicatorPal [ ] = INCBIN_U16 ( " graphics/battle_interface/alpha_indicator.gbapal " ) ;
static const u8 sOmegaIndicatorGfx [ ] = INCBIN_U8 ( " graphics/battle_interface/omega_indicator.4bpp " ) ;
static const u16 sOmegaIndicatorPal [ ] = INCBIN_U16 ( " graphics/battle_interface/omega_indicator.gbapal " ) ;
static const struct SpriteSheet sSpriteSheet_AlphaIndicator =
{
sAlphaIndicatorGfx , sizeof ( sAlphaIndicatorGfx ) , TAG_ALPHA_INDICATOR_TILE
} ;
static const struct SpritePalette sSpritePalette_AlphaIndicator =
{
sAlphaIndicatorPal , TAG_ALPHA_INDICATOR_PAL
} ;
static const struct SpriteSheet sSpriteSheet_OmegaIndicator =
{
sOmegaIndicatorGfx , sizeof ( sOmegaIndicatorGfx ) , TAG_OMEGA_INDICATOR_TILE
} ;
static const struct SpritePalette sSpritePalette_OmegaIndicator =
{
sOmegaIndicatorPal , TAG_OMEGA_INDICATOR_PAL
} ;
2019-05-02 23:10:01 +02:00
static const struct OamData sOamData_MegaIndicator =
{
. y = 0 ,
. affineMode = 0 ,
. objMode = 0 ,
. mosaic = 0 ,
. bpp = 0 ,
. shape = SPRITE_SHAPE ( 16 x16 ) ,
. x = 0 ,
. matrixNum = 0 ,
. size = SPRITE_SIZE ( 16 x16 ) ,
. tileNum = 0 ,
2019-08-25 15:33:28 +02:00
. priority = 1 ,
2019-05-02 23:10:01 +02:00
. paletteNum = 0 ,
. affineParam = 0 ,
} ;
static const struct SpriteTemplate sSpriteTemplate_MegaIndicator =
{
. tileTag = TAG_MEGA_INDICATOR_TILE ,
. paletteTag = TAG_MEGA_INDICATOR_PAL ,
. oam = & sOamData_MegaIndicator ,
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCb_MegaIndicator ,
} ;
2021-08-25 03:35:21 -03:00
static const struct SpriteTemplate sSpriteTemplate_AlphaIndicator =
{
. tileTag = TAG_ALPHA_INDICATOR_TILE ,
. paletteTag = TAG_ALPHA_INDICATOR_PAL ,
. oam = & sOamData_MegaIndicator ,
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCb_MegaIndicator ,
} ;
static const struct SpriteTemplate sSpriteTemplate_OmegaIndicator =
{
. tileTag = TAG_OMEGA_INDICATOR_TILE ,
. paletteTag = TAG_OMEGA_INDICATOR_PAL ,
. oam = & sOamData_MegaIndicator ,
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCb_MegaIndicator ,
} ;
2018-06-19 00:43:15 +02:00
// Because the healthbox is too large to fit into one sprite, it is divided into two sprites.
// healthboxLeft or healthboxMain is the left part that is used as the 'main' sprite.
// healthboxRight or healthboxOther is the right part of the healthbox.
// There's also the third sprite under name of healthbarSprite that refers to the healthbar visible on the healtbox.
2017-10-19 18:25:48 +02:00
2018-06-19 00:43:15 +02:00
// data fields for healthboxMain
// oam.affineParam holds healthboxRight spriteId
# define hMain_HealthBarSpriteId data[5]
# define hMain_Battler data[6]
# define hMain_Data7 data[7]
// data fields for healthboxRight
# define hOther_HealthBoxSpriteId data[5]
2020-06-24 12:55:08 +02:00
# define hOther_IndicatorSpriteId data[6] // For Mega Evo
2018-06-19 00:43:15 +02:00
// data fields for healthbar
# define hBar_HealthBoxSpriteId data[5]
# define hBar_Data6 data[6]
2020-06-24 12:55:08 +02:00
u8 GetMegaIndicatorSpriteId ( u32 healthboxSpriteId )
{
u8 spriteId = gSprites [ healthboxSpriteId ] . oam . affineParam ;
if ( spriteId > = MAX_SPRITES )
return 0xFF ;
return gSprites [ spriteId ] . hOther_IndicatorSpriteId ;
}
2021-07-04 10:09:57 -06:00
static void InitLastUsedBallAssets ( void )
{
gBattleStruct - > ballSpriteIds [ 0 ] = MAX_SPRITES ;
gBattleStruct - > ballSpriteIds [ 1 ] = MAX_SPRITES ;
}
2022-08-24 23:00:21 +02:00
// 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.
u32 WhichBattleCoords ( u32 battlerId ) // 0 - singles, 1 - doubles
{
2022-09-18 22:34:06 -03:00
if ( GetBattlerPosition ( battlerId ) = = B_POSITION_PLAYER_LEFT
& & gPlayerPartyCount = = 1
& & ! ( gBattleTypeFlags & BATTLE_TYPE_MULTI ) )
2022-08-24 23:00:21 +02:00
return 0 ;
else
return IsDoubleBattle ( ) ;
}
2018-06-19 00:43:15 +02:00
u8 CreateBattlerHealthboxSprites ( u8 battlerId )
2017-10-16 18:12:27 +02:00
{
s16 data6 = 0 ;
2018-06-19 00:43:15 +02:00
u8 healthboxLeftSpriteId , healthboxRightSpriteId ;
2019-08-25 15:33:28 +02:00
u8 healthbarSpriteId , megaIndicatorSpriteId ;
2018-06-19 00:43:15 +02:00
struct Sprite * healthBarSpritePtr ;
2017-10-16 18:12:27 +02:00
2022-08-24 23:00:21 +02:00
if ( WhichBattleCoords ( battlerId ) = = 0 ) // Singles
2017-10-16 18:12:27 +02:00
{
2018-06-19 00:43:15 +02:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-10-16 18:12:27 +02:00
{
2021-04-15 02:04:01 -04:00
healthboxLeftSpriteId = CreateSprite ( & sHealthboxPlayerSpriteTemplates [ 0 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
healthboxRightSpriteId = CreateSpriteAtEnd ( & sHealthboxPlayerSpriteTemplates [ 0 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
2017-10-16 18:12:27 +02:00
2019-12-04 21:00:45 -05:00
gSprites [ healthboxLeftSpriteId ] . oam . shape = ST_OAM_SQUARE ;
2017-10-16 18:12:27 +02:00
2019-12-04 21:00:45 -05:00
gSprites [ healthboxRightSpriteId ] . oam . shape = ST_OAM_SQUARE ;
2018-06-19 00:43:15 +02:00
gSprites [ healthboxRightSpriteId ] . oam . tileNum + = 64 ;
2017-10-16 18:12:27 +02:00
}
else
{
2021-04-15 02:04:01 -04:00
healthboxLeftSpriteId = CreateSprite ( & sHealthboxOpponentSpriteTemplates [ 0 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
healthboxRightSpriteId = CreateSpriteAtEnd ( & sHealthboxOpponentSpriteTemplates [ 0 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxRightSpriteId ] . oam . tileNum + = 32 ;
2017-10-16 18:12:27 +02:00
data6 = 2 ;
}
2018-06-19 00:43:15 +02:00
gSprites [ healthboxLeftSpriteId ] . oam . affineParam = healthboxRightSpriteId ;
gSprites [ healthboxRightSpriteId ] . hOther_HealthBoxSpriteId = healthboxLeftSpriteId ;
gSprites [ healthboxRightSpriteId ] . callback = SpriteCB_HealthBoxOther ;
2017-10-16 18:12:27 +02:00
}
else
{
2018-06-19 00:43:15 +02:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-10-16 18:12:27 +02:00
{
2021-04-15 02:04:01 -04:00
healthboxLeftSpriteId = CreateSprite ( & sHealthboxPlayerSpriteTemplates [ GetBattlerPosition ( battlerId ) / 2 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
healthboxRightSpriteId = CreateSpriteAtEnd ( & sHealthboxPlayerSpriteTemplates [ GetBattlerPosition ( battlerId ) / 2 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxLeftSpriteId ] . oam . affineParam = healthboxRightSpriteId ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxRightSpriteId ] . hOther_HealthBoxSpriteId = healthboxLeftSpriteId ;
gSprites [ healthboxRightSpriteId ] . oam . tileNum + = 32 ;
gSprites [ healthboxRightSpriteId ] . callback = SpriteCB_HealthBoxOther ;
2017-10-16 18:12:27 +02:00
data6 = 1 ;
}
else
{
2021-04-15 02:04:01 -04:00
healthboxLeftSpriteId = CreateSprite ( & sHealthboxOpponentSpriteTemplates [ GetBattlerPosition ( battlerId ) / 2 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
healthboxRightSpriteId = CreateSpriteAtEnd ( & sHealthboxOpponentSpriteTemplates [ GetBattlerPosition ( battlerId ) / 2 ] , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxLeftSpriteId ] . oam . affineParam = healthboxRightSpriteId ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxRightSpriteId ] . hOther_HealthBoxSpriteId = healthboxLeftSpriteId ;
gSprites [ healthboxRightSpriteId ] . oam . tileNum + = 32 ;
gSprites [ healthboxRightSpriteId ] . callback = SpriteCB_HealthBoxOther ;
2017-10-16 18:12:27 +02:00
data6 = 2 ;
}
}
2018-06-19 00:43:15 +02:00
healthbarSpriteId = CreateSpriteAtEnd ( & sHealthbarSpriteTemplates [ gBattlerPositions [ battlerId ] ] , 140 , 60 , 0 ) ;
healthBarSpritePtr = & gSprites [ healthbarSpriteId ] ;
2021-11-06 11:41:47 -04:00
SetSubspriteTables ( healthBarSpritePtr , & sHealthBar_SubspriteTables [ GetBattlerSide ( battlerId ) ] ) ;
2019-12-04 21:00:45 -05:00
healthBarSpritePtr - > subspriteMode = SUBSPRITES_IGNORE_PRIORITY ;
2018-06-19 00:43:15 +02:00
healthBarSpritePtr - > oam . priority = 1 ;
2017-10-16 18:12:27 +02:00
2022-07-29 10:52:35 -04:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_1 ) , ( void * ) ( OBJ_VRAM0 + healthBarSpritePtr - > oam . tileNum * TILE_SIZE_4BPP ) , 64 ) ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxLeftSpriteId ] . hMain_HealthBarSpriteId = healthbarSpriteId ;
gSprites [ healthboxLeftSpriteId ] . hMain_Battler = battlerId ;
2018-09-10 10:25:58 -05:00
gSprites [ healthboxLeftSpriteId ] . invisible = TRUE ;
2017-10-16 18:12:27 +02:00
2018-09-10 10:25:58 -05:00
gSprites [ healthboxRightSpriteId ] . invisible = TRUE ;
2020-06-24 12:55:08 +02:00
gSprites [ healthboxRightSpriteId ] . hOther_IndicatorSpriteId = 0xFF ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
healthBarSpritePtr - > hBar_HealthBoxSpriteId = healthboxLeftSpriteId ;
healthBarSpritePtr - > hBar_Data6 = data6 ;
2018-09-10 10:25:58 -05:00
healthBarSpritePtr - > invisible = TRUE ;
2017-10-16 18:12:27 +02:00
2021-08-25 03:35:21 -03:00
// Create mega indicator sprite if is a mega evolved or a primal reverted mon.
2022-11-01 18:37:23 -03:00
if ( IsBattlerMegaEvolved ( battlerId ) | | IsBattlerPrimalReverted ( battlerId ) )
2019-08-25 15:33:28 +02:00
{
2019-08-25 15:39:56 +02:00
megaIndicatorSpriteId = CreateMegaIndicatorSprite ( battlerId , 0 ) ;
2019-08-25 15:33:28 +02:00
gSprites [ megaIndicatorSpriteId ] . invisible = TRUE ;
}
2019-05-02 23:10:01 +02:00
2021-06-25 13:37:59 -06:00
gBattleStruct - > ballSpriteIds [ 0 ] = MAX_SPRITES ;
gBattleStruct - > ballSpriteIds [ 1 ] = MAX_SPRITES ;
2018-06-19 00:43:15 +02:00
return healthboxLeftSpriteId ;
2017-10-16 18:12:27 +02:00
}
u8 CreateSafariPlayerHealthboxSprites ( void )
{
2018-06-19 00:43:15 +02:00
u8 healthboxLeftSpriteId , healthboxRightSpriteId ;
2017-10-16 18:12:27 +02:00
2021-04-15 02:04:01 -04:00
healthboxLeftSpriteId = CreateSprite ( & sHealthboxSafariSpriteTemplate , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
healthboxRightSpriteId = CreateSpriteAtEnd ( & sHealthboxSafariSpriteTemplate , DISPLAY_WIDTH , DISPLAY_HEIGHT , 1 ) ;
2017-10-16 18:12:27 +02:00
2019-12-04 21:00:45 -05:00
gSprites [ healthboxLeftSpriteId ] . oam . shape = ST_OAM_SQUARE ;
gSprites [ healthboxRightSpriteId ] . oam . shape = ST_OAM_SQUARE ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxRightSpriteId ] . oam . tileNum + = 64 ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxLeftSpriteId ] . oam . affineParam = healthboxRightSpriteId ;
gSprites [ healthboxRightSpriteId ] . hOther_HealthBoxSpriteId = healthboxLeftSpriteId ;
2017-10-16 18:12:27 +02:00
2020-07-31 09:29:56 +02:00
gSprites [ healthboxRightSpriteId ] . hOther_IndicatorSpriteId = 0xFF ;
2018-06-19 00:43:15 +02:00
gSprites [ healthboxRightSpriteId ] . callback = SpriteCB_HealthBoxOther ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
return healthboxLeftSpriteId ;
2017-10-16 18:12:27 +02:00
}
2017-10-19 15:28:41 +02:00
static const u8 * GetHealthboxElementGfxPtr ( u8 elementId )
2017-10-16 18:12:27 +02:00
{
return gHealthboxElementsGfxTable [ elementId ] ;
}
2018-06-19 00:43:15 +02:00
// Syncs the position of healthbar accordingly with the healthbox.
static void SpriteCB_HealthBar ( struct Sprite * sprite )
2017-10-16 18:12:27 +02:00
{
2018-06-19 00:43:15 +02:00
u8 healthboxSpriteId = sprite - > hBar_HealthBoxSpriteId ;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
switch ( sprite - > hBar_Data6 )
2017-10-16 18:12:27 +02:00
{
case 0 :
2021-07-07 09:11:52 -04:00
sprite - > x = gSprites [ healthboxSpriteId ] . x + 16 ;
sprite - > y = gSprites [ healthboxSpriteId ] . y ;
2017-10-16 18:12:27 +02:00
break ;
case 1 :
2021-07-07 09:11:52 -04:00
sprite - > x = gSprites [ healthboxSpriteId ] . x + 16 ;
sprite - > y = gSprites [ healthboxSpriteId ] . y ;
2017-10-16 18:12:27 +02:00
break ;
case 2 :
default :
2021-07-07 09:11:52 -04:00
sprite - > x = gSprites [ healthboxSpriteId ] . x + 8 ;
sprite - > y = gSprites [ healthboxSpriteId ] . y ;
2017-10-16 18:12:27 +02:00
break ;
}
2021-07-07 09:11:52 -04:00
sprite - > x2 = gSprites [ healthboxSpriteId ] . x2 ;
sprite - > y2 = gSprites [ healthboxSpriteId ] . y2 ;
2017-10-16 18:12:27 +02:00
}
2018-06-19 00:43:15 +02:00
static void SpriteCB_HealthBoxOther ( struct Sprite * sprite )
2017-10-16 18:12:27 +02:00
{
2018-06-19 00:43:15 +02:00
u8 healthboxMainSpriteId = sprite - > hOther_HealthBoxSpriteId ;
2020-06-24 12:55:08 +02:00
u8 megaSpriteId = sprite - > hOther_IndicatorSpriteId ;
2017-10-16 18:12:27 +02:00
2021-07-07 09:11:52 -04:00
sprite - > x = gSprites [ healthboxMainSpriteId ] . x + 64 ;
sprite - > y = gSprites [ healthboxMainSpriteId ] . y ;
2017-10-16 18:12:27 +02:00
2021-07-07 09:11:52 -04:00
sprite - > x2 = gSprites [ healthboxMainSpriteId ] . x2 ;
sprite - > y2 = gSprites [ healthboxMainSpriteId ] . y2 ;
2019-05-02 23:10:01 +02:00
if ( megaSpriteId ! = 0xFF )
{
2021-08-11 16:33:10 -07:00
gSprites [ megaSpriteId ] . x2 = sprite - > x2 ;
gSprites [ megaSpriteId ] . y2 = sprite - > y2 ;
2019-05-02 23:10:01 +02:00
}
2017-10-16 18:12:27 +02:00
}
2018-06-19 00:43:15 +02:00
void SetBattleBarStruct ( u8 battlerId , u8 healthboxSpriteId , s32 maxVal , s32 oldVal , s32 receivedValue )
2017-10-16 18:12:27 +02:00
{
2018-03-01 00:59:52 +01:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . healthboxSpriteId = healthboxSpriteId ;
gBattleSpritesDataPtr - > battleBars [ battlerId ] . maxValue = maxVal ;
2018-06-19 00:43:15 +02:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . oldValue = oldVal ;
2018-03-01 00:59:52 +01:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . receivedValue = receivedValue ;
2018-06-19 00:43:15 +02:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . currValue = - 32768 ;
2017-10-16 18:12:27 +02:00
}
2017-10-18 00:00:46 +02:00
void SetHealthboxSpriteInvisible ( u8 healthboxSpriteId )
{
2020-06-24 12:55:08 +02:00
DestroyMegaIndicatorSprite ( healthboxSpriteId ) ;
2018-09-10 10:25:58 -05:00
gSprites [ healthboxSpriteId ] . invisible = TRUE ;
gSprites [ gSprites [ healthboxSpriteId ] . hMain_HealthBarSpriteId ] . invisible = TRUE ;
gSprites [ gSprites [ healthboxSpriteId ] . oam . affineParam ] . invisible = TRUE ;
2017-10-18 00:00:46 +02:00
}
void SetHealthboxSpriteVisible ( u8 healthboxSpriteId )
{
2019-08-25 15:33:28 +02:00
u8 battlerId = gSprites [ healthboxSpriteId ] . hMain_Battler ;
2018-09-10 10:25:58 -05:00
gSprites [ healthboxSpriteId ] . invisible = FALSE ;
gSprites [ gSprites [ healthboxSpriteId ] . hMain_HealthBarSpriteId ] . invisible = FALSE ;
gSprites [ gSprites [ healthboxSpriteId ] . oam . affineParam ] . invisible = FALSE ;
2022-11-01 18:37:23 -03:00
if ( IsBattlerMegaEvolved ( battlerId ) | | IsBattlerPrimalReverted ( battlerId ) )
2019-08-25 15:33:28 +02:00
{
2020-06-24 12:55:08 +02:00
u8 spriteId = GetMegaIndicatorSpriteId ( healthboxSpriteId ) ;
if ( spriteId ! = 0xFF )
gSprites [ spriteId ] . invisible = FALSE ;
2019-08-25 15:33:28 +02:00
else
CreateMegaIndicatorSprite ( battlerId , 0 ) ;
}
2017-10-18 00:00:46 +02:00
}
static void UpdateSpritePos ( u8 spriteId , s16 x , s16 y )
{
2021-07-07 09:11:52 -04:00
gSprites [ spriteId ] . x = x ;
gSprites [ spriteId ] . y = y ;
2017-10-18 00:00:46 +02:00
}
void DestoryHealthboxSprite ( u8 healthboxSpriteId )
{
2020-06-24 12:55:08 +02:00
DestroyMegaIndicatorSprite ( healthboxSpriteId ) ;
2017-10-18 00:00:46 +02:00
DestroySprite ( & gSprites [ gSprites [ healthboxSpriteId ] . oam . affineParam ] ) ;
2018-06-19 00:43:15 +02:00
DestroySprite ( & gSprites [ gSprites [ healthboxSpriteId ] . hMain_HealthBarSpriteId ] ) ;
2017-10-18 00:00:46 +02:00
DestroySprite ( & gSprites [ healthboxSpriteId ] ) ;
}
2018-06-19 00:43:15 +02:00
void DummyBattleInterfaceFunc ( u8 healthboxSpriteId , bool8 isDoubleBattleBattlerOnly )
2017-10-18 00:00:46 +02:00
{
}
2020-10-19 13:35:59 -06:00
static void TryToggleHealboxVisibility ( u8 priority , u8 healthboxLeftSpriteId , u8 healthboxRightSpriteId , u8 healthbarSpriteId , u8 indicatorSpriteId )
2020-07-15 16:23:44 -06:00
{
2020-10-19 13:35:59 -06:00
u8 spriteIds [ 4 ] = { healthboxLeftSpriteId , healthboxRightSpriteId , healthbarSpriteId , indicatorSpriteId } ;
int i ;
2021-04-27 18:36:37 -07:00
2020-10-19 13:35:59 -06:00
for ( i = 0 ; i < NELEMS ( spriteIds ) ; i + + )
{
if ( spriteIds [ i ] = = 0xFF )
continue ;
2021-04-27 18:36:37 -07:00
2020-10-19 13:35:59 -06:00
switch ( priority )
{
case 0 : //start of anim -> make invisible
gSprites [ spriteIds [ i ] ] . invisible = TRUE ;
break ;
case 1 : //end of anim -> make visible
gSprites [ spriteIds [ i ] ] . invisible = FALSE ;
break ;
}
}
}
2021-02-02 23:30:08 -07:00
void UpdateOamPriorityInAllHealthboxes ( u8 priority , bool32 hideHPBoxes )
2017-10-18 00:00:46 +02:00
{
s32 i ;
2018-02-05 19:46:59 -06:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-10-18 00:00:46 +02:00
{
2018-06-19 00:43:15 +02:00
u8 healthboxLeftSpriteId = gHealthboxSpriteIds [ i ] ;
u8 healthboxRightSpriteId = gSprites [ gHealthboxSpriteIds [ i ] ] . oam . affineParam ;
u8 healthbarSpriteId = gSprites [ gHealthboxSpriteIds [ i ] ] . hMain_HealthBarSpriteId ;
2020-06-24 12:55:08 +02:00
u8 indicatorSpriteId = GetMegaIndicatorSpriteId ( healthboxLeftSpriteId ) ;
2017-10-18 00:00:46 +02:00
2018-06-19 00:43:15 +02:00
gSprites [ healthboxLeftSpriteId ] . oam . priority = priority ;
gSprites [ healthboxRightSpriteId ] . oam . priority = priority ;
gSprites [ healthbarSpriteId ] . oam . priority = priority ;
2020-06-24 12:55:08 +02:00
if ( indicatorSpriteId ! = 0xFF )
gSprites [ indicatorSpriteId ] . oam . priority = priority ;
2021-04-27 18:36:37 -07:00
2022-08-23 21:00:08 -04:00
# if B_HIDE_HEALTHBOX_IN_ANIMS
2021-02-02 23:30:08 -07:00
if ( hideHPBoxes & & IsBattlerAlive ( i ) )
2020-10-19 13:35:59 -06:00
TryToggleHealboxVisibility ( priority , healthboxLeftSpriteId , healthboxRightSpriteId , healthbarSpriteId , indicatorSpriteId ) ;
2022-08-23 21:00:08 -04:00
# endif
2017-10-18 00:00:46 +02:00
}
}
2019-05-02 23:10:01 +02:00
void GetBattlerHealthboxCoords ( u8 battler , s16 * x , s16 * y )
2017-10-18 00:00:46 +02:00
{
2019-05-02 23:10:01 +02:00
* x = 0 , * y = 0 ;
2017-10-18 00:00:46 +02:00
2022-08-24 23:00:21 +02:00
if ( ! WhichBattleCoords ( battler ) )
2017-10-18 00:00:46 +02:00
{
2018-02-06 16:09:39 -06:00
if ( GetBattlerSide ( battler ) ! = B_SIDE_PLAYER )
2019-05-02 23:10:01 +02:00
* x = 44 , * y = 30 ;
2017-10-18 00:00:46 +02:00
else
2019-05-02 23:10:01 +02:00
* x = 158 , * y = 88 ;
2017-10-18 00:00:46 +02:00
}
else
{
2018-02-06 16:09:39 -06:00
switch ( GetBattlerPosition ( battler ) )
2017-10-18 00:00:46 +02:00
{
2018-01-16 14:01:31 -06:00
case B_POSITION_PLAYER_LEFT :
2019-05-02 23:10:01 +02:00
* x = 159 , * y = 76 ;
2017-10-18 00:00:46 +02:00
break ;
2018-01-16 14:01:31 -06:00
case B_POSITION_PLAYER_RIGHT :
2019-05-02 23:10:01 +02:00
* x = 171 , * y = 101 ;
2017-10-18 00:00:46 +02:00
break ;
2018-01-16 14:01:31 -06:00
case B_POSITION_OPPONENT_LEFT :
2019-05-02 23:10:01 +02:00
* x = 44 , * y = 19 ;
2017-10-18 00:00:46 +02:00
break ;
2018-01-16 14:01:31 -06:00
case B_POSITION_OPPONENT_RIGHT :
2019-05-02 23:10:01 +02:00
* x = 32 , * y = 44 ;
2017-10-18 00:00:46 +02:00
break ;
}
}
2019-05-02 23:10:01 +02:00
}
2017-10-18 00:00:46 +02:00
2019-05-02 23:10:01 +02:00
void InitBattlerHealthboxCoords ( u8 battler )
{
s16 x , y ;
GetBattlerHealthboxCoords ( battler , & x , & y ) ;
2018-02-06 16:09:39 -06:00
UpdateSpritePos ( gHealthboxSpriteIds [ battler ] , x , y ) ;
2017-10-18 00:00:46 +02:00
}
2017-10-19 15:28:41 +02:00
static void UpdateLvlInHealthbox ( u8 healthboxSpriteId , u8 lvl )
2017-10-18 00:00:46 +02:00
{
2017-10-19 15:28:41 +02:00
u32 windowId , spriteTileNum ;
u8 * windowTileData ;
2017-10-18 00:00:46 +02:00
u8 text [ 16 ] ;
2021-05-03 18:22:44 -04:00
u32 xPos ;
u8 * objVram ;
2019-05-02 23:10:01 +02:00
u8 battler = gSprites [ healthboxSpriteId ] . hMain_Battler ;
2017-10-18 00:00:46 +02:00
2021-08-25 03:35:21 -03:00
// Don't print Lv char if mon is mega evolved or primal reverted.
2022-11-01 18:37:23 -03:00
if ( IsBattlerMegaEvolved ( battler ) | | IsBattlerPrimalReverted ( battler ) )
2019-05-02 23:10:01 +02:00
{
2021-06-07 12:00:23 -07:00
objVram = ConvertIntToDecimalStringN ( text , lvl , STR_CONV_MODE_LEFT_ALIGN , 3 ) ;
2021-08-26 19:00:43 +12:00
xPos = 5 * ( 3 - ( objVram - ( text + 2 ) ) ) - 1 ;
2019-05-02 23:10:01 +02:00
}
else
{
2021-06-07 12:00:23 -07:00
text [ 0 ] = CHAR_EXTRA_SYMBOL ;
text [ 1 ] = CHAR_LV_2 ;
2019-05-02 23:10:01 +02:00
2021-06-07 12:00:23 -07:00
objVram = ConvertIntToDecimalStringN ( text + 2 , lvl , STR_CONV_MODE_LEFT_ALIGN , 3 ) ;
2021-08-26 19:00:43 +12:00
xPos = 5 * ( 3 - ( objVram - ( text + 2 ) ) ) ;
2019-05-02 23:10:01 +02:00
}
2017-10-18 00:00:46 +02:00
2021-06-07 12:00:23 -07:00
xPos = 5 * ( 3 - ( objVram - ( text + 2 ) ) ) ;
2017-10-18 00:00:46 +02:00
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox ( text , xPos , 3 , 2 , & windowId ) ;
2018-11-22 01:10:50 +00:00
spriteTileNum = gSprites [ healthboxSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ;
2017-10-18 00:00:46 +02:00
2019-05-02 23:10:01 +02:00
if ( GetBattlerSide ( battler ) = = B_SIDE_PLAYER )
2017-10-18 00:00:46 +02:00
{
2022-07-29 10:52:35 -04:00
objVram = ( void * ) ( OBJ_VRAM0 ) ;
2022-08-24 23:00:21 +02:00
if ( ! WhichBattleCoords ( battler ) )
2017-10-18 00:00:46 +02:00
objVram + = spriteTileNum + 0x820 ;
else
objVram + = spriteTileNum + 0x420 ;
}
else
{
2022-07-29 10:52:35 -04:00
objVram = ( void * ) ( OBJ_VRAM0 ) ;
2017-10-18 00:00:46 +02:00
objVram + = spriteTileNum + 0x400 ;
}
2018-06-19 00:43:15 +02:00
TextIntoHealthboxObject ( objVram , windowTileData , 3 ) ;
2017-10-18 23:05:14 +02:00
RemoveWindowOnHealthbox ( windowId ) ;
2017-10-18 00:00:46 +02:00
}
2022-08-25 16:40:56 +02:00
static void PrintHpOnHealthbox ( u32 spriteId , s16 currHp , s16 maxHp , u32 bgColor , u32 rightTile , u32 leftTile )
2017-10-18 00:00:46 +02:00
{
2017-10-19 15:28:41 +02:00
u8 * windowTileData ;
2022-08-25 16:40:56 +02:00
u32 windowId , tilesCount , x , healthboxTileNum ;
u8 text [ 28 ] , * txtPtr ;
void * objVram = ( void * ) ( OBJ_VRAM0 ) + gSprites [ spriteId ] . oam . tileNum * TILE_SIZE_4BPP ;
// 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 ;
2017-10-18 00:00:46 +02:00
else
2022-08-25 16:40:56 +02:00
x = 6 , tilesCount = 2 , leftTile + = 0x20 ;
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox ( text , x , 5 , bgColor , & windowId ) ;
HpTextIntoHealthboxObject ( objVram + leftTile , windowTileData , tilesCount ) ;
RemoveWindowOnHealthbox ( windowId ) ;
}
// 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
2017-10-18 00:00:46 +02:00
{
2022-08-25 16:40:56 +02:00
memcpy ( text , sEmptyWhiteText_TransparentHighlight , sizeof ( sEmptyWhiteText_TransparentHighlight ) ) ;
if ( maxOrCurrent = = HP_CURRENT )
var = 0 ;
else
var = 4 ;
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
txtPtr = ConvertIntToDecimalStringN ( text + 6 , value , STR_CONV_MODE_RIGHT_ALIGN , 3 ) ;
if ( ! maxOrCurrent )
StringCopy ( txtPtr , gText_Slash ) ;
RenderTextHandleBold ( gMonSpritesGfxPtr - > barFontGfx , FONT_BOLD , text ) ;
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
for ( i = var ; i < var + 3 ; i + + )
{
if ( i < 3 )
2017-10-18 00:00:46 +02:00
{
2022-08-25 16:40:56 +02:00
CpuCopy32 ( & gMonSpritesGfxPtr - > barFontGfx [ ( ( i - var ) * 64 ) + 32 ] ,
( void * ) ( ( OBJ_VRAM0 ) + 32 * ( 1 + gSprites [ barSpriteId ] . oam . tileNum + i ) ) ,
0x20 ) ;
2017-10-18 00:00:46 +02:00
}
else
{
2022-08-25 16:40:56 +02:00
CpuCopy32 ( & gMonSpritesGfxPtr - > barFontGfx [ ( ( i - var ) * 64 ) + 32 ] ,
( void * ) ( ( OBJ_VRAM0 + 0x20 ) + 32 * ( i + gSprites [ barSpriteId ] . oam . tileNum ) ) ,
0x20 ) ;
2017-10-18 00:00:46 +02:00
}
2022-08-25 16:40:56 +02:00
}
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
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 ) ;
2017-10-18 00:00:46 +02:00
}
}
}
2022-08-25 16:40:56 +02:00
// Same with this one.
static void UpdateOpponentHpTextSingles ( u32 healthboxSpriteId , s16 value , u32 maxOrCurrent )
2017-10-18 00:00:46 +02:00
{
u8 text [ 32 ] ;
2022-08-25 16:40:56 +02:00
u32 var , i ;
u32 battler = gSprites [ healthboxSpriteId ] . hMain_Battler ;
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
memcpy ( text , sEmptyWhiteText_GrayHighlight , sizeof ( sEmptyWhiteText_GrayHighlight ) ) ;
if ( gBattleSpritesDataPtr - > battlerData [ battler ] . hpNumbersNoBars ) // don't print text if only bars are visible
2017-10-18 00:00:46 +02:00
{
2022-08-25 16:40:56 +02:00
if ( maxOrCurrent = = HP_CURRENT )
var = 21 ;
else
var = 49 ;
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
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 ) ;
2017-10-18 00:00:46 +02:00
}
}
2022-08-25 16:40:56 +02:00
}
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
void UpdateHpTextInHealthbox ( u32 healthboxSpriteId , u32 maxOrCurrent , s16 currHp , s16 maxHp )
{
2022-08-25 22:10:59 +02:00
u32 battlerId = gSprites [ healthboxSpriteId ] . hMain_Battler ;
if ( WhichBattleCoords ( battlerId ) )
2022-08-25 16:40:56 +02:00
{
UpdateHpTextInHealthboxInDoubles ( healthboxSpriteId , maxOrCurrent , currHp , maxHp ) ;
}
else // Single Battle
{
2022-08-25 22:10:59 +02:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER ) // Player
2017-10-18 00:00:46 +02:00
{
2022-08-25 16:40:56 +02:00
PrintHpOnHealthbox ( healthboxSpriteId , currHp , maxHp , 2 , 0xB00 , 0x3A0 ) ;
}
else // Opponent
{
UpdateOpponentHpTextSingles ( healthboxSpriteId , currHp , HP_CURRENT ) ;
UpdateOpponentHpTextSingles ( healthboxSpriteId , maxHp , HP_MAX ) ;
}
}
}
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
static void UpdateHpTextInHealthboxInDoubles ( u32 healthboxSpriteId , u32 maxOrCurrent , s16 currHp , s16 maxHp )
{
u32 barSpriteId = gSprites [ healthboxSpriteId ] . data [ 5 ] ;
2017-10-18 00:00:46 +02:00
2022-08-25 16:40:56 +02:00
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
{
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 ) ,
2017-10-18 00:00:46 +02:00
0x20 ) ;
2022-08-25 16:40:56 +02:00
// Erases HP bar leftover.
FillHealthboxObject ( ( void * ) ( OBJ_VRAM0 ) + ( gSprites [ barSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ) , 0 , 2 ) ;
2017-10-18 00:00:46 +02:00
}
}
2022-08-25 16:40:56 +02:00
else // Opponent
{
UpdateOpponentHpTextDoubles ( healthboxSpriteId , barSpriteId , maxHp , HP_MAX ) ;
UpdateOpponentHpTextDoubles ( healthboxSpriteId , barSpriteId , currHp , HP_CURRENT ) ;
}
2017-10-18 00:00:46 +02:00
}
2017-10-18 21:42:00 +02:00
2018-07-01 11:15:42 +02:00
// Prints mon's nature, catch and flee rate. Probably used to test pokeblock-related features.
2018-06-19 00:43:15 +02:00
static void PrintSafariMonInfo ( u8 healthboxSpriteId , struct Pokemon * mon )
2017-10-18 21:42:00 +02:00
{
u8 text [ 20 ] ;
2018-11-22 01:10:50 +00:00
s32 j , spriteTileNum ;
2017-11-04 16:25:19 +01:00
u8 * barFontGfx ;
2018-06-19 00:43:15 +02:00
u8 i , var , nature , healthBarSpriteId ;
2017-10-18 21:42:00 +02:00
2021-10-30 16:47:37 -04:00
memcpy ( text , sEmptyWhiteText_GrayHighlight , sizeof ( sEmptyWhiteText_GrayHighlight ) ) ;
2018-06-19 00:43:15 +02:00
barFontGfx = & gMonSpritesGfxPtr - > barFontGfx [ 0x520 + ( GetBattlerPosition ( gSprites [ healthboxSpriteId ] . hMain_Battler ) * 384 ) ] ;
2017-10-18 21:42:00 +02:00
var = 5 ;
nature = GetNature ( mon ) ;
2021-11-06 11:41:47 -04:00
StringCopy ( & text [ 6 ] , gNatureNamePointers [ nature ] ) ;
2021-10-31 01:44:18 -04:00
RenderTextHandleBold ( barFontGfx , FONT_BOLD , text ) ;
2017-10-18 21:42:00 +02:00
for ( j = 6 , i = 0 ; i < var ; i + + , j + + )
{
u8 elementId ;
if ( ( text [ j ] > = 55 & & text [ j ] < = 74 ) | | ( text [ j ] > = 135 & & text [ j ] < = 154 ) )
elementId = 44 ;
else if ( ( text [ j ] > = 75 & & text [ j ] < = 79 ) | | ( text [ j ] > = 155 & & text [ j ] < = 159 ) )
elementId = 45 ;
else
elementId = 43 ;
2017-11-04 16:25:19 +01:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( elementId ) , barFontGfx + ( i * 64 ) , 0x20 ) ;
2017-10-18 21:42:00 +02:00
}
for ( j = 1 ; j < var + 1 ; j + + )
{
2018-11-22 01:10:50 +00:00
spriteTileNum = ( gSprites [ healthboxSpriteId ] . oam . tileNum + ( j - ( j / 8 * 8 ) ) + ( j / 8 * 64 ) ) * TILE_SIZE_4BPP ;
2022-07-29 10:52:35 -04:00
CpuCopy32 ( barFontGfx , ( void * ) ( OBJ_VRAM0 ) + ( spriteTileNum ) , 0x20 ) ;
2017-11-04 16:25:19 +01:00
barFontGfx + = 0x20 ;
2017-10-18 21:42:00 +02:00
2018-11-22 01:10:50 +00:00
spriteTileNum = ( 8 + gSprites [ healthboxSpriteId ] . oam . tileNum + ( j - ( j / 8 * 8 ) ) + ( j / 8 * 64 ) ) * TILE_SIZE_4BPP ;
2022-07-29 10:52:35 -04:00
CpuCopy32 ( barFontGfx , ( void * ) ( OBJ_VRAM0 ) + ( spriteTileNum ) , 0x20 ) ;
2017-11-04 16:25:19 +01:00
barFontGfx + = 0x20 ;
2017-10-18 21:42:00 +02:00
}
2018-06-19 00:43:15 +02:00
healthBarSpriteId = gSprites [ healthboxSpriteId ] . hMain_HealthBarSpriteId ;
2021-11-06 11:41:47 -04:00
ConvertIntToDecimalStringN ( & text [ 6 ] , gBattleStruct - > safariCatchFactor , STR_CONV_MODE_RIGHT_ALIGN , 2 ) ;
ConvertIntToDecimalStringN ( & text [ 9 ] , gBattleStruct - > safariEscapeFactor , STR_CONV_MODE_RIGHT_ALIGN , 2 ) ;
2017-10-18 21:42:00 +02:00
text [ 5 ] = CHAR_SPACE ;
text [ 8 ] = CHAR_SLASH ;
2021-10-31 01:44:18 -04:00
RenderTextHandleBold ( gMonSpritesGfxPtr - > barFontGfx , FONT_BOLD , text ) ;
2017-10-18 21:42:00 +02:00
2018-06-19 00:43:15 +02:00
j = healthBarSpriteId ; // Needed to match for some reason.
2017-10-18 21:42:00 +02:00
for ( j = 0 ; j < 5 ; j + + )
{
if ( j < = 1 )
{
2017-11-04 16:25:19 +01:00
CpuCopy32 ( & gMonSpritesGfxPtr - > barFontGfx [ 0x40 * j + 0x20 ] ,
2022-07-29 10:52:35 -04:00
( void * ) ( OBJ_VRAM0 ) + ( gSprites [ healthBarSpriteId ] . oam . tileNum + 2 + j ) * TILE_SIZE_4BPP ,
2017-10-18 21:42:00 +02:00
32 ) ;
}
else
{
2017-11-04 16:25:19 +01:00
CpuCopy32 ( & gMonSpritesGfxPtr - > barFontGfx [ 0x40 * j + 0x20 ] ,
2022-07-29 10:52:35 -04:00
( void * ) ( OBJ_VRAM0 + 0xC0 ) + ( j + gSprites [ healthBarSpriteId ] . oam . tileNum ) * TILE_SIZE_4BPP ,
2017-10-18 21:42:00 +02:00
32 ) ;
}
}
}
void SwapHpBarsWithHpText ( void )
{
2022-08-25 16:40:56 +02:00
u32 healthBarSpriteId , i ;
2017-10-18 21:42:00 +02:00
2018-02-05 19:46:59 -06:00
for ( i = 0 ; i < gBattlersCount ; i + + )
2017-10-18 21:42:00 +02:00
{
2018-02-06 13:48:02 -06:00
if ( gSprites [ gHealthboxSpriteIds [ i ] ] . callback = = SpriteCallbackDummy
2018-02-05 19:46:59 -06:00
& & GetBattlerSide ( i ) ! = B_SIDE_OPPONENT
2022-08-24 23:00:21 +02:00
& & ( WhichBattleCoords ( i ) | | GetBattlerSide ( i ) ! = B_SIDE_PLAYER ) )
2017-10-18 21:42:00 +02:00
{
2022-08-25 16:40:56 +02:00
s32 currHp = GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ i ] ] , MON_DATA_HP ) ;
s32 maxHp = GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ i ] ] , MON_DATA_MAX_HP ) ;
2017-10-18 21:42:00 +02:00
bool8 noBars ;
2018-02-06 16:09:39 -06:00
gBattleSpritesDataPtr - > battlerData [ i ] . hpNumbersNoBars ^ = 1 ;
noBars = gBattleSpritesDataPtr - > battlerData [ i ] . hpNumbersNoBars ;
2018-02-05 19:46:59 -06:00
if ( GetBattlerSide ( i ) = = B_SIDE_PLAYER )
2017-10-18 21:42:00 +02:00
{
2022-08-24 23:00:21 +02:00
if ( ! WhichBattleCoords ( i ) )
2017-10-18 21:42:00 +02:00
continue ;
if ( gBattleTypeFlags & BATTLE_TYPE_SAFARI )
continue ;
if ( noBars = = TRUE ) // bars to text
{
2018-06-19 00:43:15 +02:00
healthBarSpriteId = gSprites [ gHealthboxSpriteIds [ i ] ] . hMain_HealthBarSpriteId ;
2017-10-18 21:42:00 +02:00
2022-07-29 10:52:35 -04:00
CpuFill32 ( 0 , ( void * ) ( OBJ_VRAM0 + gSprites [ healthBarSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ) , 0x100 ) ;
2022-08-25 16:40:56 +02:00
UpdateHpTextInHealthboxInDoubles ( gHealthboxSpriteIds [ i ] , HP_BOTH , currHp , maxHp ) ;
2017-10-18 21:42:00 +02:00
}
else // text to bars
{
2018-02-06 13:48:02 -06:00
UpdateStatusIconInHealthbox ( gHealthboxSpriteIds [ i ] ) ;
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ i ] , & gPlayerParty [ gBattlerPartyIndexes [ i ] ] , HEALTHBOX_HEALTH_BAR ) ;
2022-07-29 10:52:35 -04:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_FRAME_END_BAR ) , ( void * ) ( OBJ_VRAM0 + 0x680 + gSprites [ gHealthboxSpriteIds [ i ] ] . oam . tileNum * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-18 21:42:00 +02:00
}
}
else
{
if ( noBars = = TRUE ) // bars to text
{
if ( gBattleTypeFlags & BATTLE_TYPE_SAFARI )
{
2018-06-19 00:43:15 +02:00
// Most likely a debug function.
PrintSafariMonInfo ( gHealthboxSpriteIds [ i ] , & gEnemyParty [ gBattlerPartyIndexes [ i ] ] ) ;
2017-10-18 21:42:00 +02:00
}
else
{
2018-06-19 00:43:15 +02:00
healthBarSpriteId = gSprites [ gHealthboxSpriteIds [ i ] ] . hMain_HealthBarSpriteId ;
2017-10-18 21:42:00 +02:00
2018-06-19 00:43:15 +02:00
CpuFill32 ( 0 , ( void * ) ( OBJ_VRAM0 + gSprites [ healthBarSpriteId ] . oam . tileNum * 32 ) , 0x100 ) ;
2022-08-25 16:40:56 +02:00
UpdateHpTextInHealthboxInDoubles ( gHealthboxSpriteIds [ i ] , HP_BOTH , currHp , maxHp ) ;
2017-10-18 21:42:00 +02:00
}
}
else // text to bars
{
2018-02-06 13:48:02 -06:00
UpdateStatusIconInHealthbox ( gHealthboxSpriteIds [ i ] ) ;
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ i ] , & gEnemyParty [ gBattlerPartyIndexes [ i ] ] , HEALTHBOX_HEALTH_BAR ) ;
2017-10-18 21:42:00 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_SAFARI )
2018-02-06 13:48:02 -06:00
UpdateHealthboxAttribute ( gHealthboxSpriteIds [ i ] , & gEnemyParty [ gBattlerPartyIndexes [ i ] ] , HEALTHBOX_NICK ) ;
2017-10-18 21:42:00 +02:00
}
}
2018-06-19 00:43:15 +02:00
gSprites [ gHealthboxSpriteIds [ i ] ] . hMain_Data7 ^ = 1 ;
2017-10-18 21:42:00 +02:00
}
}
}
2018-09-17 22:40:49 +02:00
// Mega Evolution gfx functions.
2018-09-20 20:59:00 +02:00
void ChangeMegaTriggerSprite ( u8 spriteId , u8 animId )
2018-09-17 22:40:49 +02:00
{
2018-09-20 20:59:00 +02:00
StartSpriteAnim ( & gSprites [ spriteId ] , animId ) ;
2018-09-17 22:40:49 +02:00
}
2018-09-20 20:59:00 +02:00
# define SINGLES_MEGA_TRIGGER_POS_X_OPTIMAL (30)
# define SINGLES_MEGA_TRIGGER_POS_X_PRIORITY (31)
# define SINGLES_MEGA_TRIGGER_POS_X_SLIDE (15)
# define SINGLES_MEGA_TRIGGER_POS_Y_DIFF (-11)
# define DOUBLES_MEGA_TRIGGER_POS_X_OPTIMAL (30)
# define DOUBLES_MEGA_TRIGGER_POS_X_PRIORITY (31)
# define DOUBLES_MEGA_TRIGGER_POS_X_SLIDE (15)
# define DOUBLES_MEGA_TRIGGER_POS_Y_DIFF (-4)
2018-09-17 22:40:49 +02:00
2018-09-20 11:23:12 +02:00
# define tBattler data[0]
# define tHide data[1]
2018-09-17 22:40:49 +02:00
void CreateMegaTriggerSprite ( u8 battlerId , u8 palId )
{
2018-09-20 20:59:00 +02:00
LoadSpritePalette ( & sSpritePalette_MegaTrigger ) ;
2018-09-17 22:40:49 +02:00
if ( GetSpriteTileStartByTag ( TAG_MEGA_TRIGGER_TILE ) = = 0xFFFF )
LoadSpriteSheet ( & sSpriteSheet_MegaTrigger ) ;
2018-09-20 17:33:27 +02:00
if ( gBattleStruct - > mega . triggerSpriteId = = 0xFF )
2018-09-17 22:40:49 +02:00
{
2018-09-20 20:59:00 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
gBattleStruct - > mega . triggerSpriteId = CreateSprite ( & sSpriteTemplate_MegaTrigger ,
2021-08-11 16:33:10 -07:00
gSprites [ gHealthboxSpriteIds [ battlerId ] ] . x - DOUBLES_MEGA_TRIGGER_POS_X_SLIDE ,
gSprites [ gHealthboxSpriteIds [ battlerId ] ] . y - DOUBLES_MEGA_TRIGGER_POS_Y_DIFF , 0 ) ;
2018-09-22 01:01:13 +02:00
else
gBattleStruct - > mega . triggerSpriteId = CreateSprite ( & sSpriteTemplate_MegaTrigger ,
2021-08-11 16:33:10 -07:00
gSprites [ gHealthboxSpriteIds [ battlerId ] ] . x - SINGLES_MEGA_TRIGGER_POS_X_SLIDE ,
gSprites [ gHealthboxSpriteIds [ battlerId ] ] . y - SINGLES_MEGA_TRIGGER_POS_Y_DIFF , 0 ) ;
2018-09-17 22:40:49 +02:00
}
2018-09-20 17:33:27 +02:00
gSprites [ gBattleStruct - > mega . triggerSpriteId ] . tBattler = battlerId ;
gSprites [ gBattleStruct - > mega . triggerSpriteId ] . tHide = FALSE ;
2018-09-17 22:40:49 +02:00
2018-09-20 20:59:00 +02:00
ChangeMegaTriggerSprite ( gBattleStruct - > mega . triggerSpriteId , palId ) ;
2018-09-17 22:40:49 +02:00
}
static void SpriteCb_MegaTrigger ( struct Sprite * sprite )
{
2018-09-20 20:59:00 +02:00
s32 xSlide , xPriority , xOptimal ;
s32 yDiff ;
if ( gBattleTypeFlags & BATTLE_TYPE_DOUBLE )
{
xSlide = DOUBLES_MEGA_TRIGGER_POS_X_SLIDE ;
xPriority = DOUBLES_MEGA_TRIGGER_POS_X_PRIORITY ;
xOptimal = DOUBLES_MEGA_TRIGGER_POS_X_OPTIMAL ;
yDiff = DOUBLES_MEGA_TRIGGER_POS_Y_DIFF ;
}
else
{
xSlide = SINGLES_MEGA_TRIGGER_POS_X_SLIDE ;
xPriority = SINGLES_MEGA_TRIGGER_POS_X_PRIORITY ;
xOptimal = SINGLES_MEGA_TRIGGER_POS_X_OPTIMAL ;
yDiff = SINGLES_MEGA_TRIGGER_POS_Y_DIFF ;
}
2018-09-20 11:23:12 +02:00
if ( sprite - > tHide )
{
2021-08-11 16:33:10 -07:00
if ( sprite - > x ! = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . x - xSlide )
sprite - > x + + ;
2018-09-20 11:23:12 +02:00
2021-08-11 16:33:10 -07:00
if ( sprite - > x > = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . x - xPriority )
2018-09-20 20:59:00 +02:00
sprite - > oam . priority = 2 ;
else
sprite - > oam . priority = 1 ;
2021-08-11 16:33:10 -07:00
sprite - > y = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . y - yDiff ;
sprite - > y2 = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . y2 - yDiff ;
if ( sprite - > x = = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . x - xSlide )
2018-09-20 11:23:12 +02:00
DestroyMegaTriggerSprite ( ) ;
}
else
{
2021-08-11 16:33:10 -07:00
if ( sprite - > x ! = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . x - xOptimal )
sprite - > x - - ;
2018-09-20 11:23:12 +02:00
2021-08-11 16:33:10 -07:00
if ( sprite - > x > = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . x - xPriority )
2018-09-20 20:59:00 +02:00
sprite - > oam . priority = 2 ;
else
sprite - > oam . priority = 1 ;
2021-08-11 16:33:10 -07:00
sprite - > y = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . y - yDiff ;
sprite - > y2 = gSprites [ gHealthboxSpriteIds [ sprite - > tBattler ] ] . y2 - yDiff ;
2018-09-20 11:23:12 +02:00
}
}
bool32 IsMegaTriggerSpriteActive ( void )
{
if ( GetSpriteTileStartByTag ( TAG_MEGA_TRIGGER_TILE ) = = 0xFFFF )
return FALSE ;
2018-09-20 20:59:00 +02:00
else if ( IndexOfSpritePaletteTag ( TAG_MEGA_TRIGGER_PAL ) ! = 0xFF )
2018-09-20 11:23:12 +02:00
return TRUE ;
else
return FALSE ;
}
2018-09-17 22:40:49 +02:00
2018-09-20 11:23:12 +02:00
void HideMegaTriggerSprite ( void )
{
2021-02-11 16:00:49 -07:00
if ( gBattleStruct - > mega . triggerSpriteId ! = 0xFF )
{
ChangeMegaTriggerSprite ( gBattleStruct - > mega . triggerSpriteId , 0 ) ;
gSprites [ gBattleStruct - > mega . triggerSpriteId ] . tHide = TRUE ;
}
2018-09-17 22:40:49 +02:00
}
2020-11-26 15:56:18 -05:00
void HideTriggerSprites ( void )
{
HideMegaTriggerSprite ( ) ;
HideZMoveTriggerSprite ( ) ;
}
2018-09-17 22:40:49 +02:00
void DestroyMegaTriggerSprite ( void )
{
2018-09-20 20:59:00 +02:00
FreeSpritePaletteByTag ( TAG_MEGA_TRIGGER_PAL ) ;
2018-09-17 22:40:49 +02:00
FreeSpriteTilesByTag ( TAG_MEGA_TRIGGER_TILE ) ;
2018-09-20 17:33:27 +02:00
if ( gBattleStruct - > mega . triggerSpriteId ! = 0xFF )
DestroySprite ( & gSprites [ gBattleStruct - > mega . triggerSpriteId ] ) ;
gBattleStruct - > mega . triggerSpriteId = 0xFF ;
2018-09-17 22:40:49 +02:00
}
2021-08-26 19:00:43 +12:00
static const s8 sIndicatorPositions [ ] [ 2 ] =
2019-05-02 23:10:01 +02:00
{
2021-08-26 19:00:43 +12:00
[ B_POSITION_PLAYER_LEFT ] = { 52 , - 9 } ,
[ B_POSITION_OPPONENT_LEFT ] = { 44 , - 9 } ,
[ B_POSITION_PLAYER_RIGHT ] = { 52 , - 9 } ,
[ B_POSITION_OPPONENT_RIGHT ] = { 44 , - 9 } ,
2019-05-02 23:10:01 +02:00
} ;
2019-08-25 15:33:28 +02:00
u32 CreateMegaIndicatorSprite ( u32 battlerId , u32 which )
2019-05-02 23:10:01 +02:00
{
2019-08-25 15:33:28 +02:00
u32 spriteId , position ;
2019-05-02 23:10:01 +02:00
s16 x , y ;
2022-11-01 18:37:23 -03:00
if ( IsBattlerMegaEvolved ( battlerId ) )
2021-08-25 03:35:21 -03:00
{
LoadSpritePalette ( & sSpritePalette_MegaIndicator ) ;
LoadSpriteSheet ( & sSpriteSheet_MegaIndicator ) ;
}
2022-10-21 02:08:37 -03:00
else if ( IsBattlerPrimalReverted ( battlerId ) )
2021-08-25 03:35:21 -03:00
{
2022-11-06 16:01:07 -03:00
if ( gBattleMons [ battlerId ] . species = = SPECIES_GROUDON_PRIMAL )
2021-08-25 03:35:21 -03:00
{
LoadSpritePalette ( & sSpritePalette_OmegaIndicator ) ;
LoadSpriteSheet ( & sSpriteSheet_OmegaIndicator ) ;
}
2022-11-06 16:01:07 -03:00
else // SPECIES_KYOGRE_PRIMAL
2021-08-25 03:35:21 -03:00
{
LoadSpritePalette ( & sSpritePalette_AlphaIndicator ) ;
LoadSpriteSheet ( & sSpriteSheet_AlphaIndicator ) ;
}
}
2019-05-02 23:10:01 +02:00
position = GetBattlerPosition ( battlerId ) ;
GetBattlerHealthboxCoords ( battlerId , & x , & y ) ;
2021-08-25 03:35:21 -03:00
2021-08-26 19:00:43 +12:00
x + = sIndicatorPositions [ position ] [ 0 ] ;
y + = sIndicatorPositions [ position ] [ 1 ] ;
if ( gBattleMons [ battlerId ] . level > = 100 )
x - = 4 ;
else if ( gBattleMons [ battlerId ] . level < 10 )
x + = 5 ;
2019-05-02 23:10:01 +02:00
2022-11-01 18:37:23 -03:00
if ( IsBattlerMegaEvolved ( battlerId ) )
2021-08-25 03:35:21 -03:00
{
spriteId = CreateSpriteAtEnd ( & sSpriteTemplate_MegaIndicator , x , y , 0 ) ;
}
2022-10-21 02:08:37 -03:00
else if ( IsBattlerPrimalReverted ( battlerId ) )
2021-08-25 03:35:21 -03:00
{
2022-11-06 16:01:07 -03:00
if ( gBattleMons [ battlerId ] . species = = SPECIES_GROUDON_PRIMAL )
2021-08-25 03:35:21 -03:00
spriteId = CreateSpriteAtEnd ( & sSpriteTemplate_OmegaIndicator , x , y , 0 ) ;
2022-11-06 16:01:07 -03:00
else // SPECIES_KYOGRE_PRIMAL
2021-08-25 03:35:21 -03:00
spriteId = CreateSpriteAtEnd ( & sSpriteTemplate_AlphaIndicator , x , y , 0 ) ;
}
gSprites [ gSprites [ gHealthboxSpriteIds [ battlerId ] ] . oam . affineParam ] . hOther_IndicatorSpriteId = spriteId ;
2019-05-02 23:10:01 +02:00
gSprites [ spriteId ] . tBattler = battlerId ;
2019-08-25 15:33:28 +02:00
return spriteId ;
2019-05-02 23:10:01 +02:00
}
2020-06-24 12:55:08 +02:00
void DestroyMegaIndicatorSprite ( u32 healthboxSpriteId )
2019-05-02 23:10:01 +02:00
{
u32 i ;
2020-06-24 12:55:08 +02:00
s16 * spriteId = & gSprites [ gSprites [ healthboxSpriteId ] . oam . affineParam ] . hOther_IndicatorSpriteId ;
2019-05-02 23:10:01 +02:00
2020-06-24 12:55:08 +02:00
if ( * spriteId ! = 0xFF )
2019-05-02 23:10:01 +02:00
{
2020-06-24 12:55:08 +02:00
DestroySprite ( & gSprites [ * spriteId ] ) ;
* spriteId = 0xFF ;
2019-05-02 23:10:01 +02:00
}
for ( i = 0 ; i < MAX_BATTLERS_COUNT ; i + + )
{
2020-06-24 12:55:08 +02:00
if ( gSprites [ gSprites [ gHealthboxSpriteIds [ i ] ] . oam . affineParam ] . hOther_IndicatorSpriteId ! = 0xFF )
2019-05-02 23:10:01 +02:00
break ;
}
// Free Sprite pal/tiles only if no indicator sprite is active for all battlers.
if ( i = = MAX_BATTLERS_COUNT )
{
FreeSpritePaletteByTag ( TAG_MEGA_INDICATOR_PAL ) ;
FreeSpriteTilesByTag ( TAG_MEGA_INDICATOR_TILE ) ;
}
}
static void SpriteCb_MegaIndicator ( struct Sprite * sprite )
{
2020-06-24 12:55:08 +02:00
2019-05-02 23:10:01 +02:00
}
2018-09-20 11:23:12 +02:00
# undef tBattler
# undef tHide
2018-06-20 23:07:51 +02:00
# define tBattler data[0]
# define tSummaryBarSpriteId data[1]
# define tBallIconSpriteId(n) data[3 + n]
# define tIsBattleStart data[10]
2021-11-06 11:41:47 -04:00
# define tBlend data[15]
2018-06-20 23:07:51 +02:00
2022-06-01 12:41:57 -04:00
u8 CreatePartyStatusSummarySprites ( u8 battlerId , struct HpAndStatus * partyInfo , bool8 skipPlayer , bool8 isBattleStart )
2017-10-18 21:42:00 +02:00
{
bool8 isOpponent ;
s16 bar_X , bar_Y , bar_pos2_X , bar_data0 ;
s32 i , j , var ;
2018-06-20 23:07:51 +02:00
u8 summaryBarSpriteId ;
2018-06-19 00:43:15 +02:00
u8 ballIconSpritesIds [ PARTY_SIZE ] ;
2017-10-18 21:42:00 +02:00
u8 taskId ;
2022-06-01 12:41:57 -04:00
if ( ! skipPlayer | | GetBattlerPosition ( battlerId ) ! = B_POSITION_OPPONENT_RIGHT )
2017-10-18 21:42:00 +02:00
{
2018-03-01 00:59:52 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-10-18 21:42:00 +02:00
{
isOpponent = FALSE ;
bar_X = 136 , bar_Y = 96 ;
bar_pos2_X = 100 ;
bar_data0 = - 5 ;
}
else
{
isOpponent = TRUE ;
2022-08-24 23:00:21 +02:00
if ( ! skipPlayer | | ! WhichBattleCoords ( battlerId ) )
2017-10-18 21:42:00 +02:00
bar_X = 104 , bar_Y = 40 ;
else
bar_X = 104 , bar_Y = 16 ;
bar_pos2_X = - 100 ;
bar_data0 = 5 ;
}
}
else
{
isOpponent = TRUE ;
bar_X = 104 , bar_Y = 40 ;
bar_pos2_X = - 100 ;
bar_data0 = 5 ;
}
2018-12-17 23:00:08 +01:00
LoadCompressedSpriteSheetUsingHeap ( & sStatusSummaryBarSpriteSheet ) ;
2017-10-19 18:25:48 +02:00
LoadSpriteSheet ( & sStatusSummaryBallsSpriteSheet ) ;
LoadSpritePalette ( & sStatusSummaryBarSpritePal ) ;
LoadSpritePalette ( & sStatusSummaryBallsSpritePal ) ;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
summaryBarSpriteId = CreateSprite ( & sStatusSummaryBarSpriteTemplates [ isOpponent ] , bar_X , bar_Y , 10 ) ;
2021-11-06 11:41:47 -04:00
SetSubspriteTables ( & gSprites [ summaryBarSpriteId ] , sStatusSummaryBar_SubspriteTable_Enter ) ;
2021-07-07 09:11:52 -04:00
gSprites [ summaryBarSpriteId ] . x2 = bar_pos2_X ;
2018-06-20 23:07:51 +02:00
gSprites [ summaryBarSpriteId ] . data [ 0 ] = bar_data0 ;
2017-10-18 21:42:00 +02:00
if ( isOpponent )
{
2021-07-07 09:11:52 -04:00
gSprites [ summaryBarSpriteId ] . x - = 96 ;
2019-08-10 12:09:06 -04:00
gSprites [ summaryBarSpriteId ] . oam . matrixNum = ST_OAM_HFLIP ;
2017-10-18 21:42:00 +02:00
}
else
{
2021-07-07 09:11:52 -04:00
gSprites [ summaryBarSpriteId ] . x + = 96 ;
2017-10-18 21:42:00 +02:00
}
2018-02-08 11:17:41 +01:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-10-18 21:42:00 +02:00
{
2017-10-19 18:25:48 +02:00
ballIconSpritesIds [ i ] = CreateSpriteAtEnd ( & sStatusSummaryBallsSpriteTemplates [ isOpponent ] , bar_X , bar_Y - 4 , 9 ) ;
2017-10-18 21:42:00 +02:00
if ( ! isBattleStart )
2021-11-06 11:41:47 -04:00
gSprites [ ballIconSpritesIds [ i ] ] . callback = SpriteCB_StatusSummaryBalls_OnSwitchout ;
2017-10-18 21:42:00 +02:00
if ( ! isOpponent )
{
2021-07-07 09:11:52 -04:00
gSprites [ ballIconSpritesIds [ i ] ] . x2 = 0 ;
gSprites [ ballIconSpritesIds [ i ] ] . y2 = 0 ;
2017-10-18 21:42:00 +02:00
}
2018-06-20 23:07:51 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . data [ 0 ] = summaryBarSpriteId ;
2017-10-18 21:42:00 +02:00
if ( ! isOpponent )
{
2021-07-07 09:11:52 -04:00
gSprites [ ballIconSpritesIds [ i ] ] . x + = 10 * i + 24 ;
2017-12-02 21:44:50 +01:00
gSprites [ ballIconSpritesIds [ i ] ] . data [ 1 ] = i * 7 + 10 ;
2021-07-07 09:11:52 -04:00
gSprites [ ballIconSpritesIds [ i ] ] . x2 = 120 ;
2017-10-18 21:42:00 +02:00
}
else
{
2021-07-07 09:11:52 -04:00
gSprites [ ballIconSpritesIds [ i ] ] . x - = 10 * ( 5 - i ) + 24 ;
2017-12-02 21:44:50 +01:00
gSprites [ ballIconSpritesIds [ i ] ] . data [ 1 ] = ( 6 - i ) * 7 + 10 ;
2021-07-07 09:11:52 -04:00
gSprites [ ballIconSpritesIds [ i ] ] . x2 = - 120 ;
2017-10-18 21:42:00 +02:00
}
2017-12-02 21:44:50 +01:00
gSprites [ ballIconSpritesIds [ i ] ] . data [ 2 ] = isOpponent ;
2017-10-18 21:42:00 +02:00
}
2018-03-01 00:59:52 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-10-18 21:42:00 +02:00
{
if ( gBattleTypeFlags & BATTLE_TYPE_MULTI )
{
2018-06-19 00:43:15 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
if ( partyInfo [ i ] . hp = = HP_EMPTY_SLOT )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// empty slot or an egg
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . oam . tileNum + = 1 ;
2017-12-02 21:44:50 +01:00
gSprites [ ballIconSpritesIds [ i ] ] . data [ 7 ] = 1 ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ i ] . hp = = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// fainted mon
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . oam . tileNum + = 3 ;
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ i ] . status ! = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// mon with major status
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . oam . tileNum + = 2 ;
}
}
}
else
{
2021-11-06 11:41:47 -04:00
for ( i = 0 , var = PARTY_SIZE - 1 , j = 0 ; j < PARTY_SIZE ; j + + )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
if ( partyInfo [ j ] . hp = = HP_EMPTY_SLOT )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// empty slot or an egg
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ var ] ] . oam . tileNum + = 1 ;
2017-12-02 21:44:50 +01:00
gSprites [ ballIconSpritesIds [ var ] ] . data [ 7 ] = 1 ;
2017-10-18 21:42:00 +02:00
var - - ;
continue ;
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ j ] . hp = = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// fainted mon
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . oam . tileNum + = 3 ;
}
2018-11-11 18:33:16 +01:00
else if ( gBattleTypeFlags & BATTLE_TYPE_ARENA & & gBattleStruct - > arenaLostPlayerMons & gBitTable [ j ] )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// fainted arena mon
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . oam . tileNum + = 3 ;
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ j ] . status ! = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// mon with primary status
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . oam . tileNum + = 2 ;
}
i + + ;
}
}
}
else
{
if ( gBattleTypeFlags & ( BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS ) )
{
2021-11-06 11:41:47 -04:00
for ( var = PARTY_SIZE - 1 , i = 0 ; i < PARTY_SIZE ; i + + )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
if ( partyInfo [ i ] . hp = = HP_EMPTY_SLOT )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// empty slot or an egg
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ var ] ] . oam . tileNum + = 1 ;
2017-12-02 21:44:50 +01:00
gSprites [ ballIconSpritesIds [ var ] ] . data [ 7 ] = 1 ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ i ] . hp = = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// fainted mon
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ var ] ] . oam . tileNum + = 3 ;
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ i ] . status ! = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// mon with primary status
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ var ] ] . oam . tileNum + = 2 ;
}
var - - ;
}
}
else
{
2018-06-19 00:43:15 +02:00
for ( var = 0 , i = 0 , j = 0 ; j < PARTY_SIZE ; j + + )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
if ( partyInfo [ j ] . hp = = HP_EMPTY_SLOT )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// empty slot or an egg
2017-10-18 21:42:00 +02:00
gSprites [ ballIconSpritesIds [ i ] ] . oam . tileNum + = 1 ;
2017-12-02 21:44:50 +01:00
gSprites [ ballIconSpritesIds [ i ] ] . data [ 7 ] = 1 ;
2017-10-18 21:42:00 +02:00
i + + ;
continue ;
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ j ] . hp = = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// fainted mon
gSprites [ ballIconSpritesIds [ PARTY_SIZE - 1 - var ] ] . oam . tileNum + = 3 ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
else if ( gBattleTypeFlags & BATTLE_TYPE_ARENA & & gBattleStruct - > arenaLostOpponentMons & gBitTable [ j ] )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// fainted arena mon
gSprites [ ballIconSpritesIds [ PARTY_SIZE - 1 - var ] ] . oam . tileNum + = 3 ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
else if ( partyInfo [ j ] . status ! = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
// mon with primary status
gSprites [ ballIconSpritesIds [ PARTY_SIZE - 1 - var ] ] . oam . tileNum + = 2 ;
2017-10-18 21:42:00 +02:00
}
var + + ;
}
}
}
taskId = CreateTask ( TaskDummy , 5 ) ;
2018-06-20 23:07:51 +02:00
gTasks [ taskId ] . tBattler = battlerId ;
gTasks [ taskId ] . tSummaryBarSpriteId = summaryBarSpriteId ;
2017-10-18 21:42:00 +02:00
2018-06-19 00:43:15 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2018-06-20 23:07:51 +02:00
gTasks [ taskId ] . tBallIconSpriteId ( i ) = ballIconSpritesIds [ i ] ;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
gTasks [ taskId ] . tIsBattleStart = isBattleStart ;
2017-10-18 21:42:00 +02:00
if ( isBattleStart )
{
gBattleSpritesDataPtr - > animationData - > field_9_x1C + + ;
}
2020-08-20 18:02:00 -04:00
PlaySE12WithPanning ( SE_BALL_TRAY_ENTER , 0 ) ;
2017-10-18 21:42:00 +02:00
return taskId ;
}
2021-11-06 11:41:47 -04:00
// Slide the party summary tray back offscreen
2018-06-28 21:06:32 +02:00
void Task_HidePartyStatusSummary ( u8 taskId )
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
u8 ballIconSpriteIds [ PARTY_SIZE ] ;
bool8 isBattleStart ;
2018-06-19 00:43:15 +02:00
u8 summaryBarSpriteId ;
2018-03-01 00:59:52 +01:00
u8 battlerId ;
2017-10-18 21:42:00 +02:00
s32 i ;
2018-06-20 23:07:51 +02:00
isBattleStart = gTasks [ taskId ] . tIsBattleStart ;
summaryBarSpriteId = gTasks [ taskId ] . tSummaryBarSpriteId ;
battlerId = gTasks [ taskId ] . tBattler ;
2017-10-18 21:42:00 +02:00
2018-06-28 21:06:32 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2018-06-20 23:07:51 +02:00
ballIconSpriteIds [ i ] = gTasks [ taskId ] . tBallIconSpriteId ( i ) ;
2017-10-18 21:42:00 +02:00
2018-07-16 20:47:30 +02:00
SetGpuReg ( REG_OFFSET_BLDCNT , BLDCNT_TGT2_ALL | BLDCNT_EFFECT_BLEND ) ;
SetGpuReg ( REG_OFFSET_BLDALPHA , BLDALPHA_BLEND ( 16 , 0 ) ) ;
2017-10-18 21:42:00 +02:00
2021-11-06 11:41:47 -04:00
gTasks [ taskId ] . tBlend = 16 ;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2019-12-04 21:00:45 -05:00
gSprites [ ballIconSpriteIds [ i ] ] . oam . objMode = ST_OAM_OBJ_BLEND ;
2017-10-18 21:42:00 +02:00
2019-12-04 21:00:45 -05:00
gSprites [ summaryBarSpriteId ] . oam . objMode = ST_OAM_OBJ_BLEND ;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
if ( isBattleStart )
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
2017-10-18 21:42:00 +02:00
{
2018-03-01 00:59:52 +01:00
if ( GetBattlerSide ( battlerId ) ! = B_SIDE_PLAYER )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
gSprites [ ballIconSpriteIds [ PARTY_SIZE - 1 - i ] ] . data [ 1 ] = 7 * i ;
gSprites [ ballIconSpriteIds [ PARTY_SIZE - 1 - i ] ] . data [ 3 ] = 0 ;
gSprites [ ballIconSpriteIds [ PARTY_SIZE - 1 - i ] ] . data [ 4 ] = 0 ;
gSprites [ ballIconSpriteIds [ PARTY_SIZE - 1 - i ] ] . callback = SpriteCB_StatusSummaryBalls_Exit ;
2017-10-18 21:42:00 +02:00
}
else
{
2018-06-20 23:07:51 +02:00
gSprites [ ballIconSpriteIds [ i ] ] . data [ 1 ] = 7 * i ;
gSprites [ ballIconSpriteIds [ i ] ] . data [ 3 ] = 0 ;
gSprites [ ballIconSpriteIds [ i ] ] . data [ 4 ] = 0 ;
2021-11-06 11:41:47 -04:00
gSprites [ ballIconSpriteIds [ i ] ] . callback = SpriteCB_StatusSummaryBalls_Exit ;
2017-10-18 21:42:00 +02:00
}
}
2018-06-19 00:43:15 +02:00
gSprites [ summaryBarSpriteId ] . data [ 0 ] / = 2 ;
gSprites [ summaryBarSpriteId ] . data [ 1 ] = 0 ;
2021-11-06 11:41:47 -04:00
gSprites [ summaryBarSpriteId ] . callback = SpriteCB_StatusSummaryBar_Exit ;
SetSubspriteTables ( & gSprites [ summaryBarSpriteId ] , sStatusSummaryBar_SubspriteTable_Exit ) ;
gTasks [ taskId ] . func = Task_HidePartyStatusSummary_BattleStart_1 ;
2017-10-18 21:42:00 +02:00
}
else
{
2021-11-06 11:41:47 -04:00
gTasks [ taskId ] . func = Task_HidePartyStatusSummary_DuringBattle ;
2017-10-18 21:42:00 +02:00
}
}
2021-11-06 11:41:47 -04:00
static void Task_HidePartyStatusSummary_BattleStart_1 ( u8 taskId )
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
if ( ( gTasks [ taskId ] . data [ 11 ] + + % 2 ) = = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
if ( - - gTasks [ taskId ] . tBlend < 0 )
2017-10-18 21:42:00 +02:00
return ;
2021-11-06 11:41:47 -04:00
SetGpuReg ( REG_OFFSET_BLDALPHA , BLDALPHA_BLEND ( gTasks [ taskId ] . tBlend , 16 - gTasks [ taskId ] . tBlend ) ) ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
if ( gTasks [ taskId ] . tBlend = = 0 )
gTasks [ taskId ] . func = Task_HidePartyStatusSummary_BattleStart_2 ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
static void Task_HidePartyStatusSummary_BattleStart_2 ( u8 taskId )
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
u8 ballIconSpriteIds [ PARTY_SIZE ] ;
2017-10-18 21:42:00 +02:00
s32 i ;
2018-06-20 23:07:51 +02:00
u8 battlerId = gTasks [ taskId ] . tBattler ;
2021-11-06 11:41:47 -04:00
if ( - - gTasks [ taskId ] . tBlend = = - 1 )
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
u8 summaryBarSpriteId = gTasks [ taskId ] . tSummaryBarSpriteId ;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
ballIconSpriteIds [ i ] = gTasks [ taskId ] . tBallIconSpriteId ( i ) ;
2017-10-18 21:42:00 +02:00
gBattleSpritesDataPtr - > animationData - > field_9_x1C - - ;
2018-06-20 23:07:51 +02:00
if ( gBattleSpritesDataPtr - > animationData - > field_9_x1C = = 0 )
2017-10-18 21:42:00 +02:00
{
2018-06-19 00:43:15 +02:00
DestroySpriteAndFreeResources ( & gSprites [ summaryBarSpriteId ] ) ;
2018-06-20 23:07:51 +02:00
DestroySpriteAndFreeResources ( & gSprites [ ballIconSpriteIds [ 0 ] ] ) ;
2017-10-18 21:42:00 +02:00
}
else
{
2018-06-19 00:43:15 +02:00
FreeSpriteOamMatrix ( & gSprites [ summaryBarSpriteId ] ) ;
DestroySprite ( & gSprites [ summaryBarSpriteId ] ) ;
2018-06-20 23:07:51 +02:00
FreeSpriteOamMatrix ( & gSprites [ ballIconSpriteIds [ 0 ] ] ) ;
DestroySprite ( & gSprites [ ballIconSpriteIds [ 0 ] ] ) ;
2017-10-18 21:42:00 +02:00
}
2018-06-20 23:07:51 +02:00
for ( i = 1 ; i < PARTY_SIZE ; i + + )
DestroySprite ( & gSprites [ ballIconSpriteIds [ i ] ] ) ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
else if ( gTasks [ taskId ] . tBlend = = - 3 )
2017-10-18 21:42:00 +02:00
{
2018-06-28 21:06:32 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battlerId ] . partyStatusSummaryShown = 0 ;
2017-10-18 21:42:00 +02:00
SetGpuReg ( REG_OFFSET_BLDCNT , 0 ) ;
SetGpuReg ( REG_OFFSET_BLDALPHA , 0 ) ;
DestroyTask ( taskId ) ;
}
}
2021-11-06 11:41:47 -04:00
static void Task_HidePartyStatusSummary_DuringBattle ( u8 taskId )
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
u8 ballIconSpriteIds [ PARTY_SIZE ] ;
2017-10-18 21:42:00 +02:00
s32 i ;
2018-06-20 23:07:51 +02:00
u8 battlerId = gTasks [ taskId ] . tBattler ;
2017-10-18 21:42:00 +02:00
2021-11-06 11:41:47 -04:00
if ( - - gTasks [ taskId ] . tBlend > = 0 )
2017-10-18 21:42:00 +02:00
{
2021-11-06 11:41:47 -04:00
SetGpuReg ( REG_OFFSET_BLDALPHA , BLDALPHA_BLEND ( gTasks [ taskId ] . tBlend , 16 - gTasks [ taskId ] . tBlend ) ) ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
else if ( gTasks [ taskId ] . tBlend = = - 1 )
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
u8 summaryBarSpriteId = gTasks [ taskId ] . tSummaryBarSpriteId ;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
for ( i = 0 ; i < PARTY_SIZE ; i + + )
ballIconSpriteIds [ i ] = gTasks [ taskId ] . tBallIconSpriteId ( i ) ;
2017-10-18 21:42:00 +02:00
2018-06-19 00:43:15 +02:00
DestroySpriteAndFreeResources ( & gSprites [ summaryBarSpriteId ] ) ;
2018-06-20 23:07:51 +02:00
DestroySpriteAndFreeResources ( & gSprites [ ballIconSpriteIds [ 0 ] ] ) ;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
for ( i = 1 ; i < PARTY_SIZE ; i + + )
DestroySprite ( & gSprites [ ballIconSpriteIds [ i ] ] ) ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
else if ( gTasks [ taskId ] . tBlend = = - 3 )
2017-10-18 21:42:00 +02:00
{
2018-06-28 21:06:32 +02:00
gBattleSpritesDataPtr - > healthBoxesData [ battlerId ] . partyStatusSummaryShown = 0 ;
2017-10-18 21:42:00 +02:00
SetGpuReg ( REG_OFFSET_BLDCNT , 0 ) ;
SetGpuReg ( REG_OFFSET_BLDALPHA , 0 ) ;
DestroyTask ( taskId ) ;
}
}
2018-06-20 23:07:51 +02:00
# undef tBattler
# undef tSummaryBarSpriteId
# undef tBallIconSpriteId
# undef tIsBattleStart
2021-11-06 11:41:47 -04:00
# undef tBlend
2018-06-20 23:07:51 +02:00
2021-11-06 11:41:47 -04:00
static void SpriteCB_StatusSummaryBar_Enter ( struct Sprite * sprite )
2017-10-18 21:42:00 +02:00
{
2021-07-07 09:11:52 -04:00
if ( sprite - > x2 ! = 0 )
sprite - > x2 + = sprite - > data [ 0 ] ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
static void SpriteCB_StatusSummaryBar_Exit ( struct Sprite * sprite )
2017-10-18 21:42:00 +02:00
{
2017-12-02 21:44:50 +01:00
sprite - > data [ 1 ] + = 32 ;
if ( sprite - > data [ 0 ] > 0 )
2021-07-07 09:11:52 -04:00
sprite - > x2 + = sprite - > data [ 1 ] > > 4 ;
2017-10-18 21:42:00 +02:00
else
2021-07-07 09:11:52 -04:00
sprite - > x2 - = sprite - > data [ 1 ] > > 4 ;
2017-12-02 21:44:50 +01:00
sprite - > data [ 1 ] & = 0xF ;
2017-10-18 21:42:00 +02:00
}
2021-11-06 11:41:47 -04:00
static void SpriteCB_StatusSummaryBalls_Enter ( struct Sprite * sprite )
2017-10-18 21:42:00 +02:00
{
u8 var1 ;
u16 var2 ;
s8 pan ;
2017-12-02 21:44:50 +01:00
if ( sprite - > data [ 1 ] > 0 )
2017-10-18 21:42:00 +02:00
{
2017-12-02 21:44:50 +01:00
sprite - > data [ 1 ] - - ;
2017-10-18 21:42:00 +02:00
return ;
}
2017-10-19 18:25:48 +02:00
2017-12-02 21:44:50 +01:00
var1 = sprite - > data [ 2 ] ;
var2 = sprite - > data [ 3 ] ;
2017-10-18 21:42:00 +02:00
var2 + = 56 ;
2017-12-02 21:44:50 +01:00
sprite - > data [ 3 ] = var2 & 0xFFF0 ;
2017-10-19 18:25:48 +02:00
2017-10-18 21:42:00 +02:00
if ( var1 ! = 0 )
{
2021-07-07 09:11:52 -04:00
sprite - > x2 + = var2 > > 4 ;
if ( sprite - > x2 > 0 )
sprite - > x2 = 0 ;
2017-10-18 21:42:00 +02:00
}
else
{
2021-07-07 09:11:52 -04:00
sprite - > x2 - = var2 > > 4 ;
if ( sprite - > x2 < 0 )
sprite - > x2 = 0 ;
2017-10-18 21:42:00 +02:00
}
2017-10-19 18:25:48 +02:00
2021-07-07 09:11:52 -04:00
if ( sprite - > x2 = = 0 )
2017-10-18 21:42:00 +02:00
{
2018-10-19 15:57:19 -04:00
pan = SOUND_PAN_TARGET ;
2017-10-18 21:42:00 +02:00
if ( var1 ! = 0 )
2018-10-19 15:57:19 -04:00
pan = SOUND_PAN_ATTACKER ;
2017-10-19 18:25:48 +02:00
2017-12-02 21:44:50 +01:00
if ( sprite - > data [ 7 ] ! = 0 )
2020-08-20 18:02:00 -04:00
PlaySE2WithPanning ( SE_BALL_TRAY_EXIT , pan ) ;
2017-10-18 21:42:00 +02:00
else
2020-08-20 18:02:00 -04:00
PlaySE1WithPanning ( SE_BALL_TRAY_BALL , pan ) ;
2017-10-19 18:25:48 +02:00
2017-10-18 21:42:00 +02:00
sprite - > callback = SpriteCallbackDummy ;
}
}
2021-11-06 11:41:47 -04:00
static void SpriteCB_StatusSummaryBalls_Exit ( struct Sprite * sprite )
2017-10-18 21:42:00 +02:00
{
u8 var1 ;
u16 var2 ;
2017-12-02 21:44:50 +01:00
if ( sprite - > data [ 1 ] > 0 )
2017-10-18 21:42:00 +02:00
{
2017-12-02 21:44:50 +01:00
sprite - > data [ 1 ] - - ;
2017-10-18 21:42:00 +02:00
return ;
}
2017-12-02 21:44:50 +01:00
var1 = sprite - > data [ 2 ] ;
var2 = sprite - > data [ 3 ] ;
2017-10-18 21:42:00 +02:00
var2 + = 56 ;
2017-12-02 21:44:50 +01:00
sprite - > data [ 3 ] = var2 & 0xFFF0 ;
2017-10-18 21:42:00 +02:00
if ( var1 ! = 0 )
2021-07-07 09:11:52 -04:00
sprite - > x2 + = var2 > > 4 ;
2017-10-18 21:42:00 +02:00
else
2021-07-07 09:11:52 -04:00
sprite - > x2 - = var2 > > 4 ;
if ( sprite - > x2 + sprite - > x > 248
| | sprite - > x2 + sprite - > x < - 8 )
2017-10-18 21:42:00 +02:00
{
sprite - > invisible = TRUE ;
sprite - > callback = SpriteCallbackDummy ;
}
}
2021-11-06 11:41:47 -04:00
static void SpriteCB_StatusSummaryBalls_OnSwitchout ( struct Sprite * sprite )
2017-10-18 21:42:00 +02:00
{
2017-12-02 21:44:50 +01:00
u8 barSpriteId = sprite - > data [ 0 ] ;
2017-10-18 21:42:00 +02:00
2021-07-07 09:11:52 -04:00
sprite - > x2 = gSprites [ barSpriteId ] . x2 ;
sprite - > y2 = gSprites [ barSpriteId ] . y2 ;
2017-10-18 21:42:00 +02:00
}
2017-10-19 15:28:41 +02:00
static void UpdateNickInHealthbox ( u8 healthboxSpriteId , struct Pokemon * mon )
2017-10-18 21:42:00 +02:00
{
u8 nickname [ POKEMON_NAME_LENGTH + 1 ] ;
void * ptr ;
2019-08-08 13:06:55 +02:00
u32 windowId , spriteTileNum , species ;
2017-10-19 15:28:41 +02:00
u8 * windowTileData ;
2017-10-18 21:42:00 +02:00
u8 gender ;
2019-08-08 13:06:55 +02:00
struct Pokemon * illusionMon = GetIllusionMonPtr ( gSprites [ healthboxSpriteId ] . hMain_Battler ) ;
if ( illusionMon ! = NULL )
mon = illusionMon ;
2017-10-18 21:42:00 +02:00
2021-11-06 11:41:47 -04:00
StringCopy ( gDisplayedStringBattle , gText_HealthboxNickname ) ;
2017-10-18 21:42:00 +02:00
GetMonData ( mon , MON_DATA_NICKNAME , nickname ) ;
2021-11-17 22:11:03 -05:00
StringGet_Nickname ( nickname ) ;
2017-10-18 21:42:00 +02:00
ptr = StringAppend ( gDisplayedStringBattle , nickname ) ;
gender = GetMonGender ( mon ) ;
species = GetMonData ( mon , MON_DATA_SPECIES ) ;
if ( ( species = = SPECIES_NIDORAN_F | | species = = SPECIES_NIDORAN_M ) & & StringCompare ( nickname , gSpeciesNames [ species ] ) = = 0 )
gender = 100 ;
// AddTextPrinterAndCreateWindowOnHealthbox's arguments are the same in all 3 cases.
// It's possible they may have been different in early development phases.
switch ( gender )
{
default :
2021-11-06 11:41:47 -04:00
StringCopy ( ptr , gText_HealthboxGender_None ) ;
2017-10-18 21:42:00 +02:00
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox ( gDisplayedStringBattle , 0 , 3 , 2 , & windowId ) ;
break ;
case MON_MALE :
2021-11-06 11:41:47 -04:00
StringCopy ( ptr , gText_HealthboxGender_Male ) ;
2017-10-18 21:42:00 +02:00
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox ( gDisplayedStringBattle , 0 , 3 , 2 , & windowId ) ;
break ;
case MON_FEMALE :
2021-11-06 11:41:47 -04:00
StringCopy ( ptr , gText_HealthboxGender_Female ) ;
2017-10-18 21:42:00 +02:00
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox ( gDisplayedStringBattle , 0 , 3 , 2 , & windowId ) ;
break ;
}
2018-11-22 01:10:50 +00:00
spriteTileNum = gSprites [ healthboxSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ;
2017-10-18 21:42:00 +02:00
2018-02-05 19:46:59 -06:00
if ( GetBattlerSide ( gSprites [ healthboxSpriteId ] . data [ 6 ] ) = = B_SIDE_PLAYER )
2017-10-18 21:42:00 +02:00
{
2022-07-29 10:52:35 -04:00
TextIntoHealthboxObject ( ( void * ) ( OBJ_VRAM0 + 0x40 + spriteTileNum ) , windowTileData , 6 ) ;
ptr = ( void * ) ( OBJ_VRAM0 ) ;
2022-08-24 23:00:21 +02:00
if ( ! WhichBattleCoords ( gSprites [ healthboxSpriteId ] . data [ 6 ] ) )
2017-10-18 21:42:00 +02:00
ptr + = spriteTileNum + 0x800 ;
else
ptr + = spriteTileNum + 0x400 ;
2018-06-19 00:43:15 +02:00
TextIntoHealthboxObject ( ptr , windowTileData + 0xC0 , 1 ) ;
2017-10-18 21:42:00 +02:00
}
else
{
2022-07-29 10:52:35 -04:00
TextIntoHealthboxObject ( ( void * ) ( OBJ_VRAM0 + 0x20 + spriteTileNum ) , windowTileData , 7 ) ;
2017-10-18 21:42:00 +02:00
}
2017-10-18 23:05:14 +02:00
RemoveWindowOnHealthbox ( windowId ) ;
}
2017-10-19 15:28:41 +02:00
static void TryAddPokeballIconToHealthbox ( u8 healthboxSpriteId , bool8 noStatus )
2017-10-18 23:05:14 +02:00
{
2018-06-19 00:43:15 +02:00
u8 battlerId , healthBarSpriteId ;
2017-10-18 23:05:14 +02:00
if ( gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL )
return ;
if ( gBattleTypeFlags & BATTLE_TYPE_TRAINER )
return ;
2018-06-19 00:43:15 +02:00
battlerId = gSprites [ healthboxSpriteId ] . hMain_Battler ;
2018-03-01 00:59:52 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-10-18 23:05:14 +02:00
return ;
2018-03-01 00:59:52 +01:00
if ( ! GetSetPokedexFlag ( SpeciesToNationalPokedexNum ( GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_SPECIES ) ) , FLAG_GET_CAUGHT ) )
2017-10-18 23:05:14 +02:00
return ;
2018-06-19 00:43:15 +02:00
healthBarSpriteId = gSprites [ healthboxSpriteId ] . hMain_HealthBarSpriteId ;
2017-10-18 23:05:14 +02:00
if ( noStatus )
2022-07-29 10:52:35 -04:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_STATUS_BALL_CAUGHT ) , ( void * ) ( OBJ_VRAM0 + ( gSprites [ healthBarSpriteId ] . oam . tileNum + 8 ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-18 23:05:14 +02:00
else
2022-07-29 10:52:35 -04:00
CpuFill32 ( 0 , ( void * ) ( OBJ_VRAM0 + ( gSprites [ healthBarSpriteId ] . oam . tileNum + 8 ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-18 23:05:14 +02:00
}
2017-10-19 15:28:41 +02:00
static void UpdateStatusIconInHealthbox ( u8 healthboxSpriteId )
2017-10-18 23:05:14 +02:00
{
s32 i ;
2018-06-19 00:43:15 +02:00
u8 battlerId , healthBarSpriteId ;
2017-10-18 23:05:14 +02:00
u32 status , pltAdder ;
2017-10-19 15:28:41 +02:00
const u8 * statusGfxPtr ;
2017-10-18 23:05:14 +02:00
s16 tileNumAdder ;
u8 statusPalId ;
2018-06-19 00:43:15 +02:00
battlerId = gSprites [ healthboxSpriteId ] . hMain_Battler ;
healthBarSpriteId = gSprites [ healthboxSpriteId ] . hMain_HealthBarSpriteId ;
2018-03-01 00:59:52 +01:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-10-18 23:05:14 +02:00
{
2018-03-01 00:59:52 +01:00
status = GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_STATUS ) ;
2022-08-24 23:00:21 +02:00
if ( ! WhichBattleCoords ( battlerId ) )
2017-10-18 23:05:14 +02:00
tileNumAdder = 0x1A ;
else
tileNumAdder = 0x12 ;
}
else
{
2018-03-01 00:59:52 +01:00
status = GetMonData ( & gEnemyParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_STATUS ) ;
2017-10-18 23:05:14 +02:00
tileNumAdder = 0x11 ;
}
2018-01-16 15:12:38 -06:00
if ( status & STATUS1_SLEEP )
2017-10-18 23:05:14 +02:00
{
2018-06-19 00:43:15 +02:00
statusGfxPtr = GetHealthboxElementGfxPtr ( GetStatusIconForBattlerId ( HEALTHBOX_GFX_STATUS_SLP_BATTLER0 , battlerId ) ) ;
2017-10-19 15:28:41 +02:00
statusPalId = PAL_STATUS_SLP ;
2017-10-18 23:05:14 +02:00
}
2018-01-16 15:12:38 -06:00
else if ( status & STATUS1_PSN_ANY )
2017-10-18 23:05:14 +02:00
{
2018-06-19 00:43:15 +02:00
statusGfxPtr = GetHealthboxElementGfxPtr ( GetStatusIconForBattlerId ( HEALTHBOX_GFX_STATUS_PSN_BATTLER0 , battlerId ) ) ;
2017-10-19 15:28:41 +02:00
statusPalId = PAL_STATUS_PSN ;
2017-10-18 23:05:14 +02:00
}
2018-01-16 15:12:38 -06:00
else if ( status & STATUS1_BURN )
2017-10-18 23:05:14 +02:00
{
2018-06-19 00:43:15 +02:00
statusGfxPtr = GetHealthboxElementGfxPtr ( GetStatusIconForBattlerId ( HEALTHBOX_GFX_STATUS_BRN_BATTLER0 , battlerId ) ) ;
2017-10-19 15:28:41 +02:00
statusPalId = PAL_STATUS_BRN ;
2017-10-18 23:05:14 +02:00
}
2018-01-16 15:12:38 -06:00
else if ( status & STATUS1_FREEZE )
2017-10-18 23:05:14 +02:00
{
2018-06-19 00:43:15 +02:00
statusGfxPtr = GetHealthboxElementGfxPtr ( GetStatusIconForBattlerId ( HEALTHBOX_GFX_STATUS_FRZ_BATTLER0 , battlerId ) ) ;
2017-10-19 15:28:41 +02:00
statusPalId = PAL_STATUS_FRZ ;
2017-10-18 23:05:14 +02:00
}
2018-01-16 15:12:38 -06:00
else if ( status & STATUS1_PARALYSIS )
2017-10-18 23:05:14 +02:00
{
2018-06-19 00:43:15 +02:00
statusGfxPtr = GetHealthboxElementGfxPtr ( GetStatusIconForBattlerId ( HEALTHBOX_GFX_STATUS_PRZ_BATTLER0 , battlerId ) ) ;
2017-10-19 15:28:41 +02:00
statusPalId = PAL_STATUS_PAR ;
2017-10-18 23:05:14 +02:00
}
else
{
2017-10-19 18:25:48 +02:00
statusGfxPtr = GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_39 ) ;
2017-10-18 23:05:14 +02:00
for ( i = 0 ; i < 3 ; i + + )
2022-07-29 10:52:35 -04:00
CpuCopy32 ( statusGfxPtr , ( void * ) ( OBJ_VRAM0 + ( gSprites [ healthboxSpriteId ] . oam . tileNum + tileNumAdder + i ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-18 23:05:14 +02:00
2018-03-01 00:59:52 +01:00
if ( ! gBattleSpritesDataPtr - > battlerData [ battlerId ] . hpNumbersNoBars )
2018-11-22 01:10:50 +00:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_1 ) , ( void * ) ( OBJ_VRAM0 + gSprites [ healthBarSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ) , 64 ) ;
2017-10-18 23:05:14 +02:00
TryAddPokeballIconToHealthbox ( healthboxSpriteId , TRUE ) ;
return ;
}
pltAdder = gSprites [ healthboxSpriteId ] . oam . paletteNum * 16 ;
2018-03-01 00:59:52 +01:00
pltAdder + = battlerId + 12 ;
2017-10-18 23:05:14 +02:00
2018-01-29 14:36:13 +01:00
FillPalette ( sStatusIconColors [ statusPalId ] , pltAdder + 0x100 , 2 ) ;
2022-07-29 10:52:35 -04:00
CpuCopy16 ( gPlttBufferUnfaded + 0x100 + pltAdder , ( void * ) ( OBJ_PLTT + pltAdder * 2 ) , 2 ) ;
CpuCopy32 ( statusGfxPtr , ( void * ) ( OBJ_VRAM0 + ( gSprites [ healthboxSpriteId ] . oam . tileNum + tileNumAdder ) * TILE_SIZE_4BPP ) , 96 ) ;
2022-08-24 23:00:21 +02:00
if ( WhichBattleCoords ( battlerId ) = = 1 | | GetBattlerSide ( battlerId ) = = B_SIDE_OPPONENT )
2017-10-18 23:05:14 +02:00
{
2018-03-01 00:59:52 +01:00
if ( ! gBattleSpritesDataPtr - > battlerData [ battlerId ] . hpNumbersNoBars )
2017-10-18 23:05:14 +02:00
{
2022-07-29 10:52:35 -04:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_0 ) , ( void * ) ( OBJ_VRAM0 + gSprites [ healthBarSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ) , 32 ) ;
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_65 ) , ( void * ) ( OBJ_VRAM0 + ( gSprites [ healthBarSpriteId ] . oam . tileNum + 1 ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-18 23:05:14 +02:00
}
}
TryAddPokeballIconToHealthbox ( healthboxSpriteId , FALSE ) ;
}
2018-06-19 00:43:15 +02:00
static u8 GetStatusIconForBattlerId ( u8 statusElementId , u8 battlerId )
2017-10-18 23:05:14 +02:00
{
u8 ret = statusElementId ;
switch ( statusElementId )
{
2018-06-19 00:43:15 +02:00
case HEALTHBOX_GFX_STATUS_PSN_BATTLER0 :
2018-03-01 00:59:52 +01:00
if ( battlerId = = 0 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER0 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 1 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER1 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 2 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER2 ;
2017-10-18 23:05:14 +02:00
else
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PSN_BATTLER3 ;
2017-10-18 23:05:14 +02:00
break ;
2018-06-19 00:43:15 +02:00
case HEALTHBOX_GFX_STATUS_PRZ_BATTLER0 :
2018-03-01 00:59:52 +01:00
if ( battlerId = = 0 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER0 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 1 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER1 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 2 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER2 ;
2017-10-18 23:05:14 +02:00
else
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_PRZ_BATTLER3 ;
2017-10-18 23:05:14 +02:00
break ;
2018-06-19 00:43:15 +02:00
case HEALTHBOX_GFX_STATUS_SLP_BATTLER0 :
2018-03-01 00:59:52 +01:00
if ( battlerId = = 0 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER0 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 1 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER1 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 2 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER2 ;
2017-10-18 23:05:14 +02:00
else
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_SLP_BATTLER3 ;
2017-10-18 23:05:14 +02:00
break ;
2018-06-19 00:43:15 +02:00
case HEALTHBOX_GFX_STATUS_FRZ_BATTLER0 :
2018-03-01 00:59:52 +01:00
if ( battlerId = = 0 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER0 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 1 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER1 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 2 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER2 ;
2017-10-18 23:05:14 +02:00
else
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_FRZ_BATTLER3 ;
2017-10-18 23:05:14 +02:00
break ;
2018-06-19 00:43:15 +02:00
case HEALTHBOX_GFX_STATUS_BRN_BATTLER0 :
2018-03-01 00:59:52 +01:00
if ( battlerId = = 0 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER0 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 1 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER1 ;
2018-03-01 00:59:52 +01:00
else if ( battlerId = = 2 )
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER2 ;
2017-10-18 23:05:14 +02:00
else
2018-06-19 00:43:15 +02:00
ret = HEALTHBOX_GFX_STATUS_BRN_BATTLER3 ;
2017-10-18 23:05:14 +02:00
break ;
}
return ret ;
}
2017-10-19 15:28:41 +02:00
static void UpdateSafariBallsTextOnHealthbox ( u8 healthboxSpriteId )
2017-10-18 23:05:14 +02:00
{
2017-10-19 15:28:41 +02:00
u32 windowId , spriteTileNum ;
u8 * windowTileData ;
2017-10-18 23:05:14 +02:00
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox ( gText_SafariBalls , 0 , 3 , 2 , & windowId ) ;
2018-11-22 01:10:50 +00:00
spriteTileNum = gSprites [ healthboxSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ;
2022-07-29 10:52:35 -04:00
TextIntoHealthboxObject ( ( void * ) ( OBJ_VRAM0 + 0x40 ) + spriteTileNum , windowTileData , 6 ) ;
TextIntoHealthboxObject ( ( void * ) ( OBJ_VRAM0 + 0x800 ) + spriteTileNum , windowTileData + 0xC0 , 2 ) ;
2017-10-18 23:05:14 +02:00
RemoveWindowOnHealthbox ( windowId ) ;
}
2017-10-19 15:28:41 +02:00
static void UpdateLeftNoOfBallsTextOnHealthbox ( u8 healthboxSpriteId )
2017-10-18 23:05:14 +02:00
{
2017-10-18 23:52:21 +02:00
u8 text [ 16 ] ;
2017-10-18 23:05:14 +02:00
u8 * txtPtr ;
2017-10-19 15:28:41 +02:00
u32 windowId , spriteTileNum ;
u8 * windowTileData ;
2017-10-18 23:05:14 +02:00
txtPtr = StringCopy ( text , gText_SafariBallLeft ) ;
ConvertIntToDecimalStringN ( txtPtr , gNumSafariBalls , STR_CONV_MODE_LEFT_ALIGN , 2 ) ;
2017-10-18 23:52:21 +02:00
2021-10-30 16:47:37 -04:00
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox ( text , GetStringRightAlignXOffset ( FONT_SMALL , text , 0x2F ) , 3 , 2 , & windowId ) ;
2018-11-22 01:10:50 +00:00
spriteTileNum = gSprites [ healthboxSpriteId ] . oam . tileNum * TILE_SIZE_4BPP ;
2022-07-29 10:52:35 -04:00
SafariTextIntoHealthboxObject ( ( void * ) ( OBJ_VRAM0 + 0x2C0 ) + spriteTileNum , windowTileData , 2 ) ;
SafariTextIntoHealthboxObject ( ( void * ) ( OBJ_VRAM0 + 0xA00 ) + spriteTileNum , windowTileData + 0x40 , 4 ) ;
2017-10-18 23:52:21 +02:00
RemoveWindowOnHealthbox ( windowId ) ;
}
void UpdateHealthboxAttribute ( u8 healthboxSpriteId , struct Pokemon * mon , u8 elementId )
{
2022-08-25 16:40:56 +02:00
u32 battlerId = gSprites [ healthboxSpriteId ] . hMain_Battler ;
s32 maxHp = GetMonData ( mon , MON_DATA_MAX_HP ) ;
s32 currHp = GetMonData ( mon , MON_DATA_HP ) ;
2017-10-18 23:52:21 +02:00
2022-08-25 16:40:56 +02:00
if ( GetBattlerSide ( battlerId ) = = B_SIDE_PLAYER )
2017-10-18 23:52:21 +02:00
{
2022-08-25 22:10:59 +02:00
u8 isDoubles = WhichBattleCoords ( battlerId ) ;
2017-10-18 23:52:21 +02:00
if ( elementId = = HEALTHBOX_LEVEL | | elementId = = HEALTHBOX_ALL )
UpdateLvlInHealthbox ( healthboxSpriteId , GetMonData ( mon , MON_DATA_LEVEL ) ) ;
2022-08-25 16:40:56 +02:00
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 ) ;
2017-10-18 23:52:21 +02:00
if ( elementId = = HEALTHBOX_HEALTH_BAR | | elementId = = HEALTHBOX_ALL )
{
LoadBattleBarGfx ( 0 ) ;
2018-03-01 00:59:52 +01:00
SetBattleBarStruct ( battlerId , healthboxSpriteId , maxHp , currHp , 0 ) ;
2018-06-19 00:43:15 +02:00
MoveBattleBar ( battlerId , healthboxSpriteId , HEALTH_BAR , 0 ) ;
2017-10-18 23:52:21 +02:00
}
2022-08-25 16:40:56 +02:00
2017-10-18 23:52:21 +02:00
if ( ! isDoubles & & ( elementId = = HEALTHBOX_EXP_BAR | | elementId = = HEALTHBOX_ALL ) )
{
u16 species ;
2017-10-19 15:28:41 +02:00
u32 exp , currLevelExp ;
s32 currExpBarValue , maxExpBarValue ;
2017-10-18 23:52:21 +02:00
u8 level ;
LoadBattleBarGfx ( 3 ) ;
species = GetMonData ( mon , MON_DATA_SPECIES ) ;
level = GetMonData ( mon , MON_DATA_LEVEL ) ;
exp = GetMonData ( mon , MON_DATA_EXP ) ;
currLevelExp = gExperienceTables [ gBaseStats [ species ] . growthRate ] [ level ] ;
currExpBarValue = exp - currLevelExp ;
maxExpBarValue = gExperienceTables [ gBaseStats [ species ] . growthRate ] [ level + 1 ] - currLevelExp ;
2018-03-01 00:59:52 +01:00
SetBattleBarStruct ( battlerId , healthboxSpriteId , maxExpBarValue , currExpBarValue , isDoubles ) ;
2018-06-19 00:43:15 +02:00
MoveBattleBar ( battlerId , healthboxSpriteId , EXP_BAR , 0 ) ;
2017-10-18 23:52:21 +02:00
}
if ( elementId = = HEALTHBOX_NICK | | elementId = = HEALTHBOX_ALL )
UpdateNickInHealthbox ( healthboxSpriteId , mon ) ;
if ( elementId = = HEALTHBOX_STATUS_ICON | | elementId = = HEALTHBOX_ALL )
UpdateStatusIconInHealthbox ( healthboxSpriteId ) ;
if ( elementId = = HEALTHBOX_SAFARI_ALL_TEXT )
UpdateSafariBallsTextOnHealthbox ( healthboxSpriteId ) ;
if ( elementId = = HEALTHBOX_SAFARI_ALL_TEXT | | elementId = = HEALTHBOX_SAFARI_BALLS_TEXT )
UpdateLeftNoOfBallsTextOnHealthbox ( healthboxSpriteId ) ;
}
else
{
if ( elementId = = HEALTHBOX_LEVEL | | elementId = = HEALTHBOX_ALL )
UpdateLvlInHealthbox ( healthboxSpriteId , GetMonData ( mon , MON_DATA_LEVEL ) ) ;
2022-08-25 16:40:56 +02:00
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 ) ;
}
2017-10-18 23:52:21 +02:00
if ( elementId = = HEALTHBOX_HEALTH_BAR | | elementId = = HEALTHBOX_ALL )
{
LoadBattleBarGfx ( 0 ) ;
2018-03-01 00:59:52 +01:00
SetBattleBarStruct ( battlerId , healthboxSpriteId , maxHp , currHp , 0 ) ;
2018-06-19 00:43:15 +02:00
MoveBattleBar ( battlerId , healthboxSpriteId , HEALTH_BAR , 0 ) ;
2017-10-18 23:52:21 +02:00
}
if ( elementId = = HEALTHBOX_NICK | | elementId = = HEALTHBOX_ALL )
UpdateNickInHealthbox ( healthboxSpriteId , mon ) ;
if ( elementId = = HEALTHBOX_STATUS_ICON | | elementId = = HEALTHBOX_ALL )
UpdateStatusIconInHealthbox ( healthboxSpriteId ) ;
}
2017-10-18 21:42:00 +02:00
}
2017-10-19 15:28:41 +02:00
2018-06-20 23:07:51 +02:00
# define B_EXPBAR_PIXELS 64
# define B_HEALTHBAR_PIXELS 48
2018-06-19 00:43:15 +02:00
s32 MoveBattleBar ( u8 battlerId , u8 healthboxSpriteId , u8 whichBar , u8 unused )
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
s32 currentBarValue ;
2017-10-19 15:28:41 +02:00
if ( whichBar = = HEALTH_BAR ) // health bar
{
2018-06-19 00:43:15 +02:00
currentBarValue = CalcNewBarValue ( gBattleSpritesDataPtr - > battleBars [ battlerId ] . maxValue ,
gBattleSpritesDataPtr - > battleBars [ battlerId ] . oldValue ,
2018-03-01 00:59:52 +01:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . receivedValue ,
2018-06-19 00:43:15 +02:00
& gBattleSpritesDataPtr - > battleBars [ battlerId ] . currValue ,
2021-12-12 12:33:49 -03:00
# if B_FAST_HP_DRAIN == TRUE
2021-12-12 12:42:14 -03:00
B_HEALTHBAR_PIXELS / 8 , max ( gBattleSpritesDataPtr - > battleBars [ battlerId ] . maxValue / B_HEALTHBAR_PIXELS , 1 ) ) ;
2021-12-12 12:33:49 -03:00
# else
2018-06-20 23:07:51 +02:00
B_HEALTHBAR_PIXELS / 8 , 1 ) ;
2021-12-12 12:33:49 -03:00
# endif
2017-10-19 15:28:41 +02:00
}
else // exp bar
{
2018-06-19 00:43:15 +02:00
u16 expFraction = GetScaledExpFraction ( gBattleSpritesDataPtr - > battleBars [ battlerId ] . oldValue ,
2018-03-01 00:59:52 +01:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . receivedValue ,
gBattleSpritesDataPtr - > battleBars [ battlerId ] . maxValue , 8 ) ;
2017-10-19 15:28:41 +02:00
if ( expFraction = = 0 )
expFraction = 1 ;
2018-03-01 00:59:52 +01:00
expFraction = abs ( gBattleSpritesDataPtr - > battleBars [ battlerId ] . receivedValue / expFraction ) ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
currentBarValue = CalcNewBarValue ( gBattleSpritesDataPtr - > battleBars [ battlerId ] . maxValue ,
gBattleSpritesDataPtr - > battleBars [ battlerId ] . oldValue ,
2018-03-01 00:59:52 +01:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . receivedValue ,
2018-06-19 00:43:15 +02:00
& gBattleSpritesDataPtr - > battleBars [ battlerId ] . currValue ,
2018-06-20 23:07:51 +02:00
B_EXPBAR_PIXELS / 8 , expFraction ) ;
2017-10-19 15:28:41 +02:00
}
2018-03-01 00:59:52 +01:00
if ( whichBar = = EXP_BAR | | ( whichBar = = HEALTH_BAR & & ! gBattleSpritesDataPtr - > battlerData [ battlerId ] . hpNumbersNoBars ) )
2018-06-19 00:43:15 +02:00
MoveBattleBarGraphically ( battlerId , whichBar ) ;
2017-10-19 15:28:41 +02:00
2018-12-05 22:31:01 +08:00
if ( currentBarValue = = - 1 )
2018-06-19 00:43:15 +02:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . currValue = 0 ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
return currentBarValue ;
2017-10-19 15:28:41 +02:00
}
2018-06-19 00:43:15 +02:00
static void MoveBattleBarGraphically ( u8 battlerId , u8 whichBar )
2017-10-19 15:28:41 +02:00
{
2017-10-22 18:43:15 +02:00
u8 array [ 8 ] ;
2018-06-19 00:43:15 +02:00
u8 filledPixelsCount , level ;
2017-10-19 15:28:41 +02:00
u8 barElementId ;
u8 i ;
switch ( whichBar )
{
case HEALTH_BAR :
2018-06-19 00:43:15 +02:00
filledPixelsCount = CalcBarFilledPixels ( gBattleSpritesDataPtr - > battleBars [ battlerId ] . maxValue ,
gBattleSpritesDataPtr - > battleBars [ battlerId ] . oldValue ,
2018-03-01 00:59:52 +01:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . receivedValue ,
2018-06-19 00:43:15 +02:00
& gBattleSpritesDataPtr - > battleBars [ battlerId ] . currValue ,
2018-06-20 23:07:51 +02:00
array , B_HEALTHBAR_PIXELS / 8 ) ;
2018-06-19 00:43:15 +02:00
2018-06-20 23:07:51 +02:00
if ( filledPixelsCount > ( B_HEALTHBAR_PIXELS * 50 / 100 ) ) // more than 50 % hp
2018-06-19 00:43:15 +02:00
barElementId = HEALTHBOX_GFX_HP_BAR_GREEN ;
2018-06-20 23:07:51 +02:00
else if ( filledPixelsCount > ( B_HEALTHBAR_PIXELS * 20 / 100 ) ) // more than 20% hp
2018-06-19 00:43:15 +02:00
barElementId = HEALTHBOX_GFX_HP_BAR_YELLOW ;
else
barElementId = HEALTHBOX_GFX_HP_BAR_RED ; // 20 % or less
2017-10-19 15:28:41 +02:00
for ( i = 0 ; i < 6 ; i + + )
{
2018-06-19 00:43:15 +02:00
u8 healthbarSpriteId = gSprites [ gBattleSpritesDataPtr - > battleBars [ battlerId ] . healthboxSpriteId ] . hMain_HealthBarSpriteId ;
2017-10-19 15:28:41 +02:00
if ( i < 2 )
CpuCopy32 ( GetHealthboxElementGfxPtr ( barElementId ) + array [ i ] * 32 ,
2022-07-29 10:52:35 -04:00
( void * ) ( OBJ_VRAM0 + ( gSprites [ healthbarSpriteId ] . oam . tileNum + 2 + i ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-19 15:28:41 +02:00
else
CpuCopy32 ( GetHealthboxElementGfxPtr ( barElementId ) + array [ i ] * 32 ,
2022-07-29 10:52:35 -04:00
( void * ) ( OBJ_VRAM0 + 64 + ( i + gSprites [ healthbarSpriteId ] . oam . tileNum ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-19 15:28:41 +02:00
}
break ;
case EXP_BAR :
2018-06-19 00:43:15 +02:00
CalcBarFilledPixels ( gBattleSpritesDataPtr - > battleBars [ battlerId ] . maxValue ,
gBattleSpritesDataPtr - > battleBars [ battlerId ] . oldValue ,
2018-03-01 00:59:52 +01:00
gBattleSpritesDataPtr - > battleBars [ battlerId ] . receivedValue ,
2018-06-19 00:43:15 +02:00
& gBattleSpritesDataPtr - > battleBars [ battlerId ] . currValue ,
2018-06-20 23:07:51 +02:00
array , B_EXPBAR_PIXELS / 8 ) ;
2018-03-01 00:59:52 +01:00
level = GetMonData ( & gPlayerParty [ gBattlerPartyIndexes [ battlerId ] ] , MON_DATA_LEVEL ) ;
2018-10-16 21:47:08 -05:00
if ( level = = MAX_LEVEL )
2017-10-19 15:28:41 +02:00
{
for ( i = 0 ; i < 8 ; i + + )
array [ i ] = 0 ;
}
for ( i = 0 ; i < 8 ; i + + )
{
if ( i < 4 )
2017-10-19 18:25:48 +02:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_12 ) + array [ i ] * 32 ,
2022-07-29 10:52:35 -04:00
( void * ) ( OBJ_VRAM0 + ( gSprites [ gBattleSpritesDataPtr - > battleBars [ battlerId ] . healthboxSpriteId ] . oam . tileNum + 0x24 + i ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-19 15:28:41 +02:00
else
2017-10-19 18:25:48 +02:00
CpuCopy32 ( GetHealthboxElementGfxPtr ( HEALTHBOX_GFX_12 ) + array [ i ] * 32 ,
2022-07-29 10:52:35 -04:00
( void * ) ( OBJ_VRAM0 + 0xB80 + ( i + gSprites [ gBattleSpritesDataPtr - > battleBars [ battlerId ] . healthboxSpriteId ] . oam . tileNum ) * TILE_SIZE_4BPP ) , 32 ) ;
2017-10-19 15:28:41 +02:00
}
break ;
}
}
2018-06-19 00:43:15 +02:00
static s32 CalcNewBarValue ( s32 maxValue , s32 oldValue , s32 receivedValue , s32 * currValue , u8 scale , u16 toAdd )
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
s32 ret , newValue ;
scale * = 8 ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
if ( * currValue = = - 32768 ) // first function call
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
if ( maxValue < scale )
2018-06-20 23:07:51 +02:00
* currValue = Q_24_8 ( oldValue ) ;
2017-10-19 15:28:41 +02:00
else
2018-06-19 00:43:15 +02:00
* currValue = oldValue ;
2017-10-19 15:28:41 +02:00
}
2018-06-19 00:43:15 +02:00
newValue = oldValue - receivedValue ;
if ( newValue < 0 )
newValue = 0 ;
else if ( newValue > maxValue )
newValue = maxValue ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
if ( maxValue < scale )
2017-10-19 15:28:41 +02:00
{
2018-06-20 23:07:51 +02:00
if ( newValue = = Q_24_8_TO_INT ( * currValue ) & & ( * currValue & 0xFF ) = = 0 )
2018-12-05 22:31:01 +08:00
return - 1 ;
2017-10-19 15:28:41 +02:00
}
else
{
2018-06-19 00:43:15 +02:00
if ( newValue = = * currValue ) // we're done, the bar's value has been updated
2018-12-05 22:31:01 +08:00
return - 1 ;
2017-10-19 15:28:41 +02:00
}
2018-06-19 00:43:15 +02:00
if ( maxValue < scale ) // handle cases of max var having less pixels than the whole bar
2017-10-19 15:28:41 +02:00
{
2018-06-20 23:07:51 +02:00
s32 toAdd = Q_24_8 ( maxValue ) / scale ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
if ( receivedValue < 0 ) // fill bar right
2017-10-19 15:28:41 +02:00
{
2018-06-20 23:07:51 +02:00
* currValue + = toAdd ;
ret = Q_24_8_TO_INT ( * currValue ) ;
2018-06-19 00:43:15 +02:00
if ( ret > = newValue )
2017-10-19 15:28:41 +02:00
{
2018-06-20 23:07:51 +02:00
* currValue = Q_24_8 ( newValue ) ;
2018-06-19 00:43:15 +02:00
ret = newValue ;
2017-10-19 15:28:41 +02:00
}
}
2018-06-19 00:43:15 +02:00
else // move bar left
2017-10-19 15:28:41 +02:00
{
2018-06-20 23:07:51 +02:00
* currValue - = toAdd ;
ret = Q_24_8_TO_INT ( * currValue ) ;
// try round up
2018-12-05 22:31:01 +08:00
if ( ( * currValue & 0xFF ) > 0 )
2017-10-19 15:28:41 +02:00
ret + + ;
2018-06-19 00:43:15 +02:00
if ( ret < = newValue )
2017-10-19 15:28:41 +02:00
{
2018-06-20 23:07:51 +02:00
* currValue = Q_24_8 ( newValue ) ;
2018-06-19 00:43:15 +02:00
ret = newValue ;
2017-10-19 15:28:41 +02:00
}
}
}
else
{
2018-06-19 00:43:15 +02:00
if ( receivedValue < 0 ) // fill bar right
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
* currValue + = toAdd ;
if ( * currValue > newValue )
* currValue = newValue ;
ret = * currValue ;
2017-10-19 15:28:41 +02:00
}
2018-06-19 00:43:15 +02:00
else // move bar left
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
* currValue - = toAdd ;
if ( * currValue < newValue )
* currValue = newValue ;
ret = * currValue ;
2017-10-19 15:28:41 +02:00
}
}
return ret ;
}
2022-06-01 12:41:57 -04:00
static u8 CalcBarFilledPixels ( s32 maxValue , s32 oldValue , s32 receivedValue , s32 * currValue , u8 * pixelsArray , u8 scale )
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
u8 pixels , filledPixels , totalPixels ;
2017-10-19 15:28:41 +02:00
u8 i ;
2018-06-19 00:43:15 +02:00
s32 newValue = oldValue - receivedValue ;
if ( newValue < 0 )
newValue = 0 ;
else if ( newValue > maxValue )
newValue = maxValue ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
totalPixels = scale * 8 ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
for ( i = 0 ; i < scale ; i + + )
2022-06-01 12:41:57 -04:00
pixelsArray [ i ] = 0 ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
if ( maxValue < totalPixels )
pixels = ( * currValue * totalPixels / maxValue ) > > 8 ;
2017-10-19 15:28:41 +02:00
else
2018-06-19 00:43:15 +02:00
pixels = * currValue * totalPixels / maxValue ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
filledPixels = pixels ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
if ( filledPixels = = 0 & & newValue > 0 )
2017-10-19 15:28:41 +02:00
{
2022-06-01 12:41:57 -04:00
pixelsArray [ 0 ] = 1 ;
2018-06-19 00:43:15 +02:00
filledPixels = 1 ;
2017-10-19 15:28:41 +02:00
}
else
{
2018-06-19 00:43:15 +02:00
for ( i = 0 ; i < scale ; i + + )
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
if ( pixels > = 8 )
2017-10-19 15:28:41 +02:00
{
2022-06-01 12:41:57 -04:00
pixelsArray [ i ] = 8 ;
2017-10-19 15:28:41 +02:00
}
else
{
2022-06-01 12:41:57 -04:00
pixelsArray [ i ] = pixels ;
2017-10-19 15:28:41 +02:00
break ;
}
2018-06-19 00:43:15 +02:00
pixels - = 8 ;
2017-10-19 15:28:41 +02:00
}
}
2018-06-19 00:43:15 +02:00
return filledPixels ;
2017-10-19 15:28:41 +02:00
}
2018-06-19 00:43:15 +02:00
static u8 GetScaledExpFraction ( s32 oldValue , s32 receivedValue , s32 maxValue , u8 scale )
2017-10-19 15:28:41 +02:00
{
2018-06-19 00:43:15 +02:00
s32 newVal , result ;
s8 oldToMax , newToMax ;
2017-10-19 15:28:41 +02:00
scale * = 8 ;
2018-06-19 00:43:15 +02:00
newVal = oldValue - receivedValue ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
if ( newVal < 0 )
newVal = 0 ;
else if ( newVal > maxValue )
newVal = maxValue ;
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
oldToMax = oldValue * scale / maxValue ;
newToMax = newVal * scale / maxValue ;
result = oldToMax - newToMax ;
2017-10-19 15:28:41 +02:00
return abs ( result ) ;
}
u8 GetScaledHPFraction ( s16 hp , s16 maxhp , u8 scale )
{
u8 result = hp * scale / maxhp ;
if ( result = = 0 & & hp > 0 )
return 1 ;
return result ;
}
u8 GetHPBarLevel ( s16 hp , s16 maxhp )
{
2018-06-20 23:07:51 +02:00
u8 result ;
2017-10-19 15:28:41 +02:00
if ( hp = = maxhp )
{
2017-11-04 16:11:13 +01:00
result = HP_BAR_FULL ;
2017-10-19 15:28:41 +02:00
}
else
{
2018-06-20 23:07:51 +02:00
u8 fraction = GetScaledHPFraction ( hp , maxhp , B_HEALTHBAR_PIXELS ) ;
if ( fraction > ( B_HEALTHBAR_PIXELS * 50 / 100 ) ) // more than 50 % hp
2017-11-04 16:11:13 +01:00
result = HP_BAR_GREEN ;
2018-06-20 23:07:51 +02:00
else if ( fraction > ( B_HEALTHBAR_PIXELS * 20 / 100 ) ) // more than 20% hp
2017-11-04 16:11:13 +01:00
result = HP_BAR_YELLOW ;
2017-10-19 15:28:41 +02:00
else if ( fraction > 0 )
2017-11-04 16:11:13 +01:00
result = HP_BAR_RED ;
2017-10-19 15:28:41 +02:00
else
2017-11-04 16:11:13 +01:00
result = HP_BAR_EMPTY ;
2017-10-19 15:28:41 +02:00
}
return result ;
}
2022-07-29 10:17:58 -04:00
static u8 * AddTextPrinterAndCreateWindowOnHealthbox ( const u8 * str , u32 x , u32 y , u32 bgColor , u32 * windowId )
2017-10-19 15:28:41 +02:00
{
u16 winId ;
2018-02-06 20:37:54 -06:00
u8 color [ 3 ] ;
2017-10-19 15:28:41 +02:00
struct WindowTemplate winTemplate = sHealthboxWindowTemplate ;
winId = AddWindow ( & winTemplate ) ;
2019-03-02 17:25:39 -05:00
FillWindowPixelBuffer ( winId , PIXEL_FILL ( bgColor ) ) ;
2017-10-19 15:28:41 +02:00
2018-11-22 01:10:50 +00:00
color [ 0 ] = bgColor ;
2018-02-06 20:37:54 -06:00
color [ 1 ] = 1 ;
color [ 2 ] = 3 ;
2017-10-19 15:28:41 +02:00
2021-11-03 18:29:18 -04:00
AddTextPrinterParameterized4 ( winId , FONT_SMALL , x , y , 0 , 0 , color , TEXT_SKIP_DRAW , str ) ;
2017-10-19 15:28:41 +02:00
* windowId = winId ;
2022-07-29 10:17:58 -04:00
return ( u8 * ) ( GetWindowAttribute ( winId , WINDOW_TILE_DATA ) ) ;
2017-10-19 15:28:41 +02:00
}
static void RemoveWindowOnHealthbox ( u32 windowId )
{
RemoveWindow ( windowId ) ;
}
2022-06-01 12:41:57 -04:00
static void FillHealthboxObject ( void * dest , u32 valMult , u32 numTiles )
2017-10-19 15:28:41 +02:00
{
2022-06-01 12:41:57 -04:00
CpuFill32 ( 0x11111111 * valMult , dest , numTiles * TILE_SIZE_4BPP ) ;
2017-10-19 15:28:41 +02:00
}
2018-11-22 01:10:50 +00:00
static void HpTextIntoHealthboxObject ( void * dest , u8 * windowTileData , u32 windowWidth )
2017-10-19 15:28:41 +02:00
{
2018-11-22 01:10:50 +00:00
CpuCopy32 ( windowTileData + 256 , dest , windowWidth * TILE_SIZE_4BPP ) ;
2017-10-19 15:28:41 +02:00
}
2018-11-22 01:10:50 +00:00
static void TextIntoHealthboxObject ( void * dest , u8 * windowTileData , s32 windowWidth )
2017-10-19 15:28:41 +02:00
{
2018-11-22 01:10:50 +00:00
CpuCopy32 ( windowTileData + 256 , dest + 256 , windowWidth * TILE_SIZE_4BPP ) ;
// + 256 as that prevents the top 4 blank rows of sHealthboxWindowTemplate from being copied
if ( windowWidth > 0 )
2017-10-19 15:28:41 +02:00
{
do
{
CpuCopy32 ( windowTileData + 20 , dest + 20 , 12 ) ;
2018-06-19 00:43:15 +02:00
dest + = 32 , windowTileData + = 32 ;
2018-11-22 01:10:50 +00:00
windowWidth - - ;
} while ( windowWidth ! = 0 ) ;
2017-10-19 15:28:41 +02:00
}
}
2018-11-22 01:10:50 +00:00
static void SafariTextIntoHealthboxObject ( void * dest , u8 * windowTileData , u32 windowWidth )
2017-10-19 15:28:41 +02:00
{
2018-11-22 01:10:50 +00:00
CpuCopy32 ( windowTileData , dest , windowWidth * TILE_SIZE_4BPP ) ;
CpuCopy32 ( windowTileData + 256 , dest + 256 , windowWidth * TILE_SIZE_4BPP ) ;
2017-10-19 15:28:41 +02:00
}
2018-09-23 14:24:06 +02:00
# define ABILITY_POP_UP_TAG 0xD720
2018-09-29 12:47:35 +02:00
// for sprite
# define tOriginalX data[0]
# define tHide data[1]
# define tFrames data[2]
# define tRightToLeft data[3]
# define tBattlerId data[4]
2018-09-29 13:36:33 +02:00
# define tIsMain data[5]
2018-09-29 12:47:35 +02:00
// for task
# define tSpriteId1 data[6]
# define tSpriteId2 data[7]
2018-09-23 14:24:06 +02:00
static const u8 sAbilityPopUpGfx [ ] = INCBIN_U8 ( " graphics/battle_interface/ability_pop_up.4bpp " ) ;
static const u16 sAbilityPopUpPalette [ ] = INCBIN_U16 ( " graphics/battle_interface/ability_pop_up.gbapal " ) ;
static const struct SpriteSheet sSpriteSheet_AbilityPopUp =
{
sAbilityPopUpGfx , sizeof ( sAbilityPopUpGfx ) , ABILITY_POP_UP_TAG
} ;
static const struct SpritePalette sSpritePalette_AbilityPopUp =
{
sAbilityPopUpPalette , ABILITY_POP_UP_TAG
} ;
static const struct OamData sOamData_AbilityPopUp =
{
. y = 0 ,
. affineMode = 0 ,
. objMode = 0 ,
. mosaic = 0 ,
. bpp = 0 ,
. shape = ST_OAM_H_RECTANGLE ,
. x = 0 ,
. matrixNum = 0 ,
. size = 3 ,
. tileNum = 0 ,
. priority = 0 ,
. paletteNum = 0 ,
. affineParam = 0 ,
} ;
static const union AnimCmd sSpriteAnim_AbilityPopUp1 [ ] =
{
ANIMCMD_FRAME ( 0 , 0 ) ,
ANIMCMD_END
} ;
static const union AnimCmd * const sSpriteAnimTable_AbilityPopUp1 [ ] =
{
sSpriteAnim_AbilityPopUp1
} ;
static const struct SpriteTemplate sSpriteTemplate_AbilityPopUp1 =
{
. tileTag = ABILITY_POP_UP_TAG ,
. paletteTag = ABILITY_POP_UP_TAG ,
. oam = & sOamData_AbilityPopUp ,
. anims = sSpriteAnimTable_AbilityPopUp1 ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2018-09-29 12:47:35 +02:00
. callback = SpriteCb_AbilityPopUp
2018-09-23 14:24:06 +02:00
} ;
static const union AnimCmd sSpriteAnim_AbilityPopUp2 [ ] =
{
ANIMCMD_FRAME ( 32 , 0 ) ,
ANIMCMD_END
} ;
static const union AnimCmd * const sSpriteAnimTable_AbilityPopUp2 [ ] =
{
sSpriteAnim_AbilityPopUp2
} ;
static const struct SpriteTemplate sSpriteTemplate_AbilityPopUp2 =
{
. tileTag = ABILITY_POP_UP_TAG ,
. paletteTag = ABILITY_POP_UP_TAG ,
. oam = & sOamData_AbilityPopUp ,
. anims = sSpriteAnimTable_AbilityPopUp2 ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
2018-09-29 12:47:35 +02:00
. callback = SpriteCb_AbilityPopUp
2018-09-23 14:24:06 +02:00
} ;
# define ABILITY_POP_UP_POS_X_DIFF 64
# define ABILITY_POP_UP_POS_X_SLIDE 68
2018-09-29 12:47:35 +02:00
static const s16 sAbilityPopUpCoordsDoubles [ MAX_BATTLERS_COUNT ] [ 2 ] =
{
2018-09-29 13:36:33 +02:00
{ 29 , 80 } , // player left
2021-12-23 08:44:54 -05:00
{ 186 , 19 } , // opponent left
2018-09-29 13:36:33 +02:00
{ 29 , 97 } , // player right
2021-12-23 08:44:54 -05:00
{ 186 , 36 } , // opponent right
2018-09-29 12:47:35 +02:00
} ;
static const s16 sAbilityPopUpCoordsSingles [ MAX_BATTLERS_COUNT ] [ 2 ] =
2018-09-23 14:24:06 +02:00
{
2021-11-29 12:42:01 -05:00
{ 29 , 97 } , // player
2021-12-23 08:44:54 -05:00
{ 186 , 57 } , // opponent
2018-09-23 14:24:06 +02:00
} ;
static u8 * AddTextPrinterAndCreateWindowOnAbilityPopUp ( const u8 * str , u32 x , u32 y , u32 color1 , u32 color2 , u32 color3 , u32 * windowId )
{
u8 color [ 3 ] = { color1 , color2 , color3 } ;
struct WindowTemplate winTemplate = { 0 } ;
winTemplate . width = 8 ;
winTemplate . height = 2 ;
* windowId = AddWindow ( & winTemplate ) ;
2021-12-23 08:44:54 -05:00
FillWindowPixelBuffer ( * windowId , PIXEL_FILL ( color1 ) ) ;
2018-09-23 14:24:06 +02:00
AddTextPrinterParameterized4 ( * windowId , 0 , x , y , 0 , 0 , color , - 1 , str ) ;
2022-08-22 20:30:45 -04:00
return ( u8 * ) ( GetWindowAttribute ( * windowId , WINDOW_TILE_DATA ) ) ;
2018-09-23 14:24:06 +02:00
}
2018-09-29 12:47:35 +02:00
static void TextIntoAbilityPopUp ( void * dest , u8 * windowTileData , s32 arg2 , bool32 arg3 )
2018-09-23 14:24:06 +02:00
{
CpuCopy32 ( windowTileData + 256 , dest + 256 , arg2 * 32 ) ;
if ( arg2 > 0 )
{
do
{
2018-09-29 12:47:35 +02:00
if ( arg3 )
CpuCopy32 ( windowTileData + 16 , dest + 16 , 16 ) ;
else
CpuCopy32 ( windowTileData + 20 , dest + 20 , 12 ) ;
2018-09-23 14:24:06 +02:00
dest + = 32 , windowTileData + = 32 ;
arg2 - - ;
} while ( arg2 ! = 0 ) ;
}
}
# define MAX_CHARS_PRINTED 12
2022-08-24 20:20:44 +02:00
static void PrintOnAbilityPopUp ( const u8 * str , u8 * spriteTileData1 , u8 * spriteTileData2 , u32 x1 , u32 x2 , u32 y , u32 color1 , u32 color2 , u32 color3 , bool32 alignAbilityChars )
2018-09-23 14:24:06 +02:00
{
u32 windowId , i ;
u8 * windowTileData ;
2021-12-23 08:44:54 -05:00
u8 text1 [ MAX_CHARS_PRINTED ] ;
u8 text2 [ MAX_CHARS_PRINTED ] ;
2018-09-23 14:24:06 +02:00
2021-12-23 08:44:54 -05:00
for ( i = 0 ; i < MAX_CHARS_PRINTED ; i + + )
2018-09-23 14:24:06 +02:00
{
text1 [ i ] = str [ i ] ;
if ( text1 [ i ] = = EOS )
break ;
}
text1 [ i ] = EOS ;
2022-08-24 20:20:44 +02:00
// Because there are two Windows, we need to align the strings, so that the first char in the second window starts right after the last char in the first window.
// Windows are 64 pixels in width.
if ( alignAbilityChars & & i = = MAX_CHARS_PRINTED )
{
u32 width = GetStringWidth ( FONT_SMALL , text1 , 0 ) ;
2022-08-25 00:03:43 -04:00
if ( x1 + width < 64 )
x1 + = 64 - ( x1 + width ) ;
2022-08-24 20:20:44 +02:00
}
2018-09-23 14:24:06 +02:00
windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp ( text1 , x1 , y , color1 , color2 , color3 , & windowId ) ;
2018-09-29 12:47:35 +02:00
TextIntoAbilityPopUp ( spriteTileData1 , windowTileData , 8 , ( y = = 0 ) ) ;
2018-09-23 14:24:06 +02:00
RemoveWindow ( windowId ) ;
2021-12-23 08:44:54 -05:00
if ( i = = MAX_CHARS_PRINTED )
2018-09-23 14:24:06 +02:00
{
for ( i = 0 ; i < MAX_CHARS_PRINTED ; i + + )
{
text2 [ i ] = str [ MAX_CHARS_PRINTED + i ] ;
if ( text2 [ i ] = = EOS )
break ;
}
text2 [ i ] = EOS ;
windowTileData = AddTextPrinterAndCreateWindowOnAbilityPopUp ( text2 , x2 , y , color1 , color2 , color3 , & windowId ) ;
2021-12-23 08:44:54 -05:00
TextIntoAbilityPopUp ( spriteTileData2 , windowTileData , 3 , ( y = = 0 ) ) ;
2018-09-23 14:24:06 +02:00
RemoveWindow ( windowId ) ;
}
}
2021-11-29 12:42:01 -05:00
static const u8 sText_Space16 [ ] = _ ( " " ) ;
static void ClearAbilityName ( u8 spriteId1 , u8 spriteId2 )
{
PrintOnAbilityPopUp ( sText_Space16 ,
( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId1 ] . oam . tileNum * 32 ) + 256 ,
( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId2 ] . oam . tileNum * 32 ) + 256 ,
6 , 1 ,
4 ,
2022-08-24 20:20:44 +02:00
7 , 9 , 1 ,
FALSE ) ;
2018-09-23 14:24:06 +02:00
}
static void PrintBattlerOnAbilityPopUp ( u8 battlerId , u8 spriteId1 , u8 spriteId2 )
{
2021-03-17 14:26:33 -06:00
int i ;
u8 lastChar ;
u8 * name ;
u8 monName [ POKEMON_NAME_LENGTH + 3 ] = { 0 } ;
u8 * nick = gBattleMons [ battlerId ] . nickname ;
for ( i = 0 ; i < POKEMON_NAME_LENGTH ; + + i )
{
monName [ i ] = nick [ i ] ;
if ( nick [ i ] = = EOS | | i + 1 = = POKEMON_NAME_LENGTH )
break ;
}
name = monName + i + 1 ;
if ( * ( name - 1 ) = = EOS )
name - - ;
lastChar = * ( name - 1 ) ;
2021-11-21 10:40:26 -08:00
name [ 0 ] = CHAR_SGL_QUOTE_RIGHT ; // apostraphe
2021-03-17 14:26:33 -06:00
name + + ;
if ( lastChar ! = CHAR_S & & lastChar ! = CHAR_s )
{
name [ 0 ] = CHAR_s ;
name + + ;
}
2021-04-27 18:36:37 -07:00
2021-03-17 14:26:33 -06:00
name [ 0 ] = EOS ;
PrintOnAbilityPopUp ( ( const u8 * ) monName ,
2018-09-23 14:24:06 +02:00
( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId1 ] . oam . tileNum * 32 ) ,
( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId2 ] . oam . tileNum * 32 ) ,
7 , 0 ,
2018-09-29 12:47:35 +02:00
0 ,
2022-08-24 20:20:44 +02:00
2 , 7 , 1 ,
FALSE ) ;
2018-09-23 14:24:06 +02:00
}
static void PrintAbilityOnAbilityPopUp ( u32 ability , u8 spriteId1 , u8 spriteId2 )
{
PrintOnAbilityPopUp ( gAbilityNames [ ability ] ,
( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId1 ] . oam . tileNum * 32 ) + 256 ,
( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId2 ] . oam . tileNum * 32 ) + 256 ,
2022-08-24 20:20:44 +02:00
6 , 0 ,
2018-09-23 14:24:06 +02:00
4 ,
2022-08-24 20:20:44 +02:00
7 , 9 , 1 ,
TRUE ) ;
2018-09-23 14:24:06 +02:00
}
2021-03-17 14:26:33 -06:00
# define PIXEL_COORDS_TO_OFFSET(x, y)( \
/*Add tiles by X*/ \
( ( y / 8 ) * 32 * 8 ) \
/*Add tiles by X*/ \
+ ( ( x / 8 ) * 32 ) \
/*Add pixels by Y*/ \
+ ( ( ( ( y ) - ( ( y / 8 ) * 8 ) ) ) * 4 ) \
/*Add pixels by X*/ \
2018-09-29 12:47:35 +02:00
+ ( ( ( ( x ) - ( ( x / 8 ) * 8 ) ) / 2 ) ) )
static const u16 sOverwrittenPixelsTable [ ] [ 2 ] =
{
2021-03-17 14:26:33 -06:00
{ PIXEL_COORDS_TO_OFFSET ( 0 , 0 ) , 5 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 1 ) , 5 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 2 ) , 5 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 3 ) , 5 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 4 ) , 5 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 5 ) , 5 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 6 ) , 5 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 7 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 8 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 9 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 10 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 11 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 12 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 13 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 8 , 13 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 16 , 13 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 24 , 13 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 32 , 13 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 40 , 13 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 48 , 13 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 56 , 13 ) , 8 } ,
2018-09-29 12:47:35 +02:00
{ PIXEL_COORDS_TO_OFFSET ( 0 , 14 ) , 8 } ,
2021-03-17 14:26:33 -06:00
{ PIXEL_COORDS_TO_OFFSET ( 8 , 14 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 16 , 14 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 24 , 14 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 32 , 14 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 40 , 14 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 48 , 14 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 56 , 14 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 15 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 16 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 17 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 18 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 19 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 20 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 21 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 22 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 23 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 24 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 25 ) , 3 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 26 ) , 3 } ,
2021-11-29 12:42:01 -05:00
//Second Row Of Image
2021-12-23 08:44:54 -05:00
{ PIXEL_COORDS_TO_OFFSET ( 0 , 45 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 46 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 0 , 47 ) , 8 } ,
//{PIXEL_COORDS_TO_OFFSET(0, 48), 8}, // cuts off the top of the 'G' in Neutralizing Gas
{ PIXEL_COORDS_TO_OFFSET ( 8 , 45 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 8 , 46 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 8 , 47 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 8 , 48 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 16 , 45 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 16 , 46 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 16 , 47 ) , 8 } ,
{ PIXEL_COORDS_TO_OFFSET ( 16 , 48 ) , 8 } ,
2018-09-29 12:47:35 +02:00
} ;
static inline void CopyPixels ( u8 * dest , const u8 * src , u32 pixelCount )
2018-09-23 14:24:06 +02:00
{
2021-03-17 14:26:33 -06:00
u32 i = 0 ;
if ( pixelCount & 1 )
{
while ( pixelCount ! = 0 )
{
dest [ i ] & = ~ ( 0xF ) ;
dest [ i ] | = ( src [ i ] & 0xF ) ;
if ( - - pixelCount ! = 0 )
{
dest [ i ] & = ~ ( 0xF0 ) ;
dest [ i ] | = ( src [ i ] & 0xF0 ) ;
pixelCount - - ;
}
i + + ;
}
}
else
{
for ( i = 0 ; i < pixelCount / 2 ; i + + )
dest [ i ] = src [ i ] ;
}
2018-09-29 12:47:35 +02:00
}
2018-09-23 14:24:06 +02:00
2018-09-29 12:47:35 +02:00
static void RestoreOverwrittenPixels ( u8 * tiles )
{
2021-03-17 14:26:33 -06:00
u32 i ;
u8 * buffer = Alloc ( sizeof ( sAbilityPopUpGfx ) * 2 ) ;
2018-09-23 14:24:06 +02:00
2021-03-17 14:26:33 -06:00
CpuCopy32 ( tiles , buffer , sizeof ( sAbilityPopUpGfx ) ) ;
2018-09-29 12:47:35 +02:00
2021-03-17 14:26:33 -06:00
for ( i = 0 ; i < ARRAY_COUNT ( sOverwrittenPixelsTable ) ; i + + )
{
CopyPixels ( buffer + sOverwrittenPixelsTable [ i ] [ 0 ] ,
sAbilityPopUpGfx + sOverwrittenPixelsTable [ i ] [ 0 ] ,
sOverwrittenPixelsTable [ i ] [ 1 ] ) ;
}
2018-09-29 12:47:35 +02:00
2021-03-17 14:26:33 -06:00
CpuCopy32 ( buffer , tiles , sizeof ( sAbilityPopUpGfx ) ) ;
Free ( buffer ) ;
2018-09-29 12:47:35 +02:00
}
void CreateAbilityPopUp ( u8 battlerId , u32 ability , bool32 isDoubleBattle )
{
2022-08-23 21:00:08 -04:00
# if B_ABILITY_POP_UP == TRUE
2018-09-29 12:47:35 +02:00
const s16 ( * coords ) [ 2 ] ;
u8 spriteId1 , spriteId2 , battlerPosition , taskId ;
2021-02-02 09:00:07 -07:00
if ( gBattleScripting . abilityPopupOverwrite ! = 0 )
ability = gBattleScripting . abilityPopupOverwrite ;
2018-11-03 10:51:51 +01:00
2018-09-29 12:47:35 +02:00
if ( ! gBattleStruct - > activeAbilityPopUps )
{
LoadSpriteSheet ( & sSpriteSheet_AbilityPopUp ) ;
LoadSpritePalette ( & sSpritePalette_AbilityPopUp ) ;
}
gBattleStruct - > activeAbilityPopUps | = gBitTable [ battlerId ] ;
battlerPosition = GetBattlerPosition ( battlerId ) ;
if ( isDoubleBattle )
coords = sAbilityPopUpCoordsDoubles ;
else
coords = sAbilityPopUpCoordsSingles ;
if ( ( battlerPosition & BIT_SIDE ) = = B_SIDE_PLAYER )
{
spriteId1 = CreateSprite ( & sSpriteTemplate_AbilityPopUp1 ,
coords [ battlerPosition ] [ 0 ] - ABILITY_POP_UP_POS_X_SLIDE ,
coords [ battlerPosition ] [ 1 ] , 0 ) ;
spriteId2 = CreateSprite ( & sSpriteTemplate_AbilityPopUp2 ,
coords [ battlerPosition ] [ 0 ] - ABILITY_POP_UP_POS_X_SLIDE + ABILITY_POP_UP_POS_X_DIFF ,
coords [ battlerPosition ] [ 1 ] , 0 ) ;
gSprites [ spriteId1 ] . tOriginalX = coords [ battlerPosition ] [ 0 ] ;
gSprites [ spriteId2 ] . tOriginalX = coords [ battlerPosition ] [ 0 ] + ABILITY_POP_UP_POS_X_DIFF ;
gSprites [ spriteId1 ] . tRightToLeft = TRUE ;
gSprites [ spriteId2 ] . tRightToLeft = TRUE ;
}
else
{
spriteId1 = CreateSprite ( & sSpriteTemplate_AbilityPopUp1 ,
coords [ battlerPosition ] [ 0 ] + ABILITY_POP_UP_POS_X_SLIDE ,
coords [ battlerPosition ] [ 1 ] , 0 ) ;
spriteId2 = CreateSprite ( & sSpriteTemplate_AbilityPopUp2 ,
coords [ battlerPosition ] [ 0 ] + ABILITY_POP_UP_POS_X_SLIDE + ABILITY_POP_UP_POS_X_DIFF ,
coords [ battlerPosition ] [ 1 ] , 0 ) ;
gSprites [ spriteId1 ] . tOriginalX = coords [ battlerPosition ] [ 0 ] ;
gSprites [ spriteId2 ] . tOriginalX = coords [ battlerPosition ] [ 0 ] + ABILITY_POP_UP_POS_X_DIFF ;
gSprites [ spriteId1 ] . tRightToLeft = FALSE ;
gSprites [ spriteId2 ] . tRightToLeft = FALSE ;
}
2021-04-27 18:36:37 -07:00
2021-10-12 10:32:51 -04:00
gBattleStruct - > abilityPopUpSpriteIds [ battlerId ] [ 0 ] = spriteId1 ;
gBattleStruct - > abilityPopUpSpriteIds [ battlerId ] [ 1 ] = spriteId2 ;
2018-09-29 12:47:35 +02:00
taskId = CreateTask ( Task_FreeAbilityPopUpGfx , 5 ) ;
gTasks [ taskId ] . tSpriteId1 = spriteId1 ;
gTasks [ taskId ] . tSpriteId2 = spriteId2 ;
2018-09-23 14:24:06 +02:00
2018-09-29 13:36:33 +02:00
gSprites [ spriteId1 ] . tIsMain = TRUE ;
2018-09-23 14:24:06 +02:00
gSprites [ spriteId1 ] . tBattlerId = battlerId ;
gSprites [ spriteId2 ] . tBattlerId = battlerId ;
2018-09-29 12:47:35 +02:00
StartSpriteAnim ( & gSprites [ spriteId1 ] , 0 ) ;
StartSpriteAnim ( & gSprites [ spriteId2 ] , 0 ) ;
2018-09-23 14:24:06 +02:00
PrintBattlerOnAbilityPopUp ( battlerId , spriteId1 , spriteId2 ) ;
PrintAbilityOnAbilityPopUp ( ability , spriteId1 , spriteId2 ) ;
2018-09-29 12:47:35 +02:00
RestoreOverwrittenPixels ( ( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId1 ] . oam . tileNum * 32 ) ) ;
2022-08-23 21:00:08 -04:00
# endif
2018-09-23 14:24:06 +02:00
}
2021-10-12 10:32:51 -04:00
void UpdateAbilityPopup ( u8 battlerId )
{
u8 spriteId1 = gBattleStruct - > abilityPopUpSpriteIds [ battlerId ] [ 0 ] ;
u8 spriteId2 = gBattleStruct - > abilityPopUpSpriteIds [ battlerId ] [ 1 ] ;
u16 ability = ( gBattleScripting . abilityPopupOverwrite ! = 0 ) ? gBattleScripting . abilityPopupOverwrite : gBattleMons [ battlerId ] . ability ;
2022-08-25 16:40:56 +02:00
2021-11-29 12:42:01 -05:00
ClearAbilityName ( spriteId1 , spriteId2 ) ;
2021-10-12 10:32:51 -04:00
PrintAbilityOnAbilityPopUp ( ability , spriteId1 , spriteId2 ) ;
RestoreOverwrittenPixels ( ( void * ) ( OBJ_VRAM0 ) + ( gSprites [ spriteId1 ] . oam . tileNum * 32 ) ) ;
}
2018-09-29 12:47:35 +02:00
# define FRAMES_TO_WAIT 48
static void SpriteCb_AbilityPopUp ( struct Sprite * sprite )
2018-09-23 14:24:06 +02:00
{
if ( ! sprite - > tHide ) // Show
{
2018-09-29 13:36:33 +02:00
if ( sprite - > tIsMain & & + + sprite - > tFrames = = 4 )
2021-06-06 22:19:17 +02:00
PlaySE ( SE_BALL_TRAY_ENTER ) ;
2021-08-11 16:33:10 -07:00
if ( ( ! sprite - > tRightToLeft & & ( sprite - > x - = 4 ) < = sprite - > tOriginalX )
| | ( sprite - > tRightToLeft & & ( sprite - > x + = 4 ) > = sprite - > tOriginalX )
2018-09-29 12:47:35 +02:00
)
2018-09-23 14:24:06 +02:00
{
2021-08-11 16:33:10 -07:00
sprite - > x = sprite - > tOriginalX ;
2018-09-23 14:24:06 +02:00
sprite - > tHide = TRUE ;
2018-09-29 12:47:35 +02:00
sprite - > tFrames = FRAMES_TO_WAIT ;
2018-09-23 14:24:06 +02:00
}
}
else // Hide
{
if ( sprite - > tFrames = = 0 )
{
2021-08-11 16:33:10 -07:00
if ( ( ! sprite - > tRightToLeft & & ( sprite - > x + = 4 ) > = sprite - > tOriginalX + ABILITY_POP_UP_POS_X_SLIDE )
| | ( sprite - > tRightToLeft & & ( sprite - > x - = 4 ) < = sprite - > tOriginalX - ABILITY_POP_UP_POS_X_SLIDE )
2018-09-29 12:47:35 +02:00
)
2018-09-23 14:24:06 +02:00
{
2018-09-29 12:47:35 +02:00
gBattleStruct - > activeAbilityPopUps & = ~ ( gBitTable [ sprite - > tBattlerId ] ) ;
2018-09-23 14:24:06 +02:00
DestroySprite ( sprite ) ;
}
}
else
{
2020-11-19 15:16:27 -07:00
if ( ! gBattleScripting . fixedPopup )
sprite - > tFrames - - ;
2018-09-23 14:24:06 +02:00
}
}
}
2020-11-19 15:16:27 -07:00
void DestroyAbilityPopUp ( u8 battlerId )
{
2020-11-20 08:26:50 -07:00
gSprites [ gBattleStruct - > abilityPopUpSpriteIds [ battlerId ] [ 0 ] ] . tFrames = 0 ;
gSprites [ gBattleStruct - > abilityPopUpSpriteIds [ battlerId ] [ 1 ] ] . tFrames = 0 ;
2020-11-19 15:16:27 -07:00
gBattleScripting . fixedPopup = FALSE ;
}
2018-09-29 12:47:35 +02:00
static void Task_FreeAbilityPopUpGfx ( u8 taskId )
2018-09-23 14:24:06 +02:00
{
2018-09-29 12:47:35 +02:00
if ( ! gSprites [ gTasks [ taskId ] . tSpriteId1 ] . inUse
& & ! gSprites [ gTasks [ taskId ] . tSpriteId2 ] . inUse
& & ! gBattleStruct - > activeAbilityPopUps )
2018-09-23 14:24:06 +02:00
{
2018-09-29 12:47:35 +02:00
FreeSpriteTilesByTag ( ABILITY_POP_UP_TAG ) ;
FreeSpritePaletteByTag ( ABILITY_POP_UP_TAG ) ;
DestroyTask ( taskId ) ;
2018-09-23 14:24:06 +02:00
}
}
2021-06-25 13:37:59 -06:00
// last used ball
# define LAST_BALL_WINDOW_TAG 0xD721
static const struct OamData sOamData_LastUsedBall =
{
2021-12-23 08:44:54 -05:00
. y = 0 ,
. affineMode = 0 ,
. objMode = 0 ,
. mosaic = 0 ,
. bpp = 0 ,
. shape = SPRITE_SHAPE ( 32 x32 ) ,
. x = 0 ,
. matrixNum = 0 ,
. size = SPRITE_SIZE ( 32 x32 ) ,
. tileNum = 0 ,
. priority = 1 ,
. paletteNum = 0 ,
. affineParam = 0 ,
2021-06-25 13:37:59 -06:00
} ;
static const struct SpriteTemplate sSpriteTemplate_LastUsedBallWindow =
{
. tileTag = LAST_BALL_WINDOW_TAG ,
. paletteTag = ABILITY_POP_UP_TAG ,
. oam = & sOamData_LastUsedBall ,
. anims = gDummySpriteAnimTable ,
. images = NULL ,
. affineAnims = gDummySpriteAffineAnimTable ,
. callback = SpriteCB_LastUsedBallWin
} ;
2021-09-23 12:03:01 -04:00
# if B_LAST_USED_BALL_BUTTON == R_BUTTON
static const u8 sLastUsedBallWindowGfx [ ] = INCBIN_U8 ( " graphics/battle_interface/last_used_ball_r.4bpp " ) ;
# else
2021-09-23 13:20:32 -04:00
static const u8 sLastUsedBallWindowGfx [ ] = INCBIN_U8 ( " graphics/battle_interface/last_used_ball_l.4bpp " ) ;
2021-09-23 12:03:01 -04:00
# endif
2021-06-25 13:37:59 -06:00
static const struct SpriteSheet sSpriteSheet_LastUsedBallWindow =
{
sLastUsedBallWindowGfx , sizeof ( sLastUsedBallWindowGfx ) , LAST_BALL_WINDOW_TAG
} ;
# define LAST_USED_BALL_X_F 15
# define LAST_USED_BALL_X_0 -15
2021-08-12 14:49:17 -06:00
# define LAST_USED_BALL_Y ((IsDoubleBattle()) ? 78 : 68)
2021-06-25 13:37:59 -06:00
# define LAST_BALL_WIN_X_F (LAST_USED_BALL_X_F - 1)
# define LAST_BALL_WIN_X_0 (LAST_USED_BALL_X_0 - 0)
# define LAST_USED_WIN_Y (LAST_USED_BALL_Y - 8)
# define sHide data[0]
bool32 CanThrowLastUsedBall ( void )
{
2021-12-05 23:10:05 +00:00
# if B_LAST_USED_BALL == FALSE
return FALSE ;
# else
if ( ! CanThrowBall ( ) )
return FALSE ;
2022-05-20 04:57:32 +03:00
if ( gBattleTypeFlags & ( BATTLE_TYPE_TRAINER | BATTLE_TYPE_FRONTIER ) )
2021-12-05 23:10:05 +00:00
return FALSE ;
if ( ! CheckBagHasItem ( gLastThrownBall , 1 ) )
2021-09-23 12:03:01 -04:00
return FALSE ;
2021-06-25 13:37:59 -06:00
2021-12-05 23:10:05 +00:00
return TRUE ;
# endif
}
2021-06-25 13:37:59 -06:00
void TryAddLastUsedBallItemSprites ( void )
{
2021-12-05 23:10:05 +00:00
# if B_LAST_USED_BALL == TRUE
2021-10-06 14:19:15 -04:00
if ( gLastThrownBall = = 0
2021-10-06 13:56:04 -04:00
| | ( gLastThrownBall ! = 0 & & ! CheckBagHasItem ( gLastThrownBall , 1 ) ) )
2021-07-04 10:09:57 -06:00
{
// we're out of the last used ball, so just set it to the first ball in the bag
// we have to compact the bag first bc it is typically only compacted when you open it
CompactItemsInBagPocket ( & gBagPockets [ BALLS_POCKET ] ) ;
2021-09-23 12:03:01 -04:00
gLastThrownBall = gBagPockets [ BALLS_POCKET ] . itemSlots [ 0 ] . itemId ;
2021-07-04 10:09:57 -06:00
}
2021-12-05 23:10:05 +00:00
if ( ! CanThrowLastUsedBall ( ) )
2021-06-25 13:37:59 -06:00
return ;
// ball
if ( gBattleStruct - > ballSpriteIds [ 0 ] = = MAX_SPRITES )
{
2021-09-23 12:03:01 -04:00
gBattleStruct - > ballSpriteIds [ 0 ] = AddItemIconSprite ( 102 , 102 , gLastThrownBall ) ;
2021-09-01 07:45:41 -04:00
gSprites [ gBattleStruct - > ballSpriteIds [ 0 ] ] . x = LAST_USED_BALL_X_0 ;
gSprites [ gBattleStruct - > ballSpriteIds [ 0 ] ] . y = LAST_USED_BALL_Y ;
2021-06-25 13:37:59 -06:00
gSprites [ gBattleStruct - > ballSpriteIds [ 0 ] ] . sHide = FALSE ; // restore
gSprites [ gBattleStruct - > ballSpriteIds [ 0 ] ] . callback = SpriteCB_LastUsedBall ;
}
// window
LoadSpritePalette ( & sSpritePalette_AbilityPopUp ) ;
if ( GetSpriteTileStartByTag ( LAST_BALL_WINDOW_TAG ) = = 0xFFFF )
LoadSpriteSheet ( & sSpriteSheet_LastUsedBallWindow ) ;
if ( gBattleStruct - > ballSpriteIds [ 1 ] = = MAX_SPRITES )
{
gBattleStruct - > ballSpriteIds [ 1 ] = CreateSprite ( & sSpriteTemplate_LastUsedBallWindow ,
2021-12-05 23:10:05 +00:00
LAST_BALL_WIN_X_0 ,
LAST_USED_WIN_Y , 5 ) ;
2021-06-25 13:37:59 -06:00
gSprites [ gBattleStruct - > ballSpriteIds [ 0 ] ] . sHide = FALSE ; // restore
}
2021-12-05 23:10:05 +00:00
# endif
2021-06-25 13:37:59 -06:00
}
static void DestroyLastUsedBallWinGfx ( struct Sprite * sprite )
{
FreeSpriteTilesByTag ( LAST_BALL_WINDOW_TAG ) ;
FreeSpritePaletteByTag ( ABILITY_POP_UP_TAG ) ;
DestroySprite ( sprite ) ;
gBattleStruct - > ballSpriteIds [ 1 ] = MAX_SPRITES ;
}
static void DestroyLastUsedBallGfx ( struct Sprite * sprite )
{
FreeSpriteTilesByTag ( 102 ) ;
FreeSpritePaletteByTag ( 102 ) ;
DestroySprite ( sprite ) ;
gBattleStruct - > ballSpriteIds [ 0 ] = MAX_SPRITES ;
}
static void SpriteCB_LastUsedBallWin ( struct Sprite * sprite )
2022-08-25 16:40:56 +02:00
{
2021-06-25 13:37:59 -06:00
if ( sprite - > sHide )
{
2021-09-01 07:45:41 -04:00
if ( sprite - > x ! = LAST_BALL_WIN_X_0 )
sprite - > x - - ;
2021-06-25 13:37:59 -06:00
2021-09-01 07:45:41 -04:00
if ( sprite - > x = = LAST_BALL_WIN_X_0 )
2021-06-25 13:37:59 -06:00
DestroyLastUsedBallWinGfx ( sprite ) ;
}
else
{
2021-09-01 07:45:41 -04:00
if ( sprite - > x ! = LAST_BALL_WIN_X_F )
sprite - > x + + ;
2021-06-25 13:37:59 -06:00
}
}
static void SpriteCB_LastUsedBall ( struct Sprite * sprite )
2022-08-25 16:40:56 +02:00
{
2021-06-25 13:37:59 -06:00
if ( sprite - > sHide )
{
2021-09-01 07:45:41 -04:00
if ( sprite - > x ! = LAST_USED_BALL_X_0 )
sprite - > x - - ;
2021-06-25 13:37:59 -06:00
2021-09-01 07:45:41 -04:00
if ( sprite - > x = = LAST_USED_BALL_X_0 )
2021-06-25 13:37:59 -06:00
DestroyLastUsedBallGfx ( sprite ) ;
}
else
{
2021-09-01 07:45:41 -04:00
if ( sprite - > x ! = LAST_USED_BALL_X_F )
sprite - > x + + ;
2021-06-25 13:37:59 -06:00
}
}
static void TryHideOrRestoreLastUsedBall ( u8 caseId )
{
2021-12-05 23:10:05 +00:00
# if B_LAST_USED_BALL == TRUE
2021-06-25 13:37:59 -06:00
if ( gBattleStruct - > ballSpriteIds [ 0 ] = = MAX_SPRITES )
return ;
switch ( caseId )
{
case 0 : // hide
if ( gBattleStruct - > ballSpriteIds [ 0 ] ! = MAX_SPRITES )
gSprites [ gBattleStruct - > ballSpriteIds [ 0 ] ] . sHide = TRUE ; // hide
if ( gBattleStruct - > ballSpriteIds [ 1 ] ! = MAX_SPRITES )
gSprites [ gBattleStruct - > ballSpriteIds [ 1 ] ] . sHide = TRUE ; // hide
break ;
case 1 : // restore
if ( gBattleStruct - > ballSpriteIds [ 0 ] ! = MAX_SPRITES )
gSprites [ gBattleStruct - > ballSpriteIds [ 0 ] ] . sHide = FALSE ; // restore
if ( gBattleStruct - > ballSpriteIds [ 1 ] ! = MAX_SPRITES )
gSprites [ gBattleStruct - > ballSpriteIds [ 1 ] ] . sHide = FALSE ; // restore
break ;
}
2021-12-05 23:10:05 +00:00
# endif
2021-06-25 13:37:59 -06:00
}
void TryHideLastUsedBall ( void )
{
2021-12-05 23:10:05 +00:00
# if B_LAST_USED_BALL == TRUE
2021-06-25 13:37:59 -06:00
TryHideOrRestoreLastUsedBall ( 0 ) ;
2021-12-05 23:10:05 +00:00
# endif
2021-06-25 13:37:59 -06:00
}
void TryRestoreLastUsedBall ( void )
{
2021-12-05 23:10:05 +00:00
# if B_LAST_USED_BALL == TRUE
2021-06-25 13:37:59 -06:00
if ( gBattleStruct - > ballSpriteIds [ 0 ] ! = MAX_SPRITES )
TryHideOrRestoreLastUsedBall ( 1 ) ;
else
TryAddLastUsedBallItemSprites ( ) ;
2021-12-05 23:10:05 +00:00
# endif
2021-06-25 13:37:59 -06:00
}