pokeemerald/src/battle_interface.c

2633 lines
80 KiB
C
Raw Normal View History

2017-10-16 18:12:27 +02:00
#include "global.h"
#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"
#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"
2017-12-11 19:27:51 +01:00
#include "constants/songs.h"
2017-10-18 21:42:00 +02:00
#include "decompress.h"
#include "task.h"
#include "util.h"
#include "gpu_regs.h"
#include "battle_message.h"
2017-12-11 19:27:51 +01:00
#include "constants/species.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"
2018-01-29 14:36:13 +01:00
#include "constants/rgb.h"
2018-03-01 00:59:52 +01:00
#include "data2.h"
2017-10-16 18:12:27 +02:00
2017-10-19 15:28:41 +02:00
struct TestingBar
{
s32 maxValue;
2018-06-19 00:43:15 +02:00
s32 oldValue;
2017-10-22 18:43:15 +02:00
s32 receivedValue;
2017-10-19 15:28:41 +02:00
u32 unkC_0:5;
u32 unk10;
};
2017-10-19 18:25:48 +02:00
enum
{
HEALTHBOX_GFX_0,
HEALTHBOX_GFX_1,
HEALTHBOX_GFX_2,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_HP_BAR_GREEN,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_4,
HEALTHBOX_GFX_5,
HEALTHBOX_GFX_6,
HEALTHBOX_GFX_7,
HEALTHBOX_GFX_8,
HEALTHBOX_GFX_9,
HEALTHBOX_GFX_10,
HEALTHBOX_GFX_11,
HEALTHBOX_GFX_12,
HEALTHBOX_GFX_13,
HEALTHBOX_GFX_14,
HEALTHBOX_GFX_15,
HEALTHBOX_GFX_16,
HEALTHBOX_GFX_17,
HEALTHBOX_GFX_18,
HEALTHBOX_GFX_19,
HEALTHBOX_GFX_20,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PSN_BATTLER0,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_22,
HEALTHBOX_GFX_23,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PRZ_BATTLER0,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_25,
HEALTHBOX_GFX_26,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER0,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_28,
HEALTHBOX_GFX_29,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER0,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_31,
HEALTHBOX_GFX_32,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER0,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_34,
HEALTHBOX_GFX_35,
HEALTHBOX_GFX_36,
HEALTHBOX_GFX_37,
HEALTHBOX_GFX_38,
HEALTHBOX_GFX_39,
HEALTHBOX_GFX_40,
HEALTHBOX_GFX_41,
HEALTHBOX_GFX_42,
HEALTHBOX_GFX_43,
HEALTHBOX_GFX_44,
HEALTHBOX_GFX_45,
HEALTHBOX_GFX_46,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_HP_BAR_YELLOW,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_48,
HEALTHBOX_GFX_49,
HEALTHBOX_GFX_50,
HEALTHBOX_GFX_51,
HEALTHBOX_GFX_52,
HEALTHBOX_GFX_53,
HEALTHBOX_GFX_54,
HEALTHBOX_GFX_55,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_HP_BAR_RED,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_57,
HEALTHBOX_GFX_58,
HEALTHBOX_GFX_59,
HEALTHBOX_GFX_60,
HEALTHBOX_GFX_61,
HEALTHBOX_GFX_62,
HEALTHBOX_GFX_63,
HEALTHBOX_GFX_64,
HEALTHBOX_GFX_65,
HEALTHBOX_GFX_66,
HEALTHBOX_GFX_67,
HEALTHBOX_GFX_68,
HEALTHBOX_GFX_69,
HEALTHBOX_GFX_70,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PSN_BATTLER1,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_72,
HEALTHBOX_GFX_73,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PRZ_BATTLER1,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_75,
HEALTHBOX_GFX_76,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER1,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_78,
HEALTHBOX_GFX_79,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER1,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_81,
HEALTHBOX_GFX_82,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER1,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_84,
HEALTHBOX_GFX_85,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PSN_BATTLER2,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_87,
HEALTHBOX_GFX_88,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PRZ_BATTLER2,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_90,
HEALTHBOX_GFX_91,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER2,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_93,
HEALTHBOX_GFX_94,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER2,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_96,
HEALTHBOX_GFX_97,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER2,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_99,
HEALTHBOX_GFX_100,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PSN_BATTLER3,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_102,
HEALTHBOX_GFX_103,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_PRZ_BATTLER3,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_105,
HEALTHBOX_GFX_106,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_SLP_BATTLER3,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_108,
HEALTHBOX_GFX_109,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_FRZ_BATTLER3,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_111,
HEALTHBOX_GFX_112,
2018-06-19 00:43:15 +02:00
HEALTHBOX_GFX_STATUS_BRN_BATTLER3,
2017-10-19 18:25:48 +02:00
HEALTHBOX_GFX_114,
HEALTHBOX_GFX_115,
HEALTHBOX_GFX_116,
HEALTHBOX_GFX_117,
};
2018-06-19 00:43:15 +02:00
extern const u8 *const gNatureNamePointers[];
2017-10-19 15:28:41 +02:00
// strings
2017-10-18 21:42:00 +02:00
extern const u8 gText_Slash[];
2017-10-19 15:28:41 +02:00
extern const u8 gText_HighlightDarkGrey[];
extern const u8 gText_DynColor2[];
extern const u8 gText_DynColor2Male[];
extern const u8 gText_DynColor1Female[];
// graphics
extern const u8 gBattleInterface_BallStatusBarGfx[];
extern const u8 gBattleInterface_BallDisplayGfx[];
extern const u16 gBattleInterface_BallStatusBarPal[];
extern const u16 gBattleInterface_BallDisplayPal[];
extern const u8 gHealthboxElementsGfxTable[][32];
2017-10-16 18:12:27 +02:00
// this file's functions
2017-10-19 15:28:41 +02:00
static const u8 *GetHealthboxElementGfxPtr(u8 elementId);
static u8* AddTextPrinterAndCreateWindowOnHealthbox(const u8 *str, u32 x, u32 y, u32 arg3, u32 *windowId);
static void RemoveWindowOnHealthbox(u32 windowId);
static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent);
static void UpdateStatusIconInHealthbox(u8 healthboxSpriteId);
2018-06-19 00:43:15 +02:00
static void TextIntoHealthboxObject(void *dest, u8 *windowTileData, s32 arg2);
static void SafariTextIntoHealthboxObject(void *dest, u8 *windowTileData, u32 arg2);
static void HpTextIntoHealthboxObject(void *dest, u8 *windowTileData, u32 arg2);
static void FillHealthboxObject(void *dest, u32 arg1, u32 arg2);
2017-10-19 15:28:41 +02:00
static void sub_8073E08(u8 taskId);
static void sub_8073F98(u8 taskId);
static void sub_8073E64(u8 taskId);
2018-06-19 00:43:15 +02:00
static void SpriteCB_HealthBoxOther(struct Sprite *sprite);
static void SpriteCB_HealthBar(struct Sprite *sprite);
2017-10-19 15:28:41 +02:00
static void sub_8074158(struct Sprite *sprite);
static void sub_8074090(struct Sprite *sprite);
2017-10-19 18:25:48 +02:00
static void SpriteCB_StatusSummaryBar(struct Sprite *sprite);
static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite *sprite);
static void SpriteCB_StatusSummaryBallsOnSwitchout(struct Sprite *sprite);
2017-10-19 15:28:41 +02:00
2018-06-19 00:43:15 +02:00
static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId);
static s32 CalcNewBarValue(s32 maxValue, s32 currValue, s32 receivedValue, s32 *arg3, u8 arg4, u16 arg5);
2017-10-22 18:43:15 +02:00
static u8 GetScaledExpFraction(s32 currValue, s32 receivedValue, s32 maxValue, u8 scale);
2018-06-19 00:43:15 +02:00
static void MoveBattleBarGraphically(u8 battlerId, u8 whichBar);
static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 *arg4, u8 scale);
2017-10-19 15:28:41 +02:00
static void sub_8074F88(struct TestingBar *barInfo, s32 *arg1, u16 *arg2);
2017-10-16 18:12:27 +02:00
// const rom data
2017-10-20 19:24:46 +02:00
static const struct OamData sUnknown_0832C138 =
2017-10-16 18:12:27 +02:00
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 1,
.x = 0,
.matrixNum = 0,
.size = 3,
.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,
2017-10-20 19:24:46 +02:00
.oam = &sUnknown_0832C138,
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,
2017-10-20 19:24:46 +02:00
.oam = &sUnknown_0832C138,
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,
2017-10-20 19:24:46 +02:00
.oam = &sUnknown_0832C138,
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,
2017-10-20 19:24:46 +02:00
.oam = &sUnknown_0832C138,
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,
2017-10-20 19:24:46 +02:00
.oam = &sUnknown_0832C138,
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,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 1,
.x = 0,
.matrixNum = 0,
.size = 1,
.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
}
};
2017-10-19 18:25:48 +02:00
static const struct Subsprite sUnknown_0832C220[] =
2017-10-19 15:28:41 +02:00
{
{240, 0, 1, 3, 0, 1},
{48, 0, 0, 2, 32, 1},
{240, 32, 1, 1, 48, 1},
{16, 32, 1, 1, 52, 1},
{48, 32, 1, 1, 56, 1}
};
2017-10-19 18:25:48 +02:00
static const struct Subsprite sUnknown_0832C234[] =
2017-10-19 15:28:41 +02:00
{
{240, 0, 1, 3, 64, 1},
{48, 0, 0, 2, 96, 1},
{240, 32, 1, 1, 112, 1},
{16, 32, 1, 1, 116, 1},
{48, 32, 1, 1, 120, 1}
};
2017-10-19 18:25:48 +02:00
static const struct Subsprite sUnknown_0832C248[] =
2017-10-19 15:28:41 +02:00
{
{240, 0, 1, 3, 0, 1},
{48, 0, 0, 2, 32, 1}
};
2017-10-19 18:25:48 +02:00
static const struct Subsprite sUnknown_0832C250[] =
2017-10-19 15:28:41 +02:00
{
{240, 0, 1, 3, 0, 1},
{48, 0, 0, 2, 32, 1}
};
2017-10-19 18:25:48 +02:00
static const struct Subsprite sUnknown_0832C258[] =
2017-10-19 15:28:41 +02:00
{
{240, 0, 1, 1, 0, 1},
{16, 0, 1, 1, 4, 1}
};
2017-10-19 18:25:48 +02:00
static const struct Subsprite sUnknown_0832C260[] =
2017-10-19 15:28:41 +02:00
{
{240, 0, 1, 1, 0, 1},
{16, 0, 1, 1, 4, 1},
{224, 0, 0, 0, 8, 1}
};
2017-10-19 18:25:48 +02:00
// unused subsprite table
static const struct SubspriteTable sUnknown_0832C26C[] =
2017-10-19 15:28:41 +02:00
{
2017-10-19 18:25:48 +02:00
{ARRAY_COUNT(sUnknown_0832C220), sUnknown_0832C220},
{ARRAY_COUNT(sUnknown_0832C248), sUnknown_0832C248},
{ARRAY_COUNT(sUnknown_0832C234), sUnknown_0832C234},
{ARRAY_COUNT(sUnknown_0832C250), sUnknown_0832C250}
2017-10-19 15:28:41 +02:00
};
2017-10-19 18:25:48 +02:00
static const struct SubspriteTable sUnknown_0832C28C[] =
2017-10-19 15:28:41 +02:00
{
2017-10-19 18:25:48 +02:00
{ARRAY_COUNT(sUnknown_0832C258), sUnknown_0832C258},
{ARRAY_COUNT(sUnknown_0832C260), sUnknown_0832C260}
2017-10-19 15:28:41 +02:00
};
2017-10-19 18:25:48 +02:00
static const struct Subsprite sStatusSummaryBar_Subsprites_0[] =
2017-10-19 15:28:41 +02:00
{
{160, 0, 1, 1, 0, 1},
{192, 0, 1, 1, 4, 1},
{224, 0, 1, 1, 8, 1},
{0, 0, 1, 1, 12, 1}
};
2017-10-20 19:24:46 +02:00
static const struct Subsprite sUnknown_0832C2AC[] =
2017-10-19 15:28:41 +02:00
{
{160, 0, 1, 1, 0, 1},
{192, 0, 1, 1, 4, 1},
{224, 0, 1, 1, 8, 1},
{0, 0, 1, 1, 8, 1},
{32, 0, 1, 1, 8, 1},
{64, 0, 1, 1, 12, 1}
};
2017-10-19 18:25:48 +02:00
static const struct SubspriteTable sStatusSummaryBar_SubspriteTable[] =
2017-10-19 15:28:41 +02:00
{
2017-10-19 18:25:48 +02:00
{ARRAY_COUNT(sStatusSummaryBar_Subsprites_0), sStatusSummaryBar_Subsprites_0}
2017-10-19 15:28:41 +02:00
};
2017-10-20 19:24:46 +02:00
static const struct SubspriteTable sUnknown_0832C2CC[] =
2017-10-19 15:28:41 +02:00
{
2017-10-20 19:24:46 +02:00
{ARRAY_COUNT(sUnknown_0832C2AC), sUnknown_0832C2AC}
2017-10-19 15:28:41 +02:00
};
2017-10-20 19:24:46 +02:00
// unused unknown image
static const u8 sUnknown_0832C2D4[] = INCBIN_U8("graphics/battle_interface/unknown_32C2D4.4bpp");
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
{
2017-10-19 18:25:48 +02:00
gBattleInterface_BallDisplayGfx, 0x80, TAG_STATUS_SUMMARY_BALLS_TILE
2017-10-19 15:28:41 +02:00
};
2017-10-19 18:25:48 +02:00
// unused oam data
static const struct OamData sUnknown_0832C354 =
2017-10-19 15:28:41 +02:00
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 1,
.x = 0,
.matrixNum = 0,
.size = 3,
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0,
};
2017-10-20 19:24:46 +02:00
static const struct OamData sOamData_StatusSummaryBalls =
2017-10-19 15:28:41 +02:00
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = 0,
.x = 0,
.matrixNum = 0,
.size = 0,
.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
{
{
2017-10-19 18:25:48 +02:00
.tileTag = TAG_STATUS_SUMMARY_BAR_TILE,
.paletteTag = TAG_STATUS_SUMMARY_BAR_PAL,
2017-10-20 19:24:46 +02:00
.oam = &sUnknown_0832C138,
2017-10-19 15:28:41 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2017-10-19 18:25:48 +02:00
.callback = SpriteCB_StatusSummaryBar
2017-10-19 15:28:41 +02:00
},
{
2017-10-19 18:25:48 +02:00
.tileTag = TAG_STATUS_SUMMARY_BAR_TILE,
.paletteTag = TAG_STATUS_SUMMARY_BAR_PAL,
2017-10-20 19:24:46 +02:00
.oam = &sUnknown_0832C138,
2017-10-19 15:28:41 +02:00
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
2017-10-19 18:25:48 +02:00
.callback = SpriteCB_StatusSummaryBar
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,
2017-10-19 18:25:48 +02:00
.callback = SpriteCB_StatusSummaryBallsOnBattleStart
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,
2017-10-19 18:25:48 +02:00
.callback = SpriteCB_StatusSummaryBallsOnBattleStart
2017-10-19 15:28:41 +02:00
}
};
// possibly text
2017-10-20 19:24:46 +02:00
static const u8 sUnknown_0832C3C4[] =
2017-10-19 15:28:41 +02:00
{
0xfc, 0x01, 0x01, 0xfc, 0x02, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
// possibly text
2017-10-20 19:24:46 +02:00
static const u8 sUnknown_0832C3D8[] =
2017-10-19 15:28:41 +02:00
{
0xfc, 0x01, 0x01, 0xfc, 0x02, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
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-01-29 14:36:13 +01:00
RGB(24, 12, 24), // PAL_STATUS_PSN
RGB(23, 23, 3), // PAL_STATUS_PAR
RGB(20, 20, 17), // PAL_STATUS_SLP
RGB(17, 22, 28), // PAL_STATUS_FRZ
RGB(28, 14, 10) // PAL_STATUS_BRN
2017-10-19 15:28:41 +02:00
};
static const struct WindowTemplate sHealthboxWindowTemplate = {0, 0, 0, 8, 2, 0, 0}; // width = 8, height = 2
// code
static s32 DummiedOutFunction(s16 unused1, s16 unused2, s32 unused3)
2017-10-16 18:12:27 +02:00
{
return 9;
}
#ifdef NONMATCHING
2017-10-19 15:28:41 +02:00
static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2)
2017-10-16 18:12:27 +02:00
{
s8 i, j;
2017-10-19 18:25:48 +02:00
u8 array[4];
u8 *arrayPtr;
s32 r9, vaaa;
2017-10-16 18:12:27 +02:00
for (i = 0; i < 4; i++)
array[i] = 0;
i = 3;
2017-10-19 18:25:48 +02:00
r9 = -1;
arrayPtr = array;
2017-10-16 18:12:27 +02:00
while (1)
{
2017-10-19 18:25:48 +02:00
if (arg0 > 0)
{
array[i] = arg0 % 10;
arg0 = arg0 / 10;
i--;
}
else
{
2017-10-16 18:12:27 +02:00
break;
2017-10-19 18:25:48 +02:00
}
2017-10-16 18:12:27 +02:00
}
2017-10-19 18:25:48 +02:00
for (; i > -1; i--)
2017-10-16 18:12:27 +02:00
{
2017-10-19 18:25:48 +02:00
array[i] = 0xFF;
2017-10-16 18:12:27 +02:00
}
2017-10-19 18:25:48 +02:00
if (arrayPtr[3] == 0xFF)
arrayPtr[3] = 0;
2017-10-16 18:12:27 +02:00
if (arg2 == 0)
{
2017-10-19 18:25:48 +02:00
for (i = 0, j = 0; i < 4; i++)
2017-10-16 18:12:27 +02:00
{
2017-10-19 18:25:48 +02:00
if (array[j] == 0xFF)
2017-10-16 18:12:27 +02:00
{
2017-10-19 18:25:48 +02:00
arg1[j] &= 0xFC00;
arg1[j] |= 0x1E;
2017-10-16 18:12:27 +02:00
arg1[i + 0x20] &= 0xFC00;
arg1[i + 0x20] |= 0x1E;
}
else
{
2017-10-19 18:25:48 +02:00
arg1[j] &= 0xFC00;
arg1[j] |= array[j] + 0x14;
2017-10-16 18:12:27 +02:00
arg1[i + 0x20] &= 0xFC00;
arg1[i + 0x20] |= array[i] + 0x34;
}
2017-10-19 18:25:48 +02:00
j++;
2017-10-16 18:12:27 +02:00
}
}
else
{
for (i = 0; i < 4; i++)
{
2017-10-19 18:25:48 +02:00
if (array[i] == 0xFF)
2017-10-16 18:12:27 +02:00
{
arg1[i] &= 0xFC00;
arg1[i] |= 0x1E;
arg1[i + 0x20] &= 0xFC00;
arg1[i + 0x20] |= 0x1E;
}
else
{
arg1[i] &= 0xFC00;
arg1[i] |= array[i] + 0x14;
arg1[i + 0x20] &= 0xFC00;
arg1[i + 0x20] |= array[i] + 0x34;
}
}
}
}
#else
NAKED
2017-10-19 15:28:41 +02:00
static void sub_8072308(s16 arg0, u16 *arg1, u8 arg2)
2017-10-16 18:12:27 +02:00
{
asm(".syntax unified\n\
push {r4-r7,lr}\n\
mov r7, r10\n\
mov r6, r9\n\
mov r5, r8\n\
push {r5-r7}\n\
sub sp, 0x4\n\
adds r7, r1, 0\n\
lsls r0, 16\n\
lsrs r5, r0, 16\n\
lsls r2, 24\n\
lsrs r2, 24\n\
mov r10, r2\n\
movs r3, 0\n\
movs r2, 0\n\
_08072324:\n\
lsls r0, r3, 24\n\
asrs r0, 24\n\
mov r3, sp\n\
adds r1, r3, r0\n\
strb r2, [r1]\n\
adds r0, 0x1\n\
lsls r0, 24\n\
lsrs r3, r0, 24\n\
asrs r0, 24\n\
cmp r0, 0x3\n\
ble _08072324\n\
movs r3, 0x3\n\
movs r0, 0x1\n\
negs r0, r0\n\
mov r9, r0\n\
mov r8, sp\n\
_08072344:\n\
lsls r0, r5, 16\n\
asrs r6, r0, 16\n\
cmp r6, 0\n\
ble _08072372\n\
lsls r4, r3, 24\n\
asrs r4, 24\n\
mov r1, sp\n\
adds r5, r1, r4\n\
adds r0, r6, 0\n\
movs r1, 0xA\n\
bl __modsi3\n\
strb r0, [r5]\n\
adds r0, r6, 0\n\
movs r1, 0xA\n\
bl __divsi3\n\
lsls r0, 16\n\
lsrs r5, r0, 16\n\
subs r4, 0x1\n\
lsls r4, 24\n\
lsrs r3, r4, 24\n\
b _08072344\n\
_08072372:\n\
lsls r1, r3, 24\n\
asrs r0, r1, 24\n\
cmp r0, r9\n\
ble _08072396\n\
movs r4, 0xFF\n\
movs r3, 0x1\n\
negs r3, r3\n\
_08072380:\n\
asrs r2, r1, 24\n\
mov r5, sp\n\
adds r1, r5, r2\n\
ldrb r0, [r1]\n\
orrs r0, r4\n\
strb r0, [r1]\n\
subs r2, 0x1\n\
lsls r1, r2, 24\n\
asrs r0, r1, 24\n\
cmp r0, r3\n\
bgt _08072380\n\
_08072396:\n\
mov r1, r8\n\
ldrb r0, [r1, 0x3]\n\
cmp r0, 0xFF\n\
bne _080723A2\n\
movs r0, 0\n\
strb r0, [r1, 0x3]\n\
_080723A2:\n\
mov r2, r10\n\
cmp r2, 0\n\
bne _08072432\n\
movs r3, 0\n\
movs r1, 0\n\
movs r6, 0xFC\n\
lsls r6, 8\n\
movs r5, 0x1E\n\
mov r12, r5\n\
_080723B4:\n\
lsls r1, 24\n\
asrs r2, r1, 24\n\
mov r0, sp\n\
adds r5, r0, r2\n\
ldrb r0, [r5]\n\
mov r8, r1\n\
cmp r0, 0xFF\n\
bne _080723EA\n\
lsls r1, r2, 1\n\
adds r1, r7\n\
ldrh r2, [r1]\n\
adds r0, r6, 0\n\
ands r0, r2\n\
mov r2, r12\n\
orrs r0, r2\n\
strh r0, [r1]\n\
lsls r3, 24\n\
asrs r1, r3, 23\n\
adds r1, r7\n\
adds r1, 0x40\n\
ldrh r2, [r1]\n\
adds r0, r6, 0\n\
ands r0, r2\n\
mov r5, r12\n\
orrs r0, r5\n\
strh r0, [r1]\n\
b _0807241A\n\
_080723EA:\n\
lsls r2, 1\n\
adds r2, r7\n\
ldrh r0, [r2]\n\
adds r1, r6, 0\n\
ands r1, r0\n\
ldrb r0, [r5]\n\
adds r0, 0x14\n\
orrs r1, r0\n\
strh r1, [r2]\n\
lsls r4, r3, 24\n\
asrs r3, r4, 24\n\
lsls r2, r3, 1\n\
adds r2, r7\n\
adds r2, 0x40\n\
ldrh r0, [r2]\n\
adds r1, r6, 0\n\
ands r1, r0\n\
mov r5, sp\n\
adds r0, r5, r3\n\
ldrb r0, [r0]\n\
adds r0, 0x34\n\
orrs r1, r0\n\
strh r1, [r2]\n\
adds r3, r4, 0\n\
_0807241A:\n\
movs r0, 0x80\n\
lsls r0, 17\n\
add r0, r8\n\
lsrs r1, r0, 24\n\
movs r2, 0x80\n\
lsls r2, 17\n\
adds r0, r3, r2\n\
lsrs r3, r0, 24\n\
asrs r0, 24\n\
cmp r0, 0x3\n\
ble _080723B4\n\
b _08072496\n\
_08072432:\n\
movs r3, 0\n\
movs r4, 0xFC\n\
lsls r4, 8\n\
movs r6, 0x1E\n\
_0807243A:\n\
lsls r1, r3, 24\n\
asrs r2, r1, 24\n\
mov r3, sp\n\
adds r5, r3, r2\n\
ldrb r0, [r5]\n\
adds r3, r1, 0\n\
cmp r0, 0xFF\n\
bne _08072466\n\
lsls r1, r2, 1\n\
adds r1, r7\n\
ldrh r2, [r1]\n\
adds r0, r4, 0\n\
ands r0, r2\n\
orrs r0, r6\n\
strh r0, [r1]\n\
adds r1, 0x40\n\
ldrh r2, [r1]\n\
adds r0, r4, 0\n\
ands r0, r2\n\
orrs r0, r6\n\
strh r0, [r1]\n\
b _08072488\n\
_08072466:\n\
lsls r2, 1\n\
adds r2, r7\n\
ldrh r0, [r2]\n\
adds r1, r4, 0\n\
ands r1, r0\n\
ldrb r0, [r5]\n\
adds r0, 0x14\n\
orrs r1, r0\n\
strh r1, [r2]\n\
adds r2, 0x40\n\
ldrh r0, [r2]\n\
adds r1, r4, 0\n\
ands r1, r0\n\
ldrb r0, [r5]\n\
adds r0, 0x34\n\
orrs r1, r0\n\
strh r1, [r2]\n\
_08072488:\n\
movs r5, 0x80\n\
lsls r5, 17\n\
adds r0, r3, r5\n\
lsrs r3, r0, 24\n\
asrs r0, 24\n\
cmp r0, 0x3\n\
ble _0807243A\n\
_08072496:\n\
add sp, 0x4\n\
pop {r3-r5}\n\
mov r8, r3\n\
mov r9, r4\n\
mov r10, r5\n\
pop {r4-r7}\n\
pop {r0}\n\
bx r0\n\
.syntax divided");
}
#endif // NONMATCHING
void sub_80724A8(s16 arg0, s16 arg1, u16 *arg2)
{
arg2[4] = 0x1E;
sub_8072308(arg1, arg2, 0);
sub_8072308(arg0, arg2 + 5, 1);
}
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]
// data fields for healthbar
#define hBar_HealthBoxSpriteId data[5]
#define hBar_Data6 data[6]
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;
u8 healthbarSpriteId;
struct Sprite *healthBarSpritePtr;
2017-10-16 18:12:27 +02:00
if (!IsDoubleBattle())
{
2018-06-19 00:43:15 +02:00
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
2017-10-16 18:12:27 +02:00
{
2018-06-19 00:43:15 +02:00
healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1);
healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[0], 240, 160, 1);
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites[healthboxLeftSpriteId].oam.shape = 0;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites[healthboxRightSpriteId].oam.shape = 0;
gSprites[healthboxRightSpriteId].oam.tileNum += 64;
2017-10-16 18:12:27 +02:00
}
else
{
2018-06-19 00:43:15 +02:00
healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 1);
healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[0], 240, 160, 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
{
2018-06-19 00:43:15 +02:00
healthboxLeftSpriteId = CreateSprite(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 1);
healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxPlayerSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 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
{
2018-06-19 00:43:15 +02:00
healthboxLeftSpriteId = CreateSprite(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 1);
healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxOpponentSpriteTemplates[GetBattlerPosition(battlerId) / 2], 240, 160, 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];
SetSubspriteTables(healthBarSpritePtr, &sUnknown_0832C28C[GetBattlerSide(battlerId)]);
healthBarSpritePtr->subspriteMode = 2;
healthBarSpritePtr->oam.priority = 1;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_1), (void*)(OBJ_VRAM0 + healthBarSpritePtr->oam.tileNum * 32), 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;
gSprites[healthboxLeftSpriteId].invisible = TRUE;
2017-10-16 18:12:27 +02:00
gSprites[healthboxRightSpriteId].invisible = TRUE;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
healthBarSpritePtr->hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
healthBarSpritePtr->hBar_Data6 = data6;
healthBarSpritePtr->invisible = TRUE;
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
}
u8 CreateSafariPlayerHealthboxSprites(void)
{
2018-06-19 00:43:15 +02:00
u8 healthboxLeftSpriteId, healthboxRightSpriteId;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
healthboxLeftSpriteId = CreateSprite(&sHealthboxSafariSpriteTemplate, 240, 160, 1);
healthboxRightSpriteId = CreateSpriteAtEnd(&sHealthboxSafariSpriteTemplate, 240, 160, 1);
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
gSprites[healthboxLeftSpriteId].oam.shape = 0;
gSprites[healthboxRightSpriteId].oam.shape = 0;
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
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:
2018-06-19 00:43:15 +02:00
sprite->pos1.x = gSprites[healthboxSpriteId].pos1.x + 16;
sprite->pos1.y = gSprites[healthboxSpriteId].pos1.y;
2017-10-16 18:12:27 +02:00
break;
case 1:
2018-06-19 00:43:15 +02:00
sprite->pos1.x = gSprites[healthboxSpriteId].pos1.x + 16;
sprite->pos1.y = gSprites[healthboxSpriteId].pos1.y;
2017-10-16 18:12:27 +02:00
break;
case 2:
default:
2018-06-19 00:43:15 +02:00
sprite->pos1.x = gSprites[healthboxSpriteId].pos1.x + 8;
sprite->pos1.y = gSprites[healthboxSpriteId].pos1.y;
2017-10-16 18:12:27 +02:00
break;
}
2018-06-19 00:43:15 +02:00
sprite->pos2.x = gSprites[healthboxSpriteId].pos2.x;
sprite->pos2.y = gSprites[healthboxSpriteId].pos2.y;
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;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
sprite->pos1.x = gSprites[healthboxMainSpriteId].pos1.x + 64;
sprite->pos1.y = gSprites[healthboxMainSpriteId].pos1.y;
2017-10-16 18:12:27 +02:00
2018-06-19 00:43:15 +02:00
sprite->pos2.x = gSprites[healthboxMainSpriteId].pos2.x;
sprite->pos2.y = gSprites[healthboxMainSpriteId].pos2.y;
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)
{
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)
{
gSprites[healthboxSpriteId].invisible = FALSE;
gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = FALSE;
gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = FALSE;
2017-10-18 00:00:46 +02:00
}
static void UpdateSpritePos(u8 spriteId, s16 x, s16 y)
{
gSprites[spriteId].pos1.x = x;
gSprites[spriteId].pos1.y = y;
}
void DestoryHealthboxSprite(u8 healthboxSpriteId)
{
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
{
}
void UpdateOamPriorityInAllHealthboxes(u8 priority)
{
s32 i;
2018-02-06 02:46:59 +01: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;
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;
2017-10-18 00:00:46 +02:00
}
}
2018-02-06 23:09:39 +01:00
void InitBattlerHealthboxCoords(u8 battler)
2017-10-18 00:00:46 +02:00
{
s16 x = 0, y = 0;
if (!IsDoubleBattle())
{
2018-02-06 23:09:39 +01:00
if (GetBattlerSide(battler) != B_SIDE_PLAYER)
2017-10-18 00:00:46 +02:00
x = 44, y = 30;
else
x = 158, y = 88;
}
else
{
2018-02-06 23:09:39 +01:00
switch (GetBattlerPosition(battler))
2017-10-18 00:00:46 +02:00
{
2018-01-16 21:01:31 +01:00
case B_POSITION_PLAYER_LEFT:
2017-10-18 00:00:46 +02:00
x = 159, y = 76;
break;
2018-01-16 21:01:31 +01:00
case B_POSITION_PLAYER_RIGHT:
2017-10-18 00:00:46 +02:00
x = 171, y = 101;
break;
2018-01-16 21:01:31 +01:00
case B_POSITION_OPPONENT_LEFT:
2017-10-18 00:00:46 +02:00
x = 44, y = 19;
break;
2018-01-16 21:01:31 +01:00
case B_POSITION_OPPONENT_RIGHT:
2017-10-18 00:00:46 +02:00
x = 32, y = 44;
break;
}
}
2018-02-06 23:09:39 +01: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];
u32 xPos, var1;
void *objVram;
text[0] = 0xF9;
text[1] = 5;
xPos = (u32) ConvertIntToDecimalStringN(text + 2, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
// Alright, that part was unmatchable. It's basically doing:
// xPos = 5 * (3 - (u32)(&text[2]));
xPos--;
xPos--;
xPos -= ((u32)(text));
var1 = (3 - xPos);
xPos = 4 * var1;
xPos += var1;
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, xPos, 3, 2, &windowId);
spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * 32;
2018-06-19 00:43:15 +02:00
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
2017-10-18 00:00:46 +02:00
{
objVram = (void*)(OBJ_VRAM0);
if (!IsDoubleBattle())
objVram += spriteTileNum + 0x820;
else
objVram += spriteTileNum + 0x420;
}
else
{
objVram = (void*)(OBJ_VRAM0);
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
}
void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
{
2017-10-19 15:28:41 +02:00
u32 windowId, spriteTileNum;
u8 *windowTileData;
2017-10-18 00:00:46 +02:00
u8 text[32];
void *objVram;
2018-06-19 00:43:15 +02:00
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER && !IsDoubleBattle())
2017-10-18 00:00:46 +02:00
{
spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * 32;
2017-10-19 18:25:48 +02:00
if (maxOrCurrent != HP_CURRENT) // singles, max
2017-10-18 00:00:46 +02:00
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, 2, &windowId);
objVram = (void*)(OBJ_VRAM0);
objVram += spriteTileNum + 0xB40;
2018-06-19 00:43:15 +02:00
HpTextIntoHealthboxObject(objVram, windowTileData, 2);
2017-10-18 23:05:14 +02:00
RemoveWindowOnHealthbox(windowId);
2017-10-18 00:00:46 +02:00
}
else // singles, current
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
text[3] = CHAR_SLASH;
text[4] = EOS;
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 4, 5, 2, &windowId);
objVram = (void*)(OBJ_VRAM0);
objVram += spriteTileNum + 0x3E0;
2018-06-19 00:43:15 +02:00
HpTextIntoHealthboxObject(objVram, windowTileData, 1);
2017-10-18 00:00:46 +02:00
objVram = (void*)(OBJ_VRAM0);
objVram += spriteTileNum + 0xB00;
2018-06-19 00:43:15 +02:00
HpTextIntoHealthboxObject(objVram, windowTileData + 0x20, 2);
2017-10-18 23:05:14 +02:00
RemoveWindowOnHealthbox(windowId);
2017-10-18 00:00:46 +02:00
}
}
else
{
2018-02-06 23:09:39 +01:00
u8 battler;
2017-10-18 00:00:46 +02:00
2017-10-20 19:24:46 +02:00
memcpy(text, sUnknown_0832C3C4, sizeof(sUnknown_0832C3C4));
2018-06-19 00:43:15 +02:00
battler = gSprites[healthboxSpriteId].hMain_Battler;
2018-02-06 23:09:39 +01:00
if (IsDoubleBattle() == TRUE || GetBattlerSide(battler) == B_SIDE_OPPONENT)
2017-10-18 00:00:46 +02:00
{
UpdateHpTextInHealthboxInDoubles(healthboxSpriteId, value, maxOrCurrent);
}
else
{
u32 var;
u8 i;
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER)
2017-10-18 00:00:46 +02:00
{
2017-10-19 18:25:48 +02:00
if (maxOrCurrent == HP_CURRENT)
2017-10-18 00:00:46 +02:00
var = 29;
else
var = 89;
}
else
{
2017-10-19 18:25:48 +02:00
if (maxOrCurrent == HP_CURRENT)
2017-10-18 00:00:46 +02:00
var = 20;
else
var = 48;
}
ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
2017-11-04 16:25:19 +01:00
RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 9, text);
2017-10-18 00:00:46 +02:00
for (i = 0; i < 3; i++)
{
2017-11-04 16:25:19 +01:00
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[i * 64 + 32],
2017-10-18 00:00:46 +02:00
(void*)((OBJ_VRAM0) + 32 * (gSprites[healthboxSpriteId].oam.tileNum + var + i)),
0x20);
}
}
}
}
2017-10-19 15:28:41 +02:00
static void UpdateHpTextInHealthboxInDoubles(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent)
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[32];
void *objVram;
2018-06-19 00:43:15 +02:00
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
2017-10-18 00:00:46 +02:00
{
2018-02-06 23:09:39 +01:00
if (gBattleSpritesDataPtr->battlerData[gSprites[healthboxSpriteId].data[6]].hpNumbersNoBars) // don't print text if only bars are visible
2017-10-18 00:00:46 +02:00
{
2017-12-02 21:44:50 +01:00
spriteTileNum = gSprites[gSprites[healthboxSpriteId].data[5]].oam.tileNum * 32;
2017-10-18 00:00:46 +02:00
objVram = (void*)(OBJ_VRAM0) + spriteTileNum;
2017-10-19 18:25:48 +02:00
if (maxOrCurrent != HP_CURRENT) // doubles, max hp
2017-10-18 00:00:46 +02:00
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 0, 5, 0, &windowId);
2018-06-19 00:43:15 +02:00
HpTextIntoHealthboxObject((void*)(OBJ_VRAM0) + spriteTileNum + 0xC0, windowTileData, 2);
2017-10-18 23:05:14 +02:00
RemoveWindowOnHealthbox(windowId);
2017-10-19 18:25:48 +02:00
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_116),
2017-10-18 00:00:46 +02:00
(void*)(OBJ_VRAM0 + 0x680) + (gSprites[healthboxSpriteId].oam.tileNum * 32),
0x20);
}
else
{
ConvertIntToDecimalStringN(text, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
text[3] = CHAR_SLASH;
text[4] = EOS;
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, 4, 5, 0, &windowId);
2018-06-19 00:43:15 +02:00
FillHealthboxObject(objVram, 0, 3); // Erases HP bar leftover.
HpTextIntoHealthboxObject((void*)(OBJ_VRAM0 + 0x60) + spriteTileNum, windowTileData, 3);
2017-10-18 23:05:14 +02:00
RemoveWindowOnHealthbox(windowId);
2017-10-18 00:00:46 +02:00
}
}
}
else
{
2018-03-01 00:59:52 +01:00
u8 battlerId;
2017-10-18 00:00:46 +02:00
2017-10-20 19:24:46 +02:00
memcpy(text, sUnknown_0832C3D8, sizeof(sUnknown_0832C3D8));
2018-06-19 00:43:15 +02:00
battlerId = gSprites[healthboxSpriteId].hMain_Battler;
2017-10-18 00:00:46 +02:00
2018-03-01 00:59:52 +01:00
if (gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars) // don't print text if only bars are visible
2017-10-18 00:00:46 +02:00
{
u8 var = 4;
u8 r7;
u8 *txtPtr;
u8 i;
2017-10-19 18:25:48 +02:00
if (maxOrCurrent == HP_CURRENT)
2017-10-18 00:00:46 +02:00
var = 0;
2017-12-02 21:44:50 +01:00
r7 = gSprites[healthboxSpriteId].data[5];
2017-10-18 00:00:46 +02:00
txtPtr = ConvertIntToDecimalStringN(text + 6, value, STR_CONV_MODE_RIGHT_ALIGN, 3);
if (!maxOrCurrent)
StringCopy(txtPtr, gText_Slash);
2017-11-04 16:25:19 +01:00
RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 9, text);
2017-10-18 00:00:46 +02:00
for (i = var; i < var + 3; i++)
{
if (i < 3)
{
2017-11-04 16:25:19 +01:00
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
2017-10-18 00:00:46 +02:00
(void*)((OBJ_VRAM0) + 32 * (1 + gSprites[r7].oam.tileNum + i)),
0x20);
}
else
{
2017-11-04 16:25:19 +01:00
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[((i - var) * 64) + 32],
2017-10-18 00:00:46 +02:00
(void*)((OBJ_VRAM0 + 0x20) + 32 * (i + gSprites[r7].oam.tileNum)),
0x20);
}
}
2017-10-19 18:25:48 +02:00
if (maxOrCurrent == HP_CURRENT)
2017-10-18 00:00:46 +02:00
{
2017-11-04 16:25:19 +01:00
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[224],
2017-10-18 00:00:46 +02:00
(void*)((OBJ_VRAM0) + ((gSprites[r7].oam.tileNum + 4) * 32)),
0x20);
CpuFill32(0, (void*)((OBJ_VRAM0) + (gSprites[r7].oam.tileNum * 32)), 0x20);
}
else
{
2018-06-19 00:43:15 +02:00
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER) // Impossible to reach part, because the battlerId is from the opponent's side.
2017-10-18 00:00:46 +02:00
{
2017-10-19 18:25:48 +02:00
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_116),
2017-10-18 00:00:46 +02:00
(void*)(OBJ_VRAM0) + ((gSprites[healthboxSpriteId].oam.tileNum + 52) * 32),
0x20);
}
}
}
}
}
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];
s32 j, var2;
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
2017-10-20 19:24:46 +02:00
memcpy(text, sUnknown_0832C3C4, sizeof(sUnknown_0832C3C4));
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);
StringCopy(text + 6, gNatureNamePointers[nature]);
2017-11-04 16:25:19 +01:00
RenderTextFont9(barFontGfx, 9, 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++)
{
var2 = (gSprites[healthboxSpriteId].oam.tileNum + (j - (j / 8 * 8)) + (j / 8 * 64)) * 32;
2017-11-04 16:25:19 +01:00
CpuCopy32(barFontGfx, (void*)(OBJ_VRAM0) + (var2), 0x20);
barFontGfx += 0x20;
2017-10-18 21:42:00 +02:00
var2 = (8 + gSprites[healthboxSpriteId].oam.tileNum + (j - (j / 8 * 8)) + (j / 8 * 64)) * 32;
2017-11-04 16:25:19 +01:00
CpuCopy32(barFontGfx, (void*)(OBJ_VRAM0) + (var2), 0x20);
barFontGfx += 0x20;
2017-10-18 21:42:00 +02:00
}
2018-06-19 00:43:15 +02:00
healthBarSpriteId = gSprites[healthboxSpriteId].hMain_HealthBarSpriteId;
2018-07-01 11:15:42 +02: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;
2017-11-04 16:25:19 +01:00
RenderTextFont9(gMonSpritesGfxPtr->barFontGfx, 9, 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],
2018-06-19 00:43:15 +02:00
(void*)(OBJ_VRAM0) + (gSprites[healthBarSpriteId].oam.tileNum + 2 + j) * 32,
2017-10-18 21:42:00 +02:00
32);
}
else
{
2017-11-04 16:25:19 +01:00
CpuCopy32(&gMonSpritesGfxPtr->barFontGfx[0x40 * j + 0x20],
2018-06-19 00:43:15 +02:00
(void*)(OBJ_VRAM0 + 0xC0) + (j + gSprites[healthBarSpriteId].oam.tileNum) * 32,
2017-10-18 21:42:00 +02:00
32);
}
}
}
void SwapHpBarsWithHpText(void)
{
s32 i;
2018-06-19 00:43:15 +02:00
u8 healthBarSpriteId;
2017-10-18 21:42:00 +02:00
2018-02-06 02:46:59 +01:00
for (i = 0; i < gBattlersCount; i++)
2017-10-18 21:42:00 +02:00
{
2018-02-06 20:48:02 +01:00
if (gSprites[gHealthboxSpriteIds[i]].callback == SpriteCallbackDummy
2018-02-06 02:46:59 +01:00
&& GetBattlerSide(i) != B_SIDE_OPPONENT
&& (IsDoubleBattle() || GetBattlerSide(i) != B_SIDE_PLAYER))
2017-10-18 21:42:00 +02:00
{
bool8 noBars;
2018-02-06 23:09:39 +01:00
gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars ^= 1;
noBars = gBattleSpritesDataPtr->battlerData[i].hpNumbersNoBars;
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(i) == B_SIDE_PLAYER)
2017-10-18 21:42:00 +02:00
{
if (!IsDoubleBattle())
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
2018-06-19 00:43:15 +02:00
CpuFill32(0, (void*)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 0x100);
2018-02-06 20:48:02 +01:00
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gPlayerParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX);
2017-10-18 21:42:00 +02:00
}
else // text to bars
{
2018-02-06 20:48:02 +01:00
UpdateStatusIconInHealthbox(gHealthboxSpriteIds[i]);
UpdateHealthboxAttribute(gHealthboxSpriteIds[i], &gPlayerParty[gBattlerPartyIndexes[i]], HEALTHBOX_HEALTH_BAR);
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_117), (void*)(OBJ_VRAM0 + 0x680 + gSprites[gHealthboxSpriteIds[i]].oam.tileNum * 32), 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);
2018-02-06 20:48:02 +01:00
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_HP), HP_CURRENT);
UpdateHpTextInHealthboxInDoubles(gHealthboxSpriteIds[i], GetMonData(&gEnemyParty[gBattlerPartyIndexes[i]], MON_DATA_MAX_HP), HP_MAX);
2017-10-18 21:42:00 +02:00
}
}
else // text to bars
{
2018-02-06 20:48:02 +01: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 20:48:02 +01: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-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]
#define tData15 data[15]
2018-03-01 00:59:52 +01:00
u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, u8 arg2, 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;
2018-03-01 00:59:52 +01:00
if (!arg2 || 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;
if (!arg2 || !IsDoubleBattle())
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;
}
2017-10-19 18:25:48 +02:00
LoadCompressedObjectPicUsingHeap(&sStatusSummaryBarSpriteSheet);
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);
SetSubspriteTables(&gSprites[summaryBarSpriteId], sStatusSummaryBar_SubspriteTable);
gSprites[summaryBarSpriteId].pos2.x = bar_pos2_X;
gSprites[summaryBarSpriteId].data[0] = bar_data0;
2017-10-18 21:42:00 +02:00
if (isOpponent)
{
2018-06-20 23:07:51 +02:00
gSprites[summaryBarSpriteId].pos1.x -= 96;
gSprites[summaryBarSpriteId].oam.matrixNum = 8;
2017-10-18 21:42:00 +02:00
}
else
{
2018-06-20 23:07:51 +02:00
gSprites[summaryBarSpriteId].pos1.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)
2017-10-19 18:25:48 +02:00
gSprites[ballIconSpritesIds[i]].callback = SpriteCB_StatusSummaryBallsOnSwitchout;
2017-10-18 21:42:00 +02:00
if (!isOpponent)
{
gSprites[ballIconSpritesIds[i]].pos2.x = 0;
gSprites[ballIconSpritesIds[i]].pos2.y = 0;
}
2018-06-20 23:07:51 +02:00
gSprites[ballIconSpritesIds[i]].data[0] = summaryBarSpriteId;
2017-10-18 21:42:00 +02:00
if (!isOpponent)
{
gSprites[ballIconSpritesIds[i]].pos1.x += 10 * i + 24;
2017-12-02 21:44:50 +01:00
gSprites[ballIconSpritesIds[i]].data[1] = i * 7 + 10;
2017-10-18 21:42:00 +02:00
gSprites[ballIconSpritesIds[i]].pos2.x = 120;
}
else
{
gSprites[ballIconSpritesIds[i]].pos1.x -= 10 * (5 - i) + 24;
2017-12-02 21:44:50 +01:00
gSprites[ballIconSpritesIds[i]].data[1] = (6 - i) * 7 + 10;
2017-10-18 21:42:00 +02:00
gSprites[ballIconSpritesIds[i]].pos2.x = -120;
}
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
{
if (partyInfo[i].hp == 0xFFFF) // empty slot or an egg
{
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
}
else if (partyInfo[i].hp == 0) // fainted mon
{
gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
}
else if (partyInfo[i].status != 0) // mon with major status
{
gSprites[ballIconSpritesIds[i]].oam.tileNum += 2;
}
}
}
else
{
2018-06-19 00:43:15 +02:00
for (i = 0, var = 5, j = 0; j < PARTY_SIZE; j++)
2017-10-18 21:42:00 +02:00
{
if (partyInfo[j].hp == 0xFFFF) // empty slot or an egg
{
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;
}
else if (partyInfo[j].hp == 0) // fainted mon
{
gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
}
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->field_2A0 & gBitTable[j]) // hmm...?
{
gSprites[ballIconSpritesIds[i]].oam.tileNum += 3;
}
else if (partyInfo[j].status != 0) // mon with major status
{
gSprites[ballIconSpritesIds[i]].oam.tileNum += 2;
}
i++;
}
}
}
else
{
if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS))
{
2018-06-19 00:43:15 +02:00
for (var = 5, i = 0; i < PARTY_SIZE; i++)
2017-10-18 21:42:00 +02:00
{
if (partyInfo[i].hp == 0xFFFF) // empty slot or an egg
{
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
}
else if (partyInfo[i].hp == 0) // fainted mon
{
gSprites[ballIconSpritesIds[var]].oam.tileNum += 3;
}
else if (partyInfo[i].status != 0) // mon with major status
{
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
{
if (partyInfo[j].hp == 0xFFFF) // empty slot or an egg
{
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;
}
else if (partyInfo[j].hp == 0) // fainted mon
{
gSprites[ballIconSpritesIds[5 - var]].oam.tileNum += 3;
}
else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->field_2A1 & gBitTable[j]) // hmm...?
{
gSprites[ballIconSpritesIds[5 - var]].oam.tileNum += 3;
}
else if (partyInfo[j].status != 0) // mon with major status
{
gSprites[ballIconSpritesIds[5 - var]].oam.tileNum += 2;
}
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++;
}
PlaySE12WithPanning(SE_TB_START, 0);
return taskId;
}
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
2018-06-20 23:07:51 +02:00
gTasks[taskId].tData15 = 16;
2017-10-18 21:42:00 +02:00
2018-06-20 23:07:51 +02:00
for (i = 0; i < PARTY_SIZE; i++)
gSprites[ballIconSpriteIds[i]].oam.objMode = 1;
2017-10-18 21:42:00 +02:00
2018-06-19 00:43:15 +02:00
gSprites[summaryBarSpriteId].oam.objMode = 1;
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
{
2018-06-20 23:07:51 +02:00
gSprites[ballIconSpriteIds[5 - i]].data[1] = 7 * i;
gSprites[ballIconSpriteIds[5 - i]].data[3] = 0;
gSprites[ballIconSpriteIds[5 - i]].data[4] = 0;
gSprites[ballIconSpriteIds[5 - i]].callback = sub_8074158;
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;
gSprites[ballIconSpriteIds[i]].callback = sub_8074158;
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;
gSprites[summaryBarSpriteId].callback = sub_8074090;
SetSubspriteTables(&gSprites[summaryBarSpriteId], sUnknown_0832C2CC);
2017-10-18 21:42:00 +02:00
gTasks[taskId].func = sub_8073E08;
}
else
{
gTasks[taskId].func = sub_8073F98;
}
}
2017-10-19 15:28:41 +02:00
static void sub_8073E08(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
{
2018-06-28 21:06:32 +02:00
if (--gTasks[taskId].tData15 < 0)
2017-10-18 21:42:00 +02:00
return;
SetGpuReg(REG_OFFSET_BLDALPHA, (gTasks[taskId].data[15]) | ((16 - gTasks[taskId].data[15]) << 8));
}
2018-06-28 21:06:32 +02:00
if (gTasks[taskId].tData15 == 0)
2017-10-18 21:42:00 +02:00
gTasks[taskId].func = sub_8073E64;
}
2017-10-19 15:28:41 +02:00
static void sub_8073E64(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;
if (--gTasks[taskId].tData15 == -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
}
2018-06-20 23:07:51 +02:00
else if (gTasks[taskId].tData15 == -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);
}
}
2017-10-19 15:28:41 +02:00
static void sub_8073F98(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
2018-06-20 23:07:51 +02:00
if (--gTasks[taskId].tData15 >= 0)
2017-10-18 21:42:00 +02:00
{
2018-06-20 23:07:51 +02:00
SetGpuReg(REG_OFFSET_BLDALPHA, (gTasks[taskId].tData15) | ((16 - gTasks[taskId].tData15) << 8));
2017-10-18 21:42:00 +02:00
}
2018-06-20 23:07:51 +02:00
else if (gTasks[taskId].tData15 == -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
}
2018-06-20 23:07:51 +02:00
else if (gTasks[taskId].tData15 == -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
#undef tData15
2017-10-19 18:25:48 +02:00
static void SpriteCB_StatusSummaryBar(struct Sprite *sprite)
2017-10-18 21:42:00 +02:00
{
if (sprite->pos2.x != 0)
2017-12-02 21:44:50 +01:00
sprite->pos2.x += sprite->data[0];
2017-10-18 21:42:00 +02:00
}
2017-10-19 15:28:41 +02:00
static void sub_8074090(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)
sprite->pos2.x += sprite->data[1] >> 4;
2017-10-18 21:42:00 +02:00
else
2017-12-02 21:44:50 +01:00
sprite->pos2.x -= sprite->data[1] >> 4;
sprite->data[1] &= 0xF;
2017-10-18 21:42:00 +02:00
}
2017-10-19 18:25:48 +02:00
static void SpriteCB_StatusSummaryBallsOnBattleStart(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)
{
sprite->pos2.x += var2 >> 4;
if (sprite->pos2.x > 0)
sprite->pos2.x = 0;
}
else
{
sprite->pos2.x -= var2 >> 4;
if (sprite->pos2.x < 0)
sprite->pos2.x = 0;
}
2017-10-19 18:25:48 +02:00
2017-10-18 21:42:00 +02:00
if (sprite->pos2.x == 0)
{
2017-10-20 19:24:46 +02:00
pan = PAN_SIDE_OPPONENT;
2017-10-18 21:42:00 +02:00
if (var1 != 0)
2017-10-20 19:24:46 +02:00
pan = PAN_SIDE_PLAYER;
2017-10-19 18:25:48 +02:00
2017-12-02 21:44:50 +01:00
if (sprite->data[7] != 0)
2017-10-18 21:42:00 +02:00
PlaySE2WithPanning(SE_TB_KARA, pan);
else
PlaySE1WithPanning(SE_TB_KON, pan);
2017-10-19 18:25:48 +02:00
2017-10-18 21:42:00 +02:00
sprite->callback = SpriteCallbackDummy;
}
}
2017-10-19 15:28:41 +02:00
static void sub_8074158(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)
sprite->pos2.x += var2 >> 4;
else
sprite->pos2.x -= var2 >> 4;
if (sprite->pos2.x + sprite->pos1.x > 248
|| sprite->pos2.x + sprite->pos1.x < -8)
{
sprite->invisible = TRUE;
sprite->callback = SpriteCallbackDummy;
}
}
2017-10-19 18:25:48 +02:00
static void SpriteCB_StatusSummaryBallsOnSwitchout(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
sprite->pos2.x = gSprites[barSpriteId].pos2.x;
sprite->pos2.y = gSprites[barSpriteId].pos2.y;
}
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;
const u8 *genderTxt;
2017-10-19 15:28:41 +02:00
u32 windowId, spriteTileNum;
u8 *windowTileData;
2017-10-18 21:42:00 +02:00
u16 species;
u8 gender;
StringCopy(gDisplayedStringBattle, gText_HighlightDarkGrey);
GetMonData(mon, MON_DATA_NICKNAME, nickname);
StringGetEnd10(nickname);
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:
StringCopy(ptr, gText_DynColor2);
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(gDisplayedStringBattle, 0, 3, 2, &windowId);
break;
case MON_MALE:
StringCopy(ptr, gText_DynColor2Male);
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(gDisplayedStringBattle, 0, 3, 2, &windowId);
break;
case MON_FEMALE:
StringCopy(ptr, gText_DynColor1Female);
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(gDisplayedStringBattle, 0, 3, 2, &windowId);
break;
}
spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * 32;
2018-02-06 02:46:59 +01:00
if (GetBattlerSide(gSprites[healthboxSpriteId].data[6]) == B_SIDE_PLAYER)
2017-10-18 21:42:00 +02:00
{
2018-06-19 00:43:15 +02:00
TextIntoHealthboxObject((void*)(VRAM + 0x10040 + spriteTileNum), windowTileData, 6);
2017-10-18 21:42:00 +02:00
ptr = (void*)(OBJ_VRAM0);
if (!IsDoubleBattle())
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
{
2018-06-19 00:43:15 +02:00
TextIntoHealthboxObject((void*)(VRAM + 0x10020 + 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)
2018-06-19 00:43:15 +02:00
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_70), (void*)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * 32), 32);
2017-10-18 23:05:14 +02:00
else
2018-06-19 00:43:15 +02:00
CpuFill32(0, (void*)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 8) * 32), 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);
2017-10-18 23:05:14 +02:00
if (!IsDoubleBattle())
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 22:12:38 +01: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 22:12:38 +01: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 22:12:38 +01: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 22:12:38 +01: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 22:12:38 +01: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++)
CpuCopy32(statusGfxPtr, (void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder + i) * 32), 32);
2018-03-01 00:59:52 +01:00
if (!gBattleSpritesDataPtr->battlerData[battlerId].hpNumbersNoBars)
2018-06-19 00:43:15 +02:00
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_1), (void *)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 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);
2017-10-18 23:05:14 +02:00
CpuCopy16(gPlttBufferUnfaded + 0x100 + pltAdder, (void*)(OBJ_PLTT + pltAdder * 2), 2);
CpuCopy32(statusGfxPtr, (void*)(OBJ_VRAM0 + (gSprites[healthboxSpriteId].oam.tileNum + tileNumAdder) * 32), 96);
2018-03-01 00:59:52 +01:00
if (IsDoubleBattle() == TRUE || 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
{
2018-06-19 00:43:15 +02:00
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_0), (void*)(OBJ_VRAM0 + gSprites[healthBarSpriteId].oam.tileNum * 32), 32);
CpuCopy32(GetHealthboxElementGfxPtr(HEALTHBOX_GFX_65), (void*)(OBJ_VRAM0 + (gSprites[healthBarSpriteId].oam.tileNum + 1) * 32), 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);
spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * 32;
2018-06-19 00:43:15 +02: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
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, GetStringRightAlignXOffset(0, text, 0x2F), 3, 2, &windowId);
spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * 32;
2018-06-19 00:43:15 +02: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)
{
2017-10-19 15:28:41 +02:00
s32 maxHp, currHp;
2018-06-19 00:43:15 +02:00
u8 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
2017-10-18 23:52:21 +02:00
if (elementId == HEALTHBOX_ALL && !IsDoubleBattle())
2018-06-19 00:43:15 +02:00
GetBattlerSide(battlerId); // Pointless function call.
2017-10-18 23:52:21 +02:00
2018-06-19 00:43:15 +02:00
if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER)
2017-10-18 23:52:21 +02:00
{
u8 isDoubles;
if (elementId == HEALTHBOX_LEVEL || elementId == HEALTHBOX_ALL)
UpdateLvlInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_LEVEL));
if (elementId == HEALTHBOX_CURRENT_HP || elementId == HEALTHBOX_ALL)
2017-10-19 18:25:48 +02:00
UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_HP), HP_CURRENT);
2017-10-18 23:52:21 +02:00
if (elementId == HEALTHBOX_MAX_HP || elementId == HEALTHBOX_ALL)
2017-10-19 18:25:48 +02:00
UpdateHpTextInHealthbox(healthboxSpriteId, GetMonData(mon, MON_DATA_MAX_HP), HP_MAX);
2017-10-18 23:52:21 +02:00
if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL)
{
LoadBattleBarGfx(0);
maxHp = GetMonData(mon, MON_DATA_MAX_HP);
currHp = GetMonData(mon, MON_DATA_HP);
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
}
isDoubles = IsDoubleBattle();
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));
if (elementId == HEALTHBOX_HEALTH_BAR || elementId == HEALTHBOX_ALL)
{
LoadBattleBarGfx(0);
maxHp = GetMonData(mon, MON_DATA_MAX_HP);
currHp = GetMonData(mon, MON_DATA_HP);
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,
2018-06-20 23:07:51 +02:00
B_HEALTHBAR_PIXELS / 8, 1);
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-06-19 00:43:15 +02:00
if (currentBarValue == -1)
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,
2018-06-19 00:43:15 +02:00
(void*)(OBJ_VRAM0 + (gSprites[healthbarSpriteId].oam.tileNum + 2 + i) * 32), 32);
2017-10-19 15:28:41 +02:00
else
CpuCopy32(GetHealthboxElementGfxPtr(barElementId) + array[i] * 32,
2018-06-19 00:43:15 +02:00
(void*)(OBJ_VRAM0 + 64 + (i + gSprites[healthbarSpriteId].oam.tileNum) * 32), 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);
2017-10-19 15:28:41 +02:00
if (level == MAX_MON_LEVEL)
{
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,
2018-03-01 00:59:52 +01:00
(void*)(OBJ_VRAM0 + (gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum + 0x24 + i) * 32), 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,
2018-03-01 00:59:52 +01:00
(void*)(OBJ_VRAM0 + 0xB80 + (i + gSprites[gBattleSpritesDataPtr->battleBars[battlerId].healthboxSpriteId].oam.tileNum) * 32), 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)
2017-10-19 15:28:41 +02:00
return -1;
}
else
{
2018-06-19 00:43:15 +02:00
if (newValue == *currValue) // we're done, the bar's value has been updated
2017-10-19 15:28:41 +02:00
return -1;
}
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-06-19 00:43:15 +02: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;
}
2018-06-19 00:43:15 +02:00
static u8 CalcBarFilledPixels(s32 maxValue, s32 oldValue, s32 receivedValue, s32 *currValue, u8 *arg4, 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++)
2017-10-19 15:28:41 +02:00
arg4[i] = 0;
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
{
arg4[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
{
arg4[i] = 8;
}
else
{
2018-06-19 00:43:15 +02:00
arg4[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-20 23:07:51 +02:00
// These two functions seem as if they were made for testing the health bar.
static s16 sub_8074F28(struct TestingBar *barInfo, s32 *currValue, u16 *arg2, s32 arg3)
2017-10-19 15:28:41 +02:00
{
s16 ret, var;
2018-06-19 00:43:15 +02:00
ret = CalcNewBarValue(barInfo->maxValue,
barInfo->oldValue,
2017-10-22 18:43:15 +02:00
barInfo->receivedValue,
2018-06-20 23:07:51 +02:00
currValue, B_HEALTHBAR_PIXELS / 8, 1);
sub_8074F88(barInfo, currValue, arg2);
2017-10-19 15:28:41 +02:00
2018-06-20 23:07:51 +02:00
if (barInfo->maxValue < B_HEALTHBAR_PIXELS)
var = *currValue >> 8;
2017-10-19 15:28:41 +02:00
else
2018-06-20 23:07:51 +02:00
var = *currValue;
2017-10-19 15:28:41 +02:00
DummiedOutFunction(barInfo->maxValue, var, arg3);
return ret;
}
2018-06-20 23:07:51 +02:00
static void sub_8074F88(struct TestingBar *barInfo, s32 *currValue, u16 *arg2)
2017-10-19 15:28:41 +02:00
{
u8 sp8[6];
u16 sp10[6];
u8 i;
2018-06-19 00:43:15 +02:00
CalcBarFilledPixels(barInfo->maxValue, barInfo->oldValue,
2018-06-20 23:07:51 +02:00
barInfo->receivedValue, currValue, sp8, B_HEALTHBAR_PIXELS / 8);
2017-10-19 15:28:41 +02:00
for (i = 0; i < 6; i++)
sp10[i] = (barInfo->unkC_0 << 12) | (barInfo->unk10 + sp8[i]);
CpuCopy16(sp10, arg2, sizeof(sp10));
}
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;
}
static u8* AddTextPrinterAndCreateWindowOnHealthbox(const u8 *str, u32 x, u32 y, u32 arg3, u32 *windowId)
{
u16 winId;
2018-02-07 03:37:54 +01:00
u8 color[3];
2017-10-19 15:28:41 +02:00
struct WindowTemplate winTemplate = sHealthboxWindowTemplate;
winId = AddWindow(&winTemplate);
FillWindowPixelBuffer(winId, (arg3 << 4) | (arg3));
2018-02-07 03:37:54 +01:00
color[0] = arg3;
color[1] = 1;
color[2] = 3;
2017-10-19 15:28:41 +02:00
AddTextPrinterParameterized4(winId, 0, x, y, 0, 0, color, -1, str);
2017-10-19 15:28:41 +02:00
*windowId = winId;
return (u8*)(GetWindowAttribute(winId, WINDOW_TILE_DATA));
}
static void RemoveWindowOnHealthbox(u32 windowId)
{
RemoveWindow(windowId);
}
2018-06-19 00:43:15 +02:00
static void FillHealthboxObject(void *dest, u32 arg1, u32 arg2)
2017-10-19 15:28:41 +02:00
{
CpuFill32(0x11111111 * arg1, dest, arg2 * 32);
}
2018-06-19 00:43:15 +02:00
static void HpTextIntoHealthboxObject(void *dest, u8 *windowTileData, u32 arg2)
2017-10-19 15:28:41 +02:00
{
CpuCopy32(windowTileData + 256, dest, arg2 * 32);
}
2018-06-19 00:43:15 +02:00
static void TextIntoHealthboxObject(void *dest, u8 *windowTileData, s32 arg2)
2017-10-19 15:28:41 +02:00
{
CpuCopy32(windowTileData + 256, dest + 256, arg2 * 32);
if (arg2 > 0)
{
do
{
CpuCopy32(windowTileData + 20, dest + 20, 12);
2018-06-19 00:43:15 +02:00
dest += 32, windowTileData += 32;
2017-10-19 15:28:41 +02:00
arg2--;
} while (arg2 != 0);
}
}
2018-06-19 00:43:15 +02:00
static void SafariTextIntoHealthboxObject(void *dest, u8 *windowTileData, u32 arg2)
2017-10-19 15:28:41 +02:00
{
CpuCopy32(windowTileData, dest, arg2 * 32);
CpuCopy32(windowTileData + 256, dest + 256, arg2 * 32);
}