Refactoring Battle Form changes into the form change tables (#2411)

This commit is contained in:
ghoulslash 2023-04-30 08:41:54 -04:00 committed by GitHub
commit 62ca66bc6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 1528 additions and 747 deletions

View File

@ -5174,7 +5174,7 @@ BattleScript_MoveWeatherChange::
waitanimation
printfromtable gMoveWeatherChangeStringIds
waitmessage B_WAIT_TIME_LONG
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
goto BattleScript_MoveEnd
BattleScript_EffectSunnyDay::
@ -6878,7 +6878,7 @@ BattleScript_OverworldWeatherStarts::
printfromtable gWeatherStartsStringIds
waitmessage B_WAIT_TIME_LONG
playanimation_var BS_ATTACKER, sB_ANIM_ARG1
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_OverworldTerrain::
@ -7874,14 +7874,13 @@ BattleScript_MegaEvolution::
printstring STRINGID_EMPTYSTRING3
trytrainerslidemegaevolutionmsg BS_ATTACKER
printstring STRINGID_MEGAEVOREACTING
BattleScript_MegaEvolutionAfeterString:
BattleScript_MegaEvolutionAfterString:
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
handlemegaevo BS_ATTACKER, 1
printstring STRINGID_MEGAEVOEVOLVED
waitmessage B_WAIT_TIME_LONG
switchinabilities BS_ATTACKER
@ -7891,7 +7890,7 @@ BattleScript_WishMegaEvolution::
printstring STRINGID_EMPTYSTRING3
trytrainerslidemegaevolutionmsg BS_ATTACKER
printstring STRINGID_FERVENTWISHREACHED
goto BattleScript_MegaEvolutionAfeterString
goto BattleScript_MegaEvolutionAfterString
BattleScript_PrimalReversion::
printstring STRINGID_EMPTYSTRING3
@ -7940,6 +7939,7 @@ BattleScript_AttackerFormChangeEnd3::
BattleScript_AttackerFormChangeEnd3NoPopup::
call BattleScript_AttackerFormChangeNoPopup
end3
BattleScript_AttackerFormChangeMoveEffect::
waitmessage 1
@ -8434,7 +8434,7 @@ BattleScript_DrizzleActivates::
printstring STRINGID_PKMNMADEITRAIN
waitstate
playanimation BS_BATTLER_0, B_ANIM_RAIN_CONTINUES
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_AbilityRaisesDefenderStat::
@ -8596,7 +8596,7 @@ BattleScript_SandstreamActivates::
printstring STRINGID_PKMNSXWHIPPEDUPSANDSTORM
waitstate
playanimation BS_BATTLER_0, B_ANIM_SANDSTORM_CONTINUES
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_SandSpitActivates::
@ -8605,7 +8605,7 @@ BattleScript_SandSpitActivates::
printstring STRINGID_ASANDSTORMKICKEDUP
waitstate
playanimation BS_BATTLER_0, B_ANIM_SANDSTORM_CONTINUES
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
return
BattleScript_ShedSkinActivates::
@ -8615,37 +8615,15 @@ BattleScript_ShedSkinActivates::
updatestatusicon BS_ATTACKER
end3
BattleScript_WeatherFormChanges::
setbyte sBATTLER, 0
BattleScript_WeatherFormChangesLoop::
tryweatherformdatachange
activateweatherchangeabilities BS_SCRIPTING
addbyte sBATTLER, 1
jumpifbytenotequal sBATTLER, gBattlersCount, BattleScript_WeatherFormChangesLoop
return
BattleScript_WeatherFormChange::
call BattleScript_DoWeatherFormChange
end3
BattleScript_DoWeatherFormChange::
copybyte gBattlerAbility, sBATTLER
.if B_WEATHER_FORMS >= GEN_5
jumpifspecies BS_SCRIPTING, SPECIES_CASTFORM, BattleScript_DoWeatherFormChange_ForecastCheck
BattleScript_DoWeatherFormChange_FlowerGiftCheck:
jumpifability BS_SCRIPTING, ABILITY_FLOWER_GIFT, BattleScript_DoWeatherFormChange_PopUp
goto BattleScript_DoWeatherFormChange_AfterPopUp
.endif
BattleScript_DoWeatherFormChange_ForecastCheck:
jumpifability BS_SCRIPTING, ABILITY_FORECAST, BattleScript_DoWeatherFormChange_PopUp
goto BattleScript_DoWeatherFormChange_AfterPopUp
BattleScript_DoWeatherFormChange_PopUp:
call BattleScript_AbilityPopUp
BattleScript_DoWeatherFormChange_AfterPopUp:
doweatherformchangeanimation
waitstate
printstring STRINGID_PKMNTRANSFORMED
waitmessage B_WAIT_TIME_LONG
BattleScript_ActivateWeatherAbilities:
copybyte sBATTLER, gBattlerAttacker
setbyte gBattlerAttacker, 0
BattleScript_ActivateWeatherAbilities_Loop:
activateweatherchangeabilities BS_ATTACKER
BattleScript_ActivateWeatherAbilities_Increment:
addbyte gBattlerAttacker, 1
jumpifbytenotequal gBattlerAttacker, gBattlersCount, BattleScript_ActivateWeatherAbilities_Loop
copybyte gBattlerAttacker, sBATTLER
return
BattleScript_TryAdrenalineOrb:
@ -8740,7 +8718,7 @@ BattleScript_DroughtActivates::
printstring STRINGID_PKMNSXINTENSIFIEDSUN
waitstate
playanimation BS_BATTLER_0, B_ANIM_SUN_CONTINUES
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_DesolateLandActivates::
@ -8749,7 +8727,7 @@ BattleScript_DesolateLandActivates::
printstring STRINGID_EXTREMELYHARSHSUNLIGHT
waitstate
playanimation BS_BATTLER_0, B_ANIM_SUN_CONTINUES
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_DesolateLandEvaporatesWaterTypeMoves::
@ -8769,7 +8747,7 @@ BattleScript_PrimordialSeaActivates::
printstring STRINGID_HEAVYRAIN
waitstate
playanimation BS_BATTLER_0, B_ANIM_RAIN_CONTINUES
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_PrimordialSeaFizzlesOutFireTypeMoves::
@ -8846,7 +8824,7 @@ BattleScript_SnowWarningActivates::
printstring STRINGID_SNOWWARNINGHAIL
waitstate
playanimation BS_BATTLER_0, B_ANIM_HAIL_CONTINUES
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_ActivateTerrainEffects:
@ -10009,7 +9987,7 @@ BattleScript_AnnounceAirLockCloudNine::
call BattleScript_AbilityPopUp
printstring STRINGID_AIRLOCKACTIVATES
waitmessage B_WAIT_TIME_LONG
call BattleScript_WeatherFormChanges
call BattleScript_ActivateWeatherAbilities
end3
BattleScript_QuickClawActivation::

View File

@ -3,6 +3,7 @@
// should they be included here or included individually by every file?
#include "constants/battle.h"
#include "constants/form_change_types.h"
#include "battle_main.h"
#include "battle_message.h"
#include "battle_util.h"
@ -477,13 +478,7 @@ struct LinkBattlerHeader
struct MegaEvolutionData
{
u8 toEvolve; // As flags using gBitTable.
u8 evolvedPartyIds[2]; // As flags using gBitTable;
bool8 alreadyEvolved[4]; // Array id is used for mon position.
u16 evolvedSpecies[MAX_BATTLERS_COUNT];
u16 playerEvolvedSpecies;
u8 primalRevertedPartyIds[2]; // As flags using gBitTable;
u16 primalRevertedSpecies[MAX_BATTLERS_COUNT];
u16 playerPrimalRevertedSpecies;
u8 battlerId;
bool8 playerSelect;
u8 triggerSpriteId;

View File

@ -149,9 +149,6 @@ extern const u8 BattleScript_TraceActivatesEnd3[];
extern const u8 BattleScript_RainDishActivates[];
extern const u8 BattleScript_SandstreamActivates[];
extern const u8 BattleScript_ShedSkinActivates[];
extern const u8 BattleScript_WeatherFormChanges[];
extern const u8 BattleScript_WeatherFormChangesLoop[];
extern const u8 BattleScript_WeatherFormChange[];
extern const u8 BattleScript_IntimidateActivates[];
extern const u8 BattleScript_DroughtActivates[];
extern const u8 BattleScript_TookAttack[];

View File

@ -173,12 +173,11 @@ u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilit
u16 GetTypeModifier(u8 atkType, u8 defType);
s32 GetStealthHazardDamage(u8 hazardType, u8 battlerId);
s32 GetStealthHazardDamageByTypesAndHP(u8 hazardType, u8 type1, u8 type2, u32 maxHp);
u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId);
u16 GetPrimalReversionSpecies(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, bool32 isSwitchingOut);
bool32 IsBattlerMegaEvolved(u8 battlerId);
bool32 IsBattlerPrimalReverted(u8 battlerId);
u16 GetBattleFormChangeTargetSpecies(u8 battlerId, u16 method);
bool32 TryBattleFormChange(u8 battlerId, u16 method);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u8 battlerId, u16 itemId);
u32 GetIllusionMonSpecies(u32 battlerId);
@ -206,13 +205,15 @@ void SortBattlersBySpeed(u8 *battlers, bool8 slowToFast);
bool32 CompareStat(u8 battlerId, u8 statId, u8 cmpTo, u8 cmpKind);
bool32 TryRoomService(u8 battlerId);
void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
void DoBurmyFormChange(u32 monId);
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
u16 GetUsedHeldItem(u8 battler);
bool32 IsBattlerWeatherAffected(u8 battlerId, u32 weatherFlags);
u32 GetBattlerMoveTargetType(u8 battlerId, u16 move);
bool32 CanTargetBattler(u8 battlerAtk, u8 battlerDef, u16 move);
bool8 IsMoveAffectedByParentalBond(u16 move, u8 battlerId);
void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon);
void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon);
void RecalcBattlerStats(u32 battler, struct Pokemon *mon);
// Ability checks
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
bool32 IsRolePlayBannedAbility(u16 ability);

View File

@ -99,6 +99,7 @@
// Additionally, in gen8+ the Healing Wish's effect will be stored until the user switches into a statused or hurt mon.
#define B_DEFOG_CLEARS_TERRAIN GEN_LATEST // In Gen8+, Defog also clears active Terrain.
#define B_STOCKPILE_RAISES_DEFS GEN_LATEST // In Gen4+, Stockpile also raises Defense and Sp. Defense stats. Once Spit Up / Swallow is used, these stat changes are lost.
#define B_TRANSFORM_FORM_CHANGES GEN_LATEST // In Gen5+, Transformed Pokemon cannot change forms.
// Ability settings
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.

View File

@ -9,6 +9,7 @@
#define I_SITRUS_BERRY_HEAL GEN_LATEST // In Gen4+, Sitrus Berry was changed from healing 30 HP to healing 25% of Max HP.
#define I_VITAMIN_EV_CAP GEN_LATEST // In Gen8+, the Vitamins no longer have a cap of 100 EV per stat.
#define I_BERRY_EV_JUMP GEN_LATEST // In Gen4 only, EV-lowering Berries lower a stat's EV to 100 if it is above 100.
#define I_GRISEOUS_ORB_FORM_CHANGE GEN_LATEST // In Gen9+, the Griseous Orb no longer changes Giratina's form when held.
// TM config
#define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1.

View File

@ -270,6 +270,7 @@
#define MOVE_RESULT_NO_EFFECT (MOVE_RESULT_MISSED | MOVE_RESULT_DOESNT_AFFECT_FOE | MOVE_RESULT_FAILED)
// Battle Weather flags
#define B_WEATHER_NONE 0
#define B_WEATHER_RAIN_TEMPORARY (1 << 0)
#define B_WEATHER_RAIN_DOWNPOUR (1 << 1) // unused
#define B_WEATHER_RAIN_PERMANENT (1 << 2)

View File

@ -335,10 +335,9 @@
#define MOVEEND_PICKPOCKET 30
#define MOVEEND_DANCER 31
#define MOVEEND_EMERGENCY_EXIT 32
#define MOVEEND_WEATHER_FORM 33
#define MOVEEND_SYMBIOSIS 34
#define MOVEEND_CLEAR_BITS 35
#define MOVEEND_COUNT 36
#define MOVEEND_SYMBIOSIS 33
#define MOVEEND_CLEAR_BITS 34
#define MOVEEND_COUNT 35
// switch cases
#define B_SWITCH_NORMAL 0

View File

@ -0,0 +1,98 @@
#ifndef GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
#define GUARD_CONSTANTS_FORM_CHANGE_TYPES_H
// FORM_CHANGE_BATTLE_HP_PERCENT param2 arguments
#define HP_HIGHER_THAN 1
#define HP_LOWER_EQ_THAN 2
// FORM_CHANGE_MOVE param2 Arguments
#define WHEN_LEARNED 0
#define WHEN_FORGOTTEN 1
// FORM_CHANGE_ITEM_USE param2 Arguments
#define DAY 1
#define NIGHT 2
#define FORM_CHANGE_TERMINATOR 0
// Form change that activates when the specified item is given to or taken from the selected Pokémon.
// param1: item to hold.
// param2: ability to check for, optional.
#define FORM_CHANGE_ITEM_HOLD 1
// Form change that activates when the item is used on the selected Pokémon.
// param1: item to use
// param2: time of day to check, optional.
// - DAY if Form change that activates in the daytime.
// - NIGHT if Form change that activates at nighttime.
#define FORM_CHANGE_ITEM_USE 2
// TODO: Form change that activates when the Pokémon learns or forgets the move.
// param1: move to check for
// param2:
// - WHEN_LEARNED if Form change that activates when move is forgotten
// - WHEN_FORGOTTEN if Form change that activates when move is learned
#define FORM_CHANGE_MOVE 3
// Form change that activates when the Pokémon is withdrawn from the PC or Daycare.
// Daycare withdraw done, PC withdraw TODO.
// - No parameters.
#define FORM_CHANGE_WITHDRAW 4
// Form change that activates when the Pokémon faints, either in battle or in the overworld by poison.
// If species is not specified and it's on the player's side, it will try to use the value
// saved in gBattleStruct->changedSpecies from a previous form change.
// - No parameters.
#define FORM_CHANGE_FAINT 5
// Form change that activates when the Pokémon is sent out at the beginning of a battle
// param1: item to hold, optional
// param2: a move that will be replaced, optional
// param3: a new move to replace it with, optional
#define FORM_CHANGE_BEGIN_BATTLE 6
// Form change that activates at the end of a battle. If species is not specified and it's on the player's side, it will try to use the value saved in gBattleStruct->changedSpecies from a previous form change.
// param1: item to hold, optional
// param2: a move that will be replaced, optional
// param3: a new move to replace it with, optional
#define FORM_CHANGE_END_BATTLE 7
// Form change that activates at the end of a battle based on the terrain if it participated in the battle and hasn't fainted. Takes priority over FORM_CHANGE_END_BATTLE.
// param1: battle terrain to check.
#define FORM_CHANGE_END_BATTLE_TERRAIN 8
// Form change that activates when the Pokémon is switched out in battle.
// - No parameters.
#define FORM_CHANGE_BATTLE_SWITCH 9
// Form change that activates when the Pokémon's HP % passes a certain threshold.
// param1: Ability to check.
// param2: HP comparer
// - HP_HIGHER_THAN if the form triggers when the current HP is higher than the specified threshold.
// - HP_LOWER_EQ_THAN if the form triggers when the current HP is lower or equal than the specified threshold.
// param3: HP percentage threshold.
#define FORM_CHANGE_BATTLE_HP_PERCENT 10
// Form change that activates when the mon has the defined item.
// If it's on the player's side, it also requires ITEM_MEGA_RING in the user's bag and for the player to trigger it by pressing START before selecting a move.
// param1: item to hold.
#define FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM 11
// Form change that activates when the mon has the defined move.
// If it's on the player's side, it also requires ITEM_MEGA_RING in the user's bag and for the player to trigger it by pressing START before selecting a move.
// param1: move to have.
#define FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE 12
// Form change that activates automatically when entering battle with the specified item.
// If the item is a Red Orb, it uses the Omega Symbol for the animation and icon. Otherwise, it defaults to the Alpha symbol.
// The battle indicator icon is based on the species, with Primal Groudon's as Omega and otherwise being Alpha.
// param1: item to hold.
#define FORM_CHANGE_BATTLE_PRIMAL_REVERSION 13
// Form change that activates when a specific weather is set during battle.
// param1: weather to check
#define FORM_CHANGE_BATTLE_WEATHER 14
// Form change that activates automatically when the turn ends.
// param1: ability to check.
#define FORM_CHANGE_BATTLE_TURN_END 15
#endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H

View File

@ -273,9 +273,6 @@
#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_MOVE_MEGA_EVOLUTION 0xfffe // Mega Evolution that checks for a move instead of held item.
#define EVO_PRIMAL_REVERSION 0xfffd // Not an actual evolution, used to undergo primal reversion 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
@ -326,15 +323,6 @@
#define EVO_MODE_BATTLE_SPECIAL 4
#define EVO_MODE_OVERWORLD_SPECIAL 5
// Form change types
#define FORM_CHANGE_END 0
#define FORM_ITEM_HOLD 1
#define FORM_ITEM_USE 2
#define FORM_MOVE 3
#define FORM_WITHDRAW 4
#define FORM_BATTLE_BEGIN 5
#define FORM_BATTLE_END 6
#define MON_PIC_WIDTH 64
#define MON_PIC_HEIGHT 64
#define MON_PIC_SIZE (MON_PIC_WIDTH * MON_PIC_HEIGHT / 2)
@ -362,13 +350,14 @@
#define SPECIES_FLAG_LEGENDARY (1 << 0)
#define SPECIES_FLAG_MYTHICAL (1 << 1)
#define SPECIES_FLAG_MEGA_EVOLUTION (1 << 2)
#define SPECIES_FLAG_ULTRA_BEAST (1 << 3)
#define SPECIES_FLAG_ALOLAN_FORM (1 << 4)
#define SPECIES_FLAG_GALARIAN_FORM (1 << 5)
#define SPECIES_FLAG_HISUIAN_FORM (1 << 6)
#define SPECIES_FLAG_GENDER_DIFFERENCE (1 << 7)
#define SPECIES_FLAG_ALL_PERFECT_IVS (1 << 8)
#define SPECIES_FLAG_CANNOT_BE_TRADED (1 << 9)
#define SPECIES_FLAG_PRIMAL_REVERSION (1 << 3)
#define SPECIES_FLAG_ULTRA_BEAST (1 << 4)
#define SPECIES_FLAG_ALOLAN_FORM (1 << 5)
#define SPECIES_FLAG_GALARIAN_FORM (1 << 6)
#define SPECIES_FLAG_HISUIAN_FORM (1 << 7)
#define SPECIES_FLAG_GENDER_DIFFERENCE (1 << 8)
#define SPECIES_FLAG_ALL_PERFECT_IVS (1 << 9)
#define SPECIES_FLAG_CANNOT_BE_TRADED (1 << 10)
#define LEGENDARY_PERFECT_IV_COUNT 3

