Merge pull request #1375 from ExpoSeed/PE/form-change-table

Form change table
This commit is contained in:
Eduardo Quezada D'Ottone 2021-09-22 00:04:26 -03:00 committed by GitHub
commit f9d1375451
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 428 additions and 2 deletions

View File

@ -348,6 +348,13 @@
#define EVOS_PER_MON 10
// 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
// Evolution 'modes,' for GetEvolutionTargetSpecies
#define EVO_MODE_NORMAL 0
#define EVO_MODE_TRADE 1

View File

@ -95,6 +95,78 @@
#define ITEM_RAZOR_FANG ITEM_NONE
#define ITEM_RAZOR_CLAW ITEM_NONE
#define ITEM_OVAL_STONE ITEM_NONE
#endif
//FORM_ITEM_HOLD
#define ITEM_GRISEOUS_ORB ITEM_NONE
#define ITEM_DRACO_PLATE ITEM_NONE
#define ITEM_DREAD_PLATE ITEM_NONE
#define ITEM_EARTH_PLATE ITEM_NONE
#define ITEM_FIST_PLATE ITEM_NONE
#define ITEM_FLAME_PLATE ITEM_NONE
#define ITEM_ICICLE_PLATE ITEM_NONE
#define ITEM_INSECT_PLATE ITEM_NONE
#define ITEM_IRON_PLATE ITEM_NONE
#define ITEM_MEADOW_PLATE ITEM_NONE
#define ITEM_MIND_PLATE ITEM_NONE
#define ITEM_PIXIE_PLATE ITEM_NONE
#define ITEM_SKY_PLATE ITEM_NONE
#define ITEM_SPLASH_PLATE ITEM_NONE
#define ITEM_SPOOKY_PLATE ITEM_NONE
#define ITEM_STONE_PLATE ITEM_NONE
#define ITEM_TOXIC_PLATE ITEM_NONE
#define ITEM_ZAP_PLATE ITEM_NONE
#define ITEM_FIGHTINIUM_Z ITEM_NONE
#define ITEM_FLYINIUM_Z ITEM_NONE
#define ITEM_POISONIUM_Z ITEM_NONE
#define ITEM_GROUNDIUM_Z ITEM_NONE
#define ITEM_ROCKIUM_Z ITEM_NONE
#define ITEM_BUGINIUM_Z ITEM_NONE
#define ITEM_GHOSTIUM_Z ITEM_NONE
#define ITEM_STEELIUM_Z ITEM_NONE
#define ITEM_FIRIUM_Z ITEM_NONE
#define ITEM_WATERIUM_Z ITEM_NONE
#define ITEM_GRASSIUM_Z ITEM_NONE
#define ITEM_ELECTRIUM_Z ITEM_NONE
#define ITEM_PSYCHIUM_Z ITEM_NONE
#define ITEM_ICIUM_Z ITEM_NONE
#define ITEM_DRAGONIUM_Z ITEM_NONE
#define ITEM_DARKINIUM_Z ITEM_NONE
#define ITEM_FAIRIUM_Z ITEM_NONE
#define ITEM_DOUSE_DRIVE ITEM_NONE
#define ITEM_SHOCK_DRIVE ITEM_NONE
#define ITEM_BURN_DRIVE ITEM_NONE
#define ITEM_CHILL_DRIVE ITEM_NONE
#define ITEM_BUG_MEMORY ITEM_NONE
#define ITEM_DARK_MEMORY ITEM_NONE
#define ITEM_DRAGON_MEMORY ITEM_NONE
#define ITEM_ELECTRIC_MEMORY ITEM_NONE
#define ITEM_FAIRY_MEMORY ITEM_NONE
#define ITEM_FIGHTING_MEMORY ITEM_NONE
#define ITEM_FIRE_MEMORY ITEM_NONE
#define ITEM_FLYING_MEMORY ITEM_NONE
#define ITEM_GHOST_MEMORY ITEM_NONE
#define ITEM_GRASS_MEMORY ITEM_NONE
#define ITEM_GROUND_MEMORY ITEM_NONE
#define ITEM_ICE_MEMORY ITEM_NONE
#define ITEM_POISON_MEMORY ITEM_NONE
#define ITEM_PSYCHIC_MEMORY ITEM_NONE
#define ITEM_ROCK_MEMORY ITEM_NONE
#define ITEM_STEEL_MEMORY ITEM_NONE
#define ITEM_WATER_MEMORY ITEM_NONE
//FORM_ITEM_USE
#define ITEM_GRACIDEA ITEM_NONE
// #define ITEM_REVEAL_GLASS ITEM_NONE
// #define ITEM_PRISON_BOTTLE ITEM_NONE
#define ITEM_RED_NECTAR ITEM_NONE
#define ITEM_YELLOW_NECTAR ITEM_NONE
#define ITEM_PINK_NECTAR ITEM_NONE
#define ITEM_PURPLE_NECTAR ITEM_NONE
#endif // ITEM_EXPANSION
#ifndef BATTLE_ENGINE
#define ABILITY_MULTITYPE ABILITY_NONE
#define ABILITY_RKS_SYSTEM ABILITY_NONE
#endif // BATTLE_ENGINE
#endif // GUARD_CONSTANTS_POKEMON_CONFIG_H

