Remove form change function footguns (#5995)

This commit is contained in:
Eduardo Quezada 2025-01-11 05:57:39 -03:00 committed by GitHub
parent f8151f0be5
commit c33c38e020
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 44 additions and 37 deletions

View File

@ -783,8 +783,8 @@ void DestroyMonSpritesGfxManager(u8 managerId);
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 *boxMon, u16 method, u32 arg);
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);

View File

@ -254,12 +254,12 @@ static u16 GetTypeBasedMaxMove(u32 battler, u32 type)
// Gigantamax check
u32 i;
u32 species = gBattleMons[battler].species;
u32 targetSpecies = SPECIES_NONE;
u32 targetSpecies = species;
if (!gSpeciesInfo[species].isGigantamax)
targetSpecies = GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_GIGANTAMAX);
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != species)
species = targetSpecies;
if (gSpeciesInfo[species].isGigantamax)

View File

@ -11102,7 +11102,7 @@ static void Cmd_various(void)
case VARIOUS_JUMP_IF_CANT_REVERT_TO_PRIMAL:
{
VARIOUS_ARGS(const u8 *jumpInstr);
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) == SPECIES_NONE)
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) == gBattleMons[battler].species)
gBattlescriptCurrInstr = cmd->jumpInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;

View File

@ -6609,7 +6609,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32
bool32 TryPrimalReversion(u32 battler)
{
if (GetBattlerHoldEffect(battler, FALSE) == HOLD_EFFECT_PRIMAL_ORB
&& GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) != SPECIES_NONE)
&& GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_PRIMAL_REVERSION) != gBattleMons[battler].species)
{
gBattleScripting.battler = battler;
BattleScriptPushCursorAndCallback(BattleScript_PrimalReversion);
@ -10946,11 +10946,11 @@ bool32 CanMegaEvolve(u32 battler)
return FALSE;
// Check if there is an entry in the form change table for regular Mega Evolution and battler is holding Mega Stone.
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM) != SPECIES_NONE && holdEffect == HOLD_EFFECT_MEGA_STONE)
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM) != gBattleMons[battler].species && holdEffect == HOLD_EFFECT_MEGA_STONE)
return TRUE;
// Check if there is an entry in the form change table for Wish Mega Evolution.
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE)
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != gBattleMons[battler].species)
return TRUE;
// No checks passed, the mon CAN'T mega evolve.
@ -10980,7 +10980,7 @@ bool32 CanUltraBurst(u32 battler)
return FALSE;
// Check if there is an entry in the form change table for Ultra Burst and battler is holding a Z-Crystal.
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_ULTRA_BURST) != SPECIES_NONE && holdEffect == HOLD_EFFECT_Z_CRYSTAL)
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_ULTRA_BURST) != gBattleMons[battler].species && holdEffect == HOLD_EFFECT_Z_CRYSTAL)
return TRUE;
// No checks passed, the mon CAN'T ultra burst.
@ -10991,7 +10991,7 @@ void ActivateMegaEvolution(u32 battler)
{
gLastUsedItem = gBattleMons[battler].item;
SetActiveGimmick(battler, GIMMICK_MEGA);
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != SPECIES_NONE)
if (GetBattleFormChangeTargetSpecies(battler, FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE) != gBattleMons[battler].species)
BattleScriptExecute(BattleScript_WishMegaEvolution);
else
BattleScriptExecute(BattleScript_MegaEvolution);
@ -11040,8 +11040,8 @@ bool32 IsBattlerInTeraForm(u32 battler)
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
{
u32 i;
u16 targetSpecies = SPECIES_NONE;
u16 species = gBattleMons[battler].species;
u32 species = gBattleMons[battler].species;
u32 targetSpecies = species;
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
struct Pokemon *mon = &GetBattlerParty(battler)[gBattlerPartyIndexes[battler]];
u16 heldItem;
@ -11170,15 +11170,16 @@ bool32 TryBattleFormChange(u32 battler, u32 method)
u32 monId = gBattlerPartyIndexes[battler];
u32 side = GetBattlerSide(battler);
struct Pokemon *party = GetBattlerParty(battler);
u32 currentSpecies = GetMonData(&party[monId], MON_DATA_SPECIES);
u32 targetSpecies;
if (!CanBattlerFormChange(battler, method))
return FALSE;
targetSpecies = GetBattleFormChangeTargetSpecies(battler, method);
if (targetSpecies == SPECIES_NONE)
if (targetSpecies == currentSpecies)
targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != currentSpecies)
{
// Saves the original species on the first form change.
if (gBattleStruct->changedSpecies[side][monId] == SPECIES_NONE)

View File

@ -83,9 +83,10 @@ static void FormChangeTimeUpdate()
for (i = 0; i < PARTY_SIZE; i++)
{
struct Pokemon *mon = &gPlayerParty[i];
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_TIME_OF_DAY, 0);
u32 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_TIME_OF_DAY, 0);
u32 currentSpecies = GetMonData(mon, MON_DATA_SPECIES);
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != currentSpecies)
{
SetMonData(mon, MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(mon);

View File

@ -330,8 +330,8 @@ static void ApplyDaycareExperience(struct Pokemon *mon)
static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon)
{
u16 species;
u16 newSpecies;
u32 species;
u32 newSpecies;
u32 experience;
struct Pokemon pokemon;
@ -340,7 +340,7 @@ static u16 TakeSelectedPokemonFromDaycare(struct DaycareMon *daycareMon)
BoxMonToMon(&daycareMon->mon, &pokemon);
newSpecies = GetFormChangeTargetSpecies(&pokemon, FORM_CHANGE_WITHDRAW, 0);
if (newSpecies != SPECIES_NONE)
if (newSpecies != species)
{
SetMonData(&pokemon, MON_DATA_SPECIES, &newSpecies);
CalculateMonStats(&pokemon);

View File

@ -6442,9 +6442,10 @@ static void Task_TryItemUseFormChange(u8 taskId)
bool32 TryItemUseFormChange(u8 taskId, TaskFunc task)
{
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_USE, gSpecialVar_ItemId);
u32 currentSpecies = GetMonData(mon, MON_DATA_SPECIES);
u32 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_USE, gSpecialVar_ItemId);
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != currentSpecies)
{
gPartyMenuUseExitCallback = TRUE;
SetWordTaskArg(taskId, tNextFunc, (u32)task);
@ -6490,12 +6491,13 @@ void ItemUseCB_RotomCatalog(u8 taskId, TaskFunc task)
bool32 TryMultichoiceFormChange(u8 taskId)
{
struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId];
u32 currentSpecies = GetMonData(mon, MON_DATA_SPECIES);
u32 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_USE_MULTICHOICE, gSpecialVar_ItemId);
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[0]);
PartyMenuRemoveWindow(&sPartyMenuInternal->windowId[1]);
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != currentSpecies)
{
gPartyMenuUseExitCallback = TRUE;
SetWordTaskArg(taskId, tNextFunc, (u32)Task_ClosePartyMenuAfterText);
@ -6582,8 +6584,9 @@ static void CursorCb_ChangeAbility(u8 taskId)
void TryItemHoldFormChange(struct Pokemon *mon)
{
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != SPECIES_NONE)
u32 currentSpecies = GetMonData(mon, MON_DATA_SPECIES);
u32 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != currentSpecies)
{
PlayCry_NormalNoDucking(targetSpecies, 0, CRY_VOLUME_RS, CRY_VOLUME_RS);
SetMonData(mon, MON_DATA_SPECIES, &targetSpecies);

View File

@ -6529,17 +6529,18 @@ u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId)
return targetFormId;
}
u16 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg)
// Returns the current species if no form change is possible
u32 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 *boxMon, u16 method, u32 arg)
// Returns the current species if no form change is possible
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg)
{
u32 i;
u16 targetSpecies = SPECIES_NONE;
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
u32 targetSpecies = species;
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
u16 heldItem;
u32 ability;
@ -6762,18 +6763,18 @@ bool32 SpeciesHasGenderDifferences(u16 species)
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);
u32 currentSpecies = GetMonData(&party[monId], MON_DATA_SPECIES);
u32 targetSpecies = GetFormChangeTargetSpecies(&party[monId], method, 0);
if (targetSpecies == SPECIES_NONE && gBattleStruct != NULL)
if (targetSpecies == currentSpecies && gBattleStruct != NULL && gBattleStruct->changedSpecies[side][monId] != SPECIES_NONE)
targetSpecies = gBattleStruct->changedSpecies[side][monId];
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != currentSpecies)
{
TryToSetBattleFormChangeMoves(&party[monId], method);
SetMonData(&party[monId], MON_DATA_SPECIES, &targetSpecies);
@ -6962,9 +6963,10 @@ void UpdateDaysPassedSinceFormChange(u16 days)
for (i = 0; i < PARTY_SIZE; i++)
{
struct Pokemon *mon = &gPlayerParty[i];
u32 currentSpecies = GetMonData(mon, MON_DATA_SPECIES);
u8 daysSinceFormChange;
if (!GetMonData(mon, MON_DATA_SPECIES, 0))
if (currentSpecies == SPECIES_NONE)
continue;
daysSinceFormChange = GetMonData(mon, MON_DATA_DAYS_SINCE_FORM_CHANGE, 0);
@ -6980,9 +6982,9 @@ void UpdateDaysPassedSinceFormChange(u16 days)
if (daysSinceFormChange == 0)
{
u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_DAYS_PASSED, 0);
u32 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_DAYS_PASSED, 0);
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != currentSpecies)
{
SetMonData(mon, MON_DATA_SPECIES, &targetSpecies);
CalculateMonStats(mon);

View File

@ -6965,7 +6965,7 @@ static void ReshowDisplayMon(void)
void SetMonFormPSS(struct BoxPokemon *boxMon)
{
u16 targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, FORM_CHANGE_ITEM_HOLD, 0);
if (targetSpecies != SPECIES_NONE)
if (targetSpecies != GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL))
{
SetBoxMonData(boxMon, MON_DATA_SPECIES, &targetSpecies);
UpdateSpeciesSpritePSS(boxMon);