View File

@ -414,6 +414,7 @@ extern const u16 gUnionRoomFacilityClasses[];
extern const struct SpriteTemplate gBattlerSpriteTemplates[];
extern const s8 gNatureStatTable[][5];
extern const u16 *const gFormSpeciesIdTables[NUM_SPECIES];
extern const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES];
extern const u32 sExpCandyExperienceTable[];
void ZeroBoxMonData(struct BoxPokemon *boxMon);
@ -565,10 +566,12 @@ u8 *MonSpritesGfxManager_GetSpritePtr(u8 managerId, u8 spriteNum);
u16 GetFormSpeciesId(u16 speciesId, u8 formId);
u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg);
u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
bool32 ShouldShowFemaleDifferences(u16 species, u32 personality);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon);
bool32 TryFormChange(u32 monId, u32 side, u16 method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
u32 GetMonFriendshipScore(struct Pokemon *pokemon);
void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality);

View File

@ -3081,12 +3081,8 @@ static bool32 IsPinchBerryItemEffect(u16 holdEffect)
case HOLD_EFFECT_SP_DEFENSE_UP:
case HOLD_EFFECT_CRITICAL_UP:
case HOLD_EFFECT_RANDOM_STAT_UP:
#ifdef HOLD_EFFECT_CUSTAP_BERRY
case HOLD_EFFECT_CUSTAP_BERRY:
#endif
#ifdef HOLD_EFFECT_MICLE_BERRY
case HOLD_EFFECT_MICLE_BERRY:
#endif
return TRUE;
}
@ -3861,7 +3857,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break;
case MOVE_KINGS_SHIELD:
#if (defined SPECIES_AEGISLASH && defined SPECIES_AEGISLASH_BLADE)
if (AI_DATA->abilities[battlerAtk] == ABILITY_STANCE_CHANGE //Special logic for Aegislash
&& gBattleMons[battlerAtk].species == SPECIES_AEGISLASH_BLADE
&& !IsBattlerIncapacitated(battlerDef, AI_DATA->abilities[battlerDef]))
@ -3869,7 +3864,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 3;
break;
}
#endif
//fallthrough
default: // protect
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
@ -4538,7 +4532,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 3;
break;
case EFFECT_RELIC_SONG:
#if (defined SPECIES_MELOETTA && defined SPECIES_MELOETTA_PIROUETTE)
if (!(gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED)) // Don't try to change form if it's transformed.
{
if (gBattleMons[battlerAtk].species == SPECIES_MELOETTA && gBattleMons[battlerDef].defense < gBattleMons[battlerDef].spDefense)
@ -4546,7 +4539,6 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
else if (gBattleMons[battlerAtk].species == SPECIES_MELOETTA_PIROUETTE && gBattleMons[battlerDef].spDefense < gBattleMons[battlerDef].defense)
score += 3; // Change to Aria if can do more damage
}
#endif
break;
case EFFECT_ELECTRIC_TERRAIN:
case EFFECT_MISTY_TERRAIN:

View File

@ -980,8 +980,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl)
u8 battler = gSprites[healthboxSpriteId].hMain_Battler;
// Don't print Lv char if mon is mega evolved or primal reverted.
if (gBattleStruct->mega.evolvedPartyIds[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]]
|| gBattleStruct->mega.primalRevertedPartyIds[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])
if (IsBattlerMegaEvolved(battler) || IsBattlerPrimalReverted(battler))
{
objVram = ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3);
xPos = 5 * (3 - (objVram - (text + 2))) - 1;
@ -1503,22 +1502,16 @@ static bool32 MegaIndicator_ShouldBeInvisible(u32 battlerId, u32 indicatorType)
u32 side = GetBattlerSide(battlerId);
if (indicatorType == INDICATOR_MEGA)
{
if (gBattleStruct->mega.evolvedPartyIds[side] & gBitTable[gBattlerPartyIndexes[battlerId]])
if (IsBattlerMegaEvolved(battlerId))
return FALSE;
}
else
{
if (indicatorType == INDICATOR_ALPHA)
{
if (gBattleMons[battlerId].species != SPECIES_KYOGRE_PRIMAL)
if (indicatorType == INDICATOR_ALPHA && gBattleMons[battlerId].species != SPECIES_KYOGRE_PRIMAL)
return TRUE;
}
else if (indicatorType == INDICATOR_OMEGA)
{
if (gBattleMons[battlerId].species != SPECIES_GROUDON_PRIMAL)
else if (indicatorType == INDICATOR_OMEGA && gBattleMons[battlerId].species != SPECIES_GROUDON_PRIMAL)
return TRUE;
}
if (gBattleStruct->mega.primalRevertedPartyIds[side] & gBitTable[gBattlerPartyIndexes[battlerId]])
if (IsBattlerPrimalReverted(battlerId))
return FALSE;
}
return TRUE;

View File

@ -607,21 +607,9 @@ static void CB2_InitBattleInternal(void)
for (i = 0; i < PARTY_SIZE; i++)
{
// Player's side
targetSpecies = GetFormChangeTargetSpecies(&gPlayerParty[i], FORM_BATTLE_BEGIN, 0);
if (targetSpecies != SPECIES_NONE)
{
SetMonData(&gPlayerParty[i], MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&gPlayerParty[i]);
TryToSetBattleFormChangeMoves(&gPlayerParty[i]);
}
TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_BEGIN_BATTLE);
// Opponent's side
targetSpecies = GetFormChangeTargetSpecies(&gEnemyParty[i], FORM_BATTLE_BEGIN, 0);
if (targetSpecies != SPECIES_NONE)
{
SetMonData(&gEnemyParty[i], MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&gEnemyParty[i]);
TryToSetBattleFormChangeMoves(&gEnemyParty[i]);
}
TryFormChange(i, B_SIDE_OPPONENT, FORM_CHANGE_BEGIN_BATTLE);
}
gBattleCommunication[MULTIUSE_STATE] = 0;
@ -3411,9 +3399,7 @@ void FaintClearSetData(void)
gBattleMons[gActiveBattler].type3 = TYPE_MYSTERY;
Ai_UpdateFaintData(gActiveBattler);
UndoFormChange(gBattlerPartyIndexes[gActiveBattler], GET_BATTLER_SIDE(gActiveBattler), FALSE);
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
UndoMegaEvolution(gBattlerPartyIndexes[gActiveBattler]);
TryBattleFormChange(gActiveBattler, FORM_CHANGE_FAINT);
gBattleStruct->overwrittenAbilities[gActiveBattler] = ABILITY_NONE;
@ -3845,24 +3831,6 @@ static void TryDoEventsBeforeFirstTurn(void)
}
memset(gTotemBoosts, 0, sizeof(gTotemBoosts)); // erase all totem boosts just to be safe
// Primal Reversion
for (i = 0; i < gBattlersCount; i++)
{
if (GetBattlerHoldEffect(i, TRUE) == HOLD_EFFECT_PRIMAL_ORB)
{
for (j = 0; j < EVOS_PER_MON; j++)
{
if (gEvolutionTable[gBattleMons[i].species][j].targetSpecies != SPECIES_NONE
&& gEvolutionTable[gBattleMons[i].species][j].method == EVO_PRIMAL_REVERSION)
{
gBattlerAttacker = i;
BattleScriptExecute(BattleScript_PrimalReversion);
return;
}
}
}
}
// Check neutralizing gas
if (AbilityBattleEffects(ABILITYEFFECT_NEUTRALIZINGGAS, 0, 0, 0, 0) != 0)
return;
@ -3871,6 +3839,14 @@ static void TryDoEventsBeforeFirstTurn(void)
while (gBattleStruct->switchInAbilitiesCounter < gBattlersCount)
{
gBattlerAttacker = gBattlerByTurnOrder[gBattleStruct->switchInAbilitiesCounter++];
// Primal Reversion
if (GetBattlerHoldEffect(gBattlerAttacker, TRUE) == HOLD_EFFECT_PRIMAL_ORB
&& GetBattleFormChangeTargetSpecies(gBattlerAttacker, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) != SPECIES_NONE)
{
BattleScriptExecute(BattleScript_PrimalReversion);
return;
}
if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, gBattlerAttacker, 0, 0, 0) != 0)
return;
}
@ -5054,7 +5030,7 @@ static void CheckMegaEvolutionBeforeTurn(void)
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)))
if (GetBattleFormChangeTargetSpecies(gActiveBattler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE)
BattleScriptExecute(BattleScript_WishMegaEvolution);
else
BattleScriptExecute(BattleScript_MegaEvolution);
@ -5410,21 +5386,31 @@ static void HandleEndTurn_FinishBattle(void)
#endif
for (i = 0; i < PARTY_SIZE; i++)
{
UndoMegaEvolution(i);
UndoFormChange(i, B_SIDE_PLAYER, FALSE);
DoBurmyFormChange(i);
}
bool8 changedForm = FALSE;
// Appeared in battle and didn't faint
if ((gBattleStruct->appearedInBattle & gBitTable[i]) && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0)
changedForm = TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE_TERRAIN);
if (!changedForm)
changedForm = TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE);
// Clear original species field
gBattleStruct->changedSpecies[i] = SPECIES_NONE;
#if B_RECALCULATE_STATS >= GEN_5
// Recalculate the stats of every party member before the end
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG) != SPECIES_NONE
&& GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG) != SPECIES_EGG)
{
if (!changedForm)
CalculateMonStats(&gPlayerParty[i]);
}
}
#endif
}
// Clear battle mon species to avoid a bug on the next battle that causes
// healthboxes loading incorrectly due to it trying to create a Mega Indicator
// if the previous battler would've had it.
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
gBattleMons[i].species = SPECIES_NONE;
}
gBattleMainFunc = FreeResetData_ReturnToOvOrDoEvolutions;
gCB2_AfterEvolution = BattleMainCB2;
}

View File

@ -4480,15 +4480,7 @@ static void Cmd_getexp(void)
if (battlerId != 0xFF)
{
gBattleMons[battlerId].level = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_LEVEL);
gBattleMons[battlerId].hp = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_HP);
gBattleMons[battlerId].maxHP = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_MAX_HP);
gBattleMons[battlerId].attack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_ATK);
gBattleMons[battlerId].defense = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_DEF);
gBattleMons[battlerId].speed = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPEED);
gBattleMons[battlerId].spAttack = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPATK);
gBattleMons[battlerId].spDefense = GetMonData(&gPlayerParty[gBattleStruct->expGetterMonId], MON_DATA_SPDEF);
CopyMonLevelAndBaseStatsToBattleMon(battlerId, &gPlayerParty[gBattleStruct->expGetterMonId]);
if (gStatuses3[battlerId] & STATUS3_POWER_TRICK)
SWAP(gBattleMons[battlerId].attack, gBattleMons[battlerId].defense, temp);
}
@ -6273,28 +6265,6 @@ static void Cmd_moveend(void)
}
gBattleScripting.moveendState++;
break;
case MOVEEND_WEATHER_FORM:
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
{
switch (gBattleMons[i].species)
{
case SPECIES_CASTFORM:
case SPECIES_CASTFORM_RAINY:
case SPECIES_CASTFORM_SNOWY:
case SPECIES_CASTFORM_SUNNY:
case SPECIES_CHERRIM:
case SPECIES_CHERRIM_SUNSHINE:
effect = TryWeatherFormChange(i);
if (effect)
{
BattleScriptPushCursorAndCallback(BattleScript_WeatherFormChange);
gBattleScripting.battler = i;
gBattleStruct->formToChangeInto = effect - 1;
}
}
}
gBattleScripting.moveendState++;
break;
case MOVEEND_SYMBIOSIS:
for (i = 0; i < gBattlersCount; i++)
{
@ -8614,22 +8584,6 @@ u32 IsAbilityStatusProtected(u32 battler)
|| IsShieldsDownProtected(battler);
}
static void RecalcBattlerStats(u32 battler, struct Pokemon *mon)
{
CalculateMonStats(mon);
gBattleMons[battler].level = GetMonData(mon, MON_DATA_LEVEL);
gBattleMons[battler].hp = GetMonData(mon, MON_DATA_HP);
gBattleMons[battler].maxHP = GetMonData(mon, MON_DATA_MAX_HP);
gBattleMons[battler].attack = GetMonData(mon, MON_DATA_ATK);
gBattleMons[battler].defense = GetMonData(mon, MON_DATA_DEF);
gBattleMons[battler].speed = GetMonData(mon, MON_DATA_SPEED);
gBattleMons[battler].spAttack = GetMonData(mon, MON_DATA_SPATK);
gBattleMons[battler].spDefense = GetMonData(mon, MON_DATA_SPDEF);
gBattleMons[battler].ability = GetMonAbility(mon);
gBattleMons[battler].type1 = gSpeciesInfo[gBattleMons[battler].species].types[0];
gBattleMons[battler].type2 = gSpeciesInfo[gBattleMons[battler].species].types[1];
}
u32 GetHighestStatId(u32 battlerId)
{
u32 i, highestId = STAT_ATK, highestStat = gBattleMons[battlerId].attack;
@ -8792,62 +8746,27 @@ static void HandleScriptMegaPrimal(u32 caseId, u32 battlerId, bool32 isMega)
// 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]);
}
if (!TryBattleFormChange(battlerId, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM))
TryBattleFormChange(battlerId, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE);
}
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);
}
TryBattleFormChange(battlerId, FORM_CHANGE_BATTLE_PRIMAL_REVERSION);
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);
if (isMega)
gBattleStruct->mega.alreadyEvolved[position] = TRUE;
}
}
@ -10751,15 +10670,7 @@ static void Cmd_various(void)
case VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL:
{
VARIOUS_ARGS(const u8 *jumpInstr);
bool8 canDoPrimalReversion = FALSE;
for (i = 0; i < EVOS_PER_MON; i++)
{
if (gEvolutionTable[gBattleMons[gActiveBattler].species][i].method == EVO_PRIMAL_REVERSION
&& gEvolutionTable[gBattleMons[gActiveBattler].species][i].param == gBattleMons[gActiveBattler].item)
canDoPrimalReversion = TRUE;
}
if (!canDoPrimalReversion)
if (GetBattleFormChangeTargetSpecies(gActiveBattler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) == SPECIES_NONE)
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
@ -15237,15 +15148,7 @@ static void Cmd_tryweatherformdatachange(void)
{
CMD_ARGS();
u8 form;
gBattlescriptCurrInstr = cmd->nextInstr;
form = TryWeatherFormChange(gBattleScripting.battler);
if (form)
{
BattleScriptPushCursorAndCallback(BattleScript_WeatherFormChange);
*(&gBattleStruct->formToChangeInto) = form - 1;
}
// removed in favor of new form system
}
// Water and Mud Sport
@ -15732,7 +15635,7 @@ static void Cmd_handleballthrow(void)
{
BtlController_EmitBallThrowAnim(BUFFER_A, BALL_3_SHAKES_SUCCESS);
MarkBattlerForControllerExec(gActiveBattler);
UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget), FALSE);
TryBattleFormChange(gBattlerTarget, FORM_CHANGE_END_BATTLE);
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);
@ -15786,7 +15689,7 @@ static void Cmd_handleballthrow(void)
if (IsCriticalCapture())
gBattleSpritesDataPtr->animationData->criticalCaptureSuccess = TRUE;
UndoFormChange(gBattlerPartyIndexes[gBattlerTarget], GET_BATTLER_SIDE(gBattlerTarget), FALSE);
TryBattleFormChange(gBattlerTarget, FORM_CHANGE_END_BATTLE);
gBattlescriptCurrInstr = BattleScript_SuccessBallThrow;
SetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_POKEBALL, &gLastUsedItem);

View File