View File

@ -23,6 +23,8 @@ void ItemUseOutOfBattle_BlackWhiteFlute(u8);
void ItemUseOutOfBattle_EvolutionStone(u8);
void ItemUseOutOfBattle_Berry(u8);
void ItemUseOutOfBattle_EnigmaBerry(u8);
void ItemUseOutOfBattle_FormChange(u8);
void ItemUseOutOfBattle_FormChange_ConsumedOnUse(u8);
void ItemUseOutOfBattle_CannotUse(u8);
void ItemUseInBattle_PokeBall(u8);
void ItemUseInBattle_StatIncrease(u8);

View File

@ -59,6 +59,8 @@ void ItemUseCB_TMHM(u8 taskId, TaskFunc task);
void ItemUseCB_RareCandy(u8 taskId, TaskFunc task);
void ItemUseCB_SacredAsh(u8 taskId, TaskFunc task);
void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task);
void ItemUseCB_FormChange(u8 taskId, TaskFunc task);
void ItemUseCB_FormChange_ConsumedOnUse(u8 taskId, TaskFunc task);
u8 GetItemEffectType(u16 item);
void CB2_PartyMenuFromStartMenu(void);
void CB2_ChooseMonToGiveItem(void);

View File

@ -243,6 +243,13 @@ struct Evolution
u16 targetSpecies;
};
struct FormChange {
u16 method;
u16 targetSpecies;
u16 param1;
u16 param2;
};
#define NUM_UNOWN_FORMS 28
#define GET_UNOWN_LETTER(personality) (( \
@ -431,5 +438,5 @@ void sub_806F47C(u8 id);
u8 *sub_806F4F8(u8 id, u8 arg1);
u16 GetFormSpeciesId(u16 speciesId, u8 formId);
u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
#endif // GUARD_POKEMON_H

View File

@ -0,0 +1,61 @@
const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
{
[SPECIES_GIRATINA] = sGiratinaFormChangeTable,
[SPECIES_SHAYMIN] = sShayminFormChangeTable,
[SPECIES_SHAYMIN_SKY] = sShayminSkyFormChangeTable,
[SPECIES_ARCEUS] = sArceusFormChangeTable,
[SPECIES_ARCEUS_FIGHTING] = sArceusFormChangeTable,
[SPECIES_ARCEUS_FLYING] = sArceusFormChangeTable,
[SPECIES_ARCEUS_POISON] = sArceusFormChangeTable,
[SPECIES_ARCEUS_ROCK] = sArceusFormChangeTable,
[SPECIES_ARCEUS_GROUND] = sArceusFormChangeTable,
[SPECIES_ARCEUS_BUG] = sArceusFormChangeTable,
[SPECIES_ARCEUS_GHOST] = sArceusFormChangeTable,
[SPECIES_ARCEUS_STEEL] = sArceusFormChangeTable,
[SPECIES_ARCEUS_FIRE] = sArceusFormChangeTable,
[SPECIES_ARCEUS_WATER] = sArceusFormChangeTable,
[SPECIES_ARCEUS_GRASS] = sArceusFormChangeTable,
[SPECIES_ARCEUS_ELECTRIC] = sArceusFormChangeTable,
[SPECIES_ARCEUS_PSYCHIC] = sArceusFormChangeTable,
[SPECIES_ARCEUS_ICE] = sArceusFormChangeTable,
[SPECIES_ARCEUS_DRAGON] = sArceusFormChangeTable,
[SPECIES_ARCEUS_DARK] = sArceusFormChangeTable,
[SPECIES_ARCEUS_FAIRY] = sArceusFormChangeTable,
[SPECIES_TORNADUS] = sTornadusFormChangeTable,
[SPECIES_TORNADUS_THERIAN] = sTornadusTherianFormChangeTable,
[SPECIES_THUNDURUS] = sThundurusFormChangeTable,
[SPECIES_THUNDURUS_THERIAN] = sThundurusTherianFormChangeTable,
[SPECIES_LANDORUS] = sLandorusFormChangeTable,
[SPECIES_LANDORUS_THERIAN] = sLandorusTherianFormChangeTable,
[SPECIES_KELDEO] = sKeldeoFormChangeTable,
[SPECIES_KELDEO_RESOLUTE] = sKeldeoResoluteFormChangeTable,
[SPECIES_GENESECT] = sGenesectFormChangeTable,
[SPECIES_GENESECT_DOUSE_DRIVE] = sGenesectFormChangeTable,
[SPECIES_GENESECT_SHOCK_DRIVE] = sGenesectFormChangeTable,
[SPECIES_GENESECT_BURN_DRIVE] = sGenesectFormChangeTable,
[SPECIES_GENESECT_CHILL_DRIVE] = sGenesectFormChangeTable,
[SPECIES_HOOPA] = sHoopaFormChangeTable,
[SPECIES_HOOPA_UNBOUND] = sHoopaUnboundFormChangeTable,
[SPECIES_ORICORIO] = sOricorioFormChangeTable,
[SPECIES_ORICORIO_POM_POM] = sOricorioFormChangeTable,
[SPECIES_ORICORIO_PAU] = sOricorioFormChangeTable,
[SPECIES_ORICORIO_SENSU] = sOricorioFormChangeTable,
[SPECIES_SILVALLY] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_BUG] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_DARK] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_DRAGON] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_ELECTRIC] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_FAIRY] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_FIGHTING] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_FIRE] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_FLYING] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_GHOST] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_GRASS] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_GROUND] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_ICE] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_POISON] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_PSYCHIC] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_ROCK] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_STEEL] = sSilvallyFormChangeTable,
[SPECIES_SILVALLY_WATER] = sSilvallyFormChangeTable,
};

