Make form change methods into enum + type checking (#6631)

This commit is contained in:
Bassoonian 2025-04-16 23:45:41 +02:00 committed by GitHub
parent cca969b04d
commit 1c3d346d4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 155 additions and 161 deletions

View File

@ -268,8 +268,8 @@ void ActivateUltraBurst(u32 battler);
bool32 IsBattlerMegaEvolved(u32 battler);
bool32 IsBattlerPrimalReverted(u32 battler);
bool32 IsBattlerUltraBursted(u32 battler);
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method);
bool32 TryBattleFormChange(u32 battler, u32 method);
u16 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method);
bool32 TryBattleFormChange(u32 battler, enum FormChanges method);
bool32 DoBattlersShareType(u32 battler1, u32 battler2);
bool32 CanBattlerGetOrLoseItem(u32 battler, u16 itemId);
u32 GetIllusionMonSpecies(u32 battler);

View File

@ -2,153 +2,139 @@
#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
enum FormChangeBattleHPPercentArguments
{
HP_HIGHER_THAN = 1,
HP_LOWER_EQ_THAN,
};
// FORM_CHANGE_MOVE param2 Arguments
#define WHEN_LEARNED 0
#define WHEN_FORGOTTEN 1
enum FormChangeMoveArguments
{
WHEN_LEARNED,
WHEN_FORGOTTEN,
};
// FORM_CHANGE_ITEM_USE param2 Arguments
#define DAY 1
#define NIGHT 2
enum FormChangeItemUseArguments
{
DAY = 1,
NIGHT,
};
#define FUSION_TERMINATOR 0xFF
#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.
// - 0 if irrelevant, but param3 is necessary.
// param3: illegal statuses to have, optional.
#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.
// param1: ability to check, optional
#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
// param2: (optional) revert if specified ability is lost
#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
// Form change that activates when the mon has the defined item.
// If it's on the player's side, it also requires for the player to trigger it by pressing START before selecting a move.
// param1: item to hold.
#define FORM_CHANGE_BATTLE_ULTRA_BURST 16
// Form change that activates when the mon Dynamaxes (TODO: with Gigantamax factor).
// - No parameters
#define FORM_CHANGE_BATTLE_GIGANTAMAX 17
// Form change that activates at a certain time of day in the overworld automatically.
// param1: time of day to check.
// - DAY if Form change that activates in the daytime.
// - NIGHT if Form change that activates at nighttime.
#define FORM_CHANGE_TIME_OF_DAY 18
// Form change that depends on a multichoice (e.g. Rotom Catalog).
// param1: multichoice list (starting at 0).
#define FORM_CHANGE_ITEM_USE_MULTICHOICE 19
// Form change that activates when inflicted with a specific status
// param1: status
#define FORM_CHANGE_STATUS 20
// Form change that activates after move is used. Currently only used for activating Gulp Missile.
#define FORM_CHANGE_HIT_BY_MOVE 21
// Form change that activates when terastallized as as a specific type
// param1: tera type
#define FORM_CHANGE_BATTLE_TERASTALLIZATION 22
// Form change that activates at midnight after a certain amount of days has passed.
// Adding this form change will automatically make the countdown start as soon the Pokémon changes into a species other than the one specified for this form change.
// param1: amount of days
#define FORM_CHANGE_DAYS_PASSED 23
// Form change that activates before using a move.
// param1: move to check
// param2: ability to check, optional
#define FORM_CHANGE_BATTLE_BEFORE_MOVE 24
// Form change that activates before using a specific move category.
// param1: move category to check
// param2: ability to check, optional
#define FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY 25
// Form change that activates when overworld weather changes.
// param1: weather to check.
#define FORM_CHANGE_OVERWORLD_WEATHER 26
// Form change that activates when the Pokémon is deposited into the PC or Daycare.
#define FORM_CHANGE_DEPOSIT 27
enum FormChanges
{
FORM_CHANGE_TERMINATOR,
// 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.
FORM_CHANGE_ITEM_HOLD,
// 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.
// - 0 if irrelevant, but param3 is necessary.
// param3: illegal statuses to have, optional.
FORM_CHANGE_ITEM_USE,
// 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
FORM_CHANGE_MOVE,
// Form change that activates when the Pokémon is withdrawn from the PC or Daycare.
// Daycare withdraw done, PC withdraw TODO.
// - No parameters.
FORM_CHANGE_WITHDRAW,
// 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.
FORM_CHANGE_FAINT,
// 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
FORM_CHANGE_BEGIN_BATTLE,
// 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
FORM_CHANGE_END_BATTLE,
// 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.
FORM_CHANGE_END_BATTLE_TERRAIN,
// Form change that activates when the Pokémon is switched out in battle.
// param1: ability to check, optional
FORM_CHANGE_BATTLE_SWITCH,
// 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.
FORM_CHANGE_BATTLE_HP_PERCENT,
// 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.
FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM,
// 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.
FORM_CHANGE_BATTLE_MEGA_EVOLUTION_MOVE,
// 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.
FORM_CHANGE_BATTLE_PRIMAL_REVERSION,
// Form change that activates when a specific weather is set during battle.
// param1: weather to check
// param2: (optional) revert if specified ability is lost
FORM_CHANGE_BATTLE_WEATHER,
// Form change that activates automatically when the turn ends.
// param1: ability to check.
FORM_CHANGE_BATTLE_TURN_END,
// Form change that activates when the mon has the defined item.
// If it's on the player's side, it also requires for the player to trigger it by pressing START before selecting a move.
// param1: item to hold.
FORM_CHANGE_BATTLE_ULTRA_BURST,
// Form change that activates when the mon Dynamaxes.
// - No parameters
FORM_CHANGE_BATTLE_GIGANTAMAX,
// Form change that activates at a certain time of day in the overworld automatically.
// param1: time of day to check.
// - DAY if Form change that activates in the daytime.
// - NIGHT if Form change that activates at nighttime.
FORM_CHANGE_TIME_OF_DAY,
// Form change that depends on a multichoice (e.g. Rotom Catalog).
// param1: multichoice list (starting at 0).
FORM_CHANGE_ITEM_USE_MULTICHOICE,
// Form change that activates when inflicted with a specific status
// param1: status
FORM_CHANGE_STATUS,
// Form change that activates after move is used. Currently only used for activating Gulp Missile.
FORM_CHANGE_HIT_BY_MOVE,
// Form change that activates when terastallized as as a specific type
// param1: tera type
FORM_CHANGE_BATTLE_TERASTALLIZATION,
// Form change that activates at midnight after a certain amount of days has passed.
// Adding this form change will automatically make the countdown start as soon the Pokémon changes into a species other than the one specified for this form change.
// param1: amount of days
FORM_CHANGE_DAYS_PASSED,
// Form change that activates before using a move.
// param1: move to check
// param2: ability to check, optional
FORM_CHANGE_BATTLE_BEFORE_MOVE,
// Form change that activates before using a specific move category.
// param1: move category to check
// param2: ability to check, optional
FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY,
// Form change that activates when overworld weather changes.
// param1: weather to check.
FORM_CHANGE_OVERWORLD_WEATHER,
// Form change that activates when the Pokémon is deposited into the PC or Daycare.
FORM_CHANGE_DEPOSIT,
};
#endif // GUARD_CONSTANTS_FORM_CHANGE_TYPES_H