@ -542,7 +542,7 @@ void HandleAction_Switch(void)
if (gBattleResults.playerSwitchesCounter < 255)
gBattleResults.playerSwitchesCounter++;
UndoFormChange(gBattlerPartyIndexes[gBattlerAttacker], GetBattlerSide(gBattlerAttacker), TRUE);
TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_SWITCH);
}
void HandleAction_UseItem(void)
@ -2487,7 +2487,15 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_WEATHER_FORM:
AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, 0, 0, 0, 0);
for (i = 0; i < gBattlersCount; i++)
{
if (AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, i, 0, 0, 0))
{
effect++;
break;
}
}
if (effect == 0)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_STATUS_HEAL:
@ -4115,51 +4123,6 @@ static bool32 TryChangeBattleTerrain(u32 battler, u32 statusFlag, u8 *timer)
return FALSE;
}
static bool32 ShouldChangeFormHpBased(u32 battler)
{
// Ability, form >, form <=, hp divided
static const u16 forms[][4] =
{
{ABILITY_ZEN_MODE, SPECIES_DARMANITAN, SPECIES_DARMANITAN_ZEN_MODE, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_BLUE, SPECIES_MINIOR_CORE_BLUE, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_GREEN, SPECIES_MINIOR_CORE_GREEN, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_INDIGO, SPECIES_MINIOR_CORE_INDIGO, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_ORANGE, SPECIES_MINIOR_CORE_ORANGE, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET, 2},
{ABILITY_SHIELDS_DOWN, SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW, 2},
{ABILITY_SCHOOLING, SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, 4},
{ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GORGING, 2},
{ABILITY_GULP_MISSILE, SPECIES_CRAMORANT, SPECIES_CRAMORANT_GULPING, 1},
{ABILITY_ZEN_MODE, SPECIES_DARMANITAN_GALARIAN, SPECIES_DARMANITAN_ZEN_MODE_GALARIAN, 2},
};
u32 i;
u16 battlerAbility = GetBattlerAbility(battler);
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED)
return FALSE;
for (i = 0; i < ARRAY_COUNT(forms); i++)
{
if (battlerAbility == forms[i][0])
{
if (gBattleMons[battler].species == forms[i][2]
&& gBattleMons[battler].hp > gBattleMons[battler].maxHP / forms[i][3])
{
gBattleMons[battler].species = forms[i][1];
return TRUE;
}
if (gBattleMons[battler].species == forms[i][1]
&& gBattleMons[battler].hp <= gBattleMons[battler].maxHP / forms[i][3])
{
gBattleMons[battler].species = forms[i][2];
return TRUE;
}
}
}
return FALSE;
}
static u8 ForewarnChooseMove(u32 battler)
{
struct Forewarn {
@ -4712,8 +4675,10 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITY_SCHOOLING:
if (gBattleMons[battler].level < 20)
break;
// Fallthrough
case ABILITY_ZEN_MODE:
case ABILITY_SHIELDS_DOWN:
if (ShouldChangeFormHpBased(battler))
if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_HP_PERCENT))
{
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3);
effect++;
@ -4984,17 +4949,12 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
case ABILITY_SCHOOLING:
if (gBattleMons[battler].level < 20)
break;
// Fallthrough
case ABILITY_ZEN_MODE:
case ABILITY_SHIELDS_DOWN:
if ((effect = ShouldChangeFormHpBased(battler)))
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3);
break;
case ABILITY_POWER_CONSTRUCT:
if ((gBattleMons[battler].species == SPECIES_ZYGARDE || gBattleMons[battler].species == SPECIES_ZYGARDE_10)
&& gBattleMons[battler].hp <= gBattleMons[battler].maxHP / 2)
if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_HP_PERCENT))
{
gBattleStruct->changedSpecies[gBattlerPartyIndexes[battler]] = gBattleMons[battler].species;
gBattleMons[battler].species = SPECIES_ZYGARDE_COMPLETE;
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3);
effect++;
}
@ -5014,18 +4974,9 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
break;
case ABILITY_HUNGER_SWITCH:
if (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED))
if (TryBattleFormChange(battler, FORM_CHANGE_BATTLE_TURN_END))
{
if (gBattleMons[battler].species == SPECIES_MORPEKO)
{
gBattleMons[battler].species = SPECIES_MORPEKO_HANGRY;
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3NoPopup);
}
else if (gBattleMons[battler].species == SPECIES_MORPEKO_HANGRY)
{
gBattleMons[battler].species = SPECIES_MORPEKO;
BattleScriptPushCursorAndCallback(BattleScript_AttackerFormChangeEnd3NoPopup);
}
effect++;
}
break;
@ -5709,7 +5660,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
{
if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GORGING)
{
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species;
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
@ -5723,7 +5673,6 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
}
else if (gBattleMons[gBattlerTarget].species == SPECIES_CRAMORANT_GULPING)
{
gBattleStruct->changedSpecies[gBattlerPartyIndexes[gBattlerTarget]] = gBattleMons[gBattlerTarget].species;
gBattleMons[gBattlerTarget].species = SPECIES_CRAMORANT;
if (GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD)
{
@ -5846,7 +5795,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
break;
case ABILITY_GULP_MISSILE:
if (((gCurrentMove == MOVE_SURF && TARGET_TURN_DAMAGED) || gStatuses3[gBattlerAttacker] & STATUS3_UNDERWATER)
&& (effect = ShouldChangeFormHpBased(gBattlerAttacker)))
&& TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_HP_PERCENT))
{
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_AttackerFormChange;
@ -6125,11 +6074,11 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u16 ability, u8 special, u16 move
#else
TRY_WEATHER_FORM:
#endif
effect = TryWeatherFormChange(battler);
if (effect != 0)
if ((IsBattlerWeatherAffected(battler, gBattleWeather) || gBattleWeather == B_WEATHER_NONE)
&& TryBattleFormChange(battler, FORM_CHANGE_BATTLE_WEATHER))
{
BattleScriptPushCursorAndCallback(BattleScript_WeatherFormChange);
*(&gBattleStruct->formToChangeInto) = effect - 1;
BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3);
effect++;
}
break;
case ABILITY_ICE_FACE:
@ -9349,10 +9298,7 @@ static bool32 CanEvolve(u32 species)
for (i = 0; i < EVOS_PER_MON; i++)
{
if (gEvolutionTable[species][i].method
&& gEvolutionTable[species][i].method != EVO_MEGA_EVOLUTION
&& gEvolutionTable[species][i].method != EVO_MOVE_MEGA_EVOLUTION
&& gEvolutionTable[species][i].method != EVO_PRIMAL_REVERSION)
if (gEvolutionTable[species][i].method)
return TRUE;
}
return FALSE;
@ -10016,46 +9962,27 @@ bool32 IsPartnerMonFromSameTrainer(u8 battlerId)
return TRUE;
}
u16 GetMegaEvolutionSpecies(u16 preEvoSpecies, u16 heldItemId)
bool32 DoesSpeciesUseHoldItemToChangeForm(u16 species, u16 heldItemId)
{
u32 i;
const struct FormChange *formChanges = gFormChangeTablePointers[species];
for (i = 0; i < EVOS_PER_MON; i++)
if (formChanges != NULL)
{
if (gEvolutionTable[preEvoSpecies][i].method == EVO_MEGA_EVOLUTION
&& gEvolutionTable[preEvoSpecies][i].param == heldItemId)
return gEvolutionTable[preEvoSpecies][i].targetSpecies;
}
return SPECIES_NONE;
}
u16 GetPrimalReversionSpecies(u16 preEvoSpecies, u16 heldItemId)
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
{
u32 i;
for (i = 0; i < EVOS_PER_MON; i++)
switch (formChanges[i].method)
{
if (gEvolutionTable[preEvoSpecies][i].method == EVO_PRIMAL_REVERSION
&& gEvolutionTable[preEvoSpecies][i].param == heldItemId)
return gEvolutionTable[preEvoSpecies][i].targetSpecies;
}
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_MOVE_MEGA_EVOLUTION)
{
par = gEvolutionTable[preEvoSpecies][i].param;
if (par == moveId1 || par == moveId2 || par == moveId3 || par == moveId4)
return gEvolutionTable[preEvoSpecies][i].targetSpecies;
case FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM:
case FORM_CHANGE_BATTLE_PRIMAL_REVERSION:
case FORM_CHANGE_ITEM_HOLD:
if (formChanges[i].param1 == heldItemId)
return TRUE;
break;
}
}
return SPECIES_NONE;
}
return FALSE;
}
bool32 CanMegaEvolve(u8 battlerId)
@ -10098,7 +10025,7 @@ bool32 CanMegaEvolve(u8 battlerId)
itemId = GetMonData(mon, MON_DATA_HELD_ITEM);
// Check if there is an entry in the evolution table for regular Mega Evolution.
if (GetMegaEvolutionSpecies(species, itemId) != SPECIES_NONE)
if (GetBattleFormChangeTargetSpecies(battlerId, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM) != SPECIES_NONE)
{
#if DEBUG_BATTLE_MENU == TRUE
if (gBattleStruct->debugHoldEffects[battlerId])
@ -10116,85 +10043,162 @@ bool32 CanMegaEvolve(u8 battlerId)
}
// 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)))
if (GetBattleFormChangeTargetSpecies(battlerId, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE)
return TRUE;
// No checks passed, the mon CAN'T mega evolve.
return FALSE;
}
void UndoMegaEvolution(u32 monId)
bool32 IsBattlerMegaEvolved(u8 battlerId)
{
u16 baseSpecies = GET_BASE_SPECIES_ID(GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES));
if (gBattleStruct->mega.evolvedPartyIds[B_SIDE_PLAYER] & gBitTable[monId])
{
gBattleStruct->mega.evolvedPartyIds[B_SIDE_PLAYER] &= ~(gBitTable[monId]);
SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &baseSpecies);
CalculateMonStats(&gPlayerParty[monId]);
}
else if (gBattleStruct->mega.primalRevertedPartyIds[B_SIDE_PLAYER] & gBitTable[monId])
{
gBattleStruct->mega.primalRevertedPartyIds[B_SIDE_PLAYER] &= ~(gBitTable[monId]);
SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &baseSpecies);
CalculateMonStats(&gPlayerParty[monId]);
}
// While not exactly a mega evolution, Zygarde follows the same rules.
else if (GetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, NULL) == SPECIES_ZYGARDE_COMPLETE)
{
SetMonData(&gPlayerParty[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[monId]);
gBattleStruct->changedSpecies[monId] = 0;
CalculateMonStats(&gPlayerParty[monId]);
}
// While Transform does copy stats and visuals, it shouldn't be counted as true Mega Evolution.
if (gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED)
return FALSE;
return (gSpeciesInfo[gBattleMons[battlerId].species].flags & SPECIES_FLAG_MEGA_EVOLUTION);
}
void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut)
bool32 IsBattlerPrimalReverted(u8 battlerId)
{
u32 i, currSpecies, targetSpecies;
struct Pokemon *party = GetSideParty(side);
static const u16 species[][3] =
{
// Changed Form ID Default Form ID Should change on switch
{SPECIES_EISCUE_NOICE_FACE, SPECIES_EISCUE, TRUE},
{SPECIES_MIMIKYU_BUSTED, SPECIES_MIMIKYU, FALSE},
{SPECIES_GRENINJA_ASH, SPECIES_GRENINJA_BATTLE_BOND, FALSE},
{SPECIES_MELOETTA_PIROUETTE, SPECIES_MELOETTA, FALSE},
{SPECIES_AEGISLASH_BLADE, SPECIES_AEGISLASH, TRUE},
{SPECIES_DARMANITAN_ZEN_MODE, SPECIES_DARMANITAN, TRUE},
{SPECIES_MINIOR, SPECIES_MINIOR_CORE_RED, TRUE},
{SPECIES_MINIOR_METEOR_BLUE, SPECIES_MINIOR_CORE_BLUE, TRUE},
{SPECIES_MINIOR_METEOR_GREEN, SPECIES_MINIOR_CORE_GREEN, TRUE},
{SPECIES_MINIOR_METEOR_INDIGO, SPECIES_MINIOR_CORE_INDIGO, TRUE},
{SPECIES_MINIOR_METEOR_ORANGE, SPECIES_MINIOR_CORE_ORANGE, TRUE},
{SPECIES_MINIOR_METEOR_VIOLET, SPECIES_MINIOR_CORE_VIOLET, TRUE},
{SPECIES_MINIOR_METEOR_YELLOW, SPECIES_MINIOR_CORE_YELLOW, TRUE},
{SPECIES_WISHIWASHI_SCHOOL, SPECIES_WISHIWASHI, TRUE},
{SPECIES_CRAMORANT_GORGING, SPECIES_CRAMORANT, TRUE},
{SPECIES_CRAMORANT_GULPING, SPECIES_CRAMORANT, TRUE},
{SPECIES_MORPEKO_HANGRY, SPECIES_MORPEKO, TRUE},
{SPECIES_DARMANITAN_ZEN_MODE_GALARIAN, SPECIES_DARMANITAN_GALARIAN, TRUE},
};
// While Transform does copy stats and visuals, it shouldn't be counted as true Primal Revesion.
if (gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED)
return FALSE;
return (gSpeciesInfo[gBattleMons[battlerId].species].flags & SPECIES_FLAG_PRIMAL_REVERSION);
}
currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);
for (i = 0; i < ARRAY_COUNT(species); i++)
// Returns SPECIES_NONE if no form change is possible
u16 GetBattleFormChangeTargetSpecies(u8 battlerId, u16 method)
{
if (currSpecies == species[i][0] && (!isSwitchingOut || species[i][2] == TRUE))
u32 i, j;
u16 targetSpecies = SPECIES_NONE;
u16 species = gBattleMons[battlerId].species;
const struct FormChange *formChanges = gFormChangeTablePointers[species];
u16 heldItem;
u32 ability;
if (formChanges != NULL)
{
SetMonData(&party[monId], MON_DATA_SPECIES, &species[i][1]);
CalculateMonStats(&party[monId]);
heldItem = gBattleMons[battlerId].item;
ability = GetBattlerAbility(battlerId);
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
{
if (method == formChanges[i].method && species != formChanges[i].targetSpecies)
{
switch (method)
{
case FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM:
case FORM_CHANGE_BATTLE_PRIMAL_REVERSION:
if (heldItem == formChanges[i].param1)
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE:
if (gBattleMons[battlerId].moves[0] == formChanges[i].param1
|| gBattleMons[battlerId].moves[1] == formChanges[i].param1
|| gBattleMons[battlerId].moves[2] == formChanges[i].param1
|| gBattleMons[battlerId].moves[3] == formChanges[i].param1)
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_BATTLE_SWITCH:
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_BATTLE_HP_PERCENT:
if (formChanges[i].param1 == GetBattlerAbility(battlerId))
{
// We multiply by 100 to make sure that integer division doesn't mess with the health check.
u32 hpCheck = gBattleMons[battlerId].hp * 100 * 100 / gBattleMons[battlerId].maxHP;
switch(formChanges[i].param2)
{
case HP_HIGHER_THAN:
if (hpCheck > formChanges[i].param3 * 100)
targetSpecies = formChanges[i].targetSpecies;
break;
case HP_LOWER_EQ_THAN:
if (hpCheck <= formChanges[i].param3 * 100)
targetSpecies = formChanges[i].targetSpecies;
break;
}
}
if (!isSwitchingOut)
break;
case FORM_CHANGE_BATTLE_WEATHER:
if (gBattleWeather & formChanges[i].param1
|| (gBattleWeather == B_WEATHER_NONE && formChanges[i].param1 == B_WEATHER_NONE))
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_BATTLE_TURN_END:
if (formChanges[i].param1 == GetBattlerAbility(battlerId))
targetSpecies = formChanges[i].targetSpecies;
break;
}
}
}
}
return targetSpecies;
}
bool32 CanBattlerFormChange(u8 battlerId, u16 method)
{
targetSpecies = GetFormChangeTargetSpecies(&party[monId], FORM_BATTLE_END, 0);
// Can't change form if transformed.
if (gBattleMons[battlerId].status2 & STATUS2_TRANSFORMED
&& B_TRANSFORM_FORM_CHANGES >= GEN_5)
return FALSE;
// Mega Evolved Pokémon should always revert to normal upon fainting or ending the battle.
if (IsBattlerMegaEvolved(battlerId) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_END_BATTLE))
return TRUE;
else if (IsBattlerPrimalReverted(battlerId) && (method == FORM_CHANGE_END_BATTLE))
return TRUE;
return DoesSpeciesHaveFormChangeMethod(gBattleMons[battlerId].species, method);
}
bool32 TryBattleFormChange(u8 battlerId, u16 method)
{
u8 monId = gBattlerPartyIndexes[battlerId];
u8 side = GET_BATTLER_SIDE(battlerId);
struct Pokemon *party = GetBattlerParty(battlerId);
u16 targetSpecies;
if (!CanBattlerFormChange(battlerId, method))
return FALSE;
targetSpecies = GetBattleFormChangeTargetSpecies(battlerId, method);
if (targetSpecies == SPECIES_NONE)
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
if (targetSpecies != SPECIES_NONE)
{
// Saves the original species on the first form change for the player.
if (side == B_SIDE_PLAYER && gBattleStruct->changedSpecies[monId] == SPECIES_NONE)
gBattleStruct->changedSpecies[monId] = gBattleMons[battlerId].species;
TryToSetBattleFormChangeMoves(&party[monId], method);
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&party[monId]);
TryToSetBattleFormChangeMoves(&party[monId]);
gBattleMons[battlerId].species = targetSpecies;
RecalcBattlerStats(battlerId, &party[monId]);
return TRUE;
}
else if (gBattleStruct->changedSpecies[monId] != SPECIES_NONE)
{
bool8 restoreSpecies = FALSE;
// Mega Evolved Pokémon should always revert to normal upon fainting or ending the battle, so no need to add it to the form change tables.
if (IsBattlerMegaEvolved(battlerId) && (method == FORM_CHANGE_FAINT || method == FORM_CHANGE_END_BATTLE))
restoreSpecies = TRUE;
// Unlike Megas, Primal Reversion isn't canceled on fainting.
else if (IsBattlerPrimalReverted(battlerId) && (method == FORM_CHANGE_END_BATTLE))
restoreSpecies = TRUE;
if (restoreSpecies)
{
// Reverts the original species
TryToSetBattleFormChangeMoves(&party[monId], method);
SetMonData(&party[monId], MON_DATA_SPECIES, &gBattleStruct->changedSpecies[monId]);
RecalcBattlerStats(battlerId, &party[monId]);
return TRUE;
}
}
return FALSE;
}
bool32 DoBattlersShareType(u32 battler1, u32 battler2)
@ -10225,24 +10229,10 @@ bool32 CanBattlerGetOrLoseItem(u8 battlerId, u16 itemId)
// Mail can be stolen now
if (itemId == ITEM_ENIGMA_BERRY_E_READER)
return FALSE;
// Primal Reversion inducing items cannot be lost if pokemon's base species can undergo primal reversion with it.
else if (holdEffect == HOLD_EFFECT_PRIMAL_ORB && (GetPrimalReversionSpecies(GET_BASE_SPECIES_ID(species), itemId) != SPECIES_NONE))
else if (DoesSpeciesUseHoldItemToChangeForm(species, itemId))
return FALSE;
// Mega stone cannot be lost if pokemon's base species can mega evolve with it.
else if (holdEffect == HOLD_EFFECT_MEGA_STONE && (GetMegaEvolutionSpecies(GET_BASE_SPECIES_ID(species), itemId) != SPECIES_NONE))
return FALSE;
else if (GET_BASE_SPECIES_ID(species) == SPECIES_GIRATINA && itemId == ITEM_GRISEOUS_ORB)
return FALSE;
else if (GET_BASE_SPECIES_ID(species) == SPECIES_GENESECT && holdEffect == HOLD_EFFECT_DRIVE)
return FALSE;
else if (GET_BASE_SPECIES_ID(species) == SPECIES_SILVALLY && holdEffect == HOLD_EFFECT_MEMORY)
return FALSE;
else if (GET_BASE_SPECIES_ID(species) == SPECIES_ARCEUS && holdEffect == HOLD_EFFECT_PLATE)
return FALSE;
#ifdef HOLD_EFFECT_Z_CRYSTAL
else if (holdEffect == HOLD_EFFECT_Z_CRYSTAL)
return FALSE;
#endif
else
return TRUE;
}
@ -10753,46 +10743,6 @@ bool32 TryRoomService(u8 battlerId)
}
}
void DoBurmyFormChange(u32 monId)
{
u16 newSpecies, currSpecies;
struct Pokemon *party = gPlayerParty;
currSpecies = GetMonData(&party[monId], MON_DATA_SPECIES, NULL);
if ((GET_BASE_SPECIES_ID(currSpecies) == SPECIES_BURMY)
&& (gBattleStruct->appearedInBattle & gBitTable[monId]) // Burmy appeared in battle
&& GetMonData(&party[monId], MON_DATA_HP, NULL) != 0) // Burmy isn't fainted
{
switch (gBattleTerrain)
{
case BATTLE_TERRAIN_GRASS:
case BATTLE_TERRAIN_LONG_GRASS:
case BATTLE_TERRAIN_POND:
case BATTLE_TERRAIN_MOUNTAIN:
case BATTLE_TERRAIN_PLAIN:
newSpecies = SPECIES_BURMY;
break;
case BATTLE_TERRAIN_CAVE:
case BATTLE_TERRAIN_SAND:
newSpecies = SPECIES_BURMY_SANDY_CLOAK;
break;
case BATTLE_TERRAIN_BUILDING:
newSpecies = SPECIES_BURMY_TRASH_CLOAK;
break;
default: // Don't change form if last battle was water-related
newSpecies = SPECIES_NONE;
break;
}
if (newSpecies != SPECIES_NONE)
{
SetMonData(&party[monId], MON_DATA_SPECIES, &newSpecies);
CalculateMonStats(&party[monId]);
}
}
}
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget)
{
#if B_PRANKSTER_DARK_TYPES >= GEN_7
@ -10886,6 +10836,33 @@ static void SetRandomMultiHitCounter()
}
}
void CopyMonLevelAndBaseStatsToBattleMon(u32 battler, struct Pokemon *mon)
{
gBattleMons[battler].level = GetMonData(mon, MON_DATA_LEVEL);
gBattleMons[battler].hp = GetMonData(mon, MON_DATA_HP);
gBattleMons[battler].maxHP = GetMonData(mon, MON_DATA_MAX_HP);
gBattleMons[battler].attack = GetMonData(mon, MON_DATA_ATK);
gBattleMons[battler].defense = GetMonData(mon, MON_DATA_DEF);
gBattleMons[battler].speed = GetMonData(mon, MON_DATA_SPEED);
gBattleMons[battler].spAttack = GetMonData(mon, MON_DATA_SPATK);
gBattleMons[battler].spDefense = GetMonData(mon, MON_DATA_SPDEF);
}
void CopyMonAbilityAndTypesToBattleMon(u32 battler, struct Pokemon *mon)
{
gBattleMons[battler].ability = GetMonAbility(mon);
gBattleMons[battler].type1 = gSpeciesInfo[gBattleMons[battler].species].types[0];
gBattleMons[battler].type2 = gSpeciesInfo[gBattleMons[battler].species].types[1];
gBattleMons[battler].type3 = TYPE_MYSTERY;
}
void RecalcBattlerStats(u32 battler, struct Pokemon *mon)
{
CalculateMonStats(mon);
CopyMonLevelAndBaseStatsToBattleMon(battler, mon);
CopyMonAbilityAndTypesToBattleMon(battler, mon);
}
void RemoveConfusionStatus(u8 battlerId)
{
gBattleMons[battlerId].status2 &= ~STATUS2_CONFUSION;

View File

@ -3125,7 +3125,6 @@ const struct Item gItems[] =
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange_ConsumedOnUse,
.secondaryId = FORM_ITEM_USE,
.flingPower = 10,
},
@ -3139,7 +3138,6 @@ const struct Item gItems[] =
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange_ConsumedOnUse,
.secondaryId = FORM_ITEM_USE,
.flingPower = 10,
},
@ -3153,7 +3151,6 @@ const struct Item gItems[] =
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange_ConsumedOnUse,
.secondaryId = FORM_ITEM_USE,
.flingPower = 10,
},
@ -3167,7 +3164,6 @@ const struct Item gItems[] =
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange_ConsumedOnUse,
.secondaryId = FORM_ITEM_USE,
.flingPower = 10,
},
@ -9092,7 +9088,6 @@ const struct Item gItems[] =
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange,
.secondaryId = FORM_ITEM_USE,
},
[ITEM_REVEAL_GLASS] =
@ -9104,7 +9099,6 @@ const struct Item gItems[] =
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange,
.secondaryId = FORM_ITEM_USE,
},
[ITEM_DNA_SPLICERS] =
@ -9114,9 +9108,8 @@ const struct Item gItems[] =
.price = 0,
.description = sDNASplicersDesc,
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange,
.secondaryId = FORM_ITEM_USE,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo: ItemUseOutOfBattle_FormChange_Fusion
},
[ITEM_ZYGARDE_CUBE] =
@ -9140,7 +9133,6 @@ const struct Item gItems[] =
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange,
.secondaryId = FORM_ITEM_USE,
},
[ITEM_N_SOLARIZER] =
@ -9150,9 +9142,8 @@ const struct Item gItems[] =
.price = 0,
.description = sNSolarizerDesc,
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange,
.secondaryId = FORM_ITEM_USE,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo: ItemUseOutOfBattle_FormChange_Fusion
},
[ITEM_N_LUNARIZER] =
@ -9162,9 +9153,8 @@ const struct Item gItems[] =
.price = 0,
.description = sNLunarizerDesc,
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange,
.secondaryId = FORM_ITEM_USE,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo: ItemUseOutOfBattle_FormChange_Fusion
},
[ITEM_REINS_OF_UNITY] =
@ -9174,9 +9164,8 @@ const struct Item gItems[] =
.price = 0,
.description = sReinsOfUnityDesc,
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_FormChange,
.secondaryId = FORM_ITEM_USE,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse, // Todo: ItemUseOutOfBattle_FormChange_Fusion
},
// Battle Mechanic Key Items