View File

@ -0,0 +1,169 @@
/*
FORM_ITEM_USE:
Changes any pokemon with a matching base species (even if
it is a form) to the target species.
param1 = item to use
param1 = ability to check for (none means any)
FORM_ITEM_HOLD:
param1 = item to hold
param2 = ability to check for (none means any)
FORM_MOVE:
param1 = move to check for
param2 = true if form change activates when move is forgotten,
false if form change activates when move is learned
FORM_WITHDRAW:
Form change activates when the Pokemon is withdrawn from the PC or Daycare.
no parameters
*/
#define WHEN_LEARNED FALSE
#define WHEN_FORGOTTEN TRUE
static const struct FormChange sGiratinaFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_GIRATINA_ORIGIN, ITEM_GRISEOUS_ORB},
{FORM_CHANGE_END},
};
static const struct FormChange sShayminFormChangeTable[] = {
{FORM_ITEM_USE, SPECIES_SHAYMIN_SKY, ITEM_GRACIDEA},
{FORM_CHANGE_END},
};
static const struct FormChange sShayminSkyFormChangeTable[] = {
{FORM_WITHDRAW, SPECIES_SHAYMIN},
{FORM_CHANGE_END},
};
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},
};
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 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_CHANGE_END},
};
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},
};
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_CHANGE_END},
};
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},
};
static const struct FormChange sSilvallyFormChangeTable[] = {
{FORM_ITEM_HOLD, SPECIES_SILVALLY, ITEM_NONE, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_BUG, ITEM_BUG_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_DARK, ITEM_DARK_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_DRAGON, ITEM_DRAGON_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_ELECTRIC, ITEM_ELECTRIC_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FAIRY, ITEM_FAIRY_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FIGHTING, ITEM_FIGHTING_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FIRE, ITEM_FIRE_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_FLYING, ITEM_FLYING_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_GHOST, ITEM_GHOST_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_GRASS, ITEM_GRASS_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_GROUND, ITEM_GROUND_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_ICE, ITEM_ICE_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_POISON, ITEM_POISON_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_PSYCHIC, ITEM_PSYCHIC_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_ROCK, ITEM_ROCK_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_STEEL, ITEM_STEEL_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_ITEM_HOLD, SPECIES_SILVALLY_WATER, ITEM_WATER_MEMORY, ABILITY_RKS_SYSTEM},
{FORM_CHANGE_END},
};
#undef WHEN_LEARNED
#undef WHEN_FORGOTTEN

View File

