From 78d22151962dd114fd8dad1c1b972199eae6624f Mon Sep 17 00:00:00 2001 From: ultima-soul Date: Sat, 2 Oct 2021 11:55:21 -0700 Subject: [PATCH] Improve and refactor some form change code. Separated out ability checks into their own methods. Change FORM_ITEM_USE_TIME to specify time of day instead of hardcoding. --- include/constants/pokemon.h | 17 +-- include/strings.h | 1 + src/data/pokemon/form_change_tables.h | 151 ++++++++++++++------------ src/party_menu.c | 130 +++++++++++++++++++--- src/pokemon.c | 79 ++++++++------ src/strings.c | 1 + 6 files changed, 253 insertions(+), 126 deletions(-) diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index edec3a9db..85bca6615 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -348,20 +348,21 @@ #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 -#define FORM_ITEM_USE_DAY 5 - // Evolution 'modes,' for GetEvolutionTargetSpecies #define EVO_MODE_NORMAL 0 #define EVO_MODE_TRADE 1 #define EVO_MODE_ITEM_USE 2 #define EVO_MODE_ITEM_CHECK 3 // If an Everstone is being held, still want to show that the stone *could* be used on that Pokémon to evolve +// 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_ITEM_HOLD_ABILITY 5 +#define FORM_ITEM_USE_TIME 6 + #define NUM_MALE_LINK_FACILITY_CLASSES 8 #define NUM_FEMALE_LINK_FACILITY_CLASSES 8 diff --git a/include/strings.h b/include/strings.h index 2357e3777..a34313182 100644 --- a/include/strings.h +++ b/include/strings.h @@ -477,6 +477,7 @@ extern const u8 gText_PkmnBurnHealed[]; extern const u8 gText_PkmnThawedOut[]; extern const u8 gText_PkmnCuredOfParalysis[]; extern const u8 gText_PkmnGotOverInfatuation[]; +extern const u8 gText_PkmnTransformed[]; extern const u8 gText_PkmnBecameHealthy[]; extern const u8 gText_HP3[]; extern const u8 gText_SpAtk3[]; diff --git a/src/data/pokemon/form_change_tables.h b/src/data/pokemon/form_change_tables.h index f58b69b54..a84d376b0 100644 --- a/src/data/pokemon/form_change_tables.h +++ b/src/data/pokemon/form_change_tables.h @@ -1,30 +1,43 @@ /* -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: + Form change activates when the item is given to or taken from the selected Pokémon. param1 = item to hold - param2 = ability to check for (none means any) + +FORM_ITEM_USE: + Form change activates when the item is used on the selected Pokémon. + param1 = item to use FORM_MOVE: + Form change activates when the Pokémon learns or forgets the 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 + param2 = WHEN_LEARNED if form change activates when move is forgotten + WHEN_FORGOTTEN if form change activates when move is learned FORM_WITHDRAW: - Form change activates when the Pokemon is withdrawn from the PC or Daycare. + Form change activates when the Pokémon is withdrawn from the PC or Daycare. no parameters -FORM_ITEM_USE_DAY: - Same as FORM_ITEM_USE, but only works during day time. - Used by Shaymin's Gracidea-based form change. +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 */ -#define WHEN_LEARNED FALSE -#define WHEN_FORGOTTEN TRUE +// FORM_MOVE param2 Arguments +#define WHEN_LEARNED 0 +#define WHEN_FORGOTTEN 1 + +// FORM_ITEM_USE_TIME param2 Arguments +#define DAY 0 +#define NIGHT 1 static const struct FormChange sGiratinaFormChangeTable[] = { {FORM_ITEM_HOLD, SPECIES_GIRATINA_ORIGIN, ITEM_GRISEOUS_ORB}, @@ -32,7 +45,7 @@ static const struct FormChange sGiratinaFormChangeTable[] = { }; static const struct FormChange sShayminFormChangeTable[] = { - {FORM_ITEM_USE_DAY, SPECIES_SHAYMIN_SKY, ITEM_GRACIDEA}, + {FORM_ITEM_USE_TIME, SPECIES_SHAYMIN_SKY, ITEM_GRACIDEA, DAY}, {FORM_CHANGE_END}, }; @@ -42,41 +55,41 @@ static const struct FormChange sShayminSkyFormChangeTable[] = { }; 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_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_CHANGE_END}, }; @@ -148,24 +161,24 @@ static const struct FormChange sOricorioFormChangeTable[] = { }; 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_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_CHANGE_END}, }; diff --git a/src/party_menu.c b/src/party_menu.c index 46c528302..f39eea147 100755 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -409,8 +409,6 @@ 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) { @@ -5167,27 +5165,119 @@ void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task) } } +#define tState data[0] +#define tSpecies data[1] +#define tTargetSpecies data[2] +#define tAnimWait data[3] +#define tNextFunc 4 + +static void SpriteCB_FormChangeIconMosaic(struct Sprite *sprite) +{ + u8 taskId = sprite->data[2]; + + sprite->data[0] -= sprite->data[1]; + + if (sprite->data[0] <= 0) + { + if (gTasks[taskId].tAnimWait == 60) + sprite->data[0] = 0; + else + sprite->data[0] = 10; + } + + SetGpuReg(REG_OFFSET_MOSAIC, (sprite->data[0] << 12) | (sprite->data[1] << 8)); + + if (sprite->data[0] == 0) + { + sprite->oam.mosaic = FALSE; + sprite->callback = SpriteCallbackDummy; + } +} + +static void Task_TryItemUseFormChange(u8 taskId) +{ + struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId]; + u16 species; + u16 targetSpecies; + struct Sprite *icon = &gSprites[sPartyMenuBoxes[gPartyMenu.slotId].monSpriteId]; + + switch (gTasks[taskId].tState) + { + case 0: + species = gTasks[taskId].tSpecies; + targetSpecies = gTasks[taskId].tTargetSpecies; + SetMonData(mon, MON_DATA_SPECIES, &targetSpecies); + CalculateMonStats(mon); + gTasks[taskId].tState++; + break; + case 1: + gTasks[taskId].tState++; + break; + case 2: + PlaySE(SE_M_TELEPORT); + gTasks[taskId].tState++; + break; + case 3: + targetSpecies = gTasks[taskId].tTargetSpecies; + + if (gTasks[taskId].tAnimWait == 0) + { + FreeAndDestroyMonIconSprite(icon); + CreatePartyMonIconSpriteParameterized(targetSpecies, GetMonData(mon, MON_DATA_PERSONALITY, NULL), &sPartyMenuBoxes[gPartyMenu.slotId], 1); + icon->oam.mosaic = TRUE; + icon->data[0] = 10; + icon->data[1] = 1; + icon->data[2] = taskId; + icon->callback = SpriteCB_FormChangeIconMosaic; + SetGpuReg(REG_OFFSET_MOSAIC, (icon->data[0] << 12) | (icon->data[1] << 8)); + } + + if (++gTasks[taskId].tAnimWait == 60) + gTasks[taskId].tState++; + + break; + case 4: + targetSpecies = gTasks[taskId].tTargetSpecies; + PlayCry1(targetSpecies, 0); + gTasks[taskId].tState++; + break; + case 5: + if (IsCryFinished()) + { + GetMonNickname(mon, gStringVar1); + StringExpandPlaceholders(gStringVar4, gText_PkmnTransformed); + DisplayPartyMenuMessage(gStringVar4, FALSE); + ScheduleBgCopyTilemapToVram(2); + gTasks[taskId].tState++; + } + + break; + case 6: + if (!IsPartyMenuTextPrinterActive()) + gTasks[taskId].tState++; + + break; + case 7: + gTasks[taskId].func = (void *)GetWordTaskArg(taskId, tNextFunc); + break; + } +} + 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_DAY, gSpecialVar_ItemId); - if (targetSpecies == SPECIES_NONE) - targetSpecies = GetFormChangeTargetSpecies(mon, FORM_ITEM_USE, gSpecialVar_ItemId); + u16 targetSpecies = GetFormChangeTargetSpecies(mon, ItemId_GetSecondaryId(gSpecialVar_ItemId), 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], 1); - CalculateMonStats(mon); - GetMonNickname(mon, gStringVar1); - StringExpandPlaceholders(gStringVar4, ChangedForm); - DisplayPartyMenuMessage(gStringVar4, FALSE); - ScheduleBgCopyTilemapToVram(2); - gTasks[taskId].func = task; + SetWordTaskArg(taskId, tNextFunc, (u32)task); + gTasks[taskId].func = Task_TryItemUseFormChange; + gTasks[taskId].tState = 0; + gTasks[taskId].tSpecies = species; + gTasks[taskId].tTargetSpecies = targetSpecies; + gTasks[taskId].tAnimWait = 0; return TRUE; } else @@ -5209,11 +5299,15 @@ void ItemUseCB_FormChange(u8 taskId, TaskFunc task) void ItemUseCB_FormChange_ConsumedOnUse(u8 taskId, TaskFunc task) { if (TryItemUseFormChange(taskId, task)) - { RemoveBagItem(gSpecialVar_ItemId, 1); - } } +#undef tState +#undef tSpecies +#undef tTargetSpecies +#undef tAnimWait +#undef tNextFunc + u8 GetItemEffectType(u16 item) { const u8 *itemEffect; diff --git a/src/pokemon.c b/src/pokemon.c index bc04c42f9..a0fb94256 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -8054,42 +8054,59 @@ 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]; + u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); + const struct FormChange *formChanges = gFormChangeTablePointers[species]; + u16 heldItem; + u32 ability; - if (formChanges == NULL) - return SPECIES_NONE; - - for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++) + if (formChanges != NULL) { - if (method == formChanges[i].method) + heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL); + ability = GetAbilityBySpecies(species, GetMonData(mon, MON_DATA_ABILITY_NUM, NULL)); + + for (i = 0; formChanges[i].method != FORM_CHANGE_END; i++) { - u32 ability = GetAbilityBySpecies(originalSpecies, GetMonData(mon, MON_DATA_ABILITY_NUM, NULL)); - switch (method) + if (method == formChanges[i].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)) - targetSpecies = formChanges[i].targetSpecies; - 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; - case FORM_ITEM_USE_DAY: - RtcCalcLocalTime(); - if (arg == formChanges[i].param1 && (ability == formChanges[i].param2 || formChanges[i].param2 == ABILITY_NONE) - && (gLocalTime.hours >= 12 && gLocalTime.hours < 24)) - targetSpecies = formChanges[i].targetSpecies; - break; - default: - targetSpecies = formChanges[i].targetSpecies; - break; + switch (method) + { + case FORM_ITEM_HOLD: + if (heldItem == formChanges[i].param1) + targetSpecies = formChanges[i].targetSpecies; + break; + case FORM_ITEM_USE: + if (arg == formChanges[i].param1) + targetSpecies = formChanges[i].targetSpecies; + break; + case FORM_MOVE: + if (MonKnowsMove(mon, formChanges[i].param1) != formChanges[i].param2) + targetSpecies = formChanges[i].targetSpecies; + break; + case FORM_ITEM_HOLD_ABILITY: + if (heldItem == formChanges[i].param1 && ability == formChanges[i].param2) + targetSpecies = formChanges[i].targetSpecies; + break; + case FORM_ITEM_USE_TIME: + RtcCalcLocalTime(); + if (arg == formChanges[i].param1) + { + switch (formChanges[i].param2) + { + case DAY: + if (gLocalTime.hours >= 12 && gLocalTime.hours < 24) + targetSpecies = formChanges[i].targetSpecies; + break; + case NIGHT: + if (gLocalTime.hours >= 0 && gLocalTime.hours < 12) + targetSpecies = formChanges[i].targetSpecies; + break; + } + } + break; + } } } } - return originalSpecies != targetSpecies ? targetSpecies : SPECIES_NONE; + + return species != targetSpecies ? targetSpecies : SPECIES_NONE; } diff --git a/src/strings.c b/src/strings.c index e1a6d2efb..9be2cfb32 100644 --- a/src/strings.c +++ b/src/strings.c @@ -423,6 +423,7 @@ const u8 gText_PkmnAdoresBaseVar2Fell[] = _("{STR_VAR_1} adores you!\nThe base { const u8 gText_PkmnFriendlyBaseVar2CantFall[] = _("{STR_VAR_1} turned friendly.\nThe base {STR_VAR_2} can't fall!{PAUSE_UNTIL_PRESS}"); const u8 gText_PkmnSnappedOutOfConfusion[] = _("{STR_VAR_1} snapped out of its\nconfusion.{PAUSE_UNTIL_PRESS}"); const u8 gText_PkmnGotOverInfatuation[] = _("{STR_VAR_1} got over its\ninfatuation.{PAUSE_UNTIL_PRESS}"); +const u8 gText_PkmnTransformed[] = _("{STR_VAR_1} transformed!{PAUSE_UNTIL_PRESS}"); const u8 gText_ThrowAwayItem[] = _("Throw away this\n{STR_VAR_1}?"); const u8 gText_ItemThrownAway[] = _("The {STR_VAR_1}\nwas thrown away.{PAUSE_UNTIL_PRESS}"); const u8 gText_TeachWhichPokemon2[] = _("Teach which POKéMON?"); // Unused