View File

@ -2,22 +2,16 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{
[SPECIES_BULBASAUR] = {{EVO_LEVEL, 16, SPECIES_IVYSAUR}},
[SPECIES_IVYSAUR] = {{EVO_LEVEL, 32, SPECIES_VENUSAUR}},
[SPECIES_VENUSAUR] = {{EVO_MEGA_EVOLUTION, ITEM_VENUSAURITE, SPECIES_VENUSAUR_MEGA}},
[SPECIES_CHARMANDER] = {{EVO_LEVEL, 16, SPECIES_CHARMELEON}},
[SPECIES_CHARMELEON] = {{EVO_LEVEL, 36, SPECIES_CHARIZARD}},
[SPECIES_CHARIZARD] = {{EVO_MEGA_EVOLUTION, ITEM_CHARIZARDITE_X, SPECIES_CHARIZARD_MEGA_X},
{EVO_MEGA_EVOLUTION, ITEM_CHARIZARDITE_Y, SPECIES_CHARIZARD_MEGA_Y}},
[SPECIES_SQUIRTLE] = {{EVO_LEVEL, 16, SPECIES_WARTORTLE}},
[SPECIES_WARTORTLE] = {{EVO_LEVEL, 36, SPECIES_BLASTOISE}},
[SPECIES_BLASTOISE] = {{EVO_MEGA_EVOLUTION, ITEM_BLASTOISINITE, SPECIES_BLASTOISE_MEGA}},
[SPECIES_CATERPIE] = {{EVO_LEVEL, 7, SPECIES_METAPOD}},
[SPECIES_METAPOD] = {{EVO_LEVEL, 10, SPECIES_BUTTERFREE}},
[SPECIES_WEEDLE] = {{EVO_LEVEL, 7, SPECIES_KAKUNA}},
[SPECIES_KAKUNA] = {{EVO_LEVEL, 10, SPECIES_BEEDRILL}},
[SPECIES_BEEDRILL] = {{EVO_MEGA_EVOLUTION, ITEM_BEEDRILLITE, SPECIES_BEEDRILL_MEGA}},
[SPECIES_PIDGEY] = {{EVO_LEVEL, 18, SPECIES_PIDGEOTTO}},
[SPECIES_PIDGEOTTO] = {{EVO_LEVEL, 36, SPECIES_PIDGEOT}},
[SPECIES_PIDGEOT] = {{EVO_MEGA_EVOLUTION, ITEM_PIDGEOTITE, SPECIES_PIDGEOT_MEGA}},
[SPECIES_RATTATA] = {{EVO_LEVEL, 20, SPECIES_RATICATE}},
[SPECIES_SPEAROW] = {{EVO_LEVEL, 20, SPECIES_FEAROW}},
[SPECIES_EKANS] = {{EVO_LEVEL, 22, SPECIES_ARBOK}},
@ -49,7 +43,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_ABRA] = {{EVO_LEVEL, 16, SPECIES_KADABRA}},
[SPECIES_KADABRA] = {{EVO_TRADE, 0, SPECIES_ALAKAZAM},
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_ALAKAZAM}},
[SPECIES_ALAKAZAM] = {{EVO_MEGA_EVOLUTION, ITEM_ALAKAZITE, SPECIES_ALAKAZAM_MEGA}},
[SPECIES_MACHOP] = {{EVO_LEVEL, 28, SPECIES_MACHOKE}},
[SPECIES_MACHOKE] = {{EVO_TRADE, 0, SPECIES_MACHAMP},
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_MACHAMP}},
@ -62,7 +55,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_PONYTA] = {{EVO_LEVEL, 40, SPECIES_RAPIDASH}},
[SPECIES_SLOWPOKE] = {{EVO_LEVEL, 37, SPECIES_SLOWBRO},
{EVO_TRADE_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING}},
[SPECIES_SLOWBRO] = {{EVO_MEGA_EVOLUTION, ITEM_SLOWBRONITE, SPECIES_SLOWBRO_MEGA}},
[SPECIES_MAGNEMITE] = {{EVO_LEVEL, 30, SPECIES_MAGNETON}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_MAGNETON] = {{EVO_MAPSEC, MAPSEC_NEW_MAUVILLE, SPECIES_MAGNEZONE},
@ -75,7 +67,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_GASTLY] = {{EVO_LEVEL, 25, SPECIES_HAUNTER}},
[SPECIES_HAUNTER] = {{EVO_TRADE, 0, SPECIES_GENGAR},
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_GENGAR}},
[SPECIES_GENGAR] = {{EVO_MEGA_EVOLUTION, ITEM_GENGARITE, SPECIES_GENGAR_MEGA}},
[SPECIES_ONIX] = {{EVO_TRADE_ITEM, ITEM_METAL_COAT, SPECIES_STEELIX}},
[SPECIES_DROWZEE] = {{EVO_LEVEL, 26, SPECIES_HYPNO}},
[SPECIES_KRABBY] = {{EVO_LEVEL, 28, SPECIES_KINGLER}},
@ -96,7 +87,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
#if P_GEN_4_POKEMON == TRUE
[SPECIES_TANGELA] = {{EVO_MOVE, MOVE_ANCIENT_POWER, SPECIES_TANGROWTH}},
#endif
[SPECIES_KANGASKHAN] = {{EVO_MEGA_EVOLUTION, ITEM_KANGASKHANITE, SPECIES_KANGASKHAN_MEGA}},
[SPECIES_HORSEA] = {{EVO_LEVEL, 32, SPECIES_SEADRA}},
[SPECIES_SEADRA] = {{EVO_TRADE_ITEM, ITEM_DRAGON_SCALE, SPECIES_KINGDRA}},
[SPECIES_GOLDEEN] = {{EVO_LEVEL, 33, SPECIES_SEAKING}},
@ -107,9 +97,7 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_ELECTABUZZ] = {{EVO_TRADE_ITEM, ITEM_ELECTIRIZER, SPECIES_ELECTIVIRE}},
[SPECIES_MAGMAR] = {{EVO_TRADE_ITEM, ITEM_MAGMARIZER, SPECIES_MAGMORTAR}},
#endif
[SPECIES_PINSIR] = {{EVO_MEGA_EVOLUTION, ITEM_PINSIRITE, SPECIES_PINSIR_MEGA}},
[SPECIES_MAGIKARP] = {{EVO_LEVEL, 20, SPECIES_GYARADOS}},
[SPECIES_GYARADOS] = {{EVO_MEGA_EVOLUTION, ITEM_GYARADOSITE, SPECIES_GYARADOS_MEGA}},
[SPECIES_EEVEE] = {{EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_JOLTEON},
{EVO_ITEM, ITEM_WATER_STONE, SPECIES_VAPOREON},
{EVO_ITEM, ITEM_FIRE_STONE, SPECIES_FLAREON},
@ -128,11 +116,8 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_PORYGON] = {{EVO_TRADE_ITEM, ITEM_UPGRADE, SPECIES_PORYGON2}},
[SPECIES_OMANYTE] = {{EVO_LEVEL, 40, SPECIES_OMASTAR}},
[SPECIES_KABUTO] = {{EVO_LEVEL, 40, SPECIES_KABUTOPS}},
[SPECIES_AERODACTYL] = {{EVO_MEGA_EVOLUTION, ITEM_AERODACTYLITE, SPECIES_AERODACTYL_MEGA}},
[SPECIES_DRATINI] = {{EVO_LEVEL, 30, SPECIES_DRAGONAIR}},
[SPECIES_DRAGONAIR] = {{EVO_LEVEL, 55, SPECIES_DRAGONITE}},
[SPECIES_MEWTWO] = {{EVO_MEGA_EVOLUTION, ITEM_MEWTWONITE_X, SPECIES_MEWTWO_MEGA_X},
{EVO_MEGA_EVOLUTION, ITEM_MEWTWONITE_Y, SPECIES_MEWTWO_MEGA_Y}},
[SPECIES_CHIKORITA] = {{EVO_LEVEL, 16, SPECIES_BAYLEEF}},
[SPECIES_BAYLEEF] = {{EVO_LEVEL, 32, SPECIES_MEGANIUM}},
[SPECIES_CYNDAQUIL] = {{EVO_LEVEL, 14, SPECIES_QUILAVA}},
@ -154,7 +139,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_NATU] = {{EVO_LEVEL, 25, SPECIES_XATU}},
[SPECIES_MAREEP] = {{EVO_LEVEL, 15, SPECIES_FLAAFFY}},
[SPECIES_FLAAFFY] = {{EVO_LEVEL, 30, SPECIES_AMPHAROS}},
[SPECIES_AMPHAROS] = {{EVO_MEGA_EVOLUTION, ITEM_AMPHAROSITE, SPECIES_AMPHAROS_MEGA}},
[SPECIES_MARILL] = {{EVO_LEVEL, 18, SPECIES_AZUMARILL}},
[SPECIES_HOPPIP] = {{EVO_LEVEL, 18, SPECIES_SKIPLOOM}},
[SPECIES_SKIPLOOM] = {{EVO_LEVEL, 27, SPECIES_JUMPLUFF}},
@ -172,10 +156,7 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
#if P_GEN_4_POKEMON == TRUE
[SPECIES_GLIGAR] = {{EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_FANG, SPECIES_GLISCOR}},
#endif
[SPECIES_STEELIX] = {{EVO_MEGA_EVOLUTION, ITEM_STEELIXITE, SPECIES_STEELIX_MEGA}},
[SPECIES_SNUBBULL] = {{EVO_LEVEL, 23, SPECIES_GRANBULL}},
[SPECIES_SCIZOR] = {{EVO_MEGA_EVOLUTION, ITEM_SCIZORITE, SPECIES_SCIZOR_MEGA}},
[SPECIES_HERACROSS] = {{EVO_MEGA_EVOLUTION, ITEM_HERACRONITE, SPECIES_HERACROSS_MEGA}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_SNEASEL] = {{EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_CLAW, SPECIES_WEAVILE}},
#endif
@ -187,7 +168,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
#endif
[SPECIES_REMORAID] = {{EVO_LEVEL, 25, SPECIES_OCTILLERY}},
[SPECIES_HOUNDOUR] = {{EVO_LEVEL, 24, SPECIES_HOUNDOOM}},
[SPECIES_HOUNDOOM] = {{EVO_MEGA_EVOLUTION, ITEM_HOUNDOOMINITE, SPECIES_HOUNDOOM_MEGA}},
[SPECIES_PHANPY] = {{EVO_LEVEL, 25, SPECIES_DONPHAN}},
#if P_GEN_4_POKEMON == TRUE
[SPECIES_PORYGON2] = {{EVO_TRADE_ITEM, ITEM_DUBIOUS_DISC, SPECIES_PORYGON_Z}},
@ -200,16 +180,12 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_MAGBY] = {{EVO_LEVEL, 30, SPECIES_MAGMAR}},
[SPECIES_LARVITAR] = {{EVO_LEVEL, 30, SPECIES_PUPITAR}},
[SPECIES_PUPITAR] = {{EVO_LEVEL, 55, SPECIES_TYRANITAR}},
[SPECIES_TYRANITAR] = {{EVO_MEGA_EVOLUTION, ITEM_TYRANITARITE, SPECIES_TYRANITAR_MEGA}},
[SPECIES_TREECKO] = {{EVO_LEVEL, 16, SPECIES_GROVYLE}},
[SPECIES_GROVYLE] = {{EVO_LEVEL, 36, SPECIES_SCEPTILE}},
[SPECIES_SCEPTILE] = {{EVO_MEGA_EVOLUTION, ITEM_SCEPTILITE, SPECIES_SCEPTILE_MEGA}},
[SPECIES_TORCHIC] = {{EVO_LEVEL, 16, SPECIES_COMBUSKEN}},
[SPECIES_COMBUSKEN] = {{EVO_LEVEL, 36, SPECIES_BLAZIKEN}},
[SPECIES_BLAZIKEN] = {{EVO_MEGA_EVOLUTION, ITEM_BLAZIKENITE, SPECIES_BLAZIKEN_MEGA}},
[SPECIES_MUDKIP] = {{EVO_LEVEL, 16, SPECIES_MARSHTOMP}},
[SPECIES_MARSHTOMP] = {{EVO_LEVEL, 36, SPECIES_SWAMPERT}},
[SPECIES_SWAMPERT] = {{EVO_MEGA_EVOLUTION, ITEM_SWAMPERTITE, SPECIES_SWAMPERT_MEGA}},
[SPECIES_POOCHYENA] = {{EVO_LEVEL, 18, SPECIES_MIGHTYENA}},
[SPECIES_ZIGZAGOON] = {{EVO_LEVEL, 20, SPECIES_LINOONE}},
[SPECIES_WURMPLE] = {{EVO_LEVEL_SILCOON, 7, SPECIES_SILCOON},
@ -232,20 +208,16 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
#if P_GEN_4_POKEMON == TRUE
[SPECIES_NOSEPASS] = {{EVO_MAPSEC, MAPSEC_NEW_MAUVILLE, SPECIES_PROBOPASS}},
#endif
[SPECIES_SABLEYE] = {{EVO_MEGA_EVOLUTION, ITEM_SABLENITE, SPECIES_SABLEYE_MEGA}},
[SPECIES_BARBOACH] = {{EVO_LEVEL, 30, SPECIES_WHISCASH}},
[SPECIES_CORPHISH] = {{EVO_LEVEL, 30, SPECIES_CRAWDAUNT}},
[SPECIES_FEEBAS] = {{EVO_BEAUTY, 170, SPECIES_MILOTIC},
{EVO_TRADE_ITEM, ITEM_PRISM_SCALE, SPECIES_MILOTIC}},
[SPECIES_CARVANHA] = {{EVO_LEVEL, 30, SPECIES_SHARPEDO}},
[SPECIES_SHARPEDO] = {{EVO_MEGA_EVOLUTION, ITEM_SHARPEDONITE, SPECIES_SHARPEDO_MEGA}},
[SPECIES_TRAPINCH] = {{EVO_LEVEL, 35, SPECIES_VIBRAVA}},
[SPECIES_VIBRAVA] = {{EVO_LEVEL, 45, SPECIES_FLYGON}},
[SPECIES_MAKUHITA] = {{EVO_LEVEL, 24, SPECIES_HARIYAMA}},
[SPECIES_ELECTRIKE] = {{EVO_LEVEL, 26, SPECIES_MANECTRIC}},
[SPECIES_MANECTRIC] = {{EVO_MEGA_EVOLUTION, ITEM_MANECTITE, SPECIES_MANECTRIC_MEGA}},
[SPECIES_NUMEL] = {{EVO_LEVEL, 33, SPECIES_CAMERUPT}},
[SPECIES_CAMERUPT] = {{EVO_MEGA_EVOLUTION, ITEM_CAMERUPTITE, SPECIES_CAMERUPT_MEGA}},
[SPECIES_SPHEAL] = {{EVO_LEVEL, 32, SPECIES_SEALEO}},
[SPECIES_SEALEO] = {{EVO_LEVEL, 44, SPECIES_WALREIN}},
[SPECIES_CACNEA] = {{EVO_LEVEL, 32, SPECIES_CACTURNE}},
@ -254,14 +226,10 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{EVO_ITEM_FEMALE, ITEM_DAWN_STONE, SPECIES_FROSLASS}
#endif
},
[SPECIES_GLALIE] = {{EVO_MEGA_EVOLUTION, ITEM_GLALITITE, SPECIES_GLALIE_MEGA}},
[SPECIES_AZURILL] = {{EVO_FRIENDSHIP, 0, SPECIES_MARILL}},
[SPECIES_SPOINK] = {{EVO_LEVEL, 32, SPECIES_GRUMPIG}},
[SPECIES_MAWILE] = {{EVO_MEGA_EVOLUTION, ITEM_MAWILITE, SPECIES_MAWILE_MEGA}},
[SPECIES_MEDITITE] = {{EVO_LEVEL, 37, SPECIES_MEDICHAM}},
[SPECIES_MEDICHAM] = {{EVO_MEGA_EVOLUTION, ITEM_MEDICHAMITE, SPECIES_MEDICHAM_MEGA}},
[SPECIES_SWABLU] = {{EVO_LEVEL, 35, SPECIES_ALTARIA}},
[SPECIES_ALTARIA] = {{EVO_MEGA_EVOLUTION, ITEM_ALTARIANITE, SPECIES_ALTARIA_MEGA}},
[SPECIES_WYNAUT] = {{EVO_LEVEL, 15, SPECIES_WOBBUFFET}},
[SPECIES_DUSKULL] = {{EVO_LEVEL, 37, SPECIES_DUSCLOPS}},
#if P_GEN_4_POKEMON == TRUE
@ -275,12 +243,9 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_LOUDRED] = {{EVO_LEVEL, 40, SPECIES_EXPLOUD}},
[SPECIES_CLAMPERL] = {{EVO_TRADE_ITEM, ITEM_DEEP_SEA_TOOTH, SPECIES_HUNTAIL},
{EVO_TRADE_ITEM, ITEM_DEEP_SEA_SCALE, SPECIES_GOREBYSS}},
[SPECIES_ABSOL] = {{EVO_MEGA_EVOLUTION, ITEM_ABSOLITE, SPECIES_ABSOL_MEGA}},
[SPECIES_SHUPPET] = {{EVO_LEVEL, 37, SPECIES_BANETTE}},
[SPECIES_BANETTE] = {{EVO_MEGA_EVOLUTION, ITEM_BANETTITE, SPECIES_BANETTE_MEGA}},
[SPECIES_ARON] = {{EVO_LEVEL, 32, SPECIES_LAIRON}},
[SPECIES_LAIRON] = {{EVO_LEVEL, 42, SPECIES_AGGRON}},
[SPECIES_AGGRON] = {{EVO_MEGA_EVOLUTION, ITEM_AGGRONITE, SPECIES_AGGRON_MEGA}},
[SPECIES_LILEEP] = {{EVO_LEVEL, 40, SPECIES_CRADILY}},
[SPECIES_ANORITH] = {{EVO_LEVEL, 40, SPECIES_ARMALDO}},
[SPECIES_RALTS] = {{EVO_LEVEL, 20, SPECIES_KIRLIA}},
@ -289,19 +254,10 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{EVO_ITEM_MALE, ITEM_DAWN_STONE, SPECIES_GALLADE}
#endif
},
[SPECIES_GARDEVOIR] = {{EVO_MEGA_EVOLUTION, ITEM_GARDEVOIRITE, SPECIES_GARDEVOIR_MEGA}},
[SPECIES_BAGON] = {{EVO_LEVEL, 30, SPECIES_SHELGON}},
[SPECIES_SHELGON] = {{EVO_LEVEL, 50, SPECIES_SALAMENCE}},
[SPECIES_SALAMENCE] = {{EVO_MEGA_EVOLUTION, ITEM_SALAMENCITE, SPECIES_SALAMENCE_MEGA}},
[SPECIES_BELDUM] = {{EVO_LEVEL, 20, SPECIES_METANG}},
[SPECIES_METANG] = {{EVO_LEVEL, 45, SPECIES_METAGROSS}},
[SPECIES_METAGROSS] = {{EVO_MEGA_EVOLUTION, ITEM_METAGROSSITE, SPECIES_METAGROSS_MEGA}},
[SPECIES_LATIAS] = {{EVO_MEGA_EVOLUTION, ITEM_LATIASITE, SPECIES_LATIAS_MEGA}},
[SPECIES_LATIOS] = {{EVO_MEGA_EVOLUTION, ITEM_LATIOSITE, SPECIES_LATIOS_MEGA}},
[SPECIES_KYOGRE] = {{EVO_PRIMAL_REVERSION, ITEM_BLUE_ORB, SPECIES_KYOGRE_PRIMAL}},
[SPECIES_GROUDON] = {{EVO_PRIMAL_REVERSION, ITEM_RED_ORB, SPECIES_GROUDON_PRIMAL}},
[SPECIES_RAYQUAZA] = {{EVO_MOVE_MEGA_EVOLUTION, MOVE_DRAGON_ASCENT, SPECIES_RAYQUAZA_MEGA}},
#if P_GEN_4_POKEMON == TRUE
// Gens 4-7
[SPECIES_TURTWIG] = {{EVO_LEVEL, 18, SPECIES_GROTLE}},
@ -327,7 +283,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_SHELLOS] = {{EVO_LEVEL, 30, SPECIES_GASTRODON}},
[SPECIES_DRIFLOON] = {{EVO_LEVEL, 28, SPECIES_DRIFBLIM}},
[SPECIES_BUNEARY] = {{EVO_FRIENDSHIP, 0, SPECIES_LOPUNNY}},
[SPECIES_LOPUNNY] = {{EVO_MEGA_EVOLUTION, ITEM_LOPUNNITE, SPECIES_LOPUNNY_MEGA}},
[SPECIES_GLAMEOW] = {{EVO_LEVEL, 38, SPECIES_PURUGLY}},
[SPECIES_CHINGLING] = {{EVO_FRIENDSHIP_NIGHT, 0, SPECIES_CHIMECHO}},
[SPECIES_STUNKY] = {{EVO_LEVEL, 34, SPECIES_SKUNTANK}},
@ -337,18 +292,14 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_HAPPINY] = {{EVO_ITEM_HOLD_DAY, ITEM_OVAL_STONE, SPECIES_CHANSEY}},
[SPECIES_GIBLE] = {{EVO_LEVEL, 24, SPECIES_GABITE}},
[SPECIES_GABITE] = {{EVO_LEVEL, 48, SPECIES_GARCHOMP}},
[SPECIES_GARCHOMP] = {{EVO_MEGA_EVOLUTION, ITEM_GARCHOMPITE, SPECIES_GARCHOMP_MEGA}},
[SPECIES_MUNCHLAX] = {{EVO_FRIENDSHIP, 0, SPECIES_SNORLAX}},
[SPECIES_RIOLU] = {{EVO_FRIENDSHIP_DAY, 0, SPECIES_LUCARIO}},
[SPECIES_LUCARIO] = {{EVO_MEGA_EVOLUTION, ITEM_LUCARIONITE, SPECIES_LUCARIO_MEGA}},
[SPECIES_HIPPOPOTAS] = {{EVO_LEVEL, 34, SPECIES_HIPPOWDON}},
[SPECIES_SKORUPI] = {{EVO_LEVEL, 40, SPECIES_DRAPION}},
[SPECIES_CROAGUNK] = {{EVO_LEVEL, 37, SPECIES_TOXICROAK}},
[SPECIES_FINNEON] = {{EVO_LEVEL, 31, SPECIES_LUMINEON}},
[SPECIES_MANTYKE] = {{EVO_SPECIFIC_MON_IN_PARTY, SPECIES_REMORAID, SPECIES_MANTINE}},
[SPECIES_SNOVER] = {{EVO_LEVEL, 40, SPECIES_ABOMASNOW}},
[SPECIES_ABOMASNOW] = {{EVO_MEGA_EVOLUTION, ITEM_ABOMASITE, SPECIES_ABOMASNOW_MEGA}},
[SPECIES_GALLADE] = {{EVO_MEGA_EVOLUTION, ITEM_GALLADITE, SPECIES_GALLADE_MEGA}},
#endif
#if P_GEN_5_POKEMON == TRUE
[SPECIES_SNIVY] = {{EVO_LEVEL, 17, SPECIES_SERVINE}},
@ -373,7 +324,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_GIGALITH}},
[SPECIES_WOOBAT] = {{EVO_FRIENDSHIP, 0, SPECIES_SWOOBAT}},
[SPECIES_DRILBUR] = {{EVO_LEVEL, 31, SPECIES_EXCADRILL}},
[SPECIES_AUDINO] = {{EVO_MEGA_EVOLUTION, ITEM_AUDINITE, SPECIES_AUDINO_MEGA}},
[SPECIES_TIMBURR] = {{EVO_LEVEL, 25, SPECIES_GURDURR}},
[SPECIES_GURDURR] = {{EVO_TRADE, 0, SPECIES_CONKELDURR},
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_CONKELDURR}},
@ -467,7 +417,6 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
{EVO_ITEM, ITEM_LINKING_CORD, SPECIES_GOURGEIST}},
[SPECIES_BERGMITE] = {{EVO_LEVEL, 37, SPECIES_AVALUGG}},
[SPECIES_NOIBAT] = {{EVO_LEVEL, 48, SPECIES_NOIVERN}},
[SPECIES_DIANCIE] = {{EVO_MEGA_EVOLUTION, ITEM_DIANCITE, SPECIES_DIANCIE_MEGA}},
#endif
#if P_GEN_7_POKEMON == TRUE
[SPECIES_ROWLET] = {{EVO_LEVEL, 17, SPECIES_DARTRIX}},

