diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 46719eb3e..863153b9d 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -12057,6 +12057,8 @@ Anim_WishHeal: end General_MegaEvolution: + createvisualtask sub_815B7D0, 0x2, 0 + waitforvisualfinish end AnimScript_82D85A3: diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 0402dc526..dbd076140 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4614,9 +4614,9 @@ BattleScript_FocusPunchSetUp:: BattleScript_MegaEvolution:: printstring STRINGID_MEGAEVOREACTING waitmessage 0x40 + handlemegaevo BS_ATTACKER playanimation BS_ATTACKER, B_ANIM_MEGA_EVOLUTION, NULL waitanimation - handlemegaevo BS_ATTACKER printstring STRINGID_MEGAEVOEVOLVED waitmessage 0x40 end2 diff --git a/include/battle.h b/include/battle.h index cedba63c0..ee2323215 100644 --- a/include/battle.h +++ b/include/battle.h @@ -602,7 +602,11 @@ struct BattleStruct u8 megaEvolvedPartyIds[2]; // As flags using gBitTable; bool8 alreadyMegaEvolved[4]; // Array id is used for mon position. u16 speciesToMegaEvolve[MAX_BATTLERS_COUNT]; + u16 playerSpeciesThatMegaEvolved; u8 megaEvoBattlerId; + bool8 playerMegaEvoSelect; + u8 megaEvoTriggerSpriteId; + u8 megaEvoIndicatorSpriteId[MAX_BATTLERS_COUNT]; }; #define GET_MOVE_TYPE(move, typeArg) \ diff --git a/include/battle_util.h b/include/battle_util.h index cf445cfa5..aa69a020b 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -89,5 +89,6 @@ u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 ability u16 GetTypeModifier(u8 atkType, u8 defType); s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId); bool32 CanMegaEvolve(u8 battlerId); +void UndoMegaEvolution(u8 monId); #endif // GUARD_BATTLE_UTIL_H diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 7334b5e79..1e417194d 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -386,7 +386,10 @@ static void HandleInputChooseTarget(void) { PlaySE(SE_SELECT); gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = sub_8039B2C; - BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + if (gBattleStruct->playerMegaEvoSelect) + BtlController_EmitTwoReturnValues(1, 10 | RET_MEGA_EVOLUTION, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + else + BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX); PlayerBufferExecCompleted(); } @@ -540,7 +543,10 @@ static void HandleInputChooseMove(void) if (!canSelectTarget) { - BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + if (gBattleStruct->playerMegaEvoSelect) + BtlController_EmitTwoReturnValues(1, 10 | RET_MEGA_EVOLUTION, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); + else + BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); PlayerBufferExecCompleted(); } else @@ -560,6 +566,7 @@ static void HandleInputChooseMove(void) else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59) { PlaySE(SE_SELECT); + gBattleStruct->playerMegaEvoSelect = FALSE; BtlController_EmitTwoReturnValues(1, 10, 0xFFFF); PlayerBufferExecCompleted(); } @@ -629,6 +636,15 @@ static void HandleInputChooseMove(void) gBattlerControllerFuncs[gActiveBattler] = HandleMoveSwitchting; } } + else if (gMain.newKeys & START_BUTTON) + { + if (gBattleStruct->megaEvoTriggerSpriteId != 0xFF) + { + gBattleStruct->playerMegaEvoSelect ^= 1; + // StartSpriteAnim(&gSprites[gBattleStruct->megaEvoTriggerSpriteId], gBattleStruct->playerMegaEvoSelect); + PlaySE(SE_SELECT); + } + } } u32 sub_8057FBC(void) // unused @@ -2628,6 +2644,11 @@ static void PlayerHandleChooseMove(void) { InitMoveSelectionsVarsAndStrings(); gBattlerControllerFuncs[gActiveBattler] = HandleChooseMoveAfterDma3; + gBattleStruct->playerMegaEvoSelect = FALSE; + if (CanMegaEvolve(gActiveBattler) && gBattleStruct->megaEvoTriggerSpriteId == 0xFF) + gBattleStruct->megaEvoTriggerSpriteId = CreateSprite(&gDummySpriteTemplate, 100, 100, 0); + else + gBattleStruct->megaEvoTriggerSpriteId = 0xFF; } } diff --git a/src/battle_main.c b/src/battle_main.c index 1f0dc57fe..50a69ec87 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3098,6 +3098,10 @@ static void BattleStartClearSetData(void) gBattleStruct->field_2A0 = 0; gBattleStruct->field_2A1 = 0; + + gBattleStruct->megaEvoTriggerSpriteId = 0xFF; + for (i = 0; i < MAX_BATTLERS_COUNT; i++) + gBattleStruct->megaEvoIndicatorSpriteId[i] = 0xFF; } void SwitchInClearSetData(void) @@ -3306,6 +3310,8 @@ void FaintClearSetData(void) ClearBattlerMoveHistory(gActiveBattler); ClearBattlerAbilityHistory(gActiveBattler); + if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER) + UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]); } static void BattleIntroGetMonsData(void) @@ -5165,6 +5171,8 @@ static void HandleEndTurn_MonFled(void) static void HandleEndTurn_FinishBattle(void) { + u32 i; + if (gCurrentActionFuncId == 0xB || gCurrentActionFuncId == 0xC) { if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK @@ -5210,6 +5218,8 @@ static void HandleEndTurn_FinishBattle(void) sub_8186444(); BeginFastPaletteFade(3); FadeOutMapMusic(5); + for (i = 0; i < PARTY_SIZE; i++) + UndoMegaEvolution(i); gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions; gCB2_AfterEvolution = BattleMainCB2; } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e23342bb6..e19a08238 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6599,6 +6599,7 @@ static void atk76_various(void) 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); @@ -6606,6 +6607,9 @@ static void atk76_various(void) 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->alreadyMegaEvolved[GetBattlerPosition(gActiveBattler)] = TRUE; diff --git a/src/battle_util.c b/src/battle_util.c index c6e40ddb8..2cf0d88ac 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5600,11 +5600,6 @@ bool32 CanMegaEvolve(u8 battlerId) if (IsPartnerMonFromSameTrainer(battlerId) && gBattleStruct->alreadyMegaEvolved[partnerPosition]) return FALSE; } - else - { - if (gBattleStruct->alreadyMegaEvolved[partnerPosition]) - return FALSE; - } // Check if the pokemon holds an appropriate item, if (GetBattlerHoldEffect(battlerId, FALSE) != HOLD_EFFECT_MEGA_STONE) @@ -5619,6 +5614,9 @@ bool32 CanMegaEvolve(u8 battlerId) && gEvolutionTable[species][i].param == itemId) { gBattleStruct->speciesToMegaEvolve[battlerId] = gEvolutionTable[species][i].targetSpecies; + if (battlerPosition == B_POSITION_PLAYER_LEFT + || (battlerPosition == B_POSITION_PLAYER_RIGHT && !(gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)))) + gBattleStruct->playerSpeciesThatMegaEvolved = species; break; } } @@ -5629,3 +5627,13 @@ bool32 CanMegaEvolve(u8 battlerId) // All checks passed, the mon CAN mega evolve. return TRUE; } + +void UndoMegaEvolution(u8 monId) +{ + if (gBattleStruct->megaEvolvedPartyIds[B_SIDE_PLAYER] & gBitTable[monId]) + { + gBattleStruct->megaEvolvedPartyIds[B_SIDE_PLAYER] &= ~(gBitTable[monId]); + SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleStruct->playerSpeciesThatMegaEvolved); + CalculateMonStats(&gPlayerParty[monId]); + } +}