diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index f5d0e9509e..6912cfe6bb 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -322,8 +322,9 @@ #define FORM_ITEM_USE 2 #define FORM_MOVE 3 #define FORM_WITHDRAW 4 -#define FORM_ITEM_HOLD_ABILITY 5 -#define FORM_ITEM_USE_TIME 6 +#define FORM_ITEM_USE_TIME 5 +#define FORM_BATTLE_BEGIN 6 +#define FORM_BATTLE_END 7 #define NUM_MALE_LINK_FACILITY_CLASSES 8 #define NUM_FEMALE_LINK_FACILITY_CLASSES 8 diff --git a/include/pokemon.h b/include/pokemon.h index ed8d868bee..39f6e406b0 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -367,11 +367,13 @@ struct Evolution u16 targetSpecies; }; -struct FormChange { +struct FormChange +{ u16 method; u16 targetSpecies; u16 param1; u16 param2; + u16 param3; }; #define NUM_UNOWN_FORMS 28 @@ -561,5 +563,6 @@ u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg); u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg); u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove); bool32 ShouldShowFemaleDifferences(u16 species, u32 personality); +void TryToSetBattleFormChangeMoves(struct Pokemon *mon); #endif // GUARD_POKEMON_H diff --git a/src/battle_main.c b/src/battle_main.c index c71a7b4985..07b4deb911 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -481,6 +481,7 @@ void CB2_InitBattle(void) static void CB2_InitBattleInternal(void) { s32 i; + u16 targetSpecies; SetHBlankCallback(NULL); SetVBlankCallback(NULL); @@ -571,6 +572,27 @@ static void CB2_InitBattleInternal(void) for (i = 0; i < PARTY_SIZE; i++) AdjustFriendship(&gPlayerParty[i], FRIENDSHIP_EVENT_LEAGUE_BATTLE); + // Apply party-wide start-of-battle form changes + 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]); + } + // 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]); + } + } + gBattleCommunication[MULTIUSE_STATE] = 0; } diff --git a/src/battle_util.c b/src/battle_util.c index 71133a8467..4b18fafb60 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -9692,7 +9692,7 @@ void UndoMegaEvolution(u32 monId) void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut) { - u32 i, currSpecies; + u32 i, currSpecies, targetSpecies; struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty; static const u16 species[][3] = { @@ -9726,6 +9726,16 @@ void UndoFormChange(u32 monId, u32 side, bool32 isSwitchingOut) break; } } + if (!isSwitchingOut) + { + targetSpecies = GetFormChangeTargetSpecies(&party[monId], FORM_BATTLE_END, 0); + if (targetSpecies != SPECIES_NONE) + { + SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies); + CalculateMonStats(&party[monId]); + TryToSetBattleFormChangeMoves(&party[monId]); + } + } } bool32 DoBattlersShareType(u32 battler1, u32 battler2) diff --git a/src/data/pokemon/form_change_table_pointers.h b/src/data/pokemon/form_change_table_pointers.h index a324fd55a8..85685e50ef 100644 --- a/src/data/pokemon/form_change_table_pointers.h +++ b/src/data/pokemon/form_change_table_pointers.h @@ -24,22 +24,24 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] = [SPECIES_ARCEUS_DARK] = sArceusFormChangeTable, [SPECIES_ARCEUS_FAIRY] = sArceusFormChangeTable, [SPECIES_TORNADUS] = sTornadusFormChangeTable, - [SPECIES_TORNADUS_THERIAN] = sTornadusTherianFormChangeTable, + [SPECIES_TORNADUS_THERIAN] = sTornadusFormChangeTable, [SPECIES_THUNDURUS] = sThundurusFormChangeTable, - [SPECIES_THUNDURUS_THERIAN] = sThundurusTherianFormChangeTable, + [SPECIES_THUNDURUS_THERIAN] = sThundurusFormChangeTable, [SPECIES_LANDORUS] = sLandorusFormChangeTable, - [SPECIES_LANDORUS_THERIAN] = sLandorusTherianFormChangeTable, + [SPECIES_LANDORUS_THERIAN] = sLandorusFormChangeTable, [SPECIES_ENAMORUS] = sEnamorusFormChangeTable, - [SPECIES_ENAMORUS_THERIAN] = sEnamorusTherianFormChangeTable, + [SPECIES_ENAMORUS_THERIAN] = sEnamorusFormChangeTable, [SPECIES_KELDEO] = sKeldeoFormChangeTable, - [SPECIES_KELDEO_RESOLUTE] = sKeldeoResoluteFormChangeTable, - [SPECIES_GENESECT] = sGenesectFormChangeTable, + [SPECIES_KELDEO_RESOLUTE] = sKeldeoFormChangeTable, + [SPECIES_GENESECT] = sGenesectFormChangeTable, [SPECIES_GENESECT_DOUSE_DRIVE] = sGenesectFormChangeTable, [SPECIES_GENESECT_SHOCK_DRIVE] = sGenesectFormChangeTable, [SPECIES_GENESECT_BURN_DRIVE] = sGenesectFormChangeTable, [SPECIES_GENESECT_CHILL_DRIVE] = sGenesectFormChangeTable, + [SPECIES_XERNEAS] = sXerneasFormChangeTable, + [SPECIES_XERNEAS_ACTIVE] = sXerneasFormChangeTable, [SPECIES_HOOPA] = sHoopaFormChangeTable, - [SPECIES_HOOPA_UNBOUND] = sHoopaUnboundFormChangeTable, + [SPECIES_HOOPA_UNBOUND] = sHoopaFormChangeTable, [SPECIES_ORICORIO] = sOricorioFormChangeTable, [SPECIES_ORICORIO_POM_POM] = sOricorioFormChangeTable, [SPECIES_ORICORIO_PAU] = sOricorioFormChangeTable, @@ -62,5 +64,9 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] = [SPECIES_SILVALLY_ROCK] = sSilvallyFormChangeTable, [SPECIES_SILVALLY_STEEL] = sSilvallyFormChangeTable, [SPECIES_SILVALLY_WATER] = sSilvallyFormChangeTable, + [SPECIES_ZACIAN] = sZacianFormChangeTable, + [SPECIES_ZACIAN_CROWNED_SWORD] = sZacianFormChangeTable, + [SPECIES_ZAMAZENTA] = sZamazentaFormChangeTable, + [SPECIES_ZAMAZENTA_CROWNED_SHIELD] = sZamazentaFormChangeTable, #endif }; diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h index 5f8541c402..ddcb4d9cbd 100644 --- a/src/data/pokemon/form_change_tables.h +++ b/src/data/pokemon/form_change_tables.h @@ -1,11 +1,10 @@ /* -For cycling between forms with the same method and parameters but different target species (eg. Tornadus using the -Reveal Glass to change between its two forms), a separate form change table is required for each form. -Otherwise, only the last form change on the table will trigger. - FORM_ITEM_HOLD: - Form change activates when the item is given to or taken from the selected Pokémon. + 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 FORM_ITEM_USE: Form change activates when the item is used on the selected Pokémon. @@ -21,18 +20,24 @@ FORM_WITHDRAW: Form change activates when the Pokémon is withdrawn from the PC or Daycare. no parameters -FORM_ITEM_HOLD_ABILITY: - Form change activates when the item is used on the selected Pokémon that has - a particular ability. - param1 = item to use - param2 = ability to check for - FORM_ITEM_USE_TIME: Form change activates when the item is used on the selected Pokémon at the appropriate time of day. param1 = item to use param2 = DAY if form change activates in the daytime NIGHT if form change activates at nighttime + +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 + +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 */ // FORM_MOVE param2 Arguments @@ -52,96 +57,70 @@ static const struct FormChange sGiratinaFormChangeTable[] = { static const struct FormChange sShayminFormChangeTable[] = { {FORM_ITEM_USE_TIME, SPECIES_SHAYMIN_SKY, ITEM_GRACIDEA, DAY}, - {FORM_WITHDRAW, SPECIES_SHAYMIN}, + // {FORM_WITHDRAW, SPECIES_SHAYMIN}, {FORM_CHANGE_END}, }; static const struct FormChange sArceusFormChangeTable[] = { - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS, ITEM_NONE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FIGHTING, ITEM_FIST_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FIGHTING, ITEM_FIGHTINIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FLYING, ITEM_SKY_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FLYING, ITEM_FLYINIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_POISON, ITEM_TOXIC_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_POISON, ITEM_POISONIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_ROCK, ITEM_STONE_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_ROCK, ITEM_ROCKIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_GROUND, ITEM_EARTH_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_GROUND, ITEM_GROUNDIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_BUG, ITEM_INSECT_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_BUG, ITEM_BUGINIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_GHOST, ITEM_SPOOKY_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_GHOST, ITEM_GHOSTIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_STEEL, ITEM_IRON_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_STEEL, ITEM_STEELIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FIRE, ITEM_FLAME_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FIRE, ITEM_FIRIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_WATER, ITEM_SPLASH_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_WATER, ITEM_WATERIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_GRASS, ITEM_MEADOW_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_GRASS, ITEM_GRASSIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_ELECTRIC, ITEM_ZAP_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_ELECTRIC, ITEM_ELECTRIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_PSYCHIC, ITEM_MIND_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_PSYCHIC, ITEM_PSYCHIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_ICE, ITEM_ICICLE_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_ICE, ITEM_ICIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_DRAGON, ITEM_DRACO_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_DRAGON, ITEM_DRAGONIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_DARK, ITEM_DREAD_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_DARK, ITEM_DARKINIUM_Z, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FAIRY, ITEM_PIXIE_PLATE, ABILITY_MULTITYPE}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_ARCEUS_FAIRY, ITEM_FAIRIUM_Z, ABILITY_MULTITYPE}, + {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}, }; static const struct FormChange sTornadusFormChangeTable[] = { {FORM_ITEM_USE, SPECIES_TORNADUS_THERIAN, ITEM_REVEAL_GLASS}, - {FORM_CHANGE_END}, -}; - -static const struct FormChange sTornadusTherianFormChangeTable[] = { {FORM_ITEM_USE, SPECIES_TORNADUS, ITEM_REVEAL_GLASS}, {FORM_CHANGE_END}, }; static const struct FormChange sThundurusFormChangeTable[] = { {FORM_ITEM_USE, SPECIES_THUNDURUS_THERIAN, ITEM_REVEAL_GLASS}, - {FORM_CHANGE_END}, -}; - -static const struct FormChange sThundurusTherianFormChangeTable[] = { {FORM_ITEM_USE, SPECIES_THUNDURUS, ITEM_REVEAL_GLASS}, {FORM_CHANGE_END}, }; static const struct FormChange sLandorusFormChangeTable[] = { {FORM_ITEM_USE, SPECIES_LANDORUS_THERIAN, ITEM_REVEAL_GLASS}, - {FORM_CHANGE_END}, -}; - -static const struct FormChange sLandorusTherianFormChangeTable[] = { {FORM_ITEM_USE, SPECIES_LANDORUS, ITEM_REVEAL_GLASS}, {FORM_CHANGE_END}, }; -static const struct FormChange sEnamorusFormChangeTable[] = { - {FORM_ITEM_USE, SPECIES_ENAMORUS, ITEM_REVEAL_GLASS}, - {FORM_CHANGE_END}, -}; - -static const struct FormChange sEnamorusTherianFormChangeTable[] = { - {FORM_ITEM_USE, SPECIES_ENAMORUS_THERIAN, ITEM_REVEAL_GLASS}, - {FORM_CHANGE_END}, -}; - static const struct FormChange sKeldeoFormChangeTable[] = { - {FORM_MOVE, SPECIES_KELDEO_RESOLUTE, MOVE_SECRET_SWORD, WHEN_LEARNED}, - {FORM_CHANGE_END}, -}; - -static const struct FormChange sKeldeoResoluteFormChangeTable[] = { - {FORM_MOVE, SPECIES_KELDEO, MOVE_SECRET_SWORD, WHEN_FORGOTTEN}, + // {FORM_MOVE, SPECIES_KELDEO_RESOLUTE, MOVE_SECRET_SWORD, WHEN_LEARNED}, + // {FORM_MOVE, SPECIES_KELDEO, MOVE_SECRET_SWORD, WHEN_FORGOTTEN}, {FORM_CHANGE_END}, }; @@ -155,12 +134,8 @@ static const struct FormChange sGenesectFormChangeTable[] = { }; static const struct FormChange sHoopaFormChangeTable[] = { - // {FORM_ITEM_USE, SPECIES_HOOPA_UNBOUND, ITEM_PRISON_BOTTLE, SPECIES_HOOPA}, - {FORM_CHANGE_END}, -}; - -static const struct FormChange sHoopaUnboundFormChangeTable[] = { - {FORM_WITHDRAW, SPECIES_HOOPA}, + {FORM_ITEM_USE, SPECIES_HOOPA_UNBOUND, ITEM_PRISON_BOTTLE, SPECIES_HOOPA}, + // {FORM_WITHDRAW, SPECIES_HOOPA}, {FORM_CHANGE_END}, }; @@ -173,27 +148,51 @@ static const struct FormChange sOricorioFormChangeTable[] = { }; static const struct FormChange sSilvallyFormChangeTable[] = { - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY, ITEM_NONE, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_FIGHTING, ITEM_FIGHTING_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_FLYING, ITEM_FLYING_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_POISON, ITEM_POISON_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_GROUND, ITEM_GROUND_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_ROCK, ITEM_ROCK_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_BUG, ITEM_BUG_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_GHOST, ITEM_GHOST_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_STEEL, ITEM_STEEL_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_FIRE, ITEM_FIRE_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_WATER, ITEM_WATER_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_GRASS, ITEM_GRASS_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_ELECTRIC, ITEM_ELECTRIC_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_PSYCHIC, ITEM_PSYCHIC_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_ICE, ITEM_ICE_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_DRAGON, ITEM_DRAGON_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_DARK, ITEM_DARK_MEMORY, ABILITY_RKS_SYSTEM}, - {FORM_ITEM_HOLD_ABILITY, SPECIES_SILVALLY_FAIRY, ITEM_FAIRY_MEMORY, ABILITY_RKS_SYSTEM}, + {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}, }; #endif +static const struct FormChange sXerneasFormChangeTable[] = { + {FORM_BATTLE_BEGIN, SPECIES_XERNEAS_ACTIVE}, + {FORM_BATTLE_END, SPECIES_XERNEAS, }, + {FORM_CHANGE_END}, +}; + +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}, +}; + +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}, +}; + +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}, +}; + #undef WHEN_LEARNED #undef WHEN_FORGOTTEN diff --git a/src/data/text/move_descriptions.h b/src/data/text/move_descriptions.h index 1275fa4c7b..ac7c910d7e 100644 --- a/src/data/text/move_descriptions.h +++ b/src/data/text/move_descriptions.h @@ -2770,12 +2770,12 @@ static const u8 sPyroBallDescription[] = _( "target. It may cause a burn."); static const u8 sBehemothBladeDescription[] = _( - "Strikes as a sword. It deals\n" - "2x damage to Dynamaxed foes."); + "Strikes as a sword. Deals 2x\n" + "damage to Dynamaxed foes."); static const u8 sBehemothBashDescription[] = _( - "Attacks as a shield. Deals\n" - "2x damage to Dynamaxed foes."); + "Attacks as a shield. Deals 2x\n" + "damage to Dynamaxed foes."); static const u8 sAuraWheelDescription[] = _( "Raises Speed to attack. The\n" diff --git a/src/party_menu.c b/src/party_menu.c index 00224f6bd6..03e4a5826d 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -5596,10 +5596,7 @@ void ItemUseCB_FormChange_ConsumedOnUse(u8 taskId, TaskFunc task) } void TryItemHoldFormChange(struct Pokemon *mon) { - u16 species = GetMonData(mon, MON_DATA_SPECIES); - u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_ITEM_HOLD_ABILITY, 0); - if (targetSpecies == SPECIES_NONE) - targetSpecies = GetFormChangeTargetSpecies(mon, FORM_ITEM_HOLD, 0); + u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_ITEM_HOLD, 0); if (targetSpecies != SPECIES_NONE) { PlayCry_NormalNoDucking(targetSpecies, 0, CRY_VOLUME_RS, CRY_VOLUME_RS); diff --git a/src/pokemon.c b/src/pokemon.c index fc80330306..722eaafe87 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -8241,34 +8241,35 @@ u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId) return targetFormId; } -u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg) +u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg) { return GetFormChangeTargetSpeciesBoxMon(&mon->box, method, arg); } // Returns SPECIES_NONE if no form change is possible -u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg) +u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg) { - u32 i; + u32 i, j; u16 targetSpecies = SPECIES_NONE; - u16 species = GetBoxMonData(mon, MON_DATA_SPECIES, NULL); + u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL); const struct FormChange *formChanges = gFormChangeTablePointers[species]; u16 heldItem; u32 ability; if (formChanges != NULL) { - heldItem = GetBoxMonData(mon, MON_DATA_HELD_ITEM, NULL); - ability = GetAbilityBySpecies(species, GetBoxMonData(mon, MON_DATA_ABILITY_NUM, NULL)); + 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++) { - if (method == formChanges[i].method) + if (method == formChanges[i].method && species != formChanges[i].targetSpecies) { switch (method) { case FORM_ITEM_HOLD: - if (heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE) + 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: @@ -8276,12 +8277,7 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg targetSpecies = formChanges[i].targetSpecies; break; case FORM_MOVE: - if (BoxMonKnowsMove(mon, formChanges[i].param1) != formChanges[i].param2) - targetSpecies = formChanges[i].targetSpecies; - break; - case FORM_ITEM_HOLD_ABILITY: - if ((heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE) - && ability == formChanges[i].param2) + if (BoxMonKnowsMove(boxMon, formChanges[i].param1) != formChanges[i].param2) targetSpecies = formChanges[i].targetSpecies; break; case FORM_ITEM_USE_TIME: @@ -8301,12 +8297,16 @@ u16 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *mon, u16 method, u32 arg } } break; + case FORM_BATTLE_BEGIN: + case FORM_BATTLE_END: + if (heldItem == formChanges[i].param1 || formChanges[i].param1 == ITEM_NONE) + targetSpecies = formChanges[i].targetSpecies; } } } } - return species != targetSpecies ? targetSpecies : SPECIES_NONE; + return targetSpecies; } u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove) @@ -8360,7 +8360,7 @@ void TrySpecialOverworldEvo(void) u8 i; u8 evoMethod = gSpecialVar_0x8000; u16 canStopEvo = gSpecialVar_0x8001; - u16 tryMultiple = gSpecialVar_0x8002; + u16 tryMultiple = gSpecialVar_0x8002; for (i = 0; i < PARTY_SIZE; i++) { @@ -8377,7 +8377,7 @@ void TrySpecialOverworldEvo(void) else gCB2_AfterEvolution = CB2_ReturnToField; return; - } + } } sTriedEvolving = 0; @@ -8388,3 +8388,43 @@ bool32 ShouldShowFemaleDifferences(u16 species, u32 personality) { return (gBaseStats[species].flags & FLAG_GENDER_DIFFERENCE) && GetGenderFromSpeciesAndPersonality(species, personality) == MON_FEMALE; } + +void TryToSetBattleFormChangeMoves(struct Pokemon *mon) +{ + 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) + return; + + for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++) + { + if ((formChanges[i].method == FORM_BATTLE_BEGIN || formChanges[i].method == FORM_BATTLE_END) + && formChanges[i].param2 && formChanges[i].param3 && formChanges[i].targetSpecies == species) + { + u16 originalMove = formChanges[i].param2; + u16 newMove = formChanges[i].param3; + + 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); + } + } + SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses); + break; + } + } +} diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c index d3fe3caa29..432b8083cc 100644 --- a/src/pokemon_storage_system.c +++ b/src/pokemon_storage_system.c @@ -6900,9 +6900,7 @@ static void ReshowDisplayMon(void) void SetMonFormPSS(struct BoxPokemon *boxMon) { - u16 targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_ITEM_HOLD_ABILITY, 0); - if (targetSpecies == SPECIES_NONE) - targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_ITEM_HOLD, 0); + u16 targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_ITEM_HOLD, 0); if (targetSpecies != SPECIES_NONE) { SetBoxMonData(boxMon, MON_DATA_SPECIES, &targetSpecies); diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index 8a9e65ff8f..e33c8ffcad 100755 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -72,9 +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_ABILITY, 0); - if (targetSpecies == SPECIES_NONE) - targetSpecies = GetFormChangeTargetSpecies(&mon, FORM_ITEM_HOLD, 0); + targetSpecies = GetFormChangeTargetSpecies(&mon, FORM_ITEM_HOLD, 0); if (targetSpecies != SPECIES_NONE) { SetMonData(&mon, MON_DATA_SPECIES, &targetSpecies);