@ -245,6 +245,7 @@ static void ApplyDaycareExperience(struct Pokemon *mon)
static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon)
{
u16 species;
u16 newSpecies;
u32 experience;
struct Pokemon pokemon;
@ -252,6 +253,13 @@ 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) {
SetMonData(&pokemon, MON_DATA_SPECIES, &newSpecies);
CalculateMonStats(&pokemon);
species = newSpecies;
}
if (GetMonData(&pokemon, MON_DATA_LEVEL) != MAX_LEVEL)
{
experience = GetMonData(&pokemon, MON_DATA_EXP) + daycareMon->steps;

View File

@ -1118,6 +1118,20 @@ void ItemUseInBattle_EnigmaBerry(u8 taskId)
}
}
void ItemUseOutOfBattle_FormChange(u8 taskId)
{
gItemUseCB = ItemUseCB_FormChange;
gTasks[taskId].data[0] = FALSE;
SetUpItemUseCallback(taskId);
}
void ItemUseOutOfBattle_FormChange_ConsumedOnUse(u8 taskId)
{
gItemUseCB = ItemUseCB_FormChange_ConsumedOnUse;
gTasks[taskId].data[0] = TRUE;
SetUpItemUseCallback(taskId);
}
void ItemUseOutOfBattle_CannotUse(u8 taskId)
{
DisplayDadsAdviceCannotUseItemMessage(taskId, gTasks[taskId].tUsingRegisteredKeyItem);

View File

@ -409,6 +409,8 @@ static bool8 SetUpFieldMove_Dive(void);
#include "data/pokemon/tutor_learnsets.h"
#include "data/party_menu.h"
static const u8 ChangedForm[] = _("{STR_VAR_1} changed Forme!{PAUSE_UNTIL_PRESS}");
// code
static void InitPartyMenu(u8 menuType, u8 layout, u8 partyAction, bool8 keepCursorPos, u8 messageId, TaskFunc task, MainCallback callback)
{
@ -5165,6 +5167,51 @@ void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task)
}
}
bool32 TryItemUseFormChange(u8 taskId, TaskFunc task)
{
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
u16 species = GetMonData(mon, MON_DATA_SPECIES);
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_ITEM_USE, gSpecialVar_ItemId);
if (targetSpecies != SPECIES_NONE)
{
gPartyMenuUseExitCallback = TRUE;
PlaySE(SE_USE_ITEM);
PlayCry2(targetSpecies, 0, 0x7D, 0xA);
SetMonData(mon, MON_DATA_SPECIES, &targetSpecies);
FreeAndDestroyMonIconSprite(&gSprites[sPartyMenuBoxes[gPartyMenu.slotId].monSpriteId]);
CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), &sPartyMenuBoxes[gPartyMenu.slotId], 0);
CalculateMonStats(mon);
GetMonNickname(mon, gStringVar1);
StringExpandPlaceholders(gStringVar4, ChangedForm);
DisplayPartyMenuMessage(gStringVar4, FALSE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = task;
return TRUE;
}
else
{
gPartyMenuUseExitCallback = FALSE;
PlaySE(SE_SELECT);
DisplayPartyMenuMessage(gText_WontHaveEffect, TRUE);
ScheduleBgCopyTilemapToVram(2);
gTasks[taskId].func = task;
return FALSE;
}
}
void ItemUseCB_FormChange(u8 taskId, TaskFunc task)
{
TryItemUseFormChange(taskId, task);
}
void ItemUseCB_FormChange_ConsumedOnUse(u8 taskId, TaskFunc task)
{
if (TryItemUseFormChange(taskId, task))
{
RemoveBagItem(gSpecialVar_ItemId, 1);
}
}
u8 GetItemEffectType(u16 item)
{
const u8 *itemEffect;

View File

@ -1850,6 +1850,8 @@ const s8 gNatureStatTable[NUM_NATURES][NUM_NATURE_STATS] =
#include "data/pokemon/level_up_learnset_pointers.h"
#include "data/pokemon/form_species_tables.h"
#include "data/pokemon/form_species_table_pointers.h"
#include "data/pokemon/form_change_tables.h"
#include "data/pokemon/form_change_table_pointers.h"
// SPECIES_NONE are ignored in the following two tables, so decrement before accessing these arrays to get the right result
@ -8046,3 +8048,38 @@ u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId)
}
return targetFormId;
}
// returns SPECIES_NONE if no form change is possible
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg)
{
u32 i;
u16 targetSpecies = SPECIES_NONE;
u16 originalSpecies = GetMonData(mon, MON_DATA_SPECIES, NULL);
const struct FormChange *formChanges = gFormChangeTablePointers[originalSpecies];
if (formChanges == NULL)
return SPECIES_NONE;
for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++) {
if (method == formChanges[i].method) {
u32 ability = GetAbilityBySpecies(originalSpecies, GetMonData(mon, MON_DATA_ABILITY_NUM, NULL));
switch (method)
{
case FORM_ITEM_HOLD:
if (GetMonData(mon, MON_DATA_HELD_ITEM, NULL) == formChanges[i].param1 && (ability == formChanges[i].param2 || formChanges[i].param2 == ABILITY_NONE))
break;
case FORM_ITEM_USE:
if (arg == formChanges[i].param1 && (ability == formChanges[i].param2 || formChanges[i].param2 == ABILITY_NONE))
targetSpecies = formChanges[i].targetSpecies;
break;
case FORM_MOVE:
if (MonKnowsMove(mon, formChanges[i].param1) != formChanges[i].param2)
targetSpecies = formChanges[i].targetSpecies;
break;
default:
targetSpecies = formChanges[i].targetSpecies;
break;
}
}
}
return originalSpecies != targetSpecies ? targetSpecies : SPECIES_NONE;
}