View File

@ -2,6 +2,7 @@
#define GUARD_POKEMON_H
#include "sprite.h"
#include "constants/form_change_types.h"
#include "constants/items.h"
#include "constants/regions.h"
#include "constants/region_map_sections.h"
@ -789,15 +790,15 @@ void DestroyMonSpritesGfxManager(u8 managerId);
u8 *MonSpritesGfxManager_GetSpritePtr(u8 managerId, u8 spriteNum);
u16 GetFormSpeciesId(u16 speciesId, u8 formId);
u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId);
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg);
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method);
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, enum FormChanges method, u32 arg);
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, enum FormChanges method, u32 arg);
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, enum FormChanges method);
u16 MonTryLearningNewMoveEvolution(struct Pokemon *mon, bool8 firstMove);
void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv);
void TrySpecialOverworldEvo(void);
bool32 SpeciesHasGenderDifferences(u16 species);
bool32 TryFormChange(u32 monId, u32 side, u16 method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method);
bool32 TryFormChange(u32 monId, u32 side, enum FormChanges method);
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, enum FormChanges method);
u32 GetMonFriendshipScore(struct Pokemon *pokemon);
u32 GetMonAffectionHearts(struct Pokemon *pokemon);
void UpdateMonPersonality(struct BoxPokemon *boxMon, u32 personality);

View File