View File

@ -1,6 +1,107 @@
const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
{
[SPECIES_VENUSAUR] = sVenusaurFormChangeTable,
[SPECIES_VENUSAUR_MEGA] = sVenusaurFormChangeTable,
[SPECIES_CHARIZARD] = sCharizardFormChangeTable,
[SPECIES_CHARIZARD_MEGA_X] = sCharizardFormChangeTable,
[SPECIES_CHARIZARD_MEGA_Y] = sCharizardFormChangeTable,
[SPECIES_BLASTOISE] = sBlastoiseFormChangeTable,
[SPECIES_BLASTOISE_MEGA] = sBlastoiseFormChangeTable,
[SPECIES_BEEDRILL] = sBeedrillFormChangeTable,
[SPECIES_BEEDRILL_MEGA] = sBeedrillFormChangeTable,
[SPECIES_PIDGEOT] = sPidgeotFormChangeTable,
[SPECIES_PIDGEOT_MEGA] = sPidgeotFormChangeTable,
[SPECIES_ALAKAZAM] = sAlakazamFormChangeTable,
[SPECIES_ALAKAZAM_MEGA] = sAlakazamFormChangeTable,
[SPECIES_SLOWBRO] = sSlowbroFormChangeTable,
[SPECIES_SLOWBRO_MEGA] = sSlowbroFormChangeTable,
[SPECIES_GENGAR] = sGengarFormChangeTable,
[SPECIES_GENGAR_MEGA] = sGengarFormChangeTable,
[SPECIES_KANGASKHAN] = sKangaskhanFormChangeTable,
[SPECIES_KANGASKHAN_MEGA] = sKangaskhanFormChangeTable,
[SPECIES_PINSIR] = sPinsirFormChangeTable,
[SPECIES_PINSIR_MEGA] = sPinsirFormChangeTable,
[SPECIES_GYARADOS] = sGyaradosFormChangeTable,
[SPECIES_GYARADOS_MEGA] = sGyaradosFormChangeTable,
[SPECIES_AERODACTYL] = sAerodactylFormChangeTable,
[SPECIES_AERODACTYL_MEGA] = sAerodactylFormChangeTable,
[SPECIES_MEWTWO] = sMewtwoFormChangeTable,
[SPECIES_MEWTWO_MEGA_X] = sMewtwoFormChangeTable,
[SPECIES_MEWTWO_MEGA_Y] = sMewtwoFormChangeTable,
[SPECIES_AMPHAROS] = sAmpharosFormChangeTable,
[SPECIES_AMPHAROS_MEGA] = sAmpharosFormChangeTable,
[SPECIES_STEELIX] = sSteelixFormChangeTable,
[SPECIES_STEELIX_MEGA] = sSteelixFormChangeTable,
[SPECIES_SCIZOR] = sScizorFormChangeTable,
[SPECIES_SCIZOR_MEGA] = sScizorFormChangeTable,
[SPECIES_HERACROSS] = sHeracrossFormChangeTable,
[SPECIES_HERACROSS_MEGA] = sHeracrossFormChangeTable,
[SPECIES_HOUNDOOM] = sHoundoomFormChangeTable,
[SPECIES_HOUNDOOM_MEGA] = sHoundoomFormChangeTable,
[SPECIES_TYRANITAR] = sTyranitarFormChangeTable,
[SPECIES_TYRANITAR_MEGA] = sTyranitarFormChangeTable,
[SPECIES_SCEPTILE] = sSceptileFormChangeTable,
[SPECIES_SCEPTILE_MEGA] = sSceptileFormChangeTable,
[SPECIES_BLAZIKEN] = sBlazikenFormChangeTable,
[SPECIES_BLAZIKEN_MEGA] = sBlazikenFormChangeTable,
[SPECIES_SWAMPERT] = sSwampertFormChangeTable,
[SPECIES_SWAMPERT_MEGA] = sSwampertFormChangeTable,
[SPECIES_SABLEYE] = sSableyeFormChangeTable,
[SPECIES_SABLEYE_MEGA] = sSableyeFormChangeTable,
[SPECIES_SHARPEDO] = sSharpedoFormChangeTable,
[SPECIES_SHARPEDO_MEGA] = sSharpedoFormChangeTable,
[SPECIES_MANECTRIC] = sManectricFormChangeTable,
[SPECIES_MANECTRIC_MEGA] = sManectricFormChangeTable,
[SPECIES_CAMERUPT] = sCameruptFormChangeTable,
[SPECIES_CAMERUPT_MEGA] = sCameruptFormChangeTable,
[SPECIES_GLALIE] = sGlalieFormChangeTable,
[SPECIES_GLALIE_MEGA] = sGlalieFormChangeTable,
[SPECIES_MAWILE] = sMawileFormChangeTable,
[SPECIES_MAWILE_MEGA] = sMawileFormChangeTable,
[SPECIES_MEDICHAM] = sMedichamFormChangeTable,
[SPECIES_MEDICHAM_MEGA] = sMedichamFormChangeTable,
[SPECIES_ALTARIA] = sAltariaFormChangeTable,
[SPECIES_ALTARIA_MEGA] = sAltariaFormChangeTable,
[SPECIES_ABSOL] = sAbsolFormChangeTable,
[SPECIES_ABSOL_MEGA] = sAbsolFormChangeTable,
[SPECIES_CASTFORM] = sCastformFormChangeTable,
[SPECIES_CASTFORM_SUNNY] = sCastformFormChangeTable,
[SPECIES_CASTFORM_RAINY] = sCastformFormChangeTable,
[SPECIES_CASTFORM_SNOWY] = sCastformFormChangeTable,
[SPECIES_BANETTE] = sBanetteFormChangeTable,
[SPECIES_BANETTE_MEGA] = sBanetteFormChangeTable,
[SPECIES_AGGRON] = sAggronFormChangeTable,
[SPECIES_AGGRON_MEGA] = sAggronFormChangeTable,
[SPECIES_GARDEVOIR] = sGardevoirFormChangeTable,
[SPECIES_GARDEVOIR_MEGA] = sGardevoirFormChangeTable,
[SPECIES_SALAMENCE] = sSalamenceFormChangeTable,
[SPECIES_SALAMENCE_MEGA] = sSalamenceFormChangeTable,
[SPECIES_METAGROSS] = sMetagrossFormChangeTable,
[SPECIES_METAGROSS_MEGA] = sMetagrossFormChangeTable,
[SPECIES_LATIAS] = sLatiasFormChangeTable,
[SPECIES_LATIAS_MEGA] = sLatiasFormChangeTable,
[SPECIES_LATIOS] = sLatiosFormChangeTable,
[SPECIES_LATIOS_MEGA] = sLatiosFormChangeTable,
[SPECIES_KYOGRE] = sKyogreFormChangeTable,
[SPECIES_KYOGRE_PRIMAL] = sKyogreFormChangeTable,
[SPECIES_GROUDON] = sGroudonFormChangeTable,
[SPECIES_GROUDON_PRIMAL] = sGroudonFormChangeTable,
[SPECIES_RAYQUAZA] = sRayquazaFormChangeTable,
[SPECIES_RAYQUAZA_MEGA] = sRayquazaFormChangeTable,
#if P_GEN_4_POKEMON == TRUE
[SPECIES_BURMY] = sBurmyFormChangeTable,
[SPECIES_BURMY_SANDY_CLOAK] = sBurmyFormChangeTable,
[SPECIES_BURMY_TRASH_CLOAK] = sBurmyFormChangeTable,
[SPECIES_LOPUNNY] = sLopunnyFormChangeTable,
[SPECIES_LOPUNNY_MEGA] = sLopunnyFormChangeTable,
[SPECIES_GARCHOMP] = sGarchompFormChangeTable,
[SPECIES_GARCHOMP_MEGA] = sGarchompFormChangeTable,
[SPECIES_LUCARIO] = sLucarioFormChangeTable,
[SPECIES_LUCARIO_MEGA] = sLucarioFormChangeTable,
[SPECIES_ABOMASNOW] = sAbomasnowFormChangeTable,
[SPECIES_ABOMASNOW_MEGA] = sAbomasnowFormChangeTable,
[SPECIES_GALLADE] = sGalladeFormChangeTable,
[SPECIES_GALLADE_MEGA] = sGalladeFormChangeTable,
[SPECIES_DIALGA] = sDialgaFormChangeTable,
[SPECIES_DIALGA_ORIGIN] = sDialgaFormChangeTable,
[SPECIES_PALKIA] = sPalkiaFormChangeTable,
@ -29,6 +130,12 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
[SPECIES_ARCEUS_FAIRY] = sArceusFormChangeTable,
#endif
#if P_GEN_5_POKEMON == TRUE
[SPECIES_AUDINO] = sAudinoFormChangeTable,
[SPECIES_AUDINO_MEGA] = sAudinoFormChangeTable,
[SPECIES_DARMANITAN] = sDarmanitanFormChangeTable,
[SPECIES_DARMANITAN_ZEN_MODE] = sDarmanitanFormChangeTable,
[SPECIES_DARMANITAN_GALARIAN] = sDarmanitanGalarianFormChangeTable,
[SPECIES_DARMANITAN_ZEN_MODE_GALARIAN] = sDarmanitanGalarianFormChangeTable,
[SPECIES_TORNADUS] = sTornadusFormChangeTable,
[SPECIES_TORNADUS_THERIAN] = sTornadusFormChangeTable,
[SPECIES_THUNDURUS] = sThundurusFormChangeTable,
@ -37,6 +144,8 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
[SPECIES_LANDORUS_THERIAN] = sLandorusFormChangeTable,
[SPECIES_KELDEO] = sKeldeoFormChangeTable,
[SPECIES_KELDEO_RESOLUTE] = sKeldeoFormChangeTable,
[SPECIES_MELOETTA] = sMeloettaFormChangeTable,
[SPECIES_MELOETTA_PIROUETTE] = sMeloettaFormChangeTable,
[SPECIES_GENESECT] = sGenesectFormChangeTable,
[SPECIES_GENESECT_DOUSE_DRIVE] = sGenesectFormChangeTable,
[SPECIES_GENESECT_SHOCK_DRIVE] = sGenesectFormChangeTable,
@ -44,8 +153,17 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
[SPECIES_GENESECT_CHILL_DRIVE] = sGenesectFormChangeTable,
#endif
#if P_GEN_6_POKEMON == TRUE
[SPECIES_GRENINJA_BATTLE_BOND] = sGreninjaBattleBondFormChangeTable,
[SPECIES_GRENINJA_ASH] = sGreninjaBattleBondFormChangeTable,
[SPECIES_AEGISLASH] = sAegislashFormChangeTable,
[SPECIES_AEGISLASH_BLADE] = sAegislashFormChangeTable,
[SPECIES_XERNEAS] = sXerneasFormChangeTable,
[SPECIES_XERNEAS_ACTIVE] = sXerneasFormChangeTable,
[SPECIES_ZYGARDE_10_POWER_CONSTRUCT] = sZygardePowerConstructFormChangeTable,
[SPECIES_ZYGARDE_50_POWER_CONSTRUCT] = sZygardePowerConstructFormChangeTable,
[SPECIES_ZYGARDE_COMPLETE] = sZygardePowerConstructFormChangeTable,
[SPECIES_DIANCIE] = sDiancieFormChangeTable,
[SPECIES_DIANCIE_MEGA] = sDiancieFormChangeTable,
[SPECIES_HOOPA] = sHoopaFormChangeTable,
[SPECIES_HOOPA_UNBOUND] = sHoopaFormChangeTable,
#endif
@ -54,6 +172,8 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
[SPECIES_ORICORIO_POM_POM] = sOricorioFormChangeTable,
[SPECIES_ORICORIO_PAU] = sOricorioFormChangeTable,
[SPECIES_ORICORIO_SENSU] = sOricorioFormChangeTable,
[SPECIES_WISHIWASHI] = sWishiwashiFormChangeTable,
[SPECIES_WISHIWASHI_SCHOOL] = sWishiwashiFormChangeTable,
[SPECIES_SILVALLY] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_BUG] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_DARK] = sSilvallyFormChangeTable,
@ -72,8 +192,31 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
[SPECIES_SILVALLY_ROCK] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_STEEL] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_WATER] = sSilvallyFormChangeTable,
[SPECIES_MIMIKYU] = sMimikyuFormChangeTable,
[SPECIES_MIMIKYU_BUSTED] = sMimikyuFormChangeTable,
[SPECIES_MINIOR] = sMiniorRedFormChangeTable,
[SPECIES_MINIOR_CORE_RED] = sMiniorRedFormChangeTable,
[SPECIES_MINIOR_METEOR_BLUE] = sMiniorBlueFormChangeTable,
[SPECIES_MINIOR_CORE_BLUE] = sMiniorBlueFormChangeTable,
[SPECIES_MINIOR_METEOR_GREEN] = sMiniorGreenFormChangeTable,
[SPECIES_MINIOR_CORE_GREEN] = sMiniorGreenFormChangeTable,
[SPECIES_MINIOR_METEOR_INDIGO] = sMiniorIndigoFormChangeTable,
[SPECIES_MINIOR_CORE_INDIGO] = sMiniorIndigoFormChangeTable,
[SPECIES_MINIOR_METEOR_ORANGE] = sMiniorOrangeFormChangeTable,
[SPECIES_MINIOR_CORE_ORANGE] = sMiniorOrangeFormChangeTable,
[SPECIES_MINIOR_METEOR_VIOLET] = sMiniorVioletFormChangeTable,
[SPECIES_MINIOR_CORE_VIOLET] = sMiniorVioletFormChangeTable,
[SPECIES_MINIOR_METEOR_YELLOW] = sMiniorYellowFormChangeTable,
[SPECIES_MINIOR_CORE_YELLOW] = sMiniorYellowFormChangeTable,
#endif
#if P_GEN_8_POKEMON == TRUE
[SPECIES_CRAMORANT] = sCramorantFormChangeTable,
[SPECIES_CRAMORANT_GULPING] = sCramorantFormChangeTable,
[SPECIES_CRAMORANT_GORGING] = sCramorantFormChangeTable,
[SPECIES_EISCUE] = sEiscueFormChangeTable,
[SPECIES_EISCUE_NOICE_FACE] = sEiscueFormChangeTable,
[SPECIES_MORPEKO] = sMorpekoFormChangeTable,
[SPECIES_MORPEKO_HANGRY] = sMorpekoFormChangeTable,
[SPECIES_ZACIAN] = sZacianFormChangeTable,
[SPECIES_ZACIAN_CROWNED_SWORD] = sZacianFormChangeTable,
[SPECIES_ZAMAZENTA] = sZamazentaFormChangeTable,

