diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 3dfba0dc21..a4b64334e6 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1525,8 +1525,9 @@ .4byte \ptr .endm - .macro handlemegaevo battler:req + .macro handlemegaevo battler:req, case:req various \battler, VARIOUS_HANDLE_MEGA_EVO + .byte \case .endm .macro jumpifcantuselastresort battler:req, ptr:req diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 377614ee0d..1ef54a202b 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -10734,7 +10734,7 @@ Move_TRANSFORM: monbg ANIM_ATTACKER playsewithpan SE_W100, SOUND_PAN_ATTACKER waitplaysewithpan SE_W107, SOUND_PAN_ATTACKER, 48 - createvisualtask sub_815B7D0, 2, 0 + createvisualtask sub_815B7D0, 2, 0, 0 waitforvisualfinish clearmonbg ANIM_ATTACKER end @@ -12772,7 +12772,7 @@ AnimScript_82D7EB2: monbg ANIM_ATTACKER playsewithpan SE_W100, SOUND_PAN_ATTACKER waitplaysewithpan SE_W107, SOUND_PAN_ATTACKER, 48 - createvisualtask sub_815B7D0, 2, 1 + createvisualtask sub_815B7D0, 2, 1, 0 waitforvisualfinish clearmonbg ANIM_ATTACKER end @@ -13153,7 +13153,7 @@ General_MegaEvolution: createsprite gBattleAnimSpriteTemplate_85972D8, ANIM_ATTACKER, 2, 4, 1, 180, 1 createvisualtask sub_8159244, 5, 234, 0 delay 20 - createvisualtask sub_815B7D0, 2, 0 + createvisualtask sub_815B7D0, 2, 0, 1 delay 4 createvisualtask sub_8117494, 50 waitforvisualfinish diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index e190bfc749..3fff8417a0 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -5726,9 +5726,12 @@ BattleScript_FocusPunchSetUp:: BattleScript_MegaEvolution:: printstring STRINGID_MEGAEVOREACTING waitmessage 0x40 - handlemegaevo BS_ATTACKER + setbyte gIsCriticalHit, 0 + handlemegaevo BS_ATTACKER, 0 + handlemegaevo BS_ATTACKER, 1 playanimation BS_ATTACKER, B_ANIM_MEGA_EVOLUTION, NULL waitanimation + handlemegaevo BS_ATTACKER, 2 printstring STRINGID_MEGAEVOEVOLVED waitmessage 0x40 end2 diff --git a/graphics/battle_interface/mega_indicator.png b/graphics/battle_interface/mega_indicator.png new file mode 100644 index 0000000000..93e113ded4 Binary files /dev/null and b/graphics/battle_interface/mega_indicator.png differ diff --git a/include/battle_gfx_sfx_util.h b/include/battle_gfx_sfx_util.h index 16253e760e..546683ebac 100644 --- a/include/battle_gfx_sfx_util.h +++ b/include/battle_gfx_sfx_util.h @@ -27,7 +27,7 @@ bool8 BattleInitAllSprites(u8 *state1, u8 *battlerId); void ClearSpritesHealthboxAnimData(void); void CopyAllBattleSpritesInvisibilities(void); void CopyBattleSpriteInvisibility(u8 battlerId); -void HandleSpeciesGfxDataChange(u8 attacker, u8 target, bool8 notTransform); +void HandleSpeciesGfxDataChange(u8 attacker, u8 target, bool8 notTransform, bool32 megaEvo); void BattleLoadSubstituteOrMonSpriteGfx(u8 battlerId, bool8 loadMonSprite); void LoadBattleMonGfxAndAnimate(u8 battlerId, bool8 loadMonSprite, u8 spriteId); void TrySetBehindSubstituteSpriteBit(u8 battlerId, u16 move); diff --git a/include/battle_interface.h b/include/battle_interface.h index 0b6cf6cf2e..f46ce3f24d 100644 --- a/include/battle_interface.h +++ b/include/battle_interface.h @@ -40,6 +40,7 @@ enum #define TAG_STATUS_SUMMARY_BALLS_TILE 0xD714 #define TAG_MEGA_TRIGGER_TILE 0xD777 +#define TAG_MEGA_INDICATOR_TILE 0xD778 #define TAG_HEALTHBOX_PAL 0xD6FF #define TAG_HEALTHBAR_PAL 0xD704 @@ -47,6 +48,7 @@ enum #define TAG_STATUS_SUMMARY_BALLS_PAL 0xD712 #define TAG_MEGA_TRIGGER_PAL 0xD777 +#define TAG_MEGA_INDICATOR_PAL 0xD778 enum { @@ -80,6 +82,8 @@ void CreateMegaTriggerSprite(u8 battlerId, u8 palId); bool32 IsMegaTriggerSpriteActive(void); void HideMegaTriggerSprite(void); void DestroyMegaTriggerSprite(void); +void CreateMegaIndicatorSprite(u32 battlerId, u32 which); +void DestroyMegaIndicatorSprite(u8 battlerId); u8 CreatePartyStatusSummarySprites(u8 battler, struct HpAndStatus *partyInfo, u8 arg2, bool8 isBattleStart); void Task_HidePartyStatusSummary(u8 taskId); void UpdateHealthboxAttribute(u8 healthboxSpriteId, struct Pokemon *mon, u8 elementId); diff --git a/src/battle_anim_effects_3.c b/src/battle_anim_effects_3.c index 98dbf71696..040438fdf1 100755 --- a/src/battle_anim_effects_3.c +++ b/src/battle_anim_effects_3.c @@ -2293,7 +2293,7 @@ void sub_815B7D0(u8 taskId) } break; case 2: - HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10]); + HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, gTasks[taskId].data[10], gBattleAnimArgs[1]); sub_80A6BFC(&animBg, gBattleAnimAttacker); if (IsContest()) @@ -2380,7 +2380,7 @@ void sub_815BB18(u8 taskId) void sub_815BB58(u8 taskId) { - HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, TRUE); + HandleSpeciesGfxDataChange(gBattleAnimAttacker, gBattleAnimTarget, TRUE, FALSE); DestroyAnimVisualTask(taskId); } @@ -4333,7 +4333,7 @@ static void AnimSmellingSaltExclamationStep(struct Sprite *sprite) // Claps a hand several times. // arg 0: which hand -// arg 1: +// arg 1: void AnimHelpingHandClap(struct Sprite *sprite) { if (gBattleAnimArgs[0] == 0) diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index f3aaaede45..9dceb3c56b 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -847,7 +847,7 @@ void CopyBattleSpriteInvisibility(u8 battlerId) gBattleSpritesDataPtr->battlerData[battlerId].invisible = gSprites[gBattlerSpriteIds[battlerId]].invisible; } -void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 notTransform) +void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 notTransform, bool32 megaEvo) { u16 paletteOffset; u32 personalityValue; @@ -932,10 +932,13 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, bool8 notTransform LoadPalette(gBattleStruct->castformPalette[0] + gBattleMonForms[battlerDef] * 16, paletteOffset, 32); } - BlendPalette(paletteOffset, 16, 6, RGB_WHITE); - CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); + if (!megaEvo) + { + BlendPalette(paletteOffset, 16, 6, RGB_WHITE); + CpuCopy32(gPlttBufferFaded + paletteOffset, gPlttBufferUnfaded + paletteOffset, 32); + } - if (!IsContest()) + if (!IsContest() && !megaEvo) { gBattleSpritesDataPtr->battlerData[battlerAtk].transformSpecies = targetSpecies; gBattleMonForms[battlerAtk] = gBattleMonForms[battlerDef]; diff --git a/src/battle_interface.c b/src/battle_interface.c index 1d70b68051..6b59e2cc20 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -186,6 +186,7 @@ static void SpriteCB_StatusSummaryBallsOnBattleStart(struct Sprite *sprite); static void SpriteCB_StatusSummaryBallsOnSwitchout(struct Sprite *sprite); static void SpriteCb_MegaTrigger(struct Sprite *sprite); +static void SpriteCb_MegaIndicator(struct Sprite *sprite); static u8 GetStatusIconForBattlerId(u8 statusElementId, u8 battlerId); static s32 CalcNewBarValue(s32 maxValue, s32 currValue, s32 receivedValue, s32 *arg3, u8 arg4, u16 arg5); @@ -548,6 +549,47 @@ 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 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 = 0, + .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, +}; + + // code // Because the healthbox is too large to fit into one sprite, it is divided into two sprites. @@ -649,6 +691,10 @@ u8 CreateBattlerHealthboxSprites(u8 battlerId) healthBarSpritePtr->hBar_Data6 = data6; healthBarSpritePtr->invisible = TRUE; + // Create mega indicator sprite if is a mega evolved mon. + if (gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(battlerId)]) + CreateMegaIndicatorSprite(battlerId, 0); + return healthboxLeftSpriteId; } @@ -706,12 +752,19 @@ static void SpriteCB_HealthBar(struct Sprite *sprite) static void SpriteCB_HealthBoxOther(struct Sprite *sprite) { u8 healthboxMainSpriteId = sprite->hOther_HealthBoxSpriteId; + u8 megaSpriteId = gBattleStruct->mega.indicatorSpriteIds[gSprites[healthboxMainSpriteId].hMain_Battler]; sprite->pos1.x = gSprites[healthboxMainSpriteId].pos1.x + 64; sprite->pos1.y = gSprites[healthboxMainSpriteId].pos1.y; sprite->pos2.x = gSprites[healthboxMainSpriteId].pos2.x; sprite->pos2.y = gSprites[healthboxMainSpriteId].pos2.y; + + if (megaSpriteId != 0xFF) + { + gSprites[megaSpriteId].pos2.x = sprite->pos2.x; + gSprites[megaSpriteId].pos2.y = sprite->pos2.y; + } } void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldVal, s32 receivedValue) @@ -725,6 +778,7 @@ void SetBattleBarStruct(u8 battlerId, u8 healthboxSpriteId, s32 maxVal, s32 oldV void SetHealthboxSpriteInvisible(u8 healthboxSpriteId) { + DestroyMegaIndicatorSprite(gSprites[healthboxSpriteId].hMain_Battler); gSprites[healthboxSpriteId].invisible = TRUE; gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId].invisible = TRUE; gSprites[gSprites[healthboxSpriteId].oam.affineParam].invisible = TRUE; @@ -745,6 +799,7 @@ static void UpdateSpritePos(u8 spriteId, s16 x, s16 y) void DestoryHealthboxSprite(u8 healthboxSpriteId) { + DestroyMegaIndicatorSprite(gSprites[healthboxSpriteId].hMain_Battler); DestroySprite(&gSprites[gSprites[healthboxSpriteId].oam.affineParam]); DestroySprite(&gSprites[gSprites[healthboxSpriteId].hMain_HealthBarSpriteId]); DestroySprite(&gSprites[healthboxSpriteId]); @@ -771,36 +826,42 @@ void UpdateOamPriorityInAllHealthboxes(u8 priority) } } -void InitBattlerHealthboxCoords(u8 battler) +void GetBattlerHealthboxCoords(u8 battler, s16 *x, s16 *y) { - s16 x = 0, y = 0; + *x = 0, *y = 0; if (!IsDoubleBattle()) { if (GetBattlerSide(battler) != B_SIDE_PLAYER) - x = 44, y = 30; + *x = 44, *y = 30; else - x = 158, y = 88; + *x = 158, *y = 88; } else { switch (GetBattlerPosition(battler)) { case B_POSITION_PLAYER_LEFT: - x = 159, y = 76; + *x = 159, *y = 76; break; case B_POSITION_PLAYER_RIGHT: - x = 171, y = 101; + *x = 171, *y = 101; break; case B_POSITION_OPPONENT_LEFT: - x = 44, y = 19; + *x = 44, *y = 19; break; case B_POSITION_OPPONENT_RIGHT: - x = 32, y = 44; + *x = 32, *y = 44; break; } } +} +void InitBattlerHealthboxCoords(u8 battler) +{ + s16 x, y; + + GetBattlerHealthboxCoords(battler, &x, &y); UpdateSpritePos(gHealthboxSpriteIds[battler], x, y); } @@ -811,11 +872,21 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl) u8 text[16]; u32 xPos, var1; void *objVram; + u8 battler = gSprites[healthboxSpriteId].hMain_Battler; - text[0] = 0xF9; - text[1] = 5; + // Don't print Lv char if mon is mega evolved. + if (gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(battler)]) + { + xPos = (u32) ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3); + } + else + { + text[0] = 0xF9; + text[1] = 5; + + xPos = (u32) ConvertIntToDecimalStringN(text + 2, lvl, STR_CONV_MODE_LEFT_ALIGN, 3); + } - 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--; @@ -828,7 +899,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl) windowTileData = AddTextPrinterAndCreateWindowOnHealthbox(text, xPos, 3, 2, &windowId); spriteTileNum = gSprites[healthboxSpriteId].oam.tileNum * TILE_SIZE_4BPP; - if (GetBattlerSide(gSprites[healthboxSpriteId].hMain_Battler) == B_SIDE_PLAYER) + if (GetBattlerSide(battler) == B_SIDE_PLAYER) { objVram = (void*)(OBJ_VRAM0); if (!IsDoubleBattle()) @@ -1266,6 +1337,76 @@ void DestroyMegaTriggerSprite(void) gBattleStruct->mega.triggerSpriteId = 0xFF; } +static const s8 sIndicatorPosSingles[][2] = +{ + [B_POSITION_PLAYER_LEFT] = {42, -7}, + [B_POSITION_OPPONENT_LEFT] = {10, 10}, +}; + +static const s8 sIndicatorPosDoubles[][2] = +{ + [B_POSITION_PLAYER_LEFT] = {53, -8}, + [B_POSITION_OPPONENT_LEFT] = {10, 10}, + [B_POSITION_PLAYER_RIGHT] = {10, 10}, + [B_POSITION_OPPONENT_RIGHT] = {10, 10}, +}; + +void CreateMegaIndicatorSprite(u32 battlerId, u32 which) +{ + u8 spriteId, position; + s16 x, y; + + LoadSpritePalette(&sSpritePalette_MegaIndicator); + LoadSpriteSheet(&sSpriteSheet_MegaIndicator); + + position = GetBattlerPosition(battlerId); + GetBattlerHealthboxCoords(battlerId, &x, &y); + if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + { + x += sIndicatorPosDoubles[position][0]; + y += sIndicatorPosDoubles[position][1]; + } + else + { + x += sIndicatorPosSingles[position][0]; + y += sIndicatorPosSingles[position][1]; + } + spriteId = CreateSpriteAtEnd(&sSpriteTemplate_MegaIndicator, x, y, 0); + gBattleStruct->mega.indicatorSpriteIds[battlerId] = spriteId; + + gSprites[spriteId].tBattler = battlerId; +} + +void DestroyMegaIndicatorSprite(u8 battlerId) +{ + u32 i; + + if (gBattleStruct->mega.indicatorSpriteIds[battlerId] != 0xFF) + { + if (gBattleStruct->mega.indicatorSpriteIds[battlerId] != 0) // If called before initialized to 0xFF. + DestroySprite(&gSprites[gBattleStruct->mega.indicatorSpriteIds[battlerId]]); + gBattleStruct->mega.indicatorSpriteIds[battlerId] = 0xFF; + } + + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + { + if (gBattleStruct->mega.indicatorSpriteIds[i] != 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); + } +} + +static void SpriteCb_MegaIndicator(struct Sprite *sprite) +{ + if (gBattleStruct->mega.indicatorSpriteIds[sprite->tBattler] == 0xFF) + DestroySprite(sprite); +} + #undef tBattler #undef tHide diff --git a/src/battle_main.c b/src/battle_main.c index bca4f26a7e..6b97aff4b2 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -2723,11 +2723,11 @@ void sub_8039C00(struct Sprite *sprite) } } -#define sSinIndex data[0] -#define sDelta data[1] -#define sAmplitude data[2] -#define sBouncerSpriteId data[3] -#define sWhich data[4] +#define sSinIndex data[3] +#define sDelta data[4] +#define sAmplitude data[5] +#define sBouncerSpriteId data[6] +#define sWhich data[7] void DoBounceEffect(u8 battler, u8 which, s8 delta, s8 amplitude) { @@ -2766,6 +2766,7 @@ void DoBounceEffect(u8 battler, u8 which, s8 delta, s8 amplitude) gSprites[invisibleSpriteId].sAmplitude = amplitude; gSprites[invisibleSpriteId].sBouncerSpriteId = bouncerSpriteId; gSprites[invisibleSpriteId].sWhich = which; + gSprites[invisibleSpriteId].sBattler = battler; gSprites[bouncerSpriteId].pos2.x = 0; gSprites[bouncerSpriteId].pos2.y = 0; } @@ -2800,15 +2801,15 @@ void EndBounceEffect(u8 battler, u8 which) static void SpriteCB_BounceEffect(struct Sprite *sprite) { u8 bouncerSpriteId = sprite->sBouncerSpriteId; - s32 index; + s32 index = sprite->sSinIndex; + s32 y = Sin(index, sprite->sAmplitude) + sprite->sAmplitude; - if (sprite->sWhich == BOUNCE_HEALTHBOX) - index = sprite->sSinIndex; - else - index = sprite->sSinIndex; - - gSprites[bouncerSpriteId].pos2.y = Sin(index, sprite->sAmplitude) + sprite->sAmplitude; + gSprites[bouncerSpriteId].pos2.y = y; sprite->sSinIndex = (sprite->sSinIndex + sprite->sDelta) & 0xFF; + + bouncerSpriteId = gBattleStruct->mega.indicatorSpriteIds[sprite->sBattler]; + if (sprite->sWhich == BOUNCE_HEALTHBOX && bouncerSpriteId != 0xFF) + gSprites[bouncerSpriteId].pos2.y = y; } #undef sSinIndex diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 86ca273e6d..8e113c3d47 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -776,7 +776,7 @@ static const u16 sMovesForbiddenToCopy[] = static const u16 sMoveEffectsForbiddenToInstruct[] = -{ +{ EFFECT_ASSIST, //EFFECT_BEAK_BLAST, EFFECT_BIDE, @@ -4010,6 +4010,7 @@ static void atk45_playanimation(void) if (gBattlescriptCurrInstr[2] == B_ANIM_STATS_CHANGE || gBattlescriptCurrInstr[2] == B_ANIM_SNATCH_MOVE + || gBattlescriptCurrInstr[2] == B_ANIM_MEGA_EVOLUTION || gBattlescriptCurrInstr[2] == B_ANIM_SUBSTITUTE_FADE) { BtlController_EmitBattleAnimation(0, gBattlescriptCurrInstr[2], *argumentPtr); @@ -4053,6 +4054,7 @@ static void atk46_playanimation2(void) // animation Id is stored in the first po if (*animationIdPtr == B_ANIM_STATS_CHANGE || *animationIdPtr == B_ANIM_SNATCH_MOVE + || *animationIdPtr == B_ANIM_MEGA_EVOLUTION || *animationIdPtr == B_ANIM_SUBSTITUTE_FADE) { BtlController_EmitBattleAnimation(0, *animationIdPtr, *argumentPtr); @@ -7041,37 +7043,49 @@ static void atk76_various(void) else mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]; - 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)))) + // Change species. + if (gBattlescriptCurrInstr[3] == 0) { - gBattleStruct->mega.playerEvolvedSpecies = gBattleStruct->mega.evolvedSpecies[gActiveBattler]; + 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]; + } + + gBattleMons[gActiveBattler].species = GetMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[gActiveBattler], gBattleMons[gActiveBattler].item); + PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species); + + BtlController_EmitSetMonData(0, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], 2, &gBattleMons[gActiveBattler].species); + MarkBattlerForControllerExec(gActiveBattler); } + // Change stats. + else if (gBattlescriptCurrInstr[3] == 1) + { + CalculateMonStats(mon); + gBattleMons[gActiveBattler].level = GetMonData(mon, MON_DATA_LEVEL); + gBattleMons[gActiveBattler].hp = GetMonData(mon, MON_DATA_HP); + gBattleMons[gActiveBattler].maxHP = GetMonData(mon, MON_DATA_MAX_HP); + gBattleMons[gActiveBattler].attack = GetMonData(mon, MON_DATA_ATK); + gBattleMons[gActiveBattler].defense = GetMonData(mon, MON_DATA_DEF); + gBattleMons[gActiveBattler].speed = GetMonData(mon, MON_DATA_SPEED); + gBattleMons[gActiveBattler].spAttack = GetMonData(mon, MON_DATA_SPATK); + gBattleMons[gActiveBattler].spDefense = GetMonData(mon, MON_DATA_SPDEF); + gBattleMons[gActiveBattler].ability = GetMonAbility(mon); + gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; + gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; - gBattleMons[gActiveBattler].species = GetMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[gActiveBattler], gBattleMons[gActiveBattler].item); - SetMonData(mon, MON_DATA_SPECIES, &gBattleMons[gActiveBattler].species); - PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species); - - CalculateMonStats(mon); - gBattleMons[gActiveBattler].level = GetMonData(mon, MON_DATA_LEVEL); - gBattleMons[gActiveBattler].hp = GetMonData(mon, MON_DATA_HP); - gBattleMons[gActiveBattler].maxHP = GetMonData(mon, MON_DATA_MAX_HP); - gBattleMons[gActiveBattler].attack = GetMonData(mon, MON_DATA_ATK); - gBattleMons[gActiveBattler].defense = GetMonData(mon, MON_DATA_DEF); - gBattleMons[gActiveBattler].speed = GetMonData(mon, MON_DATA_SPEED); - gBattleMons[gActiveBattler].spAttack = GetMonData(mon, MON_DATA_SPATK); - gBattleMons[gActiveBattler].spDefense = GetMonData(mon, MON_DATA_SPDEF); - gBattleMons[gActiveBattler].ability = GetMonAbility(mon); - gBattleMons[gActiveBattler].type1 = gBaseStats[gBattleMons[gActiveBattler].species].type1; - gBattleMons[gActiveBattler].type2 = gBaseStats[gBattleMons[gActiveBattler].species].type2; - - UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL); - gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(gActiveBattler)] = TRUE; - gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]]; - - BtlController_EmitSetMonData(0, REQUEST_ALL_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], sizeof(struct BattlePokemon), &gBattleMons[gActiveBattler]); - MarkBattlerForControllerExec(gActiveBattler); - break; + gBattleStruct->mega.alreadyEvolved[GetBattlerPosition(gActiveBattler)] = TRUE; + gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]]; + } + // Update healthbox. + else + { + UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL); + CreateMegaIndicatorSprite(gActiveBattler, 0); + } + gBattlescriptCurrInstr += 4; + return; case VARIOUS_TRY_LAST_RESORT: if (CanUseLastResort(gActiveBattler)) gBattlescriptCurrInstr += 7; @@ -7181,7 +7195,7 @@ static void atk76_various(void) gBattlerTarget = gBattleStruct->lastMoveTarget[gBattlerAttacker]; gHitMarker &= ~(HITMARKER_ATTACKSTRING_PRINTED); PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, gActiveBattler, gBattlerPartyIndexes[gActiveBattler]); - gBattlescriptCurrInstr += 7; + gBattlescriptCurrInstr += 7; } } return; diff --git a/src/data/items.h b/src/data/items.h index 4d262e6833..6d1673ee0a 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -177,6 +177,7 @@ const struct Item gItems[] = .name = _("POTION"), .itemId = ITEM_POTION, .price = 300, + .holdEffect = HOLD_EFFECT_MEGA_STONE, .holdEffectParam = 20, .description = sPotionDesc, .pocket = POCKET_ITEMS, diff --git a/src/data/pokemon/evolution.h b/src/data/pokemon/evolution.h index c9b0cf716d..9313753830 100644 --- a/src/data/pokemon/evolution.h +++ b/src/data/pokemon/evolution.h @@ -184,4 +184,5 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] = [SPECIES_SHELGON] = {{EVO_LEVEL, 50, SPECIES_SALAMENCE}}, [SPECIES_BELDUM] = {{EVO_LEVEL, 20, SPECIES_METANG}}, [SPECIES_METANG] = {{EVO_LEVEL, 45, SPECIES_METAGROSS}}, + [SPECIES_SKARMORY] = {{EVO_MEGA_EVOLUTION, ITEM_POTION, SPECIES_HO_OH}}, };