Gimmick Indicator refactor (#6553)

Co-authored-by: Hedara <hedara90@gmail.com>
This commit is contained in:
hedara90 2025-04-10 23:56:26 +02:00 committed by GitHub
parent 8cf8de1344
commit cf98d764ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 108 additions and 71 deletions

View File

@ -17,8 +17,8 @@ struct GimmickInfo
const struct SpritePalette *triggerPal; // trigger gfx data
const struct SpriteSheet *triggerSheet;
const struct SpriteTemplate *triggerTemplate;
const struct SpritePalette *indicatorPal; // indicator gfx data
const struct SpriteSheet *indicatorSheet;
const u32 indicatorPalTag;
const u8 *indicatorData;
bool32 (*CanActivate)(u32 battler);
void (*ActivateGimmick)(u32 battler);
};

View File

@ -265,20 +265,9 @@ static void SpriteCb_GimmickTrigger(struct Sprite *sprite)
void LoadIndicatorSpritesGfx(void)
{
u32 gimmick;
for (gimmick = 0; gimmick < GIMMICKS_COUNT; ++gimmick)
{
if (gimmick == GIMMICK_TERA) // special case
LoadSpriteSheets(sTeraIndicatorSpriteSheets);
else if (gGimmicksInfo[gimmick].indicatorSheet != NULL)
LoadSpriteSheet(gGimmicksInfo[gimmick].indicatorSheet);
if (gGimmicksInfo[gimmick].indicatorPal != NULL)
LoadSpritePalette(gGimmicksInfo[gimmick].indicatorPal);
}
// Primal reversion graphics aren't loaded as part of gimmick data
LoadSpriteSheet(&sSpriteSheet_AlphaIndicator);
LoadSpriteSheet(&sSpriteSheet_OmegaIndicator);
LoadSpritePalette(&sSpritePalette_MiscIndicator);
LoadSpritePalette(&sSpritePalette_MegaIndicator);
LoadSpritePalette(&sSpritePalette_TeraIndicator);
}
static void SpriteCb_GimmickIndicator(struct Sprite *sprite)
@ -295,28 +284,28 @@ static inline u32 GetIndicatorSpriteId(u32 healthboxId)
return gBattleStruct->gimmick.indicatorSpriteId[gSprites[healthboxId].hMain_Battler];
}
u32 GetIndicatorTileTag(u32 battler)
const u32 *GetIndicatorSpriteSrc(u32 battler)
{
u32 gimmick = GetActiveGimmick(battler);
if (IsBattlerPrimalReverted(battler))
{
if (gBattleMons[battler].species == SPECIES_GROUDON_PRIMAL)
return TAG_OMEGA_INDICATOR_TILE;
return (u32 *)&sOmegaIndicatorGfx;
else
return TAG_ALPHA_INDICATOR_TILE;
return (u32 *)&sAlphaIndicatorGfx;
}
else if (gimmick == GIMMICK_TERA) // special case
{
return sTeraIndicatorSpriteSheets[GetBattlerTeraType(battler)].tag;
return (u32 *)sTeraIndicatorDataPtrs[GetBattlerTeraType(battler)];
}
else if (gGimmicksInfo[gimmick].indicatorSheet != NULL)
else if (gGimmicksInfo[gimmick].indicatorData != NULL)
{
return gGimmicksInfo[gimmick].indicatorSheet->tag;
return (u32 *)gGimmicksInfo[gimmick].indicatorData;
}
else
{
return TAG_NONE;
return NULL;
}
}
@ -325,27 +314,34 @@ u32 GetIndicatorPalTag(u32 battler)
u32 gimmick = GetActiveGimmick(battler);
if (IsBattlerPrimalReverted(battler))
return TAG_MISC_INDICATOR_PAL;
else if (gGimmicksInfo[gimmick].indicatorPal != NULL)
return gGimmicksInfo[gimmick].indicatorPal->tag;
else if (gGimmicksInfo[gimmick].indicatorPalTag != 0)
return gGimmicksInfo[gimmick].indicatorPalTag;
else
return TAG_NONE;
}
#define INDICATOR_SIZE (8 * 16 / 2)
void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible)
{
u32 battler = gSprites[healthboxId].hMain_Battler;
u32 tileTag = GetIndicatorTileTag(battler);
u32 palTag = GetIndicatorPalTag(battler);
struct Sprite *sprite = &gSprites[GetIndicatorSpriteId(healthboxId)];
if (GetIndicatorSpriteId(healthboxId) == 0) // safari zone means the player doesn't have an indicator sprite id
return;
if (tileTag != TAG_NONE && palTag != TAG_NONE)
if (palTag != TAG_NONE)
{
sprite->oam.tileNum = GetSpriteTileStartByTag(tileTag);
sprite->oam.paletteNum = IndexOfSpritePaletteTag(palTag);
sprite->invisible = invisible;
u32 *dst = (u32 *)(OBJ_VRAM0 + TILE_SIZE_4BPP * GetSpriteTileStartByTag(BATTLER_INDICATOR_TAG + battler));
const u32 *src = GetIndicatorSpriteSrc(battler);
for (u32 i = 0; i < INDICATOR_SIZE / 4; i++)
dst[i] = src[i];
}
else // in case of error
{
@ -353,6 +349,8 @@ void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible)
}
}
#undef INDICATOR_SIZE
void UpdateIndicatorOamPriority(u32 healthboxId, u32 oamPriority)
{
gSprites[GetIndicatorSpriteId(healthboxId)].oam.priority = oamPriority;
@ -389,7 +387,8 @@ void CreateIndicatorSprite(u32 battler)
x = sIndicatorPositions[position][0];
y += sIndicatorPositions[position][1];
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_GimmickIndicator, 0, y, 0);
LoadSpriteSheet(&sBattler_GimmickSpritesheets[battler]);
spriteId = CreateSprite(&(sSpriteTemplate_BattlerIndicators[battler]), 0, y, 0);
gBattleStruct->gimmick.indicatorSpriteId[battler] = spriteId;
gSprites[spriteId].tBattler = battler;
gSprites[spriteId].tPosX = x;