View File

@ -1,211 +1,582 @@
/*
FORM_ITEM_HOLD:
Form change activates when the specified item is given to or taken from the selected Pokémon.
Alternatively, form change activates when the specified item is is given to or taken from
the selected Pokémon that has a particular ability.
param1 = item to hold
param2 = ability to check for, optional
static const struct FormChange sVenusaurFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_VENUSAUR_MEGA, ITEM_VENUSAURITE},
{FORM_CHANGE_TERMINATOR},
};
FORM_ITEM_USE:
Form change activates when the item is used on the selected Pokémon.
param1 = item to use
param2 = DAY if form change activates in the daytime, optional
NIGHT if form change activates at nighttime, optional
static const struct FormChange sCharizardFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_CHARIZARD_MEGA_X, ITEM_CHARIZARDITE_X},
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_CHARIZARD_MEGA_Y, ITEM_CHARIZARDITE_Y},
{FORM_CHANGE_TERMINATOR},
};
FORM_MOVE:
Form change activates when the Pokémon learns or forgets the move.
param1 = move to check for
param2 = WHEN_LEARNED if form change activates when move is forgotten
WHEN_FORGOTTEN if form change activates when move is learned
static const struct FormChange sBlastoiseFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_BLASTOISE_MEGA, ITEM_BLASTOISINITE},
{FORM_CHANGE_TERMINATOR},
};
FORM_WITHDRAW:
Form change activates when the Pokémon is withdrawn from the PC or Daycare.
no parameters
static const struct FormChange sBeedrillFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_BEEDRILL_MEGA, ITEM_BEEDRILLITE},
{FORM_CHANGE_TERMINATOR},
};
FORM_BATTLE_BEGIN:
Form change activates when the Pokémon is sent out at the beginning of a battle
param1 = item to hold, optional
param2 = a move that will be replaced, optional
param3 = a new move to replace it with, optional
static const struct FormChange sPidgeotFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_PIDGEOT_MEGA, ITEM_PIDGEOTITE},
{FORM_CHANGE_TERMINATOR},
};
FORM_BATTLE_END:
Form change activates at the end of a battle
param1 = item to hold, optional
param2 = a move that will be replaced, optional
param3 = a new move to replace it with, optional
*/
static const struct FormChange sAlakazamFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_ALAKAZAM_MEGA, ITEM_ALAKAZITE},
{FORM_CHANGE_TERMINATOR},
};
// FORM_MOVE param2 Arguments
#define WHEN_LEARNED 0
#define WHEN_FORGOTTEN 1
static const struct FormChange sSlowbroFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_SLOWBRO_MEGA, ITEM_SLOWBRONITE},
{FORM_CHANGE_TERMINATOR},
};
// FORM_ITEM_USE param2 Arguments
#define DAY 1
#define NIGHT 2
static const struct FormChange sGengarFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GENGAR_MEGA, ITEM_GENGARITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sKangaskhanFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_KANGASKHAN_MEGA, ITEM_KANGASKHANITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sPinsirFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_PINSIR_MEGA, ITEM_PINSIRITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGyaradosFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GYARADOS_MEGA, ITEM_GYARADOSITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sAerodactylFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_AERODACTYL_MEGA, ITEM_AERODACTYLITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMewtwoFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_MEWTWO_MEGA_X, ITEM_MEWTWONITE_X},
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_MEWTWO_MEGA_Y, ITEM_MEWTWONITE_Y},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sAmpharosFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_AMPHAROS_MEGA, ITEM_AMPHAROSITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sSteelixFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_STEELIX_MEGA, ITEM_STEELIXITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sScizorFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_SCIZOR_MEGA, ITEM_SCIZORITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sHeracrossFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_HERACROSS_MEGA, ITEM_HERACRONITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sHoundoomFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_HOUNDOOM_MEGA, ITEM_HOUNDOOMINITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sTyranitarFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_TYRANITAR_MEGA, ITEM_TYRANITARITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sSceptileFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_SCEPTILE_MEGA, ITEM_SCEPTILITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sBlazikenFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_BLAZIKEN_MEGA, ITEM_BLAZIKENITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sSwampertFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_SWAMPERT_MEGA, ITEM_SWAMPERTITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sSableyeFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_SABLEYE_MEGA, ITEM_SABLENITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sSharpedoFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_SHARPEDO_MEGA, ITEM_SHARPEDONITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sManectricFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_MANECTRIC_MEGA, ITEM_MANECTITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sCameruptFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_CAMERUPT_MEGA, ITEM_CAMERUPTITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGlalieFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GLALIE_MEGA, ITEM_GLALITITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMawileFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_MAWILE_MEGA, ITEM_MAWILITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMedichamFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_MEDICHAM_MEGA, ITEM_MEDICHAMITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sAltariaFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_ALTARIA_MEGA, ITEM_ALTARIANITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sAbsolFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_ABSOL_MEGA, ITEM_ABSOLITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sCastformFormChangeTable[] = {
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_SUNNY, B_WEATHER_SUN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_RAINY, B_WEATHER_RAIN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM_SNOWY, B_WEATHER_HAIL},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM, ~(B_WEATHER_SUN | B_WEATHER_RAIN | B_WEATHER_HAIL)},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CASTFORM, B_WEATHER_NONE},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_CASTFORM},
{FORM_CHANGE_FAINT, SPECIES_CASTFORM},
{FORM_CHANGE_END_BATTLE, SPECIES_CASTFORM},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sBanetteFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_BANETTE_MEGA, ITEM_BANETTITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sAggronFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_AGGRON_MEGA, ITEM_AGGRONITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGardevoirFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GARDEVOIR_MEGA, ITEM_GARDEVOIRITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sSalamenceFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_SALAMENCE_MEGA, ITEM_SALAMENCITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMetagrossFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_METAGROSS_MEGA, ITEM_METAGROSSITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sLatiasFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_LATIAS_MEGA, ITEM_LATIASITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sLatiosFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_LATIOS_MEGA, ITEM_LATIOSITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sKyogreFormChangeTable[] = {
{FORM_CHANGE_BATTLE_PRIMAL_REVERSION, SPECIES_KYOGRE_PRIMAL, ITEM_BLUE_ORB},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGroudonFormChangeTable[] = {
{FORM_CHANGE_BATTLE_PRIMAL_REVERSION, SPECIES_GROUDON_PRIMAL, ITEM_RED_ORB},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sRayquazaFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE, SPECIES_RAYQUAZA_MEGA, MOVE_DRAGON_ASCENT},
{FORM_CHANGE_TERMINATOR},
};
#if P_GEN_4_POKEMON == TRUE
static const struct FormChange sBurmyFormChangeTable[] = {
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY, BATTLE_TERRAIN_GRASS},
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY, BATTLE_TERRAIN_LONG_GRASS},
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY, BATTLE_TERRAIN_POND},
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY, BATTLE_TERRAIN_MOUNTAIN},
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY, BATTLE_TERRAIN_PLAIN},
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY_SANDY_CLOAK, BATTLE_TERRAIN_CAVE},
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY_SANDY_CLOAK, BATTLE_TERRAIN_SAND},
{FORM_CHANGE_END_BATTLE_TERRAIN, SPECIES_BURMY_TRASH_CLOAK, BATTLE_TERRAIN_BUILDING},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sCherrimFormChangeTable[] = {
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM_SUNSHINE, B_WEATHER_SUN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM, ~B_WEATHER_SUN},
{FORM_CHANGE_BATTLE_WEATHER, SPECIES_CHERRIM, B_WEATHER_NONE},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_CHERRIM},
{FORM_CHANGE_FAINT, SPECIES_CHERRIM},
{FORM_CHANGE_END_BATTLE, SPECIES_CHERRIM},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sLopunnyFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_LOPUNNY_MEGA, ITEM_LOPUNNITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGarchompFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GARCHOMP_MEGA, ITEM_GARCHOMPITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sLucarioFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_LUCARIO_MEGA, ITEM_LUCARIONITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sAbomasnowFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_ABOMASNOW_MEGA, ITEM_ABOMASITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGalladeFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_GALLADE_MEGA, ITEM_GALLADITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sDialgaFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_DIALGA, ITEM_NONE},
{FORM_ITEM_HOLD, SPECIES_DIALGA_ORIGIN, ITEM_ADAMANT_CRYSTAL},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_HOLD, SPECIES_DIALGA, ITEM_NONE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_DIALGA_ORIGIN, ITEM_ADAMANT_CRYSTAL},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sPalkiaFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_PALKIA, ITEM_NONE},
{FORM_ITEM_HOLD, SPECIES_PALKIA_ORIGIN, ITEM_LUSTROUS_GLOBE},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_HOLD, SPECIES_PALKIA, ITEM_NONE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_PALKIA_ORIGIN, ITEM_LUSTROUS_GLOBE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGiratinaFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_GIRATINA, ITEM_NONE},
{FORM_ITEM_HOLD, SPECIES_GIRATINA_ORIGIN, ITEM_GRISEOUS_CORE},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_HOLD, SPECIES_GIRATINA, ITEM_NONE},
#if I_GRISEOUS_ORB_FORM_CHANGE < GEN_9
{FORM_CHANGE_ITEM_HOLD, SPECIES_GIRATINA_ORIGIN, ITEM_GRISEOUS_ORB},
#endif
{FORM_CHANGE_ITEM_HOLD, SPECIES_GIRATINA_ORIGIN, ITEM_GRISEOUS_CORE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sShayminFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_SHAYMIN_SKY, ITEM_GRACIDEA, DAY},
// {FORM_WITHDRAW, SPECIES_SHAYMIN},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_USE, SPECIES_SHAYMIN_SKY, ITEM_GRACIDEA, DAY},
// {FORM_CHANGE_WITHDRAW, SPECIES_SHAYMIN},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sArceusFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_ARCEUS, ITEM_NONE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FIGHTING, ITEM_FIST_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FIGHTING, ITEM_FIGHTINIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FLYING, ITEM_SKY_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FLYING, ITEM_FLYINIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_POISON, ITEM_TOXIC_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_POISON, ITEM_POISONIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_ROCK, ITEM_STONE_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_ROCK, ITEM_ROCKIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_GROUND, ITEM_EARTH_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_GROUND, ITEM_GROUNDIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_BUG, ITEM_INSECT_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_BUG, ITEM_BUGINIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_GHOST, ITEM_SPOOKY_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_GHOST, ITEM_GHOSTIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_STEEL, ITEM_IRON_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_STEEL, ITEM_STEELIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FIRE, ITEM_FLAME_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FIRE, ITEM_FIRIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_WATER, ITEM_SPLASH_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_WATER, ITEM_WATERIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_GRASS, ITEM_MEADOW_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_GRASS, ITEM_GRASSIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_ELECTRIC, ITEM_ZAP_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_ELECTRIC, ITEM_ELECTRIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_PSYCHIC, ITEM_MIND_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_PSYCHIC, ITEM_PSYCHIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_ICE, ITEM_ICICLE_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_ICE, ITEM_ICIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_DRAGON, ITEM_DRACO_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_DRAGON, ITEM_DRAGONIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_DARK, ITEM_DREAD_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_DARK, ITEM_DARKINIUM_Z, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FAIRY, ITEM_PIXIE_PLATE, ABILITY_MULTITYPE},
{FORM_ITEM_HOLD, SPECIES_ARCEUS_FAIRY, ITEM_FAIRIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS, ITEM_NONE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FIGHTING, ITEM_FIST_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FIGHTING, ITEM_FIGHTINIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FLYING, ITEM_SKY_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FLYING, ITEM_FLYINIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_POISON, ITEM_TOXIC_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_POISON, ITEM_POISONIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_ROCK, ITEM_STONE_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_ROCK, ITEM_ROCKIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_GROUND, ITEM_EARTH_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_GROUND, ITEM_GROUNDIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_BUG, ITEM_INSECT_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_BUG, ITEM_BUGINIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_GHOST, ITEM_SPOOKY_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_GHOST, ITEM_GHOSTIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_STEEL, ITEM_IRON_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_STEEL, ITEM_STEELIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FIRE, ITEM_FLAME_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FIRE, ITEM_FIRIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_WATER, ITEM_SPLASH_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_WATER, ITEM_WATERIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_GRASS, ITEM_MEADOW_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_GRASS, ITEM_GRASSIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_ELECTRIC, ITEM_ZAP_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_ELECTRIC, ITEM_ELECTRIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_PSYCHIC, ITEM_MIND_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_PSYCHIC, ITEM_PSYCHIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_ICE, ITEM_ICICLE_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_ICE, ITEM_ICIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_DRAGON, ITEM_DRACO_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_DRAGON, ITEM_DRAGONIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_DARK, ITEM_DREAD_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_DARK, ITEM_DARKINIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FAIRY, ITEM_PIXIE_PLATE, ABILITY_MULTITYPE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_ARCEUS_FAIRY, ITEM_FAIRIUM_Z, ABILITY_MULTITYPE},
{FORM_CHANGE_TERMINATOR},
};
#endif
#if P_GEN_5_POKEMON == TRUE
static const struct FormChange sAudinoFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_AUDINO_MEGA, ITEM_AUDINITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sDarmanitanFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_DARMANITAN, ABILITY_ZEN_MODE, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_DARMANITAN_ZEN_MODE, ABILITY_ZEN_MODE, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_FAINT, SPECIES_DARMANITAN},
{FORM_CHANGE_END_BATTLE, SPECIES_DARMANITAN},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sDarmanitanGalarianFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_DARMANITAN_GALARIAN, ABILITY_ZEN_MODE, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_DARMANITAN_ZEN_MODE_GALARIAN, ABILITY_ZEN_MODE, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_FAINT, SPECIES_DARMANITAN_GALARIAN},
{FORM_CHANGE_END_BATTLE, SPECIES_DARMANITAN_GALARIAN},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMeloettaFormChangeTable[] = {
{FORM_CHANGE_FAINT, SPECIES_MELOETTA},
{FORM_CHANGE_END_BATTLE, SPECIES_MELOETTA},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sTornadusFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_TORNADUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_ITEM_USE, SPECIES_TORNADUS, ITEM_REVEAL_GLASS},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_USE, SPECIES_TORNADUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_CHANGE_ITEM_USE, SPECIES_TORNADUS, ITEM_REVEAL_GLASS},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sThundurusFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_THUNDURUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_ITEM_USE, SPECIES_THUNDURUS, ITEM_REVEAL_GLASS},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_USE, SPECIES_THUNDURUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_CHANGE_ITEM_USE, SPECIES_THUNDURUS, ITEM_REVEAL_GLASS},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sLandorusFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_LANDORUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_ITEM_USE, SPECIES_LANDORUS, ITEM_REVEAL_GLASS},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_USE, SPECIES_LANDORUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_CHANGE_ITEM_USE, SPECIES_LANDORUS, ITEM_REVEAL_GLASS},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sKeldeoFormChangeTable[] = {
// {FORM_MOVE, SPECIES_KELDEO_RESOLUTE, MOVE_SECRET_SWORD, WHEN_LEARNED},
// {FORM_MOVE, SPECIES_KELDEO, MOVE_SECRET_SWORD, WHEN_FORGOTTEN},
{FORM_CHANGE_END},
// {FORM_CHANGE_MOVE, SPECIES_KELDEO_RESOLUTE, MOVE_SECRET_SWORD, WHEN_LEARNED},
// {FORM_CHANGE_MOVE, SPECIES_KELDEO, MOVE_SECRET_SWORD, WHEN_FORGOTTEN},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGenesectFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_GENESECT, ITEM_NONE},
{FORM_ITEM_HOLD, SPECIES_GENESECT_DOUSE_DRIVE, ITEM_DOUSE_DRIVE},
{FORM_ITEM_HOLD, SPECIES_GENESECT_SHOCK_DRIVE, ITEM_SHOCK_DRIVE},
{FORM_ITEM_HOLD, SPECIES_GENESECT_BURN_DRIVE, ITEM_BURN_DRIVE},
{FORM_ITEM_HOLD, SPECIES_GENESECT_CHILL_DRIVE, ITEM_CHILL_DRIVE},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT, ITEM_NONE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT_DOUSE_DRIVE, ITEM_DOUSE_DRIVE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT_SHOCK_DRIVE, ITEM_SHOCK_DRIVE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT_BURN_DRIVE, ITEM_BURN_DRIVE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_GENESECT_CHILL_DRIVE, ITEM_CHILL_DRIVE},
{FORM_CHANGE_TERMINATOR},
};
#endif
#if P_GEN_6_POKEMON == TRUE
static const struct FormChange sGreninjaBattleBondFormChangeTable[] = {
{FORM_CHANGE_FAINT, SPECIES_GRENINJA_BATTLE_BOND},
{FORM_CHANGE_END_BATTLE, SPECIES_GRENINJA_BATTLE_BOND},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sAegislashFormChangeTable[] = {
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_AEGISLASH},
{FORM_CHANGE_FAINT, SPECIES_AEGISLASH},
{FORM_CHANGE_END_BATTLE, SPECIES_AEGISLASH},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sXerneasFormChangeTable[] = {
{FORM_BATTLE_BEGIN, SPECIES_XERNEAS_ACTIVE},
{FORM_BATTLE_END, SPECIES_XERNEAS, },
{FORM_CHANGE_END},
{FORM_CHANGE_BEGIN_BATTLE, SPECIES_XERNEAS_ACTIVE},
{FORM_CHANGE_END_BATTLE, SPECIES_XERNEAS, },
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sZygardePowerConstructFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_ZYGARDE_COMPLETE, ABILITY_POWER_CONSTRUCT, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_FAINT},
{FORM_CHANGE_END_BATTLE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sDiancieFormChangeTable[] = {
{FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM, SPECIES_DIANCIE_MEGA, ITEM_DIANCITE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sHoopaFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_HOOPA_UNBOUND, ITEM_PRISON_BOTTLE, SPECIES_HOOPA},
// {FORM_WITHDRAW, SPECIES_HOOPA},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_USE, SPECIES_HOOPA_UNBOUND, ITEM_PRISON_BOTTLE, SPECIES_HOOPA},
{FORM_CHANGE_WITHDRAW, SPECIES_HOOPA},
{FORM_CHANGE_TERMINATOR},
};
#endif
#if P_GEN_7_POKEMON == TRUE
static const struct FormChange sOricorioFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_ORICORIO, ITEM_RED_NECTAR},
{FORM_ITEM_USE, SPECIES_ORICORIO_POM_POM, ITEM_YELLOW_NECTAR},
{FORM_ITEM_USE, SPECIES_ORICORIO_PAU, ITEM_PINK_NECTAR},
{FORM_ITEM_USE, SPECIES_ORICORIO_SENSU, ITEM_PURPLE_NECTAR},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_USE, SPECIES_ORICORIO, ITEM_RED_NECTAR},
{FORM_CHANGE_ITEM_USE, SPECIES_ORICORIO_POM_POM, ITEM_YELLOW_NECTAR},
{FORM_CHANGE_ITEM_USE, SPECIES_ORICORIO_PAU, ITEM_PINK_NECTAR},
{FORM_CHANGE_ITEM_USE, SPECIES_ORICORIO_SENSU, ITEM_PURPLE_NECTAR},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sWishiwashiFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_WISHIWASHI_SCHOOL, ABILITY_SCHOOLING, HP_HIGHER_THAN, 25},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_WISHIWASHI, ABILITY_SCHOOLING, HP_LOWER_EQ_THAN, 25},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_WISHIWASHI},
{FORM_CHANGE_FAINT, SPECIES_WISHIWASHI},
{FORM_CHANGE_END_BATTLE, SPECIES_WISHIWASHI},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sSilvallyFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_SILVALLY, ITEM_NONE, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FIGHTING, ITEM_FIGHTING_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FLYING, ITEM_FLYING_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_POISON, ITEM_POISON_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_GROUND, ITEM_GROUND_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_ROCK, ITEM_ROCK_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_BUG, ITEM_BUG_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_GHOST, ITEM_GHOST_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_STEEL, ITEM_STEEL_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FIRE, ITEM_FIRE_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_WATER, ITEM_WATER_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_GRASS, ITEM_GRASS_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_ELECTRIC, ITEM_ELECTRIC_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_PSYCHIC, ITEM_PSYCHIC_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_ICE, ITEM_ICE_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_DRAGON, ITEM_DRAGON_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_DARK, ITEM_DARK_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FAIRY, ITEM_FAIRY_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY, ITEM_NONE, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_FIGHTING, ITEM_FIGHTING_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_FLYING, ITEM_FLYING_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_POISON, ITEM_POISON_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_GROUND, ITEM_GROUND_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_ROCK, ITEM_ROCK_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_BUG, ITEM_BUG_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_GHOST, ITEM_GHOST_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_STEEL, ITEM_STEEL_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_FIRE, ITEM_FIRE_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_WATER, ITEM_WATER_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_GRASS, ITEM_GRASS_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_ELECTRIC, ITEM_ELECTRIC_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_PSYCHIC, ITEM_PSYCHIC_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_ICE, ITEM_ICE_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_DRAGON, ITEM_DRAGON_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_DARK, ITEM_DARK_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_ITEM_HOLD, SPECIES_SILVALLY_FAIRY, ITEM_FAIRY_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMimikyuFormChangeTable[] = {
{FORM_CHANGE_FAINT, SPECIES_MIMIKYU},
{FORM_CHANGE_END_BATTLE, SPECIES_MIMIKYU},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMiniorRedFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_RED, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MINIOR_CORE_RED},
{FORM_CHANGE_FAINT, SPECIES_MINIOR_CORE_RED},
{FORM_CHANGE_END_BATTLE, SPECIES_MINIOR_CORE_RED},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMiniorBlueFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_BLUE, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_BLUE, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MINIOR_CORE_BLUE},
{FORM_CHANGE_FAINT, SPECIES_MINIOR_CORE_BLUE},
{FORM_CHANGE_END_BATTLE, SPECIES_MINIOR_CORE_BLUE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMiniorGreenFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_GREEN, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_GREEN, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MINIOR_CORE_GREEN},
{FORM_CHANGE_FAINT, SPECIES_MINIOR_CORE_GREEN},
{FORM_CHANGE_END_BATTLE, SPECIES_MINIOR_CORE_GREEN},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMiniorIndigoFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_INDIGO, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_INDIGO, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MINIOR_CORE_INDIGO},
{FORM_CHANGE_FAINT, SPECIES_MINIOR_CORE_INDIGO},
{FORM_CHANGE_END_BATTLE, SPECIES_MINIOR_CORE_INDIGO},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMiniorOrangeFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_ORANGE, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_ORANGE, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MINIOR_CORE_ORANGE},
{FORM_CHANGE_FAINT, SPECIES_MINIOR_CORE_ORANGE},
{FORM_CHANGE_END_BATTLE, SPECIES_MINIOR_CORE_ORANGE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMiniorVioletFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_VIOLET, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_VIOLET, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MINIOR_CORE_VIOLET},
{FORM_CHANGE_FAINT, SPECIES_MINIOR_CORE_VIOLET},
{FORM_CHANGE_END_BATTLE, SPECIES_MINIOR_CORE_VIOLET},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMiniorYellowFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_METEOR_YELLOW, ABILITY_SHIELDS_DOWN, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_MINIOR_CORE_YELLOW, ABILITY_SHIELDS_DOWN, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MINIOR_CORE_YELLOW},
{FORM_CHANGE_FAINT, SPECIES_MINIOR_CORE_YELLOW},
{FORM_CHANGE_END_BATTLE, SPECIES_MINIOR_CORE_YELLOW},
{FORM_CHANGE_TERMINATOR},
};
#endif
#if P_GEN_8_POKEMON == TRUE
static const struct FormChange sCramorantFormChangeTable[] = {
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_CRAMORANT_GULPING, ABILITY_GULP_MISSILE, HP_HIGHER_THAN, 50},
{FORM_CHANGE_BATTLE_HP_PERCENT, SPECIES_CRAMORANT_GORGING, ABILITY_GULP_MISSILE, HP_LOWER_EQ_THAN, 50},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_CRAMORANT},
{FORM_CHANGE_FAINT, SPECIES_CRAMORANT},
{FORM_CHANGE_END_BATTLE, SPECIES_CRAMORANT},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sEiscueFormChangeTable[] = {
{FORM_CHANGE_FAINT, SPECIES_EISCUE},
{FORM_CHANGE_END_BATTLE, SPECIES_EISCUE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sMorpekoFormChangeTable[] = {
{FORM_CHANGE_BATTLE_TURN_END, SPECIES_MORPEKO_HANGRY, ABILITY_HUNGER_SWITCH},
{FORM_CHANGE_BATTLE_TURN_END, SPECIES_MORPEKO , ABILITY_HUNGER_SWITCH},
{FORM_CHANGE_BATTLE_SWITCH, SPECIES_MORPEKO},
{FORM_CHANGE_FAINT, SPECIES_MORPEKO},
{FORM_CHANGE_END_BATTLE, SPECIES_MORPEKO},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sZacianFormChangeTable[] = {
{FORM_BATTLE_BEGIN, SPECIES_ZACIAN_CROWNED_SWORD, ITEM_RUSTED_SWORD, MOVE_IRON_HEAD, MOVE_BEHEMOTH_BLADE},
{FORM_BATTLE_END, SPECIES_ZACIAN, ITEM_RUSTED_SWORD, MOVE_BEHEMOTH_BLADE, MOVE_IRON_HEAD},
{FORM_CHANGE_END},
{FORM_CHANGE_BEGIN_BATTLE, SPECIES_ZACIAN_CROWNED_SWORD, ITEM_RUSTED_SWORD, MOVE_IRON_HEAD, MOVE_BEHEMOTH_BLADE},
{FORM_CHANGE_END_BATTLE, SPECIES_ZACIAN, ITEM_RUSTED_SWORD, MOVE_BEHEMOTH_BLADE, MOVE_IRON_HEAD},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sZamazentaFormChangeTable[] = {
{FORM_BATTLE_BEGIN, SPECIES_ZAMAZENTA_CROWNED_SHIELD, ITEM_RUSTED_SHIELD, MOVE_IRON_HEAD, MOVE_BEHEMOTH_BASH},
{FORM_BATTLE_END, SPECIES_ZAMAZENTA, ITEM_RUSTED_SHIELD, MOVE_BEHEMOTH_BASH, MOVE_IRON_HEAD},
{FORM_CHANGE_END},
{FORM_CHANGE_BEGIN_BATTLE, SPECIES_ZAMAZENTA_CROWNED_SHIELD, ITEM_RUSTED_SHIELD, MOVE_IRON_HEAD, MOVE_BEHEMOTH_BASH},
{FORM_CHANGE_END_BATTLE, SPECIES_ZAMAZENTA, ITEM_RUSTED_SHIELD, MOVE_BEHEMOTH_BASH, MOVE_IRON_HEAD},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sEnamorusFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_ENAMORUS, ITEM_REVEAL_GLASS},
{FORM_ITEM_USE, SPECIES_ENAMORUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_CHANGE_END},
{FORM_CHANGE_ITEM_USE, SPECIES_ENAMORUS, ITEM_REVEAL_GLASS},
{FORM_CHANGE_ITEM_USE, SPECIES_ENAMORUS_THERIAN, ITEM_REVEAL_GLASS},
{FORM_CHANGE_TERMINATOR},
};
#endif

View File

@ -22202,7 +22202,7 @@ const struct SpeciesInfo gSpeciesInfo[] =
.abilities = {ABILITY_PRIMORDIAL_SEA, ABILITY_PRIMORDIAL_SEA},
.bodyColor = BODY_COLOR_BLUE,
.noFlip = FALSE,
.flags = SPECIES_FLAG_LEGENDARY,
.flags = SPECIES_FLAG_LEGENDARY | SPECIES_FLAG_PRIMAL_REVERSION,
},
[SPECIES_GROUDON_PRIMAL] =
@ -22225,7 +22225,7 @@ const struct SpeciesInfo gSpeciesInfo[] =
.abilities = {ABILITY_DESOLATE_LAND, ABILITY_DESOLATE_LAND},
.bodyColor = BODY_COLOR_RED,
.noFlip = FALSE,
.flags = SPECIES_FLAG_LEGENDARY,
.flags = SPECIES_FLAG_LEGENDARY | SPECIES_FLAG_PRIMAL_REVERSION,
},
[SPECIES_RATTATA_ALOLAN] =

View File

@ -20,6 +20,7 @@
#include "list_menu.h"
#include "overworld.h"
#include "item.h"
#include "constants/form_change_types.h"
#include "constants/items.h"
#include "constants/moves.h"
#include "constants/region_map_sections.h"
@ -255,8 +256,9 @@ static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon)
species = GetBoxMonData(&daycareMon->mon, MON_DATA_SPECIES);
BoxMonToMon(&daycareMon->mon, &pokemon);
newSpecies = GetFormChangeTargetSpecies(&pokemon, FORM_WITHDRAW, 0);
if (newSpecies != SPECIES_NONE) {
newSpecies = GetFormChangeTargetSpecies(&pokemon, FORM_CHANGE_WITHDRAW, 0);
if (newSpecies != SPECIES_NONE)
{
SetMonData(&pokemon, MON_DATA_SPECIES, &newSpecies);
CalculateMonStats(&pokemon);
species = newSpecies;

View File

@ -15,6 +15,7 @@
#include "task.h"
#include "trainer_hill.h"
#include "constants/field_poison.h"
#include "constants/form_change_types.h"
#include "constants/party_menu.h"
static bool32 IsMonValidSpecies(struct Pokemon *pokemon)
@ -135,10 +136,14 @@ s32 DoPoisonFieldEffect(void)
hp = GetMonData(pokemon, MON_DATA_HP);
#if OW_POISON_DAMAGE < GEN_4
if (hp == 0 || --hp == 0)
{
TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_FAINT);
numFainted++;
}
#else
if (hp == 1 || --hp == 1)
#endif
numFainted++;
#endif
SetMonData(pokemon, MON_DATA_HP, &hp);
numPoisoned++;

View File

@ -66,6 +66,7 @@
#include "constants/battle.h"
#include "constants/battle_frontier.h"
#include "constants/field_effects.h"
#include "constants/form_change_types.h"
#include "constants/item_effects.h"
#include "constants/items.h"
#include "constants/moves.h"
@ -5731,7 +5732,7 @@ static void Task_TryItemUseFormChange(u8 taskId)
bool32 TryItemUseFormChange(u8 taskId, TaskFunc task)
{
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
u16 targetSpecies = GetFormChangeTargetSpecies(mon, ItemId_GetSecondaryId(gSpecialVar_ItemId), gSpecialVar_ItemId);
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_USE, gSpecialVar_ItemId);
if (targetSpecies != SPECIES_NONE)
{
@ -5766,7 +5767,7 @@ void ItemUseCB_FormChange_ConsumedOnUse(u8 taskId, TaskFunc task)
}
void TryItemHoldFormChange(struct Pokemon *mon)
{
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_ITEM_HOLD, 0);
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != SPECIES_NONE)
{
PlayCry_NormalNoDucking(targetSpecies, 0, CRY_VOLUME_RS, CRY_VOLUME_RS);

View File

@ -42,6 +42,7 @@
#include "constants/battle_frontier.h"
#include "constants/battle_move_effects.h"
#include "constants/battle_script_commands.h"
#include "constants/form_change_types.h"
#include "constants/hold_effects.h"
#include "constants/item_effects.h"
#include "constants/items.h"
@ -4138,13 +4139,14 @@ void CalculateMonStats(struct Pokemon *mon)
{
if (currentHP == 0 && oldMaxHP == 0)
currentHP = newMaxHP;
else if (currentHP != 0) {
// BUG: currentHP is unintentionally able to become <= 0 after the instruction below. This causes the pomeg berry glitch.
else if (currentHP != 0)
{
if (newMaxHP > oldMaxHP)
currentHP += newMaxHP - oldMaxHP;
#ifdef BUGFIX
if (currentHP <= 0)
currentHP = 1;
#endif
if (currentHP > newMaxHP)
currentHP = newMaxHP;
}
else
return;
@ -4235,6 +4237,17 @@ void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot)
SetMonData(mon, MON_DATA_PP1 + slot, &gBattleMoves[move].pp);
}
static void SetMonMoveSlot_KeepPP(struct Pokemon *mon, u16 move, u8 slot)
{
u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
u8 currPP = GetMonData(mon, MON_DATA_PP1 + slot, NULL);
u8 newPP = CalculatePPWithBonus(move, ppBonuses, slot);
u8 finalPP = min(currPP, newPP);
SetMonData(mon, MON_DATA_MOVE1 + slot, &move);
SetMonData(mon, MON_DATA_PP1 + slot, &finalPP);
}
void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
{
mon->moves[slot] = move;
@ -8311,18 +8324,18 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32
heldItem = GetBoxMonData(boxMon, MON_DATA_HELD_ITEM, NULL);
ability = GetAbilityBySpecies(species, GetBoxMonData(boxMon, MON_DATA_ABILITY_NUM, NULL));
for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++)
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
{
if (method == formChanges[i].method && species != formChanges[i].targetSpecies)
{
switch (method)
{
case FORM_ITEM_HOLD:
case FORM_CHANGE_ITEM_HOLD:
if ((heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE)
&& (ability == formChanges[i].param2 || formChanges[i].param2 == ABILITY_NONE))
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_ITEM_USE:
case FORM_CHANGE_ITEM_USE:
if (arg == formChanges[i].param1)
{
switch (formChanges[i].param2)
@ -8343,14 +8356,23 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32
}
}
break;
case FORM_MOVE:
case FORM_CHANGE_MOVE:
if (BoxMonKnowsMove(boxMon, formChanges[i].param1) != formChanges[i].param2)
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_BATTLE_BEGIN:
case FORM_BATTLE_END:
case FORM_CHANGE_BEGIN_BATTLE:
case FORM_CHANGE_END_BATTLE:
if (heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE)
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_END_BATTLE_TERRAIN:
if (gBattleTerrain == formChanges[i].param1)
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_CHANGE_WITHDRAW:
case FORM_CHANGE_FAINT:
targetSpecies = formChanges[i].targetSpecies;
break;
}
}
}
@ -8359,6 +8381,23 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32
return targetSpecies;
}
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method)
{
u32 i, j;
const struct FormChange *formChanges = gFormChangeTablePointers[species];
if (formChanges != NULL)
{
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
{
if (method == formChanges[i].method && species != formChanges[i].targetSpecies)
return TRUE;
}
}
return FALSE;
}
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
@ -8441,20 +8480,47 @@ bool32 ShouldShowFemaleDifferences(u16 species, u32 personality)
return (gSpeciesInfo[species].flags & SPECIES_FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE;
}
void TryToSetBattleFormChangeMoves(struct Pokemon *mon)
bool32 TryFormChange(u32 monId, u32 side, u16 method)
{
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
u16 targetSpecies;
if (GetMonData(&party[monId], MON_DATA_SPECIES_OR_EGG, 0) == SPECIES_NONE
|| GetMonData(&party[monId], MON_DATA_SPECIES_OR_EGG, 0) == SPECIES_EGG)
return FALSE;
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
if (targetSpecies == SPECIES_NONE && gBattleStruct != NULL)
targetSpecies = gBattleStruct->changedSpecies[monId];
if (targetSpecies != SPECIES_NONE)
{
TryToSetBattleFormChangeMoves(&party[monId], method);
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(&party[monId]);
return TRUE;
}
return FALSE;
}
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method)
{
int i, j;
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
const struct FormChange *formChanges = gFormChangeTablePointers[species];
u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
if (formChanges == NULL)
if (formChanges == NULL
|| (method != FORM_CHANGE_BEGIN_BATTLE && method != FORM_CHANGE_END_BATTLE))
return;
for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++)
for (i = 0; formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
{
if ((formChanges[i].method == FORM_BATTLE_BEGIN || formChanges[i].method == FORM_BATTLE_END)
&& formChanges[i].param2 && formChanges[i].param3 && formChanges[i].targetSpecies == species)
if (formChanges[i].method == method
&& formChanges[i].param2
&& formChanges[i].param3
&& formChanges[i].targetSpecies != species)
{
u16 originalMove = formChanges[i].param2;
u16 newMove = formChanges[i].param3;
@ -8462,20 +8528,9 @@ void TryToSetBattleFormChangeMoves(struct Pokemon *mon)
for (j = 0; j < MAX_MON_MOVES; j++)
{
u16 currMove = GetMonData(mon, MON_DATA_MOVE1 + j, NULL);
u8 totalPp = gBattleMoves[currMove].pp; // Get current move's max PP
u8 currPp = GetMonData(mon, MON_DATA_PP1 + j, NULL); // Get current move's remaining PP
u8 diffPp = totalPp - currPp; // Current move's PP difference
u8 finalPp = gBattleMoves[newMove].pp - diffPp; // Apply the PP difference to the new move
if (currMove == originalMove)
{
if (finalPp > gBattleMoves[newMove].pp)
finalPp = 0;
SetMonMoveSlot(mon, newMove, j);
SetMonData(mon, MON_DATA_PP1 + j, &finalPp);
SetMonMoveSlot_KeepPP(mon, newMove, j);
}
}
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
break;
}
}

View File

@ -36,6 +36,7 @@
#include "trig.h"
#include "walda_phrase.h"
#include "window.h"
#include "constants/form_change_types.h"
#include "constants/items.h"
#include "constants/moves.h"
#include "constants/rgb.h"
@ -6893,7 +6894,7 @@ static void ReshowDisplayMon(void)
void SetMonFormPSS(struct BoxPokemon *boxMon)
{
u16 targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_ITEM_HOLD, 0);
u16 targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != SPECIES_NONE)
{
SetBoxMonData(boxMon, MON_DATA_SPECIES, &targetSpecies);

View File

@ -72,7 +72,7 @@ u8 ScriptGiveMon(u16 species, u8 level, u16 item, u32 unused1, u32 unused2, u8 u
SetMonData(&mon, MON_DATA_HELD_ITEM, heldItem);
// In case a mon with a form changing item is given. Eg: SPECIES_ARCEUS with ITEM_SPLASH_PLATE will transform into SPECIES_ARCEUS_WATER upon gifted.
targetSpecies = GetFormChangeTargetSpecies(&mon, FORM_ITEM_HOLD, 0);
targetSpecies = GetFormChangeTargetSpecies(&mon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != SPECIES_NONE)
{
SetMonData(&mon, MON_DATA_SPECIES, &targetSpecies);

View File

@ -0,0 +1,25 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Hunger Switch switches Morpeko's forms at the end of the turn")
{
u16 species;
PARAMETRIZE { species = SPECIES_MORPEKO; }
PARAMETRIZE { species = SPECIES_MORPEKO_HANGRY; }
GIVEN {
ASSUME(P_GEN_8_POKEMON == TRUE);
PLAYER(species) { Speed(2); };
OPPONENT(SPECIES_WOBBUFFET) { Speed(1); };
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); }
} SCENE {
MESSAGE("Morpeko used Celebrate!");
MESSAGE("Foe Wobbuffet used Celebrate!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
} THEN {
if (species == SPECIES_MORPEKO)
EXPECT_EQ(player->species, SPECIES_MORPEKO_HANGRY);
else
EXPECT_EQ(player->species, SPECIES_MORPEKO);
}
}

111
test/ability_schooling.c Normal file
View File

@ -0,0 +1,111 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Schooling switches Level 20+ Wishiwashi's form when HP is 25-percent or less at the end of the turn")
{
u16 level;
PARAMETRIZE { level = 19; }
PARAMETRIZE { level = 20; }
GIVEN {
ASSUME(P_GEN_7_POKEMON == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WISHIWASHI].baseHP == gSpeciesInfo[SPECIES_WISHIWASHI_SCHOOL].baseHP);
PLAYER(SPECIES_WISHIWASHI)
{
Level(level);
HP(GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP) / 2);
Ability(ABILITY_SCHOOLING);
};
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_SUPER_FANG); }
} SCENE {
if (level >= 20)
{
ABILITY_POPUP(player, ABILITY_SCHOOLING);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
}
MESSAGE("Wishiwashi used Celebrate!");
MESSAGE("Foe Wobbuffet used Super Fang!");
HP_BAR(player);
if (level >= 20)
{
ABILITY_POPUP(player, ABILITY_SCHOOLING);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
}
} THEN {
EXPECT_EQ(player->species, SPECIES_WISHIWASHI);
}
}
SINGLE_BATTLE_TEST("Schooling switches Level 20+ Wishiwashi's form when HP is over 25-percent before the first turn")
{
u16 level;
bool32 overQuarterHP;
PARAMETRIZE { level = 19; overQuarterHP = FALSE; }
PARAMETRIZE { level = 20; overQuarterHP = FALSE; }
PARAMETRIZE { level = 19; overQuarterHP = TRUE; }
PARAMETRIZE { level = 20; overQuarterHP = TRUE; }
GIVEN {
ASSUME(P_GEN_7_POKEMON == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WISHIWASHI].baseHP == gSpeciesInfo[SPECIES_WISHIWASHI_SCHOOL].baseHP);
PLAYER(SPECIES_WISHIWASHI)
{
Level(level);
HP(GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP) / (overQuarterHP ? 2 : 4));
Ability(ABILITY_SCHOOLING);
};
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); }
} SCENE {
if (level >= 20 && overQuarterHP)
{
ABILITY_POPUP(player, ABILITY_SCHOOLING);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
}
MESSAGE("Wishiwashi used Celebrate!");
MESSAGE("Foe Wobbuffet used Celebrate!");
} THEN {
if (level >= 20 && overQuarterHP)
EXPECT_EQ(player->species, SPECIES_WISHIWASHI_SCHOOL);
else
EXPECT_EQ(player->species, SPECIES_WISHIWASHI);
}
}
SINGLE_BATTLE_TEST("Schooling switches Level 20+ Wishiwashi's form when HP is healed above 25-percent")
{
u16 level;
PARAMETRIZE { level = 19; }
PARAMETRIZE { level = 20; }
GIVEN {
ASSUME(P_GEN_7_POKEMON == TRUE);
ASSUME(gSpeciesInfo[SPECIES_WISHIWASHI].baseHP == gSpeciesInfo[SPECIES_WISHIWASHI_SCHOOL].baseHP);
PLAYER(SPECIES_WISHIWASHI)
{
Level(level);
HP(GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP) / 4);
Ability(ABILITY_SCHOOLING);
};
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_HEAL_PULSE); }
} SCENE {
MESSAGE("Wishiwashi used Celebrate!");
MESSAGE("Foe Wobbuffet used Heal Pulse!");
HP_BAR(player);
if (level >= 20)
{
ABILITY_POPUP(player, ABILITY_SCHOOLING);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
}
} THEN {
if (level >= 20)
EXPECT_EQ(player->species, SPECIES_WISHIWASHI_SCHOOL);
else
EXPECT_EQ(player->species, SPECIES_WISHIWASHI);
}
}