@ -9735,7 +9735,8 @@ bool32 DoesSpeciesUseHoldItemToChangeForm(u16 species, u16 heldItemId)
for (i = 0; formChanges != NULL && formChanges[i].method != FORM_CHANGE_TERMINATOR; i++)
{
switch (formChanges[i].method)
enum FormChanges method = formChanges[i].method;
switch (method)
{
case FORM_CHANGE_BATTLE_MEGA_EVOLUTION_ITEM:
case FORM_CHANGE_BATTLE_PRIMAL_REVERSION:
@ -9745,6 +9746,8 @@ bool32 DoesSpeciesUseHoldItemToChangeForm(u16 species, u16 heldItemId)
if (formChanges[i].param1 == heldItemId)
return TRUE;
break;
default:
break;
}
}
return FALSE;
@ -9868,7 +9871,7 @@ bool32 IsBattlerInTeraForm(u32 battler)
}
// Returns SPECIES_NONE if no form change is possible
u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
u16 GetBattleFormChangeTargetSpecies(u32 battler, enum FormChanges method)
{
u32 i;
u32 species = gBattleMons[battler].species;
@ -9967,6 +9970,8 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
&& (formChanges[i].param2 == ABILITY_NONE || formChanges[i].param2 == GetBattlerAbility(battler)))
targetSpecies = formChanges[i].targetSpecies;
break;
default:
break;
}
}
}
@ -9974,7 +9979,7 @@ u16 GetBattleFormChangeTargetSpecies(u32 battler, u16 method)
return targetSpecies;
}
bool32 CanBattlerFormChange(u32 battler, u16 method)
bool32 CanBattlerFormChange(u32 battler, enum FormChanges method)
{
// Can't change form if transformed.
if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED
@ -9991,7 +9996,7 @@ bool32 CanBattlerFormChange(u32 battler, u16 method)
return DoesSpeciesHaveFormChangeMethod(gBattleMons[battler].species, method);
}
bool32 TryBattleFormChange(u32 battler, u32 method)
bool32 TryBattleFormChange(u32 battler, enum FormChanges method)
{
u32 monId = gBattlerPartyIndexes[battler];
u32 side = GetBattlerSide(battler);

View File

@ -6552,13 +6552,13 @@ u8 GetFormIdFromFormSpeciesId(u16 formSpeciesId)
}
// Returns the current species if no form change is possible
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, u16 method, u32 arg)
u32 GetFormChangeTargetSpecies(struct Pokemon *mon, enum FormChanges method, u32 arg)
{
return GetFormChangeTargetSpeciesBoxMon(&mon->box, method, arg);
}
// Returns the current species if no form change is possible
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32 arg)
u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, enum FormChanges method, u32 arg)
{
u32 i;
u32 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
@ -6649,6 +6649,8 @@ u32 GetFormChangeTargetSpeciesBoxMon(struct BoxPokemon *boxMon, u16 method, u32
break;
}
break;
default:
break;
}
}
}
@ -6673,7 +6675,7 @@ void TrySetDayLimitToFormChange(struct Pokemon *mon)
}
}
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, u16 method)
bool32 DoesSpeciesHaveFormChangeMethod(u16 species, enum FormChanges method)
{
u32 i;
const struct FormChange *formChanges = GetSpeciesFormChanges(species);
@ -6780,7 +6782,7 @@ bool32 SpeciesHasGenderDifferences(u16 species)
return FALSE;
}
bool32 TryFormChange(u32 monId, u32 side, u16 method)
bool32 TryFormChange(u32 monId, u32 side, enum FormChanges method)
{
struct Pokemon *party = (side == B_SIDE_PLAYER) ? gPlayerParty : gEnemyParty;
@ -6818,7 +6820,7 @@ bool32 IsSpeciesEnabled(u16 species)
return gSpeciesInfo[species].baseHP > 0 || species == SPECIES_EGG;
}
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, u16 method)
void TryToSetBattleFormChangeMoves(struct Pokemon *mon, enum FormChanges method)
{
int i, j;
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);

View File

@ -845,7 +845,7 @@ static void TilemapUtil_DrawPrev(u8);
static void TilemapUtil_Draw(u8);
// Form changing
void SetMonFormPSS(struct BoxPokemon *boxMon, u32 method);
void SetMonFormPSS(struct BoxPokemon *boxMon, enum FormChanges method);
void UpdateSpeciesSpritePSS(struct BoxPokemon *boxmon);
static const u8 gText_JustOnePkmn[] = _("There is just one POKéMON with you.");
@ -6909,7 +6909,7 @@ static void ReshowDisplayMon(void)
TryRefreshDisplayMon();
}
void SetMonFormPSS(struct BoxPokemon *boxMon, u32 method)
void SetMonFormPSS(struct BoxPokemon *boxMon, enum FormChanges method)
{
u16 targetSpecies = GetFormChangeTargetSpeciesBoxMon(boxMon, method, 0);
if (targetSpecies != GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL))