Refactor Mega Evolution indicator sprite (#2805)

This commit is contained in:
Eduardo Quezada D'Ottone 2023-03-07 08:06:28 -03:00 committed by GitHub
commit 81a80e566c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 284 additions and 319 deletions

View File

@ -24860,6 +24860,7 @@ General_MegaEvolution:
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
createvisualtask AnimTask_HorizontalShake, 5, 1, 5, 14
waitforvisualfinish
createvisualtask SoundTask_PlayNormalCry, 0
createsprite gMegaSymbolSpriteTemplate ANIM_ATTACKER, 2
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
@ -25005,6 +25006,7 @@ General_PrimalReversion_Alpha:
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
createvisualtask AnimTask_HorizontalShake, 5, 1, 5, 14
waitforvisualfinish
createvisualtask SoundTask_PlayNormalCry, 0
createsprite gAlphaSymbolSpriteTemplate ANIM_ATTACKER, 2
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER
@ -25031,6 +25033,7 @@ General_PrimalReversion_Omega:
createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 16, 0, RGB_WHITEALPHA
createvisualtask AnimTask_HorizontalShake, 5, 1, 5, 14
waitforvisualfinish
createvisualtask SoundTask_PlayNormalCry, 0
createsprite gOmegaSymbolSpriteTemplate ANIM_ATTACKER, 2
waitforvisualfinish
clearmonbg ANIM_ATK_PARTNER

View File

@ -7829,6 +7829,7 @@ BattleScript_FocusPunchSetUp::
BattleScript_MegaEvolution::
printstring STRINGID_MEGAEVOREACTING
BattleScript_MegaEvolutionAfeterString:
waitmessage B_WAIT_TIME_LONG
setbyte gIsCriticalHit, 0
handlemegaevo BS_ATTACKER, 0
@ -7843,17 +7844,7 @@ BattleScript_MegaEvolution::
BattleScript_WishMegaEvolution::
printstring STRINGID_FERVENTWISHREACHED
waitmessage B_WAIT_TIME_LONG
setbyte gIsCriticalHit, 0
handlemegaevo BS_ATTACKER, 0
handlemegaevo BS_ATTACKER, 1
playanimation BS_ATTACKER, B_ANIM_MEGA_EVOLUTION
waitanimation
handlemegaevo BS_ATTACKER, 2
printstring STRINGID_MEGAEVOEVOLVED
waitmessage B_WAIT_TIME_LONG
switchinabilities BS_ATTACKER
end2
goto BattleScript_MegaEvolutionAfeterString
BattleScript_PrimalReversion::
printstring STRINGID_EMPTYSTRING3

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 B

After

Width:  |  Height:  |  Size: 209 B

View File

@ -56,8 +56,7 @@ enum
#define TAG_MEGA_TRIGGER_PAL 0xD777
#define TAG_MEGA_INDICATOR_PAL 0xD778
#define TAG_ALPHA_INDICATOR_PAL 0xD779
#define TAG_OMEGA_INDICATOR_PAL 0xD77A
#define TAG_ALPHA_OMEGA_INDICATOR_PAL 0xD779 // Alpha and Omega indicators use the same palette as each of them only uses 4 different colors.
#define TAG_ZMOVE_TRIGGER_PAL 0xD77B
enum
@ -77,7 +76,6 @@ enum
};
u32 WhichBattleCoords(u32 battlerId);
u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId);
u8 CreateBattlerHealthboxSprites(u8 battler);
u8 CreateSafariPlayerHealthboxSprites(void);
void SetBattleBarStruct(u8 battler, u8 healthboxSpriteId, s32 maxVal, s32 currVal, s32 receivedValue);
@ -94,8 +92,7 @@ void CreateMegaTriggerSprite(u8 battlerId, u8 palId);
bool32 IsMegaTriggerSpriteActive(void);
void HideMegaTriggerSprite(void);
void DestroyMegaTriggerSprite(void);
u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which);
void DestroyMegaIndicatorSprite(u32 healthboxSpriteId);
void MegaIndicator_LoadSpritesGfx(void);
u8 CreatePartyStatusSummarySprites(u8 battler, struct HpAndStatus *partyInfo, bool8 skipPlayer, bool8 isBattleStart);
void Task_HidePartyStatusSummary(u8 taskId);
void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId);

View File

@ -274,6 +274,7 @@ void LaunchBattleAnimation(u32 animType, u32 animId)
case B_ANIM_DOOM_DESIRE_HIT:
case B_ANIM_WISH_HEAL:
case B_ANIM_MEGA_EVOLUTION:
case B_ANIM_PRIMAL_REVERSION:
case B_ANIM_GULP_MISSILE:
hideHpBoxes = TRUE;
break;

View File