View File

@ -922,7 +922,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
u8 battler = gSprites[healthboxSpriteId].hMain_Battler;
// Don't print Lv char if mon has a gimmick with an indicator active.
if (GetIndicatorTileTag(battler) != TAG_NONE)
if (GetIndicatorPalTag(battler) != TAG_NONE)
{
objVram = ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
xPos = 5 * (3 - (objVram - (text + 2))) - 1;

View File

@ -10,8 +10,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] =
.triggerSheet = &sSpriteSheet_MegaTrigger,
.triggerPal = &sSpritePalette_MegaTrigger,
.triggerTemplate = &sSpriteTemplate_GimmickTrigger,
.indicatorSheet = &sSpriteSheet_MegaIndicator,
.indicatorPal = &sSpritePalette_MegaIndicator,
.indicatorData = sMegaIndicatorGfx,
.indicatorPalTag = TAG_MEGA_INDICATOR_PAL,
.CanActivate = CanMegaEvolve,
.ActivateGimmick = ActivateMegaEvolution,
},
@ -36,8 +36,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] =
.triggerSheet = &sSpriteSheet_DynamaxTrigger,
.triggerPal = &sSpritePalette_DynamaxTrigger,
.triggerTemplate = &sSpriteTemplate_GimmickTrigger,
.indicatorSheet = &sSpriteSheet_DynamaxIndicator,
.indicatorPal = &sSpritePalette_MiscIndicator,
.indicatorData = sDynamaxIndicatorGfx,
.indicatorPalTag = TAG_MISC_INDICATOR_PAL,
.CanActivate = CanDynamax,
.ActivateGimmick = ActivateDynamax,
},
@ -46,8 +46,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] =
.triggerSheet = &sSpriteSheet_TeraTrigger,
.triggerPal = &sSpritePalette_TeraTrigger,
.triggerTemplate = &sSpriteTemplate_GimmickTrigger,
.indicatorSheet = NULL, // handled separately
.indicatorPal = &sSpritePalette_TeraIndicator,
.indicatorData = NULL, // handled separately
.indicatorPalTag = TAG_TERA_INDICATOR_PAL,
.CanActivate = CanTerastallize,
.ActivateGimmick = ActivateTera,
}

View File

