diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index de84e2411f..e3770ee70c 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -6136,6 +6136,20 @@ BattleScript_MegaEvolution:: switchinabilities BS_ATTACKER end2 +BattleScript_WishMegaEvolution:: + printstring STRINGID_FERVENTWISHREACHED + waitmessage 0x40 + 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 + switchinabilities BS_ATTACKER + end2 + BattleScript_AttackerFormChange:: pause 0x5 copybyte gBattlerAbility, gBattlerAttacker diff --git a/include/battle.h b/include/battle.h index 4cf4a3a169..d04e438159 100644 --- a/include/battle.h +++ b/include/battle.h @@ -414,6 +414,7 @@ struct MegaEvolutionData u8 battlerId; bool8 playerSelect; u8 triggerSpriteId; + bool8 isWishMegaEvo; }; struct Illusion diff --git a/include/battle_scripts.h b/include/battle_scripts.h index cb2e0f9158..84a7ba2ef8 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -278,6 +278,7 @@ extern const u8 BattleScript_ToxicSpikesFree[]; extern const u8 BattleScript_StickyWebFree[]; extern const u8 BattleScript_StealthRockFree[]; extern const u8 BattleScript_MegaEvolution[]; +extern const u8 BattleScript_WishMegaEvolution[]; extern const u8 BattleScript_MoveEffectRecoilWithStatus[]; extern const u8 BattleScript_EffectWithChance[]; extern const u8 BattleScript_MoveEffectClearSmog[]; diff --git a/include/battle_util.h b/include/battle_util.h index ab98796c1b..422aa73006 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -119,6 +119,7 @@ u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 ability u16 GetTypeModifier(u8 atkType, u8 defType); s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId); u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId); +u16 GetWishMegaEvolutionSpecies(u16 preEvoSpecies, u16 moveId1, u16 moveId2, u16 moveId3, u16 moveId4); bool32 CanMegaEvolve(u8 battlerId); void UndoMegaEvolution(u32 monId); void UndoFormChange(u32 monId, u32 side); diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 2f66f97f91..76d7476c54 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -549,7 +549,8 @@ #define STRINGID_NOONEWILLBEABLETORUNAWAY 545 #define STRINGID_DESTINYKNOTACTIVATES 546 #define STRINGID_CLOAKEDINAFREEZINGLIGHT 547 +#define STRINGID_FERVENTWISHREACHED 548 -#define BATTLESTRINGS_COUNT 548 +#define BATTLESTRINGS_COUNT 549 #endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index 480a37f03a..1e2f6b335e 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -293,7 +293,8 @@ #define F_SUMMARY_SCREEN_FLIP_SPRITE 0x80 // Evolution types -#define EVO_MEGA_EVOLUTION 0xffff // Not an actual evolution, used to temporarily mega evolve in battle. +#define EVO_MEGA_EVOLUTION 0xffff // Not an actual evolution, used to temporarily mega evolve in battle. +#define EVO_WISH_MEGA_EVOLUTION 0xfffe // Not an actual evolution, used to temporarily mega evolve in battle. #define EVO_FRIENDSHIP 1 // Pokémon levels up with friendship ≥ 220 #define EVO_FRIENDSHIP_DAY 2 // Pokémon levels up during the day with friendship ≥ 220 #define EVO_FRIENDSHIP_NIGHT 3 // Pokémon levels up at night with friendship ≥ 220 diff --git a/src/battle_main.c b/src/battle_main.c index accd7605be..d5eb9a82e6 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4552,7 +4552,10 @@ static void CheckMegaEvolutionBeforeTurn(void) { gBattleStruct->mega.toEvolve &= ~(gBitTable[gActiveBattler]); gLastUsedItem = gBattleMons[gActiveBattler].item; - BattleScriptExecute(BattleScript_MegaEvolution); + if (gBattleStruct->mega.isWishMegaEvo == TRUE) + BattleScriptExecute(BattleScript_WishMegaEvolution); + else + BattleScriptExecute(BattleScript_MegaEvolution); return; } } diff --git a/src/battle_message.c b/src/battle_message.c index a528b9d9a6..070eaef840 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -634,6 +634,7 @@ static const u8 sText_AssaultVestDoesntAllow[] = _("The effects of the {B_LAST_I static const u8 sText_GravityPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} can't use {B_CURRENT_MOVE}\nbecause of gravity!\p"); static const u8 sText_HealBlockPreventsUsage[] = _("{B_ATK_NAME_WITH_PREFIX} was\nprevented from healing!\p"); static const u8 sText_MegaEvoReacting[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_LAST_ITEM} is \nreacting to {B_ATK_TRAINER_NAME}'s Mega Ring!"); +static const u8 sText_FerventWishReached[] = _("{B_ATK_TRAINER_NAME}'s fervent wish\n has reached {B_ATK_NAME_WITH_PREFIX}!"); static const u8 sText_MegaEvoEvolved[] = _("{B_ATK_NAME_WITH_PREFIX} has Mega\nEvolved into Mega {B_BUFF1}!"); static const u8 sText_drastically[] = _("drastically "); static const u8 sText_severely[] = _("severely "); @@ -1198,6 +1199,7 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_TERRAINBECOMESPSYCHIC - 12] = sText_TerrainBecomesPsychic, [STRINGID_TARGETELECTRIFIED - 12] = sText_TargetElectrified, [STRINGID_MEGAEVOREACTING - 12] = sText_MegaEvoReacting, + [STRINGID_FERVENTWISHREACHED - 12] = sText_FerventWishReached, [STRINGID_MEGAEVOEVOLVED - 12] = sText_MegaEvoEvolved, [STRINGID_DRASTICALLY - 12] = sText_drastically, [STRINGID_SEVERELY - 12] = sText_severely, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 36355d10da..41c66b8874 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7853,14 +7853,22 @@ static void Cmd_various(void) // Change species. if (gBattlescriptCurrInstr[3] == 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 = GetMegaEvolutionSpecies(gBattleStruct->mega.evolvedSpecies[gActiveBattler], gBattleMons[gActiveBattler].item); + gBattleMons[gActiveBattler].species = megaSpecies; PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species); BtlController_EmitSetMonData(0, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], 2, &gBattleMons[gActiveBattler].species); diff --git a/src/battle_util.c b/src/battle_util.c index f047cc882b..b1ec32ebf7 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -7488,9 +7488,26 @@ u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId) return SPECIES_NONE; } +u16 GetWishMegaEvolutionSpecies(u16 preEvoSpecies, u16 moveId1, u16 moveId2, u16 moveId3, u16 moveId4) +{ + u32 i, par; + + for (i = 0; i < EVOS_PER_MON; i++) + { + if (gEvolutionTable[preEvoSpecies][i].method == EVO_WISH_MEGA_EVOLUTION) + { + par = gEvolutionTable[preEvoSpecies][i].param; + if (par == moveId1 || par == moveId2 || par == moveId3 || par == moveId4) + return gEvolutionTable[preEvoSpecies][i].targetSpecies; + } + } + return SPECIES_NONE; +} + bool32 CanMegaEvolve(u8 battlerId) { - u32 itemId, holdEffect; + u8 i; + u32 itemId, holdEffect, species; struct Pokemon *mon; u8 battlerPosition = GetBattlerPosition(battlerId); u8 partnerPosition = GetBattlerPosition(BATTLE_PARTNER(battlerId)); @@ -7506,29 +7523,42 @@ bool32 CanMegaEvolve(u8 battlerId) return FALSE; } - // Check if the pokemon holds an appropriate item. + // Gets mon data. if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]]; else mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]]; + species = GetMonData(mon, MON_DATA_SPECIES); itemId = GetMonData(mon, MON_DATA_HELD_ITEM); - if (USE_BATTLE_DEBUG && gBattleStruct->debugHoldEffects[battlerId]) - holdEffect = gBattleStruct->debugHoldEffects[battlerId]; - else if (itemId == ITEM_ENIGMA_BERRY) - holdEffect = gEnigmaBerries[battlerId].holdEffect; - else - holdEffect = ItemId_GetHoldEffect(itemId); - if (holdEffect != HOLD_EFFECT_MEGA_STONE) - return FALSE; + // Check if there is an entry in the evolution table for regular Mega Evolution. + if (GetMegaEvolutionSpecies(species, itemId) != SPECIES_NONE) + { + if (USE_BATTLE_DEBUG && gBattleStruct->debugHoldEffects[battlerId]) + holdEffect = gBattleStruct->debugHoldEffects[battlerId]; + else if (itemId == ITEM_ENIGMA_BERRY) + holdEffect = gEnigmaBerries[battlerId].holdEffect; + else + holdEffect = ItemId_GetHoldEffect(itemId); - // Check if there is an entry in the evolution table. - if (GetMegaEvolutionSpecies(GetMonData(mon, MON_DATA_SPECIES), itemId) == SPECIES_NONE) - return FALSE; + // Can Mega Evolve via Item. + if (holdEffect == HOLD_EFFECT_MEGA_STONE) + { + gBattleStruct->mega.isWishMegaEvo = FALSE; + return TRUE; + } + } - // All checks passed, the mon CAN mega evolve. - return TRUE; + // Check if there is an entry in the evolution table for Wish Mega Evolution. + if (GetWishMegaEvolutionSpecies(species, GetMonData(mon, MON_DATA_MOVE1), GetMonData(mon, MON_DATA_MOVE2), GetMonData(mon, MON_DATA_MOVE3), GetMonData(mon, MON_DATA_MOVE4))) + { + gBattleStruct->mega.isWishMegaEvo = TRUE; + return TRUE; + } + + // No checks passed, the mon CAN'T mega evolve. + return FALSE; } void UndoMegaEvolution(u32 monId)