@ -283,6 +283,11 @@ void SoundTask_WaitForCry(u8 taskId)
}
}
void SoundTask_PlayNormalCry(u8 taskId)
{
PlayCry_ByMode(gBattleMons[gBattleAnimAttacker].species, BattleAnimAdjustPanning(SOUND_PAN_ATTACKER), CRY_MODE_NORMAL);
gTasks[taskId].func = SoundTask_WaitForCry;
}
#define tSpecies data[1]
#define tPan data[2]

View File

@ -691,6 +691,7 @@ bool8 BattleLoadAllHealthBoxesGfx(u8 state)
{
LoadSpritePalette(&sSpritePalettes_HealthBoxHealthBar[0]);
LoadSpritePalette(&sSpritePalettes_HealthBoxHealthBar[1]);
MegaIndicator_LoadSpritesGfx();
}
else if (!IsDoubleBattle())
{

View File

@ -182,6 +182,11 @@ static void SpriteCB_StatusSummaryBalls_Exit(struct Sprite *);
static void SpriteCB_StatusSummaryBalls_OnSwitchout(struct Sprite *);
static void SpriteCb_MegaTrigger(struct Sprite *);
static void MegaIndicator_SetVisibilities(u32 healthboxId, bool32 invisible);
static void MegaIndicator_UpdateLevel(u32 healthboxId, u32 level);
static void MegaIndicator_CreateSprites(u32 battlerId, u32 healthboxSpriteId);
static void MegaIndicator_UpdateOamPriorities(u32 healthboxId, u32 oamPriority);
static void MegaIndicator_DestroySprites(u32 healthboxSpriteId);
static void SpriteCb_MegaIndicator(struct Sprite *);
static u8 GetStatusIconForBattlerId(u8, u8);
@ -660,90 +665,6 @@ static const struct SpriteTemplate sSpriteTemplate_MegaTrigger =
.callback = SpriteCb_MegaTrigger
};
static const u8 sMegaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/mega_indicator.4bpp");
static const u16 sMegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mega_indicator.gbapal");
static const struct SpriteSheet sSpriteSheet_MegaIndicator =
{
sMegaIndicatorGfx, sizeof(sMegaIndicatorGfx), TAG_MEGA_INDICATOR_TILE
};
static const struct SpritePalette sSpritePalette_MegaIndicator =
{
sMegaIndicatorPal, TAG_MEGA_INDICATOR_PAL
};
static const u8 sAlphaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/alpha_indicator.4bpp");
static const u16 sAlphaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/alpha_indicator.gbapal");
static const u8 sOmegaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/omega_indicator.4bpp");
static const u16 sOmegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/omega_indicator.gbapal");
static const struct SpriteSheet sSpriteSheet_AlphaIndicator =
{
sAlphaIndicatorGfx, sizeof(sAlphaIndicatorGfx), TAG_ALPHA_INDICATOR_TILE
};
static const struct SpritePalette sSpritePalette_AlphaIndicator =
{
sAlphaIndicatorPal, TAG_ALPHA_INDICATOR_PAL
};
static const struct SpriteSheet sSpriteSheet_OmegaIndicator =
{
sOmegaIndicatorGfx, sizeof(sOmegaIndicatorGfx), TAG_OMEGA_INDICATOR_TILE
};
static const struct SpritePalette sSpritePalette_OmegaIndicator =
{
sOmegaIndicatorPal, TAG_OMEGA_INDICATOR_PAL
};
static const struct OamData sOamData_MegaIndicator =
{
.y = 0,
.affineMode = 0,
.objMode = 0,
.mosaic = 0,
.bpp = 0,
.shape = SPRITE_SHAPE(16x16),
.x = 0,
.matrixNum = 0,
.size = SPRITE_SIZE(16x16),
.tileNum = 0,
.priority = 1,
.paletteNum = 0,
.affineParam = 0,
};
static const struct SpriteTemplate sSpriteTemplate_MegaIndicator =
{
.tileTag = TAG_MEGA_INDICATOR_TILE,
.paletteTag = TAG_MEGA_INDICATOR_PAL,
.oam = &sOamData_MegaIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_MegaIndicator,
};
static const struct SpriteTemplate sSpriteTemplate_AlphaIndicator =
{
.tileTag = TAG_ALPHA_INDICATOR_TILE,
.paletteTag = TAG_ALPHA_INDICATOR_PAL,
.oam = &sOamData_MegaIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_MegaIndicator,
};
static const struct SpriteTemplate sSpriteTemplate_OmegaIndicator =
{
.tileTag = TAG_OMEGA_INDICATOR_TILE,
.paletteTag = TAG_OMEGA_INDICATOR_PAL,
.oam = &sOamData_MegaIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_MegaIndicator,
};
// 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.
@ -751,26 +672,18 @@ static const struct SpriteTemplate sSpriteTemplate_OmegaIndicator =
// data fields for healthboxMain
// oam.affineParam holds healthboxRight spriteId
#define hMain_MegaIndicatorIds data[3] // Mega, Alpha, Omega as u8 in data[3], data[3] + 1, data[4]
#define hMain_HealthBarSpriteId data[5]
#define hMain_Battler data[6]
#define hMain_Data7 data[7]
// data fields for healthboxRight
#define hOther_HealthBoxSpriteId data[5]
#define hOther_IndicatorSpriteId data[6] // For Mega Evo
// data fields for healthbar
#define hBar_HealthBoxSpriteId data[5]
#define hBar_Data6 data[6]
u8 GetMegaIndicatorSpriteId(u32 healthboxSpriteId)
{
u8 spriteId = gSprites[healthboxSpriteId].oam.affineParam;
if (spriteId >= MAX_SPRITES)
return 0xFF;
return gSprites[spriteId].hOther_IndicatorSpriteId;
}
static void InitLastUsedBallAssets(void)
{
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
@ -864,19 +777,13 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId)
gSprites[healthboxLeftSpriteId].invisible = TRUE;
gSprites[healthboxRightSpriteId].invisible = TRUE;
gSprites[healthboxRightSpriteId].hOther_IndicatorSpriteId = 0xFF;
healthBarSpritePtr->hBar_HealthBoxSpriteId = healthboxLeftSpriteId;
healthBarSpritePtr->hBar_Data6 = data6;
healthBarSpritePtr->invisible = TRUE;
// Create mega indicator sprite if is a mega evolved or a primal reverted mon.
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]]
|| gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
megaIndicatorSpriteId = CreateMegaIndicatorSprite(battlerId, 0);
gSprites[megaIndicatorSpriteId].invisible = TRUE;
}
// Create mega indicator sprites.
MegaIndicator_CreateSprites(battlerId, healthboxLeftSpriteId);
gBattleStruct->ballSpriteIds[0] = MAX_SPRITES;
gBattleStruct->ballSpriteIds[1] = MAX_SPRITES;
@ -899,8 +806,6 @@ u8 CreateSafariPlayerHealthboxSprites(void)
gSprites[healthboxLeftSpriteId].oam.affineParam = healthboxRightSpriteId;
gSprites[healthboxRightSpriteId].hOther_HealthBoxSpriteId = healthboxLeftSpriteId;
gSprites[healthboxRightSpriteId].hOther_IndicatorSpriteId = 0xFF;
gSprites[healthboxRightSpriteId].callback = SpriteCB_HealthBoxOther;
return healthboxLeftSpriteId;
@ -940,19 +845,12 @@ static void SpriteCB_HealthBar(struct Sprite *sprite)
static void SpriteCB_HealthBoxOther(struct Sprite *sprite)
{
u8 healthboxMainSpriteId = sprite->hOther_HealthBoxSpriteId;
u8 megaSpriteId = sprite->hOther_IndicatorSpriteId;
sprite->x = gSprites[healthboxMainSpriteId].x + 64;
sprite->y = gSprites[healthboxMainSpriteId].y;
sprite->x2 = gSprites[healthboxMainSpriteId].x2;
sprite->y2 = gSprites[healthboxMainSpriteId].y2;
if (megaSpriteId != 0xFF)
{
gSprites[megaSpriteId].x2 = sprite->x2;
gSprites[megaSpriteId].y2 = sprite->y2;
}
}
void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldVal, s32 receivedValue)
@ -966,28 +864,18 @@ void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldV
void SetHealthboxSpriteInvisible(u8 healthboxSpriteId)
{
DestroyMegaIndicatorSprite(healthboxSpriteId);
gSprites[healthboxSpriteId].invisible = TRUE;
gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = TRUE;
gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = TRUE;
MegaIndicator_SetVisibilities(healthboxSpriteId, TRUE);
}
void SetHealthboxSpriteVisible(u8 healthboxSpriteId)
{
u8 battlerId = gSprites[healthboxSpriteId].hMain_Battler;
gSprites[healthboxSpriteId].invisible = FALSE;
gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = FALSE;
gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = FALSE;
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]]
|| gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
u8 spriteId = GetMegaIndicatorSpriteId(healthboxSpriteId);
if (spriteId != 0xFF)
gSprites[spriteId].invisible = FALSE;
else
CreateMegaIndicatorSprite(battlerId, 0);
}
MegaIndicator_SetVisibilities(healthboxSpriteId, FALSE);
}
static void UpdateSpritePos(u8 spriteId, s16 x, s16 y)
@ -998,7 +886,7 @@ static void UpdateSpritePos(u8 spriteId, s16 x, s16 y)
void DestoryHealthboxSprite(u8 healthboxSpriteId)
{
DestroyMegaIndicatorSprite(healthboxSpriteId);
MegaIndicator_DestroySprites(healthboxSpriteId);
DestroySprite(&gSprites[gSprites[healthboxSpriteId].oam.affineParam]);
DestroySprite(&gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId]);
DestroySprite(&gSprites[healthboxSpriteId]);
@ -1009,26 +897,19 @@ void DummyBattleInterfaceFunc(u8 healthboxSpriteId, bool8 isDoubleBattleBattlerO
}
static void TryToggleHealboxVisibility(u8 priority, u8 healthboxLeftSpriteId, u8 healthboxRightSpriteId, u8 healthbarSpriteId, u8 indicatorSpriteId)
static void TryToggleHealboxVisibility(u32 priority, u32 healthboxLeftSpriteId, u32 healthboxRightSpriteId, u32 healthbarSpriteId)
{
u8 spriteIds[4] = {healthboxLeftSpriteId, healthboxRightSpriteId, healthbarSpriteId, indicatorSpriteId};
int i;
bool32 invisible = FALSE;
for (i = 0; i < NELEMS(spriteIds); i++)
{
if (spriteIds[i] == 0xFF)
continue;
if (priority == 0) // start of anim -> make invisible
invisible = TRUE;
else if (priority == 1) // end of anim -> make visible
invisible = FALSE;
switch (priority)
{
case 0: //start of anim -> make invisible
gSprites[spriteIds[i]].invisible = TRUE;
break;
case 1: //end of anim -> make visible
gSprites[spriteIds[i]].invisible = FALSE;
break;
}
}
gSprites[healthboxLeftSpriteId].invisible = invisible;
gSprites[healthboxRightSpriteId].invisible = invisible;
gSprites[healthbarSpriteId].invisible = invisible;
MegaIndicator_SetVisibilities(healthboxLeftSpriteId, invisible);
}
void UpdateOamPriorityInAllHealthboxes(u8 priority, bool32 hideHPBoxes)
@ -1040,17 +921,16 @@ void UpdateOamPriorityInAllHealthboxes(u8 priority, bool32 hideHPBoxes)
u8 healthboxLeftSpriteId = gHealthboxSpriteIds[i];
u8 healthboxRightSpriteId = gSprites[gHealthboxSpriteIds[i]].oam.affineParam;
u8 healthbarSpriteId = gSprites[gHealthboxSpriteIds[i]].hMain_HealthBarSpriteId;
u8 indicatorSpriteId = GetMegaIndicatorSpriteId(healthboxLeftSpriteId);
gSprites[healthboxLeftSpriteId].oam.priority = priority;
gSprites[healthboxRightSpriteId].oam.priority = priority;
gSprites[healthbarSpriteId].oam.priority = priority;
if (indicatorSpriteId != 0xFF)
gSprites[indicatorSpriteId].oam.priority = priority;
MegaIndicator_UpdateOamPriorities(healthboxLeftSpriteId, priority);
#if B_HIDE_HEALTHBOX_IN_ANIMS
if (hideHPBoxes && IsBattlerAlive(i))
TryToggleHealboxVisibility(priority, healthboxLeftSpriteId, healthboxRightSpriteId, healthbarSpriteId, indicatorSpriteId);
TryToggleHealboxVisibility(priority, healthboxLeftSpriteId, healthboxRightSpriteId, healthbarSpriteId);
#endif
}
}
@ -1109,6 +989,8 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
{
objVram = ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
xPos = 5 * (3 - (objVram - (text + 2))) - 1;
MegaIndicator_UpdateLevel(healthboxSpriteId, lvl);
MegaIndicator_SetVisibilities(healthboxSpriteId, FALSE);
}
else
{
@ -1119,7 +1001,6 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
xPos = 5 * (3 - (objVram - (text + 2)));
}
xPos = 5 * (3 - (objVram - (text + 2)));
windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, xPos, 3, 2, &windowId);
spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP;
@ -1418,7 +1299,7 @@ void SwapHpBarsWithHpText(void)
}
}
// Mega Evolution gfx functions.
// Mega Evolution Trigger icon functions.
void ChangeMegaTriggerSprite(u8 spriteId, u8 animId)
{
StartSpriteAnim(&gSprites[spriteId], animId);
@ -1543,6 +1424,64 @@ void DestroyMegaTriggerSprite(void)
gBattleStruct->mega.triggerSpriteId = 0xFF;
}
#undef tBattler
#undef tHide
// Code for Mega Evolution (And Alpha/Omega) Trigger icon visible on the battler's healthbox.
enum
{
INDICATOR_MEGA,
INDICATOR_ALPHA,
INDICATOR_OMEGA,
INDICATOR_COUNT,
};
static const u8 sMegaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/mega_indicator.4bpp");
static const u16 sMegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mega_indicator.gbapal");
static const u8 sAlphaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/alpha_indicator.4bpp");
static const u8 sOmegaIndicatorGfx[] = INCBIN_U8("graphics/battle_interface/omega_indicator.4bpp");
static const u16 sAlphaOmegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/alpha_indicator.gbapal");
static const struct SpriteSheet sMegaIndicator_SpriteSheets[] =
{
[INDICATOR_MEGA] = {sMegaIndicatorGfx, sizeof(sMegaIndicatorGfx), TAG_MEGA_INDICATOR_TILE},
[INDICATOR_ALPHA] = {sAlphaIndicatorGfx, sizeof(sAlphaIndicatorGfx), TAG_ALPHA_INDICATOR_TILE},
[INDICATOR_OMEGA] = {sOmegaIndicatorGfx, sizeof(sOmegaIndicatorGfx), TAG_OMEGA_INDICATOR_TILE},
[INDICATOR_COUNT] = {0}
};
static const struct SpritePalette sMegaIndicator_SpritePalettes[] =
{
[INDICATOR_MEGA] = {sMegaIndicatorPal, TAG_MEGA_INDICATOR_PAL},
[INDICATOR_ALPHA] = {sAlphaOmegaIndicatorPal, TAG_ALPHA_OMEGA_INDICATOR_PAL},
[INDICATOR_OMEGA] = {sAlphaOmegaIndicatorPal, TAG_ALPHA_OMEGA_INDICATOR_PAL},
[INDICATOR_COUNT] = {0}
};
static const struct OamData sOamData_MegaIndicator =
{
.shape = SPRITE_SHAPE(16x16),
.size = SPRITE_SIZE(16x16),
.priority = 1,
};
static const struct SpriteTemplate sSpriteTemplate_MegaIndicator =
{
.tileTag = TAG_MEGA_INDICATOR_TILE,
.paletteTag = TAG_MEGA_INDICATOR_PAL,
.oam = &sOamData_MegaIndicator,
.anims = gDummySpriteAnimTable,
.images = NULL,
.affineAnims = gDummySpriteAffineAnimTable,
.callback = SpriteCb_MegaIndicator,
};
static const u16 sMegaIndicatorTags[][2] =
{
[INDICATOR_MEGA] = {TAG_MEGA_INDICATOR_TILE, TAG_MEGA_INDICATOR_PAL},
[INDICATOR_ALPHA] = {TAG_ALPHA_INDICATOR_TILE, TAG_ALPHA_OMEGA_INDICATOR_PAL},
[INDICATOR_OMEGA] = {TAG_OMEGA_INDICATOR_TILE, TAG_ALPHA_OMEGA_INDICATOR_PAL},
};
static const s8 sIndicatorPositions[][2] =
{
[B_POSITION_PLAYER_LEFT] = {52, -9},
@ -1551,89 +1490,137 @@ static const s8 sIndicatorPositions[][2] =
[B_POSITION_OPPONENT_RIGHT] = {44, -9},
};
u32 CreateMegaIndicatorSprite(u32 battlerId, u32 which)
// for sprite data fields
#define tBattler data[0]
#define tType data[1] // Indicator type: mega, alpha, omega
#define tPosX data[2]
#define tLevelXDelta data[3] // X position depends whether level has 3, 2 or 1 digit
void MegaIndicator_LoadSpritesGfx(void)
{
u32 spriteId, position;
s16 x, y;
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
LoadSpritePalette(&sSpritePalette_MegaIndicator);
LoadSpriteSheet(&sSpriteSheet_MegaIndicator);
}
else if (gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_GROUDON)
{
LoadSpritePalette(&sSpritePalette_OmegaIndicator);
LoadSpriteSheet(&sSpriteSheet_OmegaIndicator);
}
else if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_KYOGRE)
{
LoadSpritePalette(&sSpritePalette_AlphaIndicator);
LoadSpriteSheet(&sSpriteSheet_AlphaIndicator);
}
}
position = GetBattlerPosition(battlerId);
GetBattlerHealthboxCoords(battlerId, &x, &y);
x += sIndicatorPositions[position][0];
y += sIndicatorPositions[position][1];
if (gBattleMons[battlerId].level >= 100)
x -= 4;
else if (gBattleMons[battlerId].level < 10)
x += 5;
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_MegaIndicator, x, y, 0);
}
else if (gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battlerId)] & gBitTable[gBattlerPartyIndexes[battlerId]])
{
if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_GROUDON)
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_OmegaIndicator, x, y, 0);
else if (GET_BASE_SPECIES_ID(gBattleMons[battlerId].species) == SPECIES_KYOGRE)
spriteId = CreateSpriteAtEnd(&sSpriteTemplate_AlphaIndicator, x, y, 0);
}
gSprites[gSprites[gHealthboxSpriteIds[battlerId]].oam.affineParam].hOther_IndicatorSpriteId = spriteId;
gSprites[spriteId].tBattler = battlerId;
return spriteId;
LoadSpriteSheets(sMegaIndicator_SpriteSheets);
LoadSpritePalettes(sMegaIndicator_SpritePalettes);
}
void DestroyMegaIndicatorSprite(u32 healthboxSpriteId)
static bool32 MegaIndicator_ShouldBeInvisible(u32 battlerId, u32 indicatorType)
{
u32 side = GetBattlerSide(battlerId);
if (indicatorType == INDICATOR_MEGA)
{
if (gBattleStruct->mega.evolvedPartyIds[side] & gBitTable[gBattlerPartyIndexes[battlerId]])
return FALSE;
}
else
{
if (indicatorType == INDICATOR_ALPHA)
{
if (gBattleMons[battlerId].species != SPECIES_KYOGRE_PRIMAL)
return TRUE;
}
else if (indicatorType == INDICATOR_OMEGA)
{
if (gBattleMons[battlerId].species != SPECIES_GROUDON_PRIMAL)
return TRUE;
}
if (gBattleStruct->mega.primalRevertedPartyIds[side] & gBitTable[gBattlerPartyIndexes[battlerId]])
return FALSE;
}
return TRUE;
}
static u8 *MegaIndicator_GetSpriteIds(u32 healthboxSpriteId)
{
u8 *spriteIds = (u8 *)(&gSprites[healthboxSpriteId].hMain_MegaIndicatorIds);
return spriteIds;
}
void MegaIndicator_SetVisibilities(u32 healthboxId, bool32 invisible)
{
u32 i;
s16 *spriteId = &gSprites[gSprites[healthboxSpriteId].oam.affineParam].hOther_IndicatorSpriteId;
u8 *spriteIds = MegaIndicator_GetSpriteIds(healthboxId);
u32 battlerId = gSprites[healthboxId].hMain_Battler;
if (*spriteId != 0xFF)
for (i = 0; i < INDICATOR_COUNT; i++)
{
DestroySprite(&gSprites[*spriteId]);
*spriteId = 0xFF;
if (invisible == TRUE)
gSprites[spriteIds[i]].invisible = TRUE;
else // Try visible.
gSprites[spriteIds[i]].invisible = MegaIndicator_ShouldBeInvisible(battlerId, i);
}
}
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
static void MegaIndicator_UpdateOamPriorities(u32 healthboxId, u32 oamPriority)
{
u32 i;
u8 *spriteIds = MegaIndicator_GetSpriteIds(healthboxId);
for (i = 0; i < INDICATOR_COUNT; i++)
gSprites[spriteIds[i]].oam.priority = oamPriority;
}
static void MegaIndicator_UpdateLevel(u32 healthboxId, u32 level)
{
u32 i;
s16 xDelta = 0;
u8 *spriteIds = MegaIndicator_GetSpriteIds(healthboxId);
if (level >= 100)
xDelta -= 4;
else if (level < 10)
xDelta += 5;
for (i = 0; i < INDICATOR_COUNT; i++)
gSprites[spriteIds[i]].tLevelXDelta = xDelta;
}
static void MegaIndicator_CreateSprites(u32 battlerId, u32 healthboxSpriteId)
{
u32 position, i, level;
u8 *spriteIds;
s16 xHealthbox = 0, y = 0;
s32 x = 0;
position = GetBattlerPosition(battlerId);
GetBattlerHealthboxCoords(battlerId, &xHealthbox, &y);
x = sIndicatorPositions[position][0];
y += sIndicatorPositions[position][1];
spriteIds = MegaIndicator_GetSpriteIds(healthboxSpriteId);
for (i = 0; i < INDICATOR_COUNT; i++)
{
if (gSprites[gSprites[gHealthboxSpriteIds[i]].oam.affineParam].hOther_IndicatorSpriteId != 0xFF)
break;
}
// Free Sprite pal/tiles only if no indicator sprite is active for all battlers.
if (i == MAX_BATTLERS_COUNT)
{
FreeSpritePaletteByTag(TAG_MEGA_INDICATOR_PAL);
FreeSpriteTilesByTag(TAG_MEGA_INDICATOR_TILE);
struct SpriteTemplate sprTemplate = sSpriteTemplate_MegaIndicator;
sprTemplate.tileTag = sMegaIndicatorTags[i][0];
sprTemplate.paletteTag = sMegaIndicatorTags[i][1];
spriteIds[i] = CreateSpriteAtEnd(&sprTemplate, 0, y, 0);
gSprites[spriteIds[i]].tType = i;
gSprites[spriteIds[i]].tBattler = battlerId;
gSprites[spriteIds[i]].tPosX = x;
gSprites[spriteIds[i]].invisible = TRUE;
}
}
static void MegaIndicator_DestroySprites(u32 healthboxSpriteId)
{
u32 i;
u8 *spriteIds = MegaIndicator_GetSpriteIds(healthboxSpriteId);
for (i = 0; i < INDICATOR_COUNT; i++)
DestroySprite(&gSprites[spriteIds[i]]);
}
static void SpriteCb_MegaIndicator(struct Sprite *sprite)
{
u32 battlerId = sprite->tBattler;
sprite->x = gSprites[gHealthboxSpriteIds[battlerId]].x + sprite->tPosX + sprite->tLevelXDelta;
sprite->x2 = gSprites[gHealthboxSpriteIds[battlerId]].x2;
sprite->y2 = gSprites[gHealthboxSpriteIds[battlerId]].y2;
}
#undef tBattler
#undef tHide
#undef tType
#undef tPosX
#undef tLevelXDelta
#define tBattler data[0]
#define tSummaryBarSpriteId data[1]