@ -99,34 +99,29 @@ static const u16 sMiscIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mis
static const u16 sMegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mega_indicator.gbapal");
static const u16 sTeraIndicatorPal[] = INCBIN_U16("graphics/battle_interface/tera_indicator.gbapal");
static const struct SpriteSheet sSpriteSheet_MegaIndicator = {sMegaIndicatorGfx, sizeof(sMegaIndicatorGfx), TAG_MEGA_INDICATOR_TILE};
static const struct SpriteSheet sSpriteSheet_AlphaIndicator = {sAlphaIndicatorGfx, sizeof(sAlphaIndicatorGfx), TAG_ALPHA_INDICATOR_TILE};
static const struct SpriteSheet sSpriteSheet_OmegaIndicator = {sOmegaIndicatorGfx, sizeof(sOmegaIndicatorGfx), TAG_OMEGA_INDICATOR_TILE};
static const struct SpriteSheet sSpriteSheet_DynamaxIndicator = {sDynamaxIndicatorGfx, sizeof(sDynamaxIndicatorGfx), TAG_DYNAMAX_INDICATOR_TILE};
static const struct SpriteSheet sTeraIndicatorSpriteSheets[NUMBER_OF_MON_TYPES + 1] =
static const u8 *sTeraIndicatorDataPtrs[] =
{
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, // TYPE_NONE
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE},
{sFightingIndicatorGfx, sizeof(sFightingIndicatorGfx), TAG_FIGHTING_INDICATOR_TILE},
{sFlyingIndicatorGfx, sizeof(sFlyingIndicatorGfx), TAG_FLYING_INDICATOR_TILE},
{sPoisonIndicatorGfx, sizeof(sPoisonIndicatorGfx), TAG_POISON_INDICATOR_TILE},
{sGroundIndicatorGfx, sizeof(sGroundIndicatorGfx), TAG_GROUND_INDICATOR_TILE},
{sRockIndicatorGfx, sizeof(sRockIndicatorGfx), TAG_ROCK_INDICATOR_TILE},
{sBugIndicatorGfx, sizeof(sBugIndicatorGfx), TAG_BUG_INDICATOR_TILE},
{sGhostIndicatorGfx, sizeof(sGhostIndicatorGfx), TAG_GHOST_INDICATOR_TILE},
{sSteelIndicatorGfx, sizeof(sSteelIndicatorGfx), TAG_STEEL_INDICATOR_TILE},
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, // TYPE_MYSTERY
{sFireIndicatorGfx, sizeof(sFireIndicatorGfx), TAG_FIRE_INDICATOR_TILE},
{sWaterIndicatorGfx, sizeof(sWaterIndicatorGfx), TAG_WATER_INDICATOR_TILE},
{sGrassIndicatorGfx, sizeof(sGrassIndicatorGfx), TAG_GRASS_INDICATOR_TILE},
{sElectricIndicatorGfx, sizeof(sElectricIndicatorGfx), TAG_ELECTRIC_INDICATOR_TILE},
{sPsychicIndicatorGfx, sizeof(sPsychicIndicatorGfx), TAG_PSYCHIC_INDICATOR_TILE},
{sIceIndicatorGfx, sizeof(sIceIndicatorGfx), TAG_ICE_INDICATOR_TILE},
{sDragonIndicatorGfx, sizeof(sDragonIndicatorGfx), TAG_DRAGON_INDICATOR_TILE},
{sDarkIndicatorGfx, sizeof(sDarkIndicatorGfx), TAG_DARK_INDICATOR_TILE},
{sFairyIndicatorGfx, sizeof(sFairyIndicatorGfx), TAG_FAIRY_INDICATOR_TILE},
{sStellarIndicatorGfx, sizeof(sStellarIndicatorGfx), TAG_STELLAR_INDICATOR_TILE},
{0}
sNormalIndicatorGfx,
sNormalIndicatorGfx,
sFightingIndicatorGfx,
sFlyingIndicatorGfx,
sPoisonIndicatorGfx,
sGroundIndicatorGfx,
sRockIndicatorGfx,
sBugIndicatorGfx,
sGhostIndicatorGfx,
sSteelIndicatorGfx,
sNormalIndicatorGfx,
sFireIndicatorGfx,
sWaterIndicatorGfx,
sGrassIndicatorGfx,
sElectricIndicatorGfx,
sPsychicIndicatorGfx,
sIceIndicatorGfx,
sDragonIndicatorGfx,
sDarkIndicatorGfx,
sFairyIndicatorGfx,
sStellarIndicatorGfx,
};
static const struct SpritePalette sSpritePalette_MiscIndicator = {sMiscIndicatorPal, TAG_MISC_INDICATOR_PAL};
@ -141,13 +136,56 @@ static const struct OamData sOamData_GimmickIndicator =
};
static void SpriteCb_GimmickIndicator(struct Sprite *sprite);
static const struct SpriteTemplate sSpriteTemplate_GimmickIndicator =
#define BATTLER_INDICATOR_TAG 0xDEDE
static const struct SpriteSheet sBattler_GimmickSpritesheets[] =
{
.tileTag = TAG_NORMAL_INDICATOR_TILE, // updated dynamically
.paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically
.oam = &sOamData_GimmickIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_GimmickIndicator,
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG},
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+1},
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+2},
{sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+3},
};
static const struct SpriteTemplate sSpriteTemplate_BattlerIndicators[] =
{
[0] =
{
.tileTag = BATTLER_INDICATOR_TAG, // updated dynamically
.paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically
.oam = &sOamData_GimmickIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_GimmickIndicator,
},
[1] =
{
.tileTag = BATTLER_INDICATOR_TAG + 1, // updated dynamically
.paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically
.oam = &sOamData_GimmickIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_GimmickIndicator,
},
[2] =
{
.tileTag = BATTLER_INDICATOR_TAG + 2, // updated dynamically
.paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically
.oam = &sOamData_GimmickIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_GimmickIndicator,
},
[3] =
{
.tileTag = BATTLER_INDICATOR_TAG + 3, // updated dynamically
.paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically
.oam = &sOamData_GimmickIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_GimmickIndicator,
},
};