93
test/ability_zen_mode.c Normal file
View File

@ -0,0 +1,93 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Zen Mode switches Darmanitan's form when HP is half or less at the end of the turn")
{
u16 standardSpecies, zenSpecies;
PARAMETRIZE { standardSpecies = SPECIES_DARMANITAN; zenSpecies = SPECIES_DARMANITAN_ZEN_MODE; }
PARAMETRIZE { standardSpecies = SPECIES_DARMANITAN_GALARIAN; zenSpecies = SPECIES_DARMANITAN_ZEN_MODE_GALARIAN; }
GIVEN {
ASSUME(P_GEN_5_POKEMON == TRUE);
ASSUME(gSpeciesInfo[standardSpecies].baseHP == 105);
ASSUME(gSpeciesInfo[zenSpecies].baseHP == 105);
PLAYER(standardSpecies)
{
Ability(ABILITY_ZEN_MODE);
HP((GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP) / 2) + 1);
};
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); }
} SCENE {
MESSAGE("Darmanitan used Celebrate!");
MESSAGE("Foe Wobbuffet used Tackle!");
HP_BAR(player);
ABILITY_POPUP(player, ABILITY_ZEN_MODE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
} THEN {
ASSUME(player->hp <= player->maxHP / 2);
EXPECT_EQ(player->species, zenSpecies);
}
}
SINGLE_BATTLE_TEST("Zen Mode switches Darmanitan's form when HP is half or less before the first turn")
{
u16 standardSpecies, zenSpecies;
PARAMETRIZE { standardSpecies = SPECIES_DARMANITAN; zenSpecies = SPECIES_DARMANITAN_ZEN_MODE; }
PARAMETRIZE { standardSpecies = SPECIES_DARMANITAN_GALARIAN; zenSpecies = SPECIES_DARMANITAN_ZEN_MODE_GALARIAN; }
GIVEN {
ASSUME(P_GEN_5_POKEMON == TRUE);
ASSUME(gSpeciesInfo[standardSpecies].baseHP == 105);
ASSUME(gSpeciesInfo[zenSpecies].baseHP == 105);
PLAYER(standardSpecies)
{
Ability(ABILITY_ZEN_MODE);
HP(GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP) / 2);
};
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); }
} SCENE {
ABILITY_POPUP(player, ABILITY_ZEN_MODE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Darmanitan used Celebrate!");
MESSAGE("Foe Wobbuffet used Celebrate!");
} THEN {
EXPECT_LE(player->hp, player->maxHP / 2);
EXPECT_EQ(player->species, zenSpecies);
}
}
SINGLE_BATTLE_TEST("Zen Mode switches Darmanitan's form when HP is healed above half")
{
u16 standardSpecies, zenSpecies;
PARAMETRIZE { standardSpecies = SPECIES_DARMANITAN; zenSpecies = SPECIES_DARMANITAN_ZEN_MODE; }
PARAMETRIZE { standardSpecies = SPECIES_DARMANITAN_GALARIAN; zenSpecies = SPECIES_DARMANITAN_ZEN_MODE_GALARIAN; }
GIVEN {
ASSUME(P_GEN_5_POKEMON == TRUE);
ASSUME(gSpeciesInfo[standardSpecies].baseHP == 105);
ASSUME(gSpeciesInfo[zenSpecies].baseHP == 105);
PLAYER(standardSpecies)
{
Ability(ABILITY_ZEN_MODE);
HP(GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP) / 2);
};
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_HEAL_PULSE); }
} SCENE {
ABILITY_POPUP(player, ABILITY_ZEN_MODE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Darmanitan used Celebrate!");
MESSAGE("Foe Wobbuffet used Heal Pulse!");
HP_BAR(player);
ABILITY_POPUP(player, ABILITY_ZEN_MODE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
} THEN {
EXPECT_GT(player->hp, player->maxHP / 2);
EXPECT_EQ(player->species, standardSpecies);
}
}

119
test/form_change.c Normal file
View File

@ -0,0 +1,119 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Xerneas changes into Active Form upon battle start")
{
GIVEN {
ASSUME(P_GEN_6_POKEMON == TRUE);
PLAYER(SPECIES_XERNEAS);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); }
} THEN {
EXPECT_EQ(player->species, SPECIES_XERNEAS_ACTIVE);
}
}
SINGLE_BATTLE_TEST("Zacian changes into its Crowned Form when holding the Rusted Sword upon battle start")
{
u16 item;
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_RUSTED_SWORD; }
GIVEN {
ASSUME(P_GEN_8_POKEMON == TRUE);
PLAYER(SPECIES_ZACIAN) { Item(item); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); }
} THEN {
if (item == ITEM_NONE)
EXPECT_EQ(player->species, SPECIES_ZACIAN);
else
EXPECT_EQ(player->species, SPECIES_ZACIAN_CROWNED_SWORD);
}
}
SINGLE_BATTLE_TEST("Zacian's Iron Head becomes Behemoth Blade upon form change")
{
GIVEN {
ASSUME(P_GEN_8_POKEMON == TRUE);
PLAYER(SPECIES_ZACIAN) { Item(ITEM_RUSTED_SWORD); Moves(MOVE_IRON_HEAD, MOVE_CELEBRATE); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); }
} THEN {
ASSUME(player->species == SPECIES_ZACIAN_CROWNED_SWORD); // Assumes form change worked.
EXPECT_EQ(player->moves[0], MOVE_BEHEMOTH_BLADE);
}
}
SINGLE_BATTLE_TEST("Zamazenta changes into its Crowned Form when holding the Rusted Shield upon battle start")
{
u16 item;
PARAMETRIZE { item = ITEM_NONE; }
PARAMETRIZE { item = ITEM_RUSTED_SHIELD; }
GIVEN {
ASSUME(P_GEN_8_POKEMON == TRUE);
PLAYER(SPECIES_ZAMAZENTA) { Item(item); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); }
} THEN {
if (item == ITEM_NONE)
EXPECT_EQ(player->species, SPECIES_ZAMAZENTA);
else
EXPECT_EQ(player->species, SPECIES_ZAMAZENTA_CROWNED_SHIELD);
}
}
SINGLE_BATTLE_TEST("Zamazenta's Iron Head becomes Behemoth Bash upon form change")
{
GIVEN {
ASSUME(P_GEN_8_POKEMON == TRUE);
PLAYER(SPECIES_ZAMAZENTA) { Item(ITEM_RUSTED_SHIELD); Moves(MOVE_IRON_HEAD, MOVE_CELEBRATE); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_CELEBRATE); }
} THEN {
ASSUME(player->species == SPECIES_ZAMAZENTA_CROWNED_SHIELD); // Assumes form change worked.
EXPECT_EQ(player->moves[0], MOVE_BEHEMOTH_BASH);
}
}
SINGLE_BATTLE_TEST("Aegislash reverts to Shield Form upon switching out")
{
GIVEN {
ASSUME(P_GEN_6_POKEMON == TRUE);
PLAYER(SPECIES_AEGISLASH);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TACKLE); }
TURN { SWITCH(player, 1); }
TURN { SWITCH(player, 0); }
} SCENE {
ABILITY_POPUP(player, ABILITY_STANCE_CHANGE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player);
MESSAGE("Aegislash used Tackle!");
MESSAGE("Foe Wobbuffet used Celebrate!");
} THEN {
EXPECT_EQ(player->species, SPECIES_AEGISLASH);
}
}
SINGLE_BATTLE_TEST("Aegislash reverts to Shield Form upon fainting")
{
GIVEN {
ASSUME(P_GEN_6_POKEMON == TRUE);
PLAYER(SPECIES_AEGISLASH) { HP(1); };
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_GUST); SEND_OUT(player, 1);}
} SCENE {
MESSAGE("Foe Wobbuffet used Gust!");
MESSAGE("Aegislash fainted!");
} THEN {
EXPECT_EQ(GetMonData(&PLAYER_PARTY[0], MON_DATA_SPECIES), SPECIES_AEGISLASH);
}
}

View File

@ -1082,9 +1082,12 @@ void Ability_(u32 sourceLine, u32 ability)
void Level_(u32 sourceLine, u32 level)
{
// TODO: Preserve any explicitly-set stats.
u32 species = GetMonData(DATA.currentMon, MON_DATA_SPECIES);
INVALID_IF(!DATA.currentMon, "Level outside of PLAYER/OPPONENT");
INVALID_IF(level == 0 || level > MAX_LEVEL, "Illegal level: %d", level);
SetMonData(DATA.currentMon, MON_DATA_LEVEL, &level);
SetMonData(DATA.currentMon, MON_DATA_EXP, &gExperienceTables[gSpeciesInfo[species].growthRate][level]);
CalculateMonStats(DATA.currentMon);
}
void MaxHP_(u32 sourceLine, u32 maxHP)