View File

@ -2878,10 +2878,6 @@ static void SpriteCB_BounceEffect(struct Sprite *sprite)
gSprites[bouncerSpriteId].y2 = y;
sprite->sSinIndex = (sprite->sSinIndex + sprite->sDelta) & 0xFF;
bouncerSpriteId = GetMegaIndicatorSpriteId(sprite->sBouncerSpriteId);
if (sprite->sWhich == BOUNCE_HEALTHBOX && bouncerSpriteId != 0xFF)
gSprites[bouncerSpriteId].y2 = y;
}
#undef sSinIndex
@ -4886,11 +4882,8 @@ static void CheckMegaEvolutionBeforeTurn(void)
if (gBattleStruct->mega.toEvolve & gBitTable[gActiveBattler]
&& !(gProtectStructs[gActiveBattler].noValidMoves))
{
struct Pokemon *mon;
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
else
mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
struct Pokemon *mon = GetBattlerPartyData(gActiveBattler);
gBattleStruct->mega.toEvolve &= ~(gBitTable[gActiveBattler]);
gLastUsedItem = gBattleMons[gActiveBattler].item;
if (GetWishMegaEvolutionSpecies(GetMonData(mon, MON_DATA_SPECIES), GetMonData(mon, MON_DATA_MOVE1), GetMonData(mon, MON_DATA_MOVE2), GetMonData(mon, MON_DATA_MOVE3), GetMonData(mon, MON_DATA_MOVE4)))

View File

@ -8694,6 +8694,74 @@ static bool32 CourtChangeSwapSideStatuses(void)
SWAP(sideTimerPlayer->stickyWebBattlerSide, sideTimerOpp->stickyWebBattlerSide, temp);
}
static void HandleScriptMegaPrimal(u32 caseId, u32 battlerId, bool32 isMega)
{
struct Pokemon *mon = GetBattlerPartyData(battlerId);
u32 position = GetBattlerPosition(battlerId);
u32 side = GET_BATTLER_SIDE(battlerId);
// Change species.
if (caseId == 0)
{
u16 newSpecies;
if (isMega)
{
gBattleStruct->mega.evolvedSpecies[battlerId] = gBattleMons[battlerId].species;
if (position == B_POSITION_PLAYER_LEFT
|| (position == B_POSITION_PLAYER_RIGHT && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))))
{
gBattleStruct->mega.playerEvolvedSpecies = gBattleStruct->mega.evolvedSpecies[battlerId];
}
//Checks regular Mega Evolution
newSpecies = GetMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[battlerId], gBattleMons[battlerId].item);
//Checks Wish Mega Evolution
if (newSpecies == SPECIES_NONE)
{
newSpecies = GetWishMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[battlerId],
gBattleMons[battlerId].moves[0], gBattleMons[battlerId].moves[1], gBattleMons[battlerId].moves[2], gBattleMons[battlerId].moves[3]);
}
}
else
{
gBattleStruct->mega.primalRevertedSpecies[battlerId] = gBattleMons[battlerId].species;
if (position == B_POSITION_PLAYER_LEFT
|| (position == B_POSITION_PLAYER_RIGHT && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))))
{
gBattleStruct->mega.playerPrimalRevertedSpecies = gBattleStruct->mega.primalRevertedSpecies[battlerId];
}
// Checks Primal Reversion.
newSpecies = GetPrimalReversionSpecies(gBattleStruct->mega.primalRevertedSpecies[battlerId], gBattleMons[battlerId].item);
}
gBattleMons[battlerId].species = newSpecies;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[battlerId].species);
BtlController_EmitSetMonData(BUFFER_A, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[battlerId]], sizeof(gBattleMons[battlerId].species), &gBattleMons[battlerId].species);
MarkBattlerForControllerExec(battlerId);
}
// Change stats.
else if (caseId == 1)
{
RecalcBattlerStats(battlerId, mon);
if (isMega)
{
gBattleStruct->mega.alreadyEvolved[position] = TRUE;
gBattleStruct->mega.evolvedPartyIds[side] |= gBitTable[gBattlerPartyIndexes[battlerId]];
}
else
{
gBattleStruct->mega.primalRevertedPartyIds[side] |= gBitTable[gBattlerPartyIndexes[battlerId]];
}
}
// Update healthbox and elevation and play cry.
else
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[battlerId], mon, HEALTHBOX_ALL);
if (side == B_SIDE_OPPONENT)
SetBattlerShadowSpriteCallback(battlerId, gBattleMons[battlerId].species);
}
}
static bool32 CanTeleport(u8 battlerId)
{
u8 side = GetBattlerSide(battlerId);
@ -9770,95 +9838,14 @@ static void Cmd_various(void)
case VARIOUS_HANDLE_MEGA_EVO:
{
VARIOUS_ARGS(u8 case_);
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
else
mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
// Change species.
if (cmd->case_ == 0)
{
u16 megaSpecies;
gBattleStruct->mega.evolvedSpecies[gActiveBattler] = gBattleMons[gActiveBattler].species;
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT
|| (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))))
{
gBattleStruct->mega.playerEvolvedSpecies = gBattleStruct->mega.evolvedSpecies[gActiveBattler];
}
//Checks regular Mega Evolution
megaSpecies = GetMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[gActiveBattler], gBattleMons[gActiveBattler].item);
//Checks Wish Mega Evolution
if (megaSpecies == SPECIES_NONE)
{
megaSpecies = GetWishMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[gActiveBattler], gBattleMons[gActiveBattler].moves[0], gBattleMons[gActiveBattler].moves[1], gBattleMons[gActiveBattler].moves[2], gBattleMons[gActiveBattler].moves[3]);
}
gBattleMons[gActiveBattler].species = megaSpecies;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
BtlController_EmitSetMonData(BUFFER_A, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], sizeof(gBattleMons[gActiveBattler].species), &gBattleMons[gActiveBattler].species);
MarkBattlerForControllerExec(gActiveBattler);
}
// Change stats.
else if (cmd->case_ == 1)
{
RecalcBattlerStats(gActiveBattler, mon);
gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(gActiveBattler)] = TRUE;
gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]];
}
// Update healthbox and elevation.
else
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL);
CreateMegaIndicatorSprite(gActiveBattler, 0);
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species);
}
HandleScriptMegaPrimal(cmd->case_, gActiveBattler, TRUE);
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_HANDLE_PRIMAL_REVERSION:
{
VARIOUS_ARGS(u8 case_);
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]];
else
mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]];
// Change species.
if (cmd->case_ == 0)
{
u16 primalSpecies;
gBattleStruct->mega.primalRevertedSpecies[gActiveBattler] = gBattleMons[gActiveBattler].species;
if (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_LEFT
|| (GetBattlerPosition(gActiveBattler) == B_POSITION_PLAYER_RIGHT && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER))))
{
gBattleStruct->mega.playerPrimalRevertedSpecies = gBattleStruct->mega.primalRevertedSpecies[gActiveBattler];
}
// Checks Primal Reversion
primalSpecies = GetPrimalReversionSpecies(gBattleStruct->mega.primalRevertedSpecies[gActiveBattler], gBattleMons[gActiveBattler].item);
gBattleMons[gActiveBattler].species = primalSpecies;
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species);
BtlController_EmitSetMonData(BUFFER_A, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], sizeof(gBattleMons[gActiveBattler].species), &gBattleMons[gActiveBattler].species);
MarkBattlerForControllerExec(gActiveBattler);
}
// Change stats.
else if (cmd->case_ == 1)
{
RecalcBattlerStats(gActiveBattler, mon);
gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]];
}
// Update healthbox and elevation.
else
{
UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL);
CreateMegaIndicatorSprite(gActiveBattler, 0);
if (GetBattlerSide(gActiveBattler) == B_SIDE_OPPONENT)
SetBattlerShadowSpriteCallback(gActiveBattler, gBattleMons[gActiveBattler].species);
}
HandleScriptMegaPrimal(cmd->case_, gActiveBattler, FALSE);
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}

View File

@ -10157,7 +10157,7 @@ void UndoMegaEvolution(u32 monId)
if (gBattleStruct->mega.evolvedPartyIds[B_SIDE_PLAYER] & gBitTable[monId])
{
gBattleStruct->mega.evolvedPartyIds[B_SIDE_PLAYER] &= ~(gBitTable[monId]);
SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleStruct->mega.playerEvolvedSpecies);
SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &baseSpecies);
CalculateMonStats(&gPlayerParty[monId]);
}
else if (gBattleStruct->mega.primalRevertedPartyIds[B_SIDE_PLAYER] & gBitTable[monId])