diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index dbd076140..d7fa9580d 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4610,7 +4610,7 @@ BattleScript_FocusPunchSetUp:: printstring STRINGID_PKMNTIGHTENINGFOCUS waitmessage 0x40 end2 - + BattleScript_MegaEvolution:: printstring STRINGID_MEGAEVOREACTING waitmessage 0x40 diff --git a/include/battle.h b/include/battle.h index ee2323215..f839f8b96 100644 --- a/include/battle.h +++ b/include/battle.h @@ -601,7 +601,7 @@ struct BattleStruct u8 toMegaEvolve; // As flags using gBitTable. u8 megaEvolvedPartyIds[2]; // As flags using gBitTable; bool8 alreadyMegaEvolved[4]; // Array id is used for mon position. - u16 speciesToMegaEvolve[MAX_BATTLERS_COUNT]; + u16 speciesThatMegaEvolved[MAX_BATTLERS_COUNT]; u16 playerSpeciesThatMegaEvolved; u8 megaEvoBattlerId; bool8 playerMegaEvoSelect; diff --git a/include/battle_interface.h b/include/battle_interface.h index c4ee835f0..cbd0bc3c6 100644 --- a/include/battle_interface.h +++ b/include/battle_interface.h @@ -78,6 +78,8 @@ void UpdateHpTextInHealthbox(u8 healthboxSpriteId, s16 value, u8 maxOrCurrent); void SwapHpBarsWithHpText(void); void SetMegaTriggerSpritePal(u8 spriteId, u8 palId); void CreateMegaTriggerSprite(u8 battlerId, u8 palId); +bool32 IsMegaTriggerSpriteActive(void); +void HideMegaTriggerSprite(void); void DestroyMegaTriggerSprite(void); u8 CreatePartyStatusSummarySprites(u8 battler, struct HpAndStatus *partyInfo, u8 arg2, bool8 isBattleStart); void Task_HidePartyStatusSummary(u8 taskId); diff --git a/include/battle_util.h b/include/battle_util.h index aa69a020b..727f9d07f 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -88,6 +88,7 @@ u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 bat u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u8 abilityDef); u16 GetTypeModifier(u8 atkType, u8 defType); s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId); +u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId); bool32 CanMegaEvolve(u8 battlerId); void UndoMegaEvolution(u8 monId); diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 56c454041..6d6f665f2 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -391,7 +391,7 @@ static void HandleInputChooseTarget(void) else BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); EndBounceEffect(gMultiUsePlayerCursor, BOUNCE_HEALTHBOX); - DestroyMegaTriggerSprite(); + HideMegaTriggerSprite(); PlayerBufferExecCompleted(); } else if (gMain.newKeys & B_BUTTON || gPlayerDpadHoldFrames > 59) @@ -548,7 +548,7 @@ static void HandleInputChooseMove(void) BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | RET_MEGA_EVOLUTION | (gMultiUsePlayerCursor << 8)); else BtlController_EmitTwoReturnValues(1, 10, gMoveSelectionCursor[gActiveBattler] | (gMultiUsePlayerCursor << 8)); - DestroyMegaTriggerSprite(); + HideMegaTriggerSprite(); PlayerBufferExecCompleted(); } else @@ -570,7 +570,7 @@ static void HandleInputChooseMove(void) PlaySE(SE_SELECT); gBattleStruct->playerMegaEvoSelect = FALSE; BtlController_EmitTwoReturnValues(1, 10, 0xFFFF); - DestroyMegaTriggerSprite(); + HideMegaTriggerSprite(); PlayerBufferExecCompleted(); } else if (gMain.newKeys & DPAD_LEFT) @@ -641,7 +641,7 @@ static void HandleInputChooseMove(void) } else if (gMain.newKeys & START_BUTTON) { - if (gBattleStruct->megaEvoTriggerSpriteId != 0xFF) + if (CanMegaEvolve(gActiveBattler)) { gBattleStruct->playerMegaEvoSelect ^= 1; SetMegaTriggerSpritePal(gBattleStruct->megaEvoTriggerSpriteId, gBattleStruct->playerMegaEvoSelect); @@ -2646,10 +2646,12 @@ static void PlayerHandleChooseMove(void) else { InitMoveSelectionsVarsAndStrings(); - gBattlerControllerFuncs[gActiveBattler] = HandleChooseMoveAfterDma3; gBattleStruct->playerMegaEvoSelect = FALSE; + if (!IsMegaTriggerSpriteActive()) + gBattleStruct->megaEvoTriggerSpriteId = 0xFF; if (CanMegaEvolve(gActiveBattler)) CreateMegaTriggerSprite(gActiveBattler, 0); + gBattlerControllerFuncs[gActiveBattler] = HandleChooseMoveAfterDma3; } } diff --git a/src/battle_interface.c b/src/battle_interface.c index d47cb6940..736b3be58 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -589,7 +589,7 @@ static const struct OamData sOamData_MegaTrigger = .matrixNum = 0, .size = 2, .tileNum = 0, - .priority = 1, + .priority = 3, .paletteNum = 0, .affineParam = 0, }; @@ -1554,6 +1554,9 @@ void SetMegaTriggerSpritePal(u8 spriteId, u8 palId) #define MEGA_TRIGGER_POS_X_DIFF 19 #define MEGA_TRIGGER_POS_Y_DIFF 1 +#define tBattler data[0] +#define tHide data[1] + void CreateMegaTriggerSprite(u8 battlerId, u8 palId) { if (GetSpriteTileStartByTag(TAG_MEGA_TRIGGER_TILE) == 0xFFFF) @@ -1561,21 +1564,55 @@ void CreateMegaTriggerSprite(u8 battlerId, u8 palId) if (gBattleStruct->megaEvoTriggerSpriteId == 0xFF) { gBattleStruct->megaEvoTriggerSpriteId = CreateSprite(&sSpriteTemplate_MegaTrigger, - gSprites[gHealthboxSpriteIds[battlerId]].pos1.x - MEGA_TRIGGER_POS_X_DIFF, + gSprites[gHealthboxSpriteIds[battlerId]].pos1.x, gSprites[gHealthboxSpriteIds[battlerId]].pos1.y - MEGA_TRIGGER_POS_Y_DIFF, 0); - gSprites[gBattleStruct->megaEvoTriggerSpriteId].data[0] = battlerId; + gSprites[gBattleStruct->megaEvoTriggerSpriteId].tBattler = battlerId; } + gSprites[gBattleStruct->megaEvoTriggerSpriteId].tHide = FALSE; SetMegaTriggerSpritePal(gBattleStruct->megaEvoTriggerSpriteId, palId); } static void SpriteCb_MegaTrigger(struct Sprite *sprite) { - sprite->pos1.x = gSprites[gHealthboxSpriteIds[sprite->data[0]]].pos1.x - MEGA_TRIGGER_POS_X_DIFF; - sprite->pos1.y = gSprites[gHealthboxSpriteIds[sprite->data[0]]].pos1.y - MEGA_TRIGGER_POS_Y_DIFF; + if (sprite->tHide) + { + if (sprite->pos1.x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos1.x + MEGA_TRIGGER_POS_X_DIFF) + sprite->pos1.x++; + if (sprite->pos2.x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos2.x + MEGA_TRIGGER_POS_X_DIFF) + sprite->pos2.x++; - sprite->pos2.x = gSprites[gHealthboxSpriteIds[sprite->data[0]]].pos2.x - MEGA_TRIGGER_POS_X_DIFF; - sprite->pos2.y = gSprites[gHealthboxSpriteIds[sprite->data[0]]].pos2.y - MEGA_TRIGGER_POS_Y_DIFF; + sprite->pos1.y = gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos1.y - MEGA_TRIGGER_POS_Y_DIFF; + sprite->pos2.y = gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos2.y - MEGA_TRIGGER_POS_Y_DIFF; + if (sprite->pos1.x == gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos1.x + MEGA_TRIGGER_POS_X_DIFF + && sprite->pos2.x == gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos2.x + MEGA_TRIGGER_POS_X_DIFF) + DestroyMegaTriggerSprite(); + } + else + { + if (sprite->pos1.x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos1.x - MEGA_TRIGGER_POS_X_DIFF) + sprite->pos1.x--; + if (sprite->pos2.x != gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos2.x - MEGA_TRIGGER_POS_X_DIFF) + sprite->pos2.x--; + + sprite->pos1.y = gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos1.y - MEGA_TRIGGER_POS_Y_DIFF; + sprite->pos2.y = gSprites[gHealthboxSpriteIds[sprite->tBattler]].pos2.y - MEGA_TRIGGER_POS_Y_DIFF; + } +} + +bool32 IsMegaTriggerSpriteActive(void) +{ + if (GetSpriteTileStartByTag(TAG_MEGA_TRIGGER_TILE) == 0xFFFF) + return FALSE; + else if (IndexOfSpritePaletteTag(TAG_MEGA_TRIGGER_OFF_PAL) != 0xFF || IndexOfSpritePaletteTag(TAG_MEGA_TRIGGER_ON_PAL) != 0xFF) + return TRUE; + else + return FALSE; +} + +void HideMegaTriggerSprite(void) +{ + gSprites[gBattleStruct->megaEvoTriggerSpriteId].tHide = TRUE; } void DestroyMegaTriggerSprite(void) @@ -1588,6 +1625,9 @@ void DestroyMegaTriggerSprite(void) gBattleStruct->megaEvoTriggerSpriteId = 0xFF; } +#undef tBattler +#undef tHide + #define tBattler data[0] #define tSummaryBarSpriteId data[1] #define tBallIconSpriteId(n) data[3 + n] diff --git a/src/battle_message.c b/src/battle_message.c index cc592b7d6..c08b83822 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -2579,7 +2579,7 @@ static const u8* TryGetStatusString(u8 *src) StringGetEnd10(text); \ toCpy = text; -static const u8 *BattleStringGetTrainerName(u16 trainerId, u8 *text, u8 multiplierId) +static const u8 *BattleStringGetTrainerName(u16 trainerId, u8 *text, u8 multiplayerId, u8 battlerId) { const u8 *toCpy; @@ -2594,7 +2594,11 @@ static const u8 *BattleStringGetTrainerName(u16 trainerId, u8 *text, u8 multipli } else if (trainerId == TRAINER_OPPONENT_C00) { - toCpy = gLinkPlayers[multiplierId ^ BIT_SIDE].name; + toCpy = gLinkPlayers[multiplayerId ^ BIT_SIDE].name; + } + else if (trainerId == TRAINER_LINK_OPPONENT && gBattleTypeFlags & BATTLE_TYPE_LINK && battlerId != 0xFF) + { + toCpy = gLinkPlayers[GetBattlerMultiplayerId(battlerId)].name; } else if (trainerId == TRAINER_FRONTIER_BRAIN) { @@ -2651,13 +2655,13 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst) u32 dstID = 0; // if they used dstID, why not use srcID as well? const u8 *toCpy = NULL; u8 text[30]; - u8 multiplayerID; + u8 multiplayerId; s32 i; if (gBattleTypeFlags & BATTLE_TYPE_x2000000) - multiplayerID = gUnknown_0203C7B4; + multiplayerId = gUnknown_0203C7B4; else - multiplayerID = GetMultiplayerId(); + multiplayerId = GetMultiplayerId(); while (*src != EOS) { @@ -2732,25 +2736,25 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst) toCpy = text; break; case B_TXT_LINK_PLAYER_MON1_NAME: // link first player poke name - GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].id]], + GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id]], MON_DATA_NICKNAME, text); StringGetEnd10(text); toCpy = text; break; case B_TXT_LINK_OPPONENT_MON1_NAME: // link first opponent poke name - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].id ^ 1]], + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id ^ 1]], MON_DATA_NICKNAME, text); StringGetEnd10(text); toCpy = text; break; case B_TXT_LINK_PLAYER_MON2_NAME: // link second player poke name - GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].id ^ 2]], + GetMonData(&gPlayerParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id ^ 2]], MON_DATA_NICKNAME, text); StringGetEnd10(text); toCpy = text; break; case B_TXT_LINK_OPPONENT_MON2_NAME: // link second opponent poke name - GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerID].id ^ 3]], + GetMonData(&gEnemyParty[gBattlerPartyIndexes[gLinkPlayers[multiplayerId].id ^ 3]], MON_DATA_NICKNAME, text); StringGetEnd10(text); toCpy = text; @@ -2857,19 +2861,19 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst) toCpy = BattleStringGetTrainerClass(gTrainerBattleOpponent_A); break; case B_TXT_TRAINER1_NAME: // trainer1 name - toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_A, text, multiplayerID); + toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_A, text, multiplayerId, 0xFF); break; case B_TXT_1E: // link player name? - toCpy = gLinkPlayers[multiplayerID].name; + toCpy = gLinkPlayers[multiplayerId].name; break; case B_TXT_1F: // link partner name? - toCpy = gLinkPlayers[GetBattlerMultiplayerId(2 ^ gLinkPlayers[multiplayerID].id)].name; + toCpy = gLinkPlayers[GetBattlerMultiplayerId(2 ^ gLinkPlayers[multiplayerId].id)].name; break; case B_TXT_20: // link opponent 1 name? - toCpy = gLinkPlayers[GetBattlerMultiplayerId(1 ^ gLinkPlayers[multiplayerID].id)].name; + toCpy = gLinkPlayers[GetBattlerMultiplayerId(1 ^ gLinkPlayers[multiplayerId].id)].name; break; case B_TXT_21: // link opponent 2 name? - toCpy = gLinkPlayers[GetBattlerMultiplayerId(3 ^ gLinkPlayers[multiplayerID].id)].name; + toCpy = gLinkPlayers[GetBattlerMultiplayerId(3 ^ gLinkPlayers[multiplayerId].id)].name; break; case B_TXT_22: // link scripting active name toCpy = gLinkPlayers[GetBattlerMultiplayerId(gBattleScripting.battler)].name; @@ -2957,7 +2961,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst) toCpy = BattleStringGetTrainerClass(gTrainerBattleOpponent_B); break; case B_TXT_TRAINER2_NAME: - toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_B, text, multiplayerID); + toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_B, text, multiplayerId, 0xFF); break; case B_TXT_TRAINER2_LOSE_TEXT: if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) @@ -3012,13 +3016,13 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst) } break; case B_POSITION_OPPONENT_LEFT: - toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_A, text, multiplayerID); + toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_A, text, multiplayerId, gBattlerAttacker); break; case B_POSITION_OPPONENT_RIGHT: if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) - toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_B, text, multiplayerID); + toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_B, text, multiplayerId, gBattlerAttacker); else - toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_A, text, multiplayerID); + toCpy = BattleStringGetTrainerName(gTrainerBattleOpponent_A, text, multiplayerId, gBattlerAttacker); break; } break; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e19a08238..4db5eb4b1 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6594,7 +6594,15 @@ static void atk76_various(void) mon = &gEnemyParty[gBattlerPartyIndexes[gActiveBattler]]; else mon = &gPlayerParty[gBattlerPartyIndexes[gActiveBattler]]; - gBattleMons[gActiveBattler].species = gBattleStruct->speciesToMegaEvolve[gActiveBattler]; + + gBattleStruct->speciesThatMegaEvolved[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->playerSpeciesThatMegaEvolved = gBattleStruct->speciesThatMegaEvolved[gActiveBattler]; + } + + gBattleMons[gActiveBattler].species = GetMegaEvolutionSpecies(gBattleStruct->speciesThatMegaEvolved[gActiveBattler], gBattleMons[gActiveBattler].item); SetMonData(mon, MON_DATA_SPECIES, &gBattleMons[gActiveBattler].species); PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gActiveBattler].species); @@ -6610,10 +6618,13 @@ static void atk76_various(void) 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); + UpdateHealthboxAttribute(gHealthboxSpriteIds[gActiveBattler], mon, HEALTHBOX_ALL); gBattleStruct->alreadyMegaEvolved[GetBattlerPosition(gActiveBattler)] = TRUE; gBattleStruct->megaEvolvedPartyIds[GetBattlerSide(gActiveBattler)] |= gBitTable[gBattlerPartyIndexes[gActiveBattler]]; + + BtlController_EmitSetMonData(0, REQUEST_ALL_BATTLE, gBitTable[gBattlerPartyIndexes[gActiveBattler]], sizeof(struct BattlePokemon), &gBattleMons[gActiveBattler]); + MarkBattlerForControllerExec(gActiveBattler); break; } diff --git a/src/battle_util.c b/src/battle_util.c index 4af0d24bc..b6e3af4d9 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5586,10 +5586,23 @@ static bool32 IsPartnerMonFromSameTrainer(u8 battlerId) return TRUE; } -bool32 CanMegaEvolve(u8 battlerId) +u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId) { u32 i; - u16 species, itemId; + + for (i = 0; i < EVOS_PER_MON; i++) + { + if (gEvolutionTable[preEvoSpecies][i].method == EVO_MEGA_EVOLUTION + && gEvolutionTable[preEvoSpecies][i].param == heldItemId) + return gEvolutionTable[preEvoSpecies][i].targetSpecies; + } + return SPECIES_NONE; +} + +bool32 CanMegaEvolve(u8 battlerId) +{ + u32 itemId, holdEffect; + struct Pokemon *mon; u8 battlerPosition = GetBattlerPosition(battlerId); u8 partnerPosition = GetBattlerPosition(BATTLE_PARTNER(battlerId)); @@ -5602,27 +5615,23 @@ bool32 CanMegaEvolve(u8 battlerId) return FALSE; } - // Check if the pokemon holds an appropriate item, - if (GetBattlerHoldEffect(battlerId, FALSE) != HOLD_EFFECT_MEGA_STONE) + // Check if the pokemon holds an appropriate item. + if (GetBattlerSide(battlerId) == B_SIDE_OPPONENT) + mon = &gEnemyParty[gBattlerPartyIndexes[battlerId]]; + else + mon = &gPlayerParty[gBattlerPartyIndexes[battlerId]]; + + itemId = GetMonData(mon, MON_DATA_HELD_ITEM); + if (itemId != ITEM_ENIGMA_BERRY) + holdEffect = ItemId_GetHoldEffect(itemId); + else + holdEffect = gEnigmaBerries[battlerId].holdEffect; + + if (holdEffect != HOLD_EFFECT_MEGA_STONE) return FALSE; // Check if there is an entry in the evolution table. - species = gBattleMons[battlerId].species; - itemId = gBattleMons[battlerId].item; - for (i = 0; i < EVOS_PER_MON; i++) - { - if (gEvolutionTable[species][i].method == EVO_MEGA_EVOLUTION - && 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; - } - } - - if (i == EVOS_PER_MON) + if (GetMegaEvolutionSpecies(GetMonData(mon, MON_DATA_SPECIES), itemId) == SPECIES_NONE) return FALSE; // All checks passed, the mon CAN mega evolve. diff --git a/src/data/pokemon/evolution.h b/src/data/pokemon/evolution.h index 4bd3df292..1c8a4a73a 100644 --- a/src/data/pokemon/evolution.h +++ b/src/data/pokemon/evolution.h @@ -188,6 +188,8 @@ 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_LEVEL, 40, SPECIES_EXPLOUD}, + {EVO_MEGA_EVOLUTION, ITEM_MEGA_STONE_TESTING, SPECIES_HO_OH}}, }; #endif //POKEEMERALD_EVOLUTION_H