diff --git a/include/constants/pokemon.h b/include/constants/pokemon.h index d147816543..659193861c 100644 --- a/include/constants/pokemon.h +++ b/include/constants/pokemon.h @@ -246,76 +246,68 @@ #define EVOLUTIONS_END 0xFFFF // Not an actual evolution, used to mark the end of an evolution array. -enum EvolutionMethods { - EVO_NONE, // Not an actual evolution, used to generate offspring that can't evolve into the specified species, like regional forms. - EVO_FRIENDSHIP, // Pokémon levels up with friendship ≥ 220 - EVO_FRIENDSHIP_DAY, // Pokémon levels up during the day with friendship ≥ 220 - EVO_FRIENDSHIP_NIGHT, // Pokémon levels up at night with friendship ≥ 220 - EVO_LEVEL, // Pokémon reaches the specified level - EVO_TRADE, // Pokémon is traded - EVO_TRADE_ITEM, // Pokémon is traded while it's holding the specified item - EVO_ITEM, // specified item is used on Pokémon - EVO_LEVEL_ATK_GT_DEF, // Pokémon reaches the specified level with attack > defense - EVO_LEVEL_ATK_EQ_DEF, // Pokémon reaches the specified level with attack = defense - EVO_LEVEL_ATK_LT_DEF, // Pokémon reaches the specified level with attack < defense - EVO_LEVEL_SILCOON, // Pokémon reaches the specified level with a Silcoon personality value - EVO_LEVEL_CASCOON, // Pokémon reaches the specified level with a Cascoon personality value - EVO_LEVEL_NINJASK, // Pokémon reaches the specified level (special value for Ninjask) - EVO_LEVEL_SHEDINJA, // Pokémon reaches the specified level (special value for Shedinja) - EVO_BEAUTY, // Pokémon levels up with beauty ≥ specified value - EVO_LEVEL_FEMALE, // Pokémon reaches the specified level, is female - EVO_LEVEL_MALE, // Pokémon reaches the specified level, is male - EVO_LEVEL_NIGHT, // Pokémon reaches the specified level, is night - EVO_LEVEL_DAY, // Pokémon reaches the specified level, is day - EVO_LEVEL_DUSK, // Pokémon reaches the specified level, is dusk (5-6 P.M) - EVO_ITEM_HOLD_DAY, // Pokémon levels up, holds specified item at day - EVO_ITEM_HOLD_NIGHT, // Pokémon levels up, holds specified item at night - EVO_MOVE, // Pokémon levels up, knows specified move - EVO_FRIENDSHIP_MOVE_TYPE, // Pokémon levels up with friendship ≥ 220, knows move with specified type - EVO_MAPSEC, // Pokémon levels up on specified mapsec - EVO_ITEM_MALE, // specified item is used on a male Pokémon - EVO_ITEM_FEMALE, // specified item is used on a female Pokémon - EVO_LEVEL_RAIN, // Pokémon reaches the specified level during rain in the overworld - EVO_SPECIFIC_MON_IN_PARTY, // Pokémon levels up with a specified Pokémon in party - EVO_LEVEL_DARK_TYPE_MON_IN_PARTY, // Pokémon reaches the specified level with a Dark Type Pokémon in party - EVO_TRADE_SPECIFIC_MON, // Pokémon is traded for a specified Pokémon - EVO_SPECIFIC_MAP, // Pokémon levels up on specified map - EVO_LEVEL_NATURE_AMPED, // Pokémon reaches the specified level, it has a Hardy, Brave, Adamant, Naughty, Docile, Impish, Lax, Hasty, Jolly, Naive, Rash, Sassy, or Quirky nature. - EVO_LEVEL_NATURE_LOW_KEY, // Pokémon reaches the specified level, it has a Lonely, Bold, Relaxed, Timid, Serious, Modest, Mild, Quiet, Bashful, Calm, Gentle, or Careful nature. - EVO_CRITICAL_HITS, // Pokémon performs specified number of critical hits in one battle - EVO_SCRIPT_TRIGGER_DMG, // Pokémon has specified HP below max, then player interacts with script calling "tryspecialevo EVO_SCRIPT_TRIGGER_DMG" - EVO_DARK_SCROLL, // interacts with Scroll of Darkness - EVO_WATER_SCROLL, // interacts with Scroll of Waters - EVO_ITEM_NIGHT, // specified item is used on Pokémon, is night - EVO_ITEM_DAY, // specified item is used on Pokémon, is day - EVO_ITEM_HOLD, // Pokémon levels up, holds specified item - EVO_LEVEL_FOG, // Pokémon reaches the specified level during fog in the overworld - EVO_MOVE_TWO_SEGMENT, // Pokémon levels up, knows specified move, has a personality value with a modulus of 0 - EVO_MOVE_THREE_SEGMENT, // Pokémon levels up, knows specified move, has a personality value with a modulus of 1-99 - EVO_LEVEL_FAMILY_OF_THREE, // Pokémon reaches the specified level in battle with a personality value with a modulus of 0 - EVO_LEVEL_FAMILY_OF_FOUR, // Pokémon reaches the specified level in battle with a personality value with a modulus of 1-99 - EVO_USE_MOVE_TWENTY_TIMES, // Pokémon levels up after having used a move for at least 20 times - EVO_RECOIL_DAMAGE_MALE, // Pokémon levels up after having suffered specified amount of non-fainting recoil damage as a male - EVO_RECOIL_DAMAGE_FEMALE, // Pokémon levels up after having suffered specified amount of non-fainting recoil damage as a female - EVO_ITEM_COUNT_999, // Pokémon levels up after trainer has collected 999 of a specific item - EVO_DEFEAT_THREE_WITH_ITEM, // Pokémon levels up after having defeat 3 Pokémon of the same species holding the specified item - EVO_OVERWORLD_STEPS, // Pokémon levels up after having taken a specific amount of steps in the overworld +enum EvolutionConditions { + // Gen 2 + IF_GENDER, // The Pokémon is of specific gender. + IF_TIME, // It is currently the specific time of day. + IF_NOT_TIME, // It is NOT currently the specific time of day. + IF_MIN_FRIENDSHIP, // The Pokémon has the defined amount of Friendship. + IF_ATK_GT_DEF, // The Pokémon's Attack is greater than its Defense stat. + IF_ATK_EQ_DEF, // The Pokémon's Attack is equal to its Defense stat. + IF_ATK_LT_DEF, // The Pokémon's Attack is lower than its Defense stat. + IF_HOLD_ITEM, // The Pokémon is holding a specific item. + // Gen 3 + IF_PID_UPPER_MODULO_10_GT, // The Pokémon's upper personality value's modulo by 10 is greater than the defined value. + IF_PID_UPPER_MODULO_10_EQ, // The Pokémon's upper personality value's modulo by 10 is equal to the defined value. + IF_PID_UPPER_MODULO_10_LT, // The Pokémon's upper personality value's modulo by 10 is lower or equal than the defined value. + IF_MIN_BEAUTY, // The Pokémon has the defined amount of Beauty. + IF_MIN_COOLNESS, // The Pokémon has the defined amount of Coolness. + IF_MIN_SMARTNESS, // The Pokémon has the defined amount of Smartness. (aka Cleverness in Gen6+) + IF_MIN_TOUGHNESS, // The Pokémon has the defined amount of Toughness. + IF_MIN_CUTENESS, // The Pokémon has the defined amount of Cuteness. + // Gen 4 + IF_SPECIES_IN_PARTY, // The party contains a Pokémon of the specified species. + IF_IN_MAP, // The player is currently in the specific map. + IF_IN_MAPSEC, // The player is currently in the specific map sector. + IF_KNOWS_MOVE, // The Pokémon knows specific move. + // Gen 5 + IF_TRADE_PARTNER_SPECIES, // The Pokémon is traded for a specific species. + // Gen 6 + IF_TYPE_IN_PARTY, // The party contains a Pokémon of the specified type. + IF_WEATHER, // It is currently the specific weather in the current map. + IF_KNOWS_MOVE_TYPE, // The Pokémon knows a move with a specific type. + // Gen 8 + IF_NATURE, // The Pokémon has a specific nature. + IF_AMPED_NATURE, // The Pokémon has one of the following natures: Hardy, Brave, Adamant, Naughty, Docile, Impish, Lax, Hasty, Jolly, Naive, Rash, Sassy, or Quirky. + IF_LOW_KEY_NATURE, // The Pokémon has one of the following natures: Lonely, Bold, Relaxed, Timid, Serious, Modest, Mild, Quiet, Bashful, Calm, Gentle, or Careful. + IF_RECOIL_DAMAGE_GE, // The Pokémon suffered at least certain amount of non-fainting recoil damage. + IF_CURRENT_DAMAGE_GE, // The Pokémon has the specified difference of HP from its Max HP. + IF_CRITICAL_HITS_GE, // The Pokémon performed the specified number of critical hits in one battle at least. + IF_USED_MOVE_X_TIMES, // The Pokémon has used a move for at least X amount of times. + // Gen 9 + IF_DEFEAT_X_WITH_ITEMS, // The Pokémon defeated X amount of Pokémon of the specified species that are holding the specified item. + IF_PID_MODULO_100_GT, // The Pokémon's personality value's modulo by 100 is greater than the defined value. + IF_PID_MODULO_100_EQ, // The Pokémon's personality value's modulo by 100 is equal than the defined value. + IF_PID_MODULO_100_LT, // The Pokémon's personality value's modulo by 100 is lower than the defined value. + IF_MIN_OVERWORLD_STEPS, // The Player has taken a specific amount of steps in the overworld with the Pokémon following them or in the first slot of the party. + IF_BAG_ITEM_COUNT, // The Player has the specific amount of an item in the bag. It then removes those items. + CONDITIONS_END +}; - // Alcremie evolutions methods. Different combinations of day, spin rotation and duration. - EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, - EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, +enum EvolutionMethods { + EVO_NONE, // Not an actual evolution, used to generate offspring that can't evolve into the specified species, like regional forms. + EVO_LEVEL, // Pokémon reaches the specified level + EVO_TRADE, // Pokémon is traded + EVO_ITEM, // specified item is used on Pokémon + EVO_SPLIT_FROM_EVO, // A clone is generated and evolved when another evolution happens + EVO_SCRIPT_TRIGGER, // Player interacts with an overworld trigger + EVO_LEVEL_BATTLE_ONLY, // Pokémon reaches the specified level, in battle only + EVO_BATTLE_END, // Battle ends, doesn't need to level up + EVO_SPIN // The player spins in the overworld }; enum EvolutionMode { EVO_MODE_NORMAL, - EVO_MODE_CANT_STOP, EVO_MODE_TRADE, EVO_MODE_ITEM_USE, EVO_MODE_ITEM_CHECK, // If an Everstone is being held, still want to show that the stone *could* be used on that Pokémon to evolve @@ -324,19 +316,27 @@ enum EvolutionMode { EVO_MODE_BATTLE_ONLY, // This mode is only used in battles to support Tandemaus' unique requirement }; -enum StartEvo -{ +// used to determine whether an evolution is happening or not, so we know if items should be removed +enum EvoState { CHECK_EVO, DO_EVO, }; -enum PokemonJumpType{ - PKMN_JUMP_TYPE_NONE, // Not allowed in Pokémon Jump +enum PokemonJumpType { + PKMN_JUMP_TYPE_NONE, // Not allowed in Pokémon Jump PKMN_JUMP_TYPE_NORMAL, PKMN_JUMP_TYPE_FAST, PKMN_JUMP_TYPE_SLOW, }; +enum EvoSpinDirections { + SPIN_CW_SHORT, // Player spins clockwise + SPIN_CW_LONG, // Player spins clockwise + SPIN_CCW_SHORT, // Player spins counter-clockwise + SPIN_CCW_LONG, // Player spins counter-clockwise + SPIN_EITHER, // Player spins either clockwise or counter-clockwise +}; + #define MON_PIC_WIDTH 64 #define MON_PIC_HEIGHT 64 #define MON_PIC_SIZE (MON_PIC_WIDTH * MON_PIC_HEIGHT / 2) diff --git a/include/constants/weather.h b/include/constants/weather.h index 32dc97a1a2..f2e41b3ab7 100644 --- a/include/constants/weather.h +++ b/include/constants/weather.h @@ -19,7 +19,8 @@ #define WEATHER_ABNORMAL 15 // The alternating weather during Groudon/Kyogre conflict #define WEATHER_ROUTE119_CYCLE 20 #define WEATHER_ROUTE123_CYCLE 21 -#define WEATHER_COUNT 22 +#define WEATHER_FOG 22 // Aggregate of WEATHER_FOG_HORIZONTAL and WEATHER_FOG_DIAGONAL +#define WEATHER_COUNT 23 // These are used in maps' coord_weather_event entries. // They are not a one-to-one mapping with the engine's diff --git a/include/debug.h b/include/debug.h index e25392091b..a009ce2e2a 100644 --- a/include/debug.h +++ b/include/debug.h @@ -3,6 +3,7 @@ void Debug_ShowMainMenu(void); extern const u8 Debug_FlagsAndVarNotSetBattleConfigMessage[]; +const u8 *GetWeatherName(u32 weatherId); extern EWRAM_DATA bool8 gIsDebugBattle; extern EWRAM_DATA u32 gDebugAIFlags; diff --git a/include/line_break.h b/include/line_break.h index c423c9bf40..af0d27ff21 100644 --- a/include/line_break.h +++ b/include/line_break.h @@ -21,13 +21,20 @@ struct StringLine { u8 extraSpaceWidth; }; +enum ToggleScrollPrompt +{ + SHOW_SCROLL_PROMPT, + HIDE_SCROLL_PROMPT, +}; + void StripLineBreaks(u8 *src); -void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId); -void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId); +u32 CountLineBreaks(u8 *src); +void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId, enum ToggleScrollPrompt toggleScrollPrompt); +void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId, enum ToggleScrollPrompt toggleScrollPrompt); bool32 IsWordSplittingChar(const u8 *src, u32 index); u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth); -void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str); +void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str, enum ToggleScrollPrompt toggleScrollPrompt); bool32 StringHasManualBreaks(u8 *src); #endif // GUARD_LINE_BREAK_H diff --git a/include/pokemon.h b/include/pokemon.h index f55918fda6..830182a324 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -344,11 +344,20 @@ struct BattlePokemon /*0x5A*/ bool8 isShiny; }; +struct EvolutionParam +{ + u16 condition; + u16 arg1; + u16 arg2; + u16 arg3; +}; + struct Evolution { u16 method; u16 param; u16 targetSpecies; + const struct EvolutionParam *params; }; struct SpeciesInfo /*0xC4*/ @@ -727,7 +736,8 @@ u8 *UseStatIncreaseItem(u16 itemId); u8 GetNature(struct Pokemon *mon); u8 GetNatureFromPersonality(u32 personality); u32 GetGMaxTargetSpecies(u32 species); -u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 evolutionItem, struct Pokemon *tradePartner, enum StartEvo prepareEvo); +bool32 DoesMonMeetAdditionalConditions(struct Pokemon *mon, const struct EvolutionParam *params, struct Pokemon *tradePartner, u32 partyId, bool32 *canStopEvo, enum EvoState evoState); +u32 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 evolutionItem, struct Pokemon *tradePartner, bool32 *canStopEvo, enum EvoState evoState); bool8 IsMonPastEvolutionLevel(struct Pokemon *mon); u16 NationalPokedexNumToSpecies(u16 nationalNum); u16 NationalToHoennOrder(u16 nationalNum); diff --git a/migration_scripts/1.12/update_evo_methods.py b/migration_scripts/1.12/update_evo_methods.py new file mode 100644 index 0000000000..78669c0130 --- /dev/null +++ b/migration_scripts/1.12/update_evo_methods.py @@ -0,0 +1,237 @@ +import re +import os + + +METHOD = 0 +CONDTION = 1 +SPECIES = 2 + + +def convert_methods(data): + new_data = "" + pattern = r'\{([^{}]+)\}' + + # make sure we're in the right directory before anything else + if not os.path.exists("Makefile"): + print("Please run this script from the project's root folder.") + quit() + + for line in data: + if "EVO_FRIENDSHIP," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}", line) + elif "EVO_FRIENDSHIP_DAY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_NOT_TIME, TIME_NIGHT})}", line) + elif "EVO_FRIENDSHIP_NIGHT," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_TIME, TIME_NIGHT})}", line) + elif "EVO_TRADE_ITEM," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_TRADE, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_HOLD_ITEM, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_LEVEL_ATK_GT_DEF," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_ATK_GT_DEF})}", line) + elif "EVO_LEVEL_ATK_EQ_DEF," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_ATK_EQ_DEF})}", line) + elif "EVO_LEVEL_ATK_LT_DEF," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_ATK_LT_DEF})}", line) + elif "EVO_LEVEL_SILCOON," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_PID_UPPER_MODULO_10_GT, 5})}", line) + elif "EVO_LEVEL_CASCOON," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_PID_UPPER_MODULO_10_LT, 5})}", line) + elif "EVO_LEVEL_NINJASK," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}', line) + # elif "EVO_LEVEL_SHEDINJA," in line: + # match = re.search(pattern, line) + # members = match.group(1).split(",") + # new_data = new_data = re.sub(pattern, " ", line) + elif "EVO_BEAUTY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_MIN_BEAUTY, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_LEVEL_FEMALE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_GENDER, MON_FEMALE})}", line) + elif "EVO_LEVEL_MALE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_GENDER, MON_MALE})}", line) + elif "EVO_LEVEL_NIGHT," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_TIME, TIME_NIGHT})}", line) + elif "EVO_LEVEL_DAY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}", line) + elif "EVO_LEVEL_DUSK," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_TIME, TIME_EVENING})}", line) + elif "EVO_ITEM_HOLD_DAY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_NOT_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_ITEM_HOLD_NIGHT," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_MOVE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_KNOWS_MOVE, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_FRIENDSHIP_MOVE_TYPE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_KNOWS_MOVE_TYPE, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_MAPSEC," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_IN_MAPSEC, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_ITEM_MALE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_ITEM, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_GENDER, MON_MALE})}", line) + elif "EVO_ITEM_FEMALE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_ITEM, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_GENDER, MON_FEMALE})}", line) + elif "EVO_LEVEL_RAIN," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_WEATHER, WEATHER_RAIN})}", line) + elif "EVO_LEVEL_FOG," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_WEATHER, WEATHER_FOG})}", line) + elif "EVO_SPECIFIC_MON_IN_PARTY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_SPECIES_IN_PARTY, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_LEVEL_DARK_TYPE_MON_IN_PARTY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_TYPE_IN_PARTY, TYPE_DARK})}", line) + elif "EVO_TRADE_SPECIFIC_MON," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_TRADE, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_TRADE_PARTNER_SPECIES, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_SPECIFIC_MAP," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_IN_MAP, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_LEVEL_NATURE_AMPED," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_AMPED_NATURE})}", line) + elif "EVO_LEVEL_NATURE_LOW_KEY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_LOW_KEY_NATURE})}", line) + elif "EVO_CRITICAL_HITS," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_BATTLE_END, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_CRITICAL_HITS_GE, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_SCRIPT_TRIGGER_DMG," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_SCRIPT_TRIGGER, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_CURRENT_DAMAGE_GE, " + f'{members[CONDTION].strip()}' + "})}", line) + elif "EVO_DARK_SCROLL," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_SCRIPT_TRIGGER, " + f'0, {members[SPECIES].strip()}' + "}", line) + elif "EVO_WATER_SCROLL," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_SCRIPT_TRIGGER, " + f'1, {members[SPECIES].strip()}' + "}", line) + elif "EVO_ITEM_NIGHT," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_ITEM, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_TIME, TIME_NIGHT})}", line) + elif "EVO_ITEM_DAY," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_ITEM, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}", line) + elif "EVO_MOVE_TWO_SEGMENT," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_KNOWS_MOVE, " + f'{members[CONDTION].strip()}' + "}, {IF_PID_MODULO_100_LT, 100})}", line) + elif "EVO_MOVE_THREE_SEGMENT," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_KNOWS_MOVE, " + f'{members[CONDTION].strip()}' + "}, {IF_PID_MODULO_100_LT, 1})}", line) + elif "EVO_LEVEL_FAMILY_OF_THREE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_PID_MODULO_100_EQ, 0})}", line) + elif "EVO_LEVEL_FAMILY_OF_FOUR," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'{members[CONDTION].strip()}, {members[SPECIES].strip()}' + ", CONDITIONS({IF_PID_MODULO_100_GT, 0})}", line) + elif "EVO_USE_MOVE_TWENTY_TIMES," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_USED_MOVE_X_TIMES, " + f'{members[CONDTION].strip()}' + ", 20})}", line) + elif "EVO_RECOIL_DAMAGE_MALE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_RECOIL_DAMAGE_GE, " + f'{members[CONDTION].strip()}' + "}, {IF_GENDER, MON_MALE})}", line) + elif "EVO_RECOIL_DAMAGE_FEMALE," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_RECOIL_DAMAGE_GE, " + f'{members[CONDTION].strip()}' + "}, {IF_GENDER, MON_FEMALE})}", line) + elif "EVO_ITEM_COUNT_999," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_BAG_ITEM_COUNT, " + f'{members[CONDTION].strip()}' + ", 999})}", line) + elif "EVO_DEFEAT_THREE_WITH_ITEM," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_DEFEAT_X_WITH_ITEMS, " + "SPECIES_BISHARP, ITEM_LEADERS_CREST, 3})}", line) + elif "EVO_OVERWORLD_STEPS," in line: + match = re.search(pattern, line) + members = match.group(1).split(",") + new_data = new_data + re.sub(pattern, "{EVO_LEVEL, " + f'0, {members[SPECIES].strip()}' + ", CONDITIONS({IF_MIN_OVERWORLD_STEPS, 1000})}", line) + else: + new_data = new_data + line + + return new_data + + +species_files = [ + "gen_1_families.h", + "gen_2_families.h", + "gen_3_families.h", + "gen_4_families.h", + "gen_5_families.h", + "gen_6_families.h", + "gen_7_families.h", + "gen_8_families.h", + "gen_9_families.h", +] + +PATH = "src/data/pokemon/species_info/" + +for source in species_files: + with open(PATH + source, 'r') as file: + data = file.readlines() + + with open(PATH + source, 'w') as file: + file.write(convert_methods(data)) diff --git a/src/battle_main.c b/src/battle_main.c index b8851bdc12..55ed945239 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5690,27 +5690,22 @@ static void TryEvolvePokemon(void) { if (!(sTriedEvolving & (1u << i))) { - u16 species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_SPECIAL, i, NULL, DO_EVO); - bool32 evoModeNormal = TRUE; + bool32 canStopEvo = TRUE; + u32 species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_SPECIAL, i, NULL, &canStopEvo, CHECK_EVO); sTriedEvolving |= 1u << i; if (species == SPECIES_NONE && (gLeveledUpInBattle & (1u << i))) { gLeveledUpInBattle &= ~(1u << i); - species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_ONLY, gLeveledUpInBattle, NULL, DO_EVO); - } - - if (species == SPECIES_NONE) - { - species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_CANT_STOP, ITEM_NONE, NULL, DO_EVO); - evoModeNormal = FALSE; + species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_ONLY, gLeveledUpInBattle, NULL, &canStopEvo, CHECK_EVO); } if (species != SPECIES_NONE) { FreeAllWindowBuffers(); gBattleMainFunc = WaitForEvoSceneToFinish; - EvolutionScene(&gPlayerParty[i], species, evoModeNormal, i); + GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_ONLY, gLeveledUpInBattle, NULL, &canStopEvo, DO_EVO); + EvolutionScene(&gPlayerParty[i], species, canStopEvo, i); return; } } diff --git a/src/battle_message.c b/src/battle_message.c index a19924050d..206ac18904 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -3177,7 +3177,7 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst, u32 dstSize) dst[dstID] = *src; dstID++; - BreakStringAutomatic(dst, BATTLE_MSG_MAX_WIDTH, BATTLE_MSG_MAX_LINES, fontId); + BreakStringAutomatic(dst, BATTLE_MSG_MAX_WIDTH, BATTLE_MSG_MAX_LINES, fontId, TRUE); return dstID; } diff --git a/src/battle_pyramid.c b/src/battle_pyramid.c index 33f2717597..7d633e345d 100644 --- a/src/battle_pyramid.c +++ b/src/battle_pyramid.c @@ -1368,9 +1368,7 @@ static bool32 CheckBattlePyramidEvoRequirement(u16 species, const u16 *evoItems, for (j = 0; evolutions[j].method != EVOLUTIONS_END; j++) { if (evolutions[j].targetSpecies == species - && (evolutions[j].method == EVO_ITEM - || evolutions[j].method == EVO_ITEM_MALE - || evolutions[j].method == EVO_ITEM_FEMALE)) + && (evolutions[j].method == EVO_ITEM)) { if (nItems == 0) { diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index e56d0c4761..9f3332f576 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -341,7 +341,7 @@ static void RemoveAllWeather(void); static void RemoveAllTerrains(void); static bool32 CanAbilityPreventStatLoss(u32 abilityDef); static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent); -static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount, u16 usedMove); +static void TryUpdateEvolutionTracker(u32 evolutionCondition, u32 upAmount, u16 usedMove); static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u8 *failInstr, u16 move); static void ResetValuesForCalledMove(void); static void TryRestoreDamageAfterCheeckPouch(u32 battler); @@ -2082,7 +2082,7 @@ static void Cmd_critcalc(void) gSpecialStatuses[battlerDef].criticalHit = RandomChance(RNG_CRITICAL_HIT, 1, GetCriticalHitOdds(gBattleStruct->critChance[battlerDef])); } - // Counter for EVO_CRITICAL_HITS. + // Counter for IF_CRITICAL_HITS_GE evolution condition. if (gSpecialStatuses[battlerDef].criticalHit && GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER && !(gBattleTypeFlags & BATTLE_TYPE_MULTI && GetBattlerPosition(gBattlerAttacker) == B_POSITION_PLAYER_LEFT)) gPartyCriticalHits[partySlot]++; @@ -7590,7 +7590,7 @@ static void Cmd_moveend(void) // If the Pokémon needs to keep track of move usage for its evolutions, do it if (originallyUsedMove != MOVE_NONE) - TryUpdateEvolutionTracker(EVO_USE_MOVE_TWENTY_TIMES, 1, originallyUsedMove); + TryUpdateEvolutionTracker(IF_USED_MOVE_X_TIMES, 1, originallyUsedMove); if (B_RAMPAGE_CANCELLING >= GEN_5 && MoveHasAdditionalEffectSelf(gCurrentMove, MOVE_EFFECT_THRASH) // If we're rampaging @@ -17963,9 +17963,9 @@ void BS_RunStatChangeItems(void) ItemBattleEffects(ITEMEFFECT_STATS_CHANGED, GetBattlerForBattleScript(cmd->battler), FALSE); } -static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount, u16 usedMove) +static void TryUpdateEvolutionTracker(u32 evolutionCondition, u32 upAmount, u16 usedMove) { - u32 i; + u32 i, j; if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER && !(gBattleTypeFlags & (BATTLE_TYPE_LINK @@ -17982,31 +17982,35 @@ static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount, u16 use { if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) continue; + if (evolutions[i].params == NULL) + continue; - if (evolutions[i].method == evolutionMethod) + for (j = 0; evolutions[i].params[j].condition != CONDITIONS_END; j++) { - // We only have 10 bits to use - u16 val = min(1023, GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_EVOLUTION_TRACKER) + upAmount); - // Reset progress if you faint for the recoil method. - switch (evolutionMethod) + if (evolutions[i].params[j].condition == evolutionCondition) { - case EVO_USE_MOVE_TWENTY_TIMES: - if (evolutions[i].param == usedMove) + // We only have 10 bits to use + u16 val = min(1023, GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_EVOLUTION_TRACKER) + upAmount); + // Reset progress if you faint for the recoil method. + switch (evolutionCondition) + { + case IF_USED_MOVE_X_TIMES: + if (evolutions[i].params[j].arg1 == usedMove) + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_EVOLUTION_TRACKER, &val); + break; + case IF_RECOIL_DAMAGE_GE: + if (gBattleMons[gBattlerAttacker].hp == 0) + val = 0; SetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_EVOLUTION_TRACKER, &val); - break; - case EVO_RECOIL_DAMAGE_MALE: - case EVO_RECOIL_DAMAGE_FEMALE: - if (gBattleMons[gBattlerAttacker].hp == 0) - val = 0; - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_EVOLUTION_TRACKER, &val); - break; - case EVO_DEFEAT_THREE_WITH_ITEM: - if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_SPECIES) == GetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_SPECIES) - && GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_HELD_ITEM) == evolutions[i].param) - SetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_EVOLUTION_TRACKER, &val); - break; + break; + case IF_DEFEAT_X_WITH_ITEMS: + if (GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_SPECIES) == evolutions[i].params[j].arg1 + && GetMonData(&gEnemyParty[gBattlerPartyIndexes[gBattlerTarget]], MON_DATA_HELD_ITEM) == evolutions[i].params[j].arg2) + SetMonData(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]], MON_DATA_EVOLUTION_TRACKER, &val); + break; + } + return; } - return; } } } @@ -18015,25 +18019,14 @@ static void TryUpdateEvolutionTracker(u32 evolutionMethod, u32 upAmount, u16 use void BS_TryUpdateRecoilTracker(void) { NATIVE_ARGS(); - u8 gender = GetMonGender(&gPlayerParty[gBattlerPartyIndexes[gBattlerAttacker]]); - - switch(gender) - { - case MON_MALE: - TryUpdateEvolutionTracker(EVO_RECOIL_DAMAGE_MALE, gBattleStruct->moveDamage[gBattlerAttacker], MOVE_NONE); - break; - case MON_FEMALE: - TryUpdateEvolutionTracker(EVO_RECOIL_DAMAGE_FEMALE, gBattleStruct->moveDamage[gBattlerAttacker], MOVE_NONE); - break; - } - + TryUpdateEvolutionTracker(IF_RECOIL_DAMAGE_GE, gBattleStruct->moveDamage[gBattlerAttacker], MOVE_NONE); gBattlescriptCurrInstr = cmd->nextInstr; } void BS_TryUpdateLeadersCrestTracker(void) { NATIVE_ARGS(); - TryUpdateEvolutionTracker(EVO_DEFEAT_THREE_WITH_ITEM, 1, MOVE_NONE); + TryUpdateEvolutionTracker(IF_DEFEAT_X_WITH_ITEMS, 1, MOVE_NONE); gBattlescriptCurrInstr = cmd->nextInstr; } diff --git a/src/data/pokemon/species_info.h b/src/data/pokemon/species_info.h index 7bd9e9f1f9..0cd1d5b1ac 100644 --- a/src/data/pokemon/species_info.h +++ b/src/data/pokemon/species_info.h @@ -5,6 +5,7 @@ // Macros for ease of use. #define EVOLUTION(...) (const struct Evolution[]) { __VA_ARGS__, { EVOLUTIONS_END }, } +#define CONDITIONS(...) ((const struct EvolutionParam[]) { __VA_ARGS__, {CONDITIONS_END} }) #define ANIM_FRAMES(...) (const union AnimCmd *const[]) { sAnim_GeneralFrame0, (const union AnimCmd[]) { __VA_ARGS__ ANIMCMD_END, }, } diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h index 0bde1f347a..70165414ba 100644 --- a/src/data/pokemon/species_info/gen_1_families.h +++ b/src/data/pokemon/species_info/gen_1_families.h @@ -2288,7 +2288,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .teachableLearnset = sRattataAlolaTeachableLearnset, .eggMoveLearnset = sRattataAlolaEggMoveLearnset, .formSpeciesIdTable = sRattataFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL_NIGHT, 20, SPECIES_RATICATE_ALOLA}, + .evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_RATICATE_ALOLA, CONDITIONS({IF_TIME, TIME_NIGHT})}, {EVO_NONE, 0, SPECIES_RATICATE_ALOLA_TOTEM}), }, @@ -2784,7 +2784,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .teachableLearnset = sPichuTeachableLearnset, .eggMoveLearnset = sPichuEggMoveLearnset, .formSpeciesIdTable = sPichuFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_PIKACHU}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_PIKACHU, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, [SPECIES_PICHU_SPIKY_EARED] = @@ -4844,7 +4844,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sCleffaLevelUpLearnset, .teachableLearnset = sCleffaTeachableLearnset, .eggMoveLearnset = sCleffaEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_CLEFAIRY}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_CLEFAIRY, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, #endif //P_GEN_2_CROSS_EVOS @@ -5369,7 +5369,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sIgglybuffLevelUpLearnset, .teachableLearnset = sIgglybuffTeachableLearnset, .eggMoveLearnset = sIgglybuffEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_JIGGLYPUFF}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_JIGGLYPUFF, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, #endif //P_GEN_2_CROSS_EVOS @@ -5730,7 +5730,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sGolbatLevelUpLearnset, .teachableLearnset = sGolbatTeachableLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_CROBAT}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_CROBAT, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, #if P_GEN_2_CROSS_EVOS @@ -7021,7 +7021,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .teachableLearnset = sMeowthAlolaTeachableLearnset, .eggMoveLearnset = sMeowthAlolaEggMoveLearnset, .formSpeciesIdTable = sMeowthFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_PERSIAN_ALOLA}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_PERSIAN_ALOLA, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, [SPECIES_PERSIAN_ALOLA] = @@ -7577,7 +7577,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sPrimeapeLevelUpLearnset, .teachableLearnset = sPrimeapeTeachableLearnset, - .evolutions = EVOLUTION({EVO_USE_MOVE_TWENTY_TIMES, MOVE_RAGE_FIST, SPECIES_ANNIHILAPE}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_ANNIHILAPE, CONDITIONS({IF_USED_MOVE_X_TIMES, MOVE_RAGE_FIST, 20})}), }, #if P_GEN_9_CROSS_EVOS @@ -8065,7 +8065,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sPoliwhirlLevelUpLearnset, .teachableLearnset = sPoliwhirlTeachableLearnset, .evolutions = EVOLUTION({EVO_ITEM, ITEM_WATER_STONE, SPECIES_POLIWRATH}, - {EVO_TRADE_ITEM, ITEM_KINGS_ROCK, SPECIES_POLITOED}, + {EVO_TRADE, 0, SPECIES_POLITOED, CONDITIONS({IF_HOLD_ITEM, ITEM_KINGS_ROCK})}, {EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_POLITOED}), }, @@ -10046,7 +10046,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .eggMoveLearnset = sSlowpokeEggMoveLearnset, .formSpeciesIdTable = sSlowpokeFormSpeciesIdTable, .evolutions = EVOLUTION({EVO_LEVEL, 37, SPECIES_SLOWBRO}, - {EVO_TRADE_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING}, + {EVO_TRADE, 0, SPECIES_SLOWKING, CONDITIONS({IF_HOLD_ITEM, ITEM_KINGS_ROCK})}, {EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING}), }, @@ -10609,7 +10609,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sMagnetonLevelUpLearnset, .teachableLearnset = sMagnetonTeachableLearnset, - .evolutions = EVOLUTION({EVO_MAPSEC, MAPSEC_NEW_MAUVILLE, SPECIES_MAGNEZONE}, + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MAGNEZONE, CONDITIONS({IF_IN_MAPSEC, MAPSEC_NEW_MAUVILLE})}, {EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_MAGNEZONE}), }, @@ -10849,7 +10849,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .teachableLearnset = sFarfetchdGalarTeachableLearnset, .eggMoveLearnset = sFarfetchdGalarEggMoveLearnset, .formSpeciesIdTable = sFarfetchdFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_CRITICAL_HITS, 3, SPECIES_SIRFETCHD}), + .evolutions = EVOLUTION({EVO_BATTLE_END, 0, SPECIES_SIRFETCHD, CONDITIONS({IF_CRITICAL_HITS_GE, 3})}), }, [SPECIES_SIRFETCHD] = @@ -12107,7 +12107,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sOnixLevelUpLearnset, .teachableLearnset = sOnixTeachableLearnset, .eggMoveLearnset = sOnixEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_METAL_COAT, SPECIES_STEELIX}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_STEELIX, CONDITIONS({IF_HOLD_ITEM, ITEM_METAL_COAT})}, {EVO_ITEM, ITEM_METAL_COAT, SPECIES_STEELIX}), }, @@ -13506,9 +13506,9 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sTyrogueLevelUpLearnset, .teachableLearnset = sTyrogueTeachableLearnset, .eggMoveLearnset = sTyrogueEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_ATK_LT_DEF, 20, SPECIES_HITMONCHAN}, - {EVO_LEVEL_ATK_GT_DEF, 20, SPECIES_HITMONLEE}, - {EVO_LEVEL_ATK_EQ_DEF, 20, SPECIES_HITMONTOP}), + .evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_HITMONCHAN, CONDITIONS({IF_ATK_LT_DEF})}, + {EVO_LEVEL, 20, SPECIES_HITMONLEE, CONDITIONS({IF_ATK_GT_DEF})}, + {EVO_LEVEL, 20, SPECIES_HITMONTOP, CONDITIONS({IF_ATK_EQ_DEF})}), }, #endif //P_GEN_2_CROSS_EVOS @@ -13805,7 +13805,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sLickitungLevelUpLearnset, .teachableLearnset = sLickitungTeachableLearnset, .eggMoveLearnset = sLickitungEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_ROLLOUT, SPECIES_LICKILICKY}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_LICKILICKY, CONDITIONS({IF_KNOWS_MOVE, MOVE_ROLLOUT})}), }, #if P_GEN_4_CROSS_EVOS @@ -14274,7 +14274,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sRhydonLevelUpLearnset, .teachableLearnset = sRhydonTeachableLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_PROTECTOR, SPECIES_RHYPERIOR}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_RHYPERIOR, CONDITIONS({IF_HOLD_ITEM, ITEM_PROTECTOR})}, {EVO_ITEM, ITEM_PROTECTOR, SPECIES_RHYPERIOR}), }, @@ -14438,8 +14438,8 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sHappinyLevelUpLearnset, .teachableLearnset = sHappinyTeachableLearnset, .eggMoveLearnset = sHappinyEggMoveLearnset, - .evolutions = EVOLUTION({EVO_ITEM_HOLD_DAY, ITEM_OVAL_STONE, SPECIES_CHANSEY}, - {EVO_ITEM_DAY, ITEM_OVAL_STONE, SPECIES_CHANSEY}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_CHANSEY, CONDITIONS({IF_NOT_TIME, TIME_NIGHT},{IF_HOLD_ITEM, ITEM_OVAL_STONE})}, + {EVO_ITEM, ITEM_OVAL_STONE, SPECIES_CHANSEY, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}), }, #endif //P_GEN_4_CROSS_EVOS @@ -14510,7 +14510,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sChanseyLevelUpLearnset, .teachableLearnset = sChanseyTeachableLearnset, .eggMoveLearnset = sChanseyEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_BLISSEY}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_BLISSEY, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, #if P_GEN_2_CROSS_EVOS @@ -14655,7 +14655,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sTangelaLevelUpLearnset, .teachableLearnset = sTangelaTeachableLearnset, .eggMoveLearnset = sTangelaEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_ANCIENT_POWER, SPECIES_TANGROWTH}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_TANGROWTH, CONDITIONS({IF_KNOWS_MOVE, MOVE_ANCIENT_POWER})}), }, #if P_GEN_4_CROSS_EVOS @@ -15037,7 +15037,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sSeadraLevelUpLearnset, .teachableLearnset = sSeadraTeachableLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_DRAGON_SCALE, SPECIES_KINGDRA}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_KINGDRA, CONDITIONS({IF_HOLD_ITEM, ITEM_DRAGON_SCALE})}, {EVO_ITEM, ITEM_DRAGON_SCALE, SPECIES_KINGDRA}), }, @@ -15525,7 +15525,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sMimeJrLevelUpLearnset, .teachableLearnset = sMimeJrTeachableLearnset, .eggMoveLearnset = sMimeJrEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_MIMIC, SPECIES_MR_MIME}, + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MR_MIME, CONDITIONS({IF_KNOWS_MOVE, MOVE_MIMIC})}, {EVO_NONE, 0, SPECIES_MR_MIME_GALAR}), }, #endif //P_GEN_4_CROSS_EVOS @@ -15826,7 +15826,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sScytherLevelUpLearnset, .teachableLearnset = sScytherTeachableLearnset, .eggMoveLearnset = sScytherEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_METAL_COAT, SPECIES_SCIZOR}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_SCIZOR, CONDITIONS({IF_HOLD_ITEM, ITEM_METAL_COAT})}, {EVO_ITEM, ITEM_BLACK_AUGURITE, SPECIES_KLEAVOR}, {EVO_ITEM, ITEM_METAL_COAT, SPECIES_SCIZOR}), }, @@ -16346,7 +16346,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sElectabuzzLevelUpLearnset, .teachableLearnset = sElectabuzzTeachableLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_ELECTIRIZER, SPECIES_ELECTIVIRE}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_ELECTIVIRE, CONDITIONS({IF_HOLD_ITEM, ITEM_ELECTIRIZER})}, {EVO_ITEM, ITEM_ELECTIRIZER, SPECIES_ELECTIVIRE}), }, @@ -16567,7 +16567,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sMagmarLevelUpLearnset, .teachableLearnset = sMagmarTeachableLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_MAGMARIZER, SPECIES_MAGMORTAR}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_MAGMORTAR, CONDITIONS({IF_HOLD_ITEM, ITEM_MAGMARIZER})}, {EVO_ITEM, ITEM_MAGMARIZER, SPECIES_MAGMORTAR}), }, @@ -17610,13 +17610,13 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .evolutions = EVOLUTION({EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_JOLTEON}, {EVO_ITEM, ITEM_WATER_STONE, SPECIES_VAPOREON}, {EVO_ITEM, ITEM_FIRE_STONE, SPECIES_FLAREON}, - {EVO_FRIENDSHIP_DAY, 0, SPECIES_ESPEON}, - {EVO_FRIENDSHIP_NIGHT, 0, SPECIES_UMBREON}, - {EVO_SPECIFIC_MAP, MAP_PETALBURG_WOODS, SPECIES_LEAFEON}, + {EVO_LEVEL, 0, SPECIES_SYLVEON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_KNOWS_MOVE_TYPE, TYPE_FAIRY})}, + {EVO_LEVEL, 0, SPECIES_ESPEON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_NOT_TIME, TIME_NIGHT})}, + {EVO_LEVEL, 0, SPECIES_UMBREON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_TIME, TIME_NIGHT})}, + {EVO_LEVEL, 0, SPECIES_LEAFEON, CONDITIONS({IF_IN_MAP, MAP_PETALBURG_WOODS})}, {EVO_ITEM, ITEM_LEAF_STONE, SPECIES_LEAFEON}, - {EVO_SPECIFIC_MAP, MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM, SPECIES_GLACEON}, - {EVO_ITEM, ITEM_ICE_STONE, SPECIES_GLACEON}, - {EVO_FRIENDSHIP_MOVE_TYPE, TYPE_FAIRY, SPECIES_SYLVEON}), + {EVO_LEVEL, 0, SPECIES_GLACEON, CONDITIONS({IF_IN_MAP, MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM})}, + {EVO_ITEM, ITEM_ICE_STONE, SPECIES_GLACEON}), }, #if P_GIGANTAMAX_FORMS @@ -18366,7 +18366,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sPorygonLevelUpLearnset, .teachableLearnset = sPorygonTeachableLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_UPGRADE, SPECIES_PORYGON2}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_PORYGON2, CONDITIONS({IF_HOLD_ITEM, ITEM_UPGRADE})}, {EVO_ITEM, ITEM_UPGRADE, SPECIES_PORYGON2}), }, @@ -18443,7 +18443,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sPorygon2LevelUpLearnset, .teachableLearnset = sPorygon2TeachableLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_DUBIOUS_DISC, SPECIES_PORYGON_Z}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_PORYGON_Z, CONDITIONS({IF_HOLD_ITEM, ITEM_DUBIOUS_DISC})}, {EVO_ITEM, ITEM_DUBIOUS_DISC, SPECIES_PORYGON_Z}), }, @@ -19047,7 +19047,7 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sMunchlaxLevelUpLearnset, .teachableLearnset = sMunchlaxTeachableLearnset, .eggMoveLearnset = sMunchlaxEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_SNORLAX}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_SNORLAX, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, #endif //P_GEN_4_CROSS_EVOS diff --git a/src/data/pokemon/species_info/gen_2_families.h b/src/data/pokemon/species_info/gen_2_families.h index 23a76e189d..c8143d02f0 100644 --- a/src/data/pokemon/species_info/gen_2_families.h +++ b/src/data/pokemon/species_info/gen_2_families.h @@ -1551,7 +1551,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sTogepiLevelUpLearnset, .teachableLearnset = sTogepiTeachableLearnset, .eggMoveLearnset = sTogepiEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_TOGETIC}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_TOGETIC, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, [SPECIES_TOGETIC] = @@ -2233,7 +2233,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sAzurillLevelUpLearnset, .teachableLearnset = sAzurillTeachableLearnset, .eggMoveLearnset = sAzurillEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_MARILL}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MARILL, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, #endif //P_GEN_3_CROSS_EVOS @@ -2462,7 +2462,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sBonslyLevelUpLearnset, .teachableLearnset = sBonslyTeachableLearnset, .eggMoveLearnset = sBonslyEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_MIMIC, SPECIES_SUDOWOODO}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_SUDOWOODO, CONDITIONS({IF_KNOWS_MOVE, MOVE_MIMIC})}), }, #endif //P_GEN_4_CROSS_EVOS @@ -2868,7 +2868,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sAipomLevelUpLearnset, .teachableLearnset = sAipomTeachableLearnset, .eggMoveLearnset = sAipomEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_DOUBLE_HIT, SPECIES_AMBIPOM}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_AMBIPOM, CONDITIONS({IF_KNOWS_MOVE, MOVE_DOUBLE_HIT})}), }, #if P_GEN_4_CROSS_EVOS @@ -3191,7 +3191,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sYanmaLevelUpLearnset, .teachableLearnset = sYanmaTeachableLearnset, .eggMoveLearnset = sYanmaEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_ANCIENT_POWER, SPECIES_YANMEGA}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_YANMEGA, CONDITIONS({IF_KNOWS_MOVE, MOVE_ANCIENT_POWER})}), }, #if P_GEN_4_CROSS_EVOS @@ -4239,7 +4239,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sGirafarigLevelUpLearnset, .teachableLearnset = sGirafarigTeachableLearnset, .eggMoveLearnset = sGirafarigEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_TWIN_BEAM, SPECIES_FARIGIRAF}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_FARIGIRAF, CONDITIONS({IF_KNOWS_MOVE, MOVE_TWIN_BEAM})}), }, #if P_GEN_9_CROSS_EVOS @@ -4527,8 +4527,8 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sDunsparceLevelUpLearnset, .teachableLearnset = sDunsparceTeachableLearnset, .eggMoveLearnset = sDunsparceEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE_TWO_SEGMENT, MOVE_HYPER_DRILL, SPECIES_DUDUNSPARCE_TWO_SEGMENT}, - {EVO_MOVE_THREE_SEGMENT, MOVE_HYPER_DRILL, SPECIES_DUDUNSPARCE_THREE_SEGMENT}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_DUDUNSPARCE_TWO_SEGMENT, CONDITIONS({IF_KNOWS_MOVE, MOVE_HYPER_DRILL}, {IF_PID_MODULO_100_GT, 0})}, + {EVO_LEVEL, 0, SPECIES_DUDUNSPARCE_THREE_SEGMENT, CONDITIONS({IF_KNOWS_MOVE, MOVE_HYPER_DRILL}, {IF_PID_MODULO_100_EQ, 0})}), }, #if P_GEN_9_CROSS_EVOS @@ -4742,8 +4742,8 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sGligarLevelUpLearnset, .teachableLearnset = sGligarTeachableLearnset, .eggMoveLearnset = sGligarEggMoveLearnset, - .evolutions = EVOLUTION({EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_FANG, SPECIES_GLISCOR}, - {EVO_ITEM_NIGHT, ITEM_RAZOR_FANG, SPECIES_GLISCOR}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_GLISCOR, CONDITIONS({IF_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_FANG})}, + {EVO_ITEM, ITEM_RAZOR_FANG, SPECIES_GLISCOR, CONDITIONS({IF_TIME, TIME_NIGHT})}), }, #if P_GEN_4_CROSS_EVOS @@ -5117,7 +5117,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sQwilfishHisuiLevelUpLearnset, .teachableLearnset = sQwilfishHisuiTeachableLearnset, .formSpeciesIdTable = sQwilfishFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_BARB_BARRAGE, SPECIES_OVERQWIL}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_OVERQWIL, CONDITIONS({IF_KNOWS_MOVE, MOVE_BARB_BARRAGE})}), }, [SPECIES_OVERQWIL] = @@ -5506,8 +5506,8 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .teachableLearnset = sSneaselTeachableLearnset, .eggMoveLearnset = sSneaselEggMoveLearnset, .formSpeciesIdTable = sSneaselFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_ITEM_HOLD_NIGHT, ITEM_RAZOR_CLAW, SPECIES_WEAVILE}, - {EVO_ITEM_NIGHT, ITEM_RAZOR_CLAW, SPECIES_WEAVILE}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_WEAVILE, CONDITIONS({IF_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_CLAW})}, + {EVO_ITEM, ITEM_RAZOR_CLAW, SPECIES_WEAVILE, CONDITIONS({IF_TIME, TIME_NIGHT})}), }, #if P_GEN_4_CROSS_EVOS @@ -5672,8 +5672,8 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sSneaselHisuiLevelUpLearnset, .teachableLearnset = sSneaselHisuiTeachableLearnset, .formSpeciesIdTable = sSneaselFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_ITEM_HOLD_DAY, ITEM_RAZOR_CLAW, SPECIES_SNEASLER}, - {EVO_ITEM_DAY, ITEM_RAZOR_CLAW, SPECIES_SNEASLER}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_SNEASLER, CONDITIONS({IF_NOT_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_CLAW})}, + {EVO_ITEM, ITEM_RAZOR_CLAW, SPECIES_SNEASLER, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}), }, [SPECIES_SNEASLER] = @@ -5897,7 +5897,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = ) .levelUpLearnset = sUrsaringLevelUpLearnset, .teachableLearnset = sUrsaringTeachableLearnset, - .evolutions = EVOLUTION({EVO_ITEM_NIGHT, ITEM_PEAT_BLOCK, SPECIES_URSALUNA}, + .evolutions = EVOLUTION({EVO_ITEM, ITEM_PEAT_BLOCK, SPECIES_URSALUNA, CONDITIONS({IF_TIME, TIME_NIGHT})}, {EVO_NONE, 0, SPECIES_URSALUNA_BLOODMOON}), }, @@ -6330,7 +6330,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = ) .levelUpLearnset = sPiloswineLevelUpLearnset, .teachableLearnset = sPiloswineTeachableLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_ANCIENT_POWER, SPECIES_MAMOSWINE}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MAMOSWINE, CONDITIONS({IF_KNOWS_MOVE, MOVE_ANCIENT_POWER})}), }, #if P_GEN_4_CROSS_EVOS @@ -6937,7 +6937,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sMantykeLevelUpLearnset, .teachableLearnset = sMantykeTeachableLearnset, .eggMoveLearnset = sMantykeEggMoveLearnset, - .evolutions = EVOLUTION({EVO_SPECIFIC_MON_IN_PARTY, SPECIES_REMORAID, SPECIES_MANTINE}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MANTINE, CONDITIONS({IF_SPECIES_IN_PARTY, SPECIES_REMORAID})}), }, #endif //P_GEN_4_CROSS_EVOS @@ -7534,7 +7534,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sStantlerLevelUpLearnset, .teachableLearnset = sStantlerTeachableLearnset, .eggMoveLearnset = sStantlerEggMoveLearnset, - .evolutions = EVOLUTION({EVO_USE_MOVE_TWENTY_TIMES, MOVE_PSYSHIELD_BASH, SPECIES_WYRDEER}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_WYRDEER, CONDITIONS({IF_USED_MOVE_X_TIMES, MOVE_PSYSHIELD_BASH, 20})}), }, #if P_GEN_8_CROSS_EVOS diff --git a/src/data/pokemon/species_info/gen_3_families.h b/src/data/pokemon/species_info/gen_3_families.h index 489de091df..272c57668e 100644 --- a/src/data/pokemon/species_info/gen_3_families.h +++ b/src/data/pokemon/species_info/gen_3_families.h @@ -1361,7 +1361,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sLinooneGalarLevelUpLearnset, .teachableLearnset = sLinooneGalarTeachableLearnset, .formSpeciesIdTable = sLinooneFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL_NIGHT, 35, SPECIES_OBSTAGOON}), + .evolutions = EVOLUTION({EVO_LEVEL, 35, SPECIES_OBSTAGOON, CONDITIONS({IF_TIME, TIME_NIGHT})}), }, [SPECIES_OBSTAGOON] = @@ -1504,8 +1504,8 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .tmIlliterate = TRUE, .levelUpLearnset = sWurmpleLevelUpLearnset, .teachableLearnset = sWurmpleTeachableLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_SILCOON, 7, SPECIES_SILCOON}, - {EVO_LEVEL_CASCOON, 7, SPECIES_CASCOON}), + .evolutions = EVOLUTION({EVO_LEVEL, 7, SPECIES_SILCOON, CONDITIONS({IF_PID_UPPER_MODULO_10_GT, 4})}, + {EVO_LEVEL, 7, SPECIES_CASCOON, CONDITIONS({IF_PID_UPPER_MODULO_10_LT, 5})}), }, [SPECIES_SILCOON] = @@ -2802,7 +2802,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sKirliaLevelUpLearnset, .teachableLearnset = sKirliaTeachableLearnset, .evolutions = EVOLUTION({EVO_LEVEL, 30, SPECIES_GARDEVOIR}, - {EVO_ITEM_MALE, ITEM_DAWN_STONE, SPECIES_GALLADE}), + {EVO_ITEM, ITEM_DAWN_STONE, SPECIES_GALLADE, CONDITIONS({IF_GENDER, MON_MALE})}), }, [SPECIES_GARDEVOIR] = @@ -3710,8 +3710,12 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sNincadaLevelUpLearnset, .teachableLearnset = sNincadaTeachableLearnset, .eggMoveLearnset = sNincadaEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_NINJASK, 20, SPECIES_NINJASK}, - {EVO_LEVEL_SHEDINJA, 20, SPECIES_SHEDINJA}), + .evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_NINJASK}, + #if P_SHEDINJA_BALL >= GEN_4 + {EVO_SPLIT_FROM_EVO, SPECIES_NINJASK, SPECIES_SHEDINJA, CONDITIONS({IF_BAG_ITEM_COUNT, ITEM_POKE_BALL, 1})}), + #else + {EVO_SPLIT_FROM_EVO, SPECIES_NINJASK, SPECIES_SHEDINJA}), + #endif }, [SPECIES_NINJASK] = @@ -4310,7 +4314,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sNosepassLevelUpLearnset, .teachableLearnset = sNosepassTeachableLearnset, .eggMoveLearnset = sNosepassEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MAPSEC, MAPSEC_NEW_MAUVILLE, SPECIES_PROBOPASS}, + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_PROBOPASS, CONDITIONS({IF_IN_MAPSEC, MAPSEC_NEW_MAUVILLE})}, {EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_PROBOPASS}), }, @@ -5980,7 +5984,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sBudewLevelUpLearnset, .teachableLearnset = sBudewTeachableLearnset, .eggMoveLearnset = sBudewEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP_DAY, 0, SPECIES_ROSELIA}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_ROSELIA, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD},{IF_NOT_TIME, TIME_NIGHT})}), }, #endif //P_GEN_4_CROSS_EVOS @@ -9036,8 +9040,8 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sFeebasLevelUpLearnset, .teachableLearnset = sFeebasTeachableLearnset, .eggMoveLearnset = sFeebasEggMoveLearnset, - .evolutions = EVOLUTION({EVO_BEAUTY, 170, SPECIES_MILOTIC}, - {EVO_TRADE_ITEM, ITEM_PRISM_SCALE, SPECIES_MILOTIC}, + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MILOTIC, CONDITIONS({IF_MIN_BEAUTY, 170})}, + {EVO_TRADE, 0, SPECIES_MILOTIC, CONDITIONS({IF_HOLD_ITEM, ITEM_PRISM_SCALE})}, {EVO_ITEM, ITEM_PRISM_SCALE, SPECIES_MILOTIC}), }, @@ -9896,7 +9900,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = ) .levelUpLearnset = sDusclopsLevelUpLearnset, .teachableLearnset = sDusclopsTeachableLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_REAPER_CLOTH, SPECIES_DUSKNOIR}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_DUSKNOIR, CONDITIONS({IF_HOLD_ITEM, ITEM_REAPER_CLOTH})}, {EVO_ITEM, ITEM_REAPER_CLOTH, SPECIES_DUSKNOIR}), }, @@ -10140,7 +10144,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sChinglingLevelUpLearnset, .teachableLearnset = sChinglingTeachableLearnset, .eggMoveLearnset = sChinglingEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP_NIGHT, 0, SPECIES_CHIMECHO}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_CHIMECHO, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD},{IF_TIME, TIME_NIGHT})}), }, #endif //P_GEN_4_CROSS_EVOS @@ -10456,7 +10460,7 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .teachableLearnset = sSnoruntTeachableLearnset, .eggMoveLearnset = sSnoruntEggMoveLearnset, .evolutions = EVOLUTION({EVO_LEVEL, 42, SPECIES_GLALIE}, - {EVO_ITEM_FEMALE, ITEM_DAWN_STONE, SPECIES_FROSLASS}), + {EVO_ITEM, ITEM_DAWN_STONE, SPECIES_FROSLASS, CONDITIONS({IF_GENDER, MON_FEMALE})}), }, [SPECIES_GLALIE] = @@ -10981,8 +10985,8 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sClamperlLevelUpLearnset, .teachableLearnset = sClamperlTeachableLearnset, .eggMoveLearnset = sClamperlEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_DEEP_SEA_TOOTH, SPECIES_HUNTAIL}, - {EVO_TRADE_ITEM, ITEM_DEEP_SEA_SCALE, SPECIES_GOREBYSS}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_HUNTAIL, CONDITIONS({IF_HOLD_ITEM, ITEM_DEEP_SEA_TOOTH})}, + {EVO_TRADE, 0, SPECIES_GOREBYSS, CONDITIONS({IF_HOLD_ITEM, ITEM_DEEP_SEA_SCALE})}, {EVO_ITEM, ITEM_DEEP_SEA_TOOTH, SPECIES_HUNTAIL}, {EVO_ITEM, ITEM_DEEP_SEA_SCALE, SPECIES_GOREBYSS}), }, diff --git a/src/data/pokemon/species_info/gen_4_families.h b/src/data/pokemon/species_info/gen_4_families.h index a7f15ffc9e..84edb98987 100644 --- a/src/data/pokemon/species_info/gen_4_families.h +++ b/src/data/pokemon/species_info/gen_4_families.h @@ -1870,8 +1870,8 @@ const struct SpeciesInfo gSpeciesInfoGen4[] = .teachableLearnset = sBurmyTeachableLearnset, .formSpeciesIdTable = sBurmyFormSpeciesIdTable, .formChangeTable = sBurmyFormChangeTable, - .evolutions = EVOLUTION({EVO_LEVEL_FEMALE, 20, SPECIES_WORMADAM_PLANT}, - {EVO_LEVEL_MALE, 20, SPECIES_MOTHIM_PLANT}), + .evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_WORMADAM_PLANT, CONDITIONS({IF_GENDER, MON_FEMALE})}, + {EVO_LEVEL, 20, SPECIES_MOTHIM_PLANT, CONDITIONS({IF_GENDER, MON_MALE})}), }, [SPECIES_BURMY_SANDY] = @@ -1939,8 +1939,8 @@ const struct SpeciesInfo gSpeciesInfoGen4[] = .teachableLearnset = sBurmyTeachableLearnset, .formSpeciesIdTable = sBurmyFormSpeciesIdTable, .formChangeTable = sBurmyFormChangeTable, - .evolutions = EVOLUTION({EVO_LEVEL_FEMALE, 20, SPECIES_WORMADAM_SANDY}, - {EVO_LEVEL_MALE, 20, SPECIES_MOTHIM_SANDY}), + .evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_WORMADAM_SANDY, CONDITIONS({IF_GENDER, MON_FEMALE})}, + {EVO_LEVEL, 20, SPECIES_MOTHIM_SANDY, CONDITIONS({IF_GENDER, MON_MALE})}), }, [SPECIES_BURMY_TRASH] = @@ -2008,8 +2008,8 @@ const struct SpeciesInfo gSpeciesInfoGen4[] = .teachableLearnset = sBurmyTeachableLearnset, .formSpeciesIdTable = sBurmyFormSpeciesIdTable, .formChangeTable = sBurmyFormChangeTable, - .evolutions = EVOLUTION({EVO_LEVEL_FEMALE, 20, SPECIES_WORMADAM_TRASH}, - {EVO_LEVEL_MALE, 20, SPECIES_MOTHIM_TRASH}), + .evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_WORMADAM_TRASH, CONDITIONS({IF_GENDER, MON_FEMALE})}, + {EVO_LEVEL, 20, SPECIES_MOTHIM_TRASH, CONDITIONS({IF_GENDER, MON_MALE})}), }, [SPECIES_WORMADAM_PLANT] = @@ -2363,7 +2363,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] = .tmIlliterate = TRUE, .levelUpLearnset = sCombeeLevelUpLearnset, .teachableLearnset = sCombeeTeachableLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_FEMALE, 21, SPECIES_VESPIQUEN}), + .evolutions = EVOLUTION({EVO_LEVEL, 21, SPECIES_VESPIQUEN, CONDITIONS({IF_GENDER, MON_FEMALE})}), }, [SPECIES_VESPIQUEN] = @@ -3379,7 +3379,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] = .levelUpLearnset = sBunearyLevelUpLearnset, .teachableLearnset = sBunearyTeachableLearnset, .eggMoveLearnset = sBunearyEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_LOPUNNY}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_LOPUNNY, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, [SPECIES_LOPUNNY] = @@ -4500,7 +4500,7 @@ const struct SpeciesInfo gSpeciesInfoGen4[] = .levelUpLearnset = sRioluLevelUpLearnset, .teachableLearnset = sRioluTeachableLearnset, .eggMoveLearnset = sRioluEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP_DAY, 0, SPECIES_LUCARIO}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_LUCARIO, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD},{IF_NOT_TIME, TIME_NIGHT})}), }, [SPECIES_LUCARIO] = diff --git a/src/data/pokemon/species_info/gen_5_families.h b/src/data/pokemon/species_info/gen_5_families.h index 58fab83247..bc9db5dffe 100644 --- a/src/data/pokemon/species_info/gen_5_families.h +++ b/src/data/pokemon/species_info/gen_5_families.h @@ -2551,7 +2551,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = .levelUpLearnset = sWoobatLevelUpLearnset, .teachableLearnset = sWoobatTeachableLearnset, .eggMoveLearnset = sWoobatEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_SWOOBAT}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_SWOOBAT, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, [SPECIES_SWOOBAT] = @@ -3624,7 +3624,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = ) .levelUpLearnset = sSwadloonLevelUpLearnset, .teachableLearnset = sSwadloonTeachableLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_LEAVANNY}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_LEAVANNY, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, [SPECIES_LEAVANNY] = @@ -4503,8 +4503,8 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = .levelUpLearnset = sBasculinWhiteStripedLevelUpLearnset, .teachableLearnset = sBasculinWhiteStripedTeachableLearnset, .formSpeciesIdTable = sBasculinFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_RECOIL_DAMAGE_MALE, 294, SPECIES_BASCULEGION_M}, - {EVO_RECOIL_DAMAGE_FEMALE, 294, SPECIES_BASCULEGION_F}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_BASCULEGION_M, CONDITIONS({IF_RECOIL_DAMAGE_GE, 294}, {IF_GENDER, MON_MALE})}, + {EVO_LEVEL, 0, SPECIES_BASCULEGION_F, CONDITIONS({IF_RECOIL_DAMAGE_GE, 294}, {IF_GENDER, MON_FEMALE})}), }, [SPECIES_BASCULEGION_M] = @@ -5896,7 +5896,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = .teachableLearnset = sYamaskGalarTeachableLearnset, .eggMoveLearnset = sYamaskGalarEggMoveLearnset, .formSpeciesIdTable = sYamaskFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_SCRIPT_TRIGGER_DMG, 49, SPECIES_RUNERIGUS}), + .evolutions = EVOLUTION({EVO_SCRIPT_TRIGGER, 0, SPECIES_RUNERIGUS, CONDITIONS({IF_CURRENT_DAMAGE_GE, 49})}), }, [SPECIES_RUNERIGUS] = @@ -8339,7 +8339,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = .levelUpLearnset = sKarrablastLevelUpLearnset, .teachableLearnset = sKarrablastTeachableLearnset, .eggMoveLearnset = sKarrablastEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE_SPECIFIC_MON, SPECIES_SHELMET, SPECIES_ESCAVALIER}), + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_ESCAVALIER, CONDITIONS({IF_TRADE_PARTNER_SPECIES, SPECIES_SHELMET})}), }, [SPECIES_ESCAVALIER] = @@ -10401,7 +10401,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = .levelUpLearnset = sShelmetLevelUpLearnset, .teachableLearnset = sShelmetTeachableLearnset, .eggMoveLearnset = sShelmetEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE_SPECIFIC_MON, SPECIES_KARRABLAST, SPECIES_ACCELGOR}), + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_ACCELGOR, CONDITIONS({IF_TRADE_PARTNER_SPECIES, SPECIES_KARRABLAST})}), }, [SPECIES_ACCELGOR] = @@ -11106,7 +11106,7 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = ) .levelUpLearnset = sBisharpLevelUpLearnset, .teachableLearnset = sBisharpTeachableLearnset, - .evolutions = EVOLUTION({EVO_DEFEAT_THREE_WITH_ITEM, ITEM_LEADERS_CREST, SPECIES_KINGAMBIT}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_KINGAMBIT, CONDITIONS({IF_DEFEAT_X_WITH_ITEMS, SPECIES_BISHARP, ITEM_LEADERS_CREST, 3})}), }, #if P_GEN_9_CROSS_EVOS diff --git a/src/data/pokemon/species_info/gen_6_families.h b/src/data/pokemon/species_info/gen_6_families.h index 5df5e2580f..9dfac96c80 100644 --- a/src/data/pokemon/species_info/gen_6_families.h +++ b/src/data/pokemon/species_info/gen_6_families.h @@ -2217,7 +2217,7 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sPanchamLevelUpLearnset, .teachableLearnset = sPanchamTeachableLearnset, .eggMoveLearnset = sPanchamEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_DARK_TYPE_MON_IN_PARTY, 32, SPECIES_PANGORO}), + .evolutions = EVOLUTION({EVO_LEVEL, 32, SPECIES_PANGORO, CONDITIONS({IF_TYPE_IN_PARTY, TYPE_DARK})}), }, [SPECIES_PANGORO] = @@ -2439,8 +2439,8 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sEspurrLevelUpLearnset, .teachableLearnset = sEspurrTeachableLearnset, .eggMoveLearnset = sEspurrEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_MALE, 25, SPECIES_MEOWSTIC_M}, - {EVO_LEVEL_FEMALE, 25, SPECIES_MEOWSTIC_F}), + .evolutions = EVOLUTION({EVO_LEVEL, 25, SPECIES_MEOWSTIC_M, CONDITIONS({IF_GENDER, MON_MALE})}, + {EVO_LEVEL, 25, SPECIES_MEOWSTIC_F, CONDITIONS({IF_GENDER, MON_FEMALE})}), }, [SPECIES_MEOWSTIC_M] = @@ -2930,7 +2930,7 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sSpritzeeLevelUpLearnset, .teachableLearnset = sSpritzeeTeachableLearnset, .eggMoveLearnset = sSpritzeeEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_SACHET, SPECIES_AROMATISSE}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_AROMATISSE, CONDITIONS({IF_HOLD_ITEM, ITEM_SACHET})}, {EVO_ITEM, ITEM_SACHET, SPECIES_AROMATISSE}), }, @@ -3072,7 +3072,7 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sSwirlixLevelUpLearnset, .teachableLearnset = sSwirlixTeachableLearnset, .eggMoveLearnset = sSwirlixEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE_ITEM, ITEM_WHIPPED_DREAM, SPECIES_SLURPUFF}, + .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_SLURPUFF, CONDITIONS({IF_HOLD_ITEM, ITEM_WHIPPED_DREAM})}, {EVO_ITEM, ITEM_WHIPPED_DREAM, SPECIES_SLURPUFF}), }, @@ -3926,7 +3926,7 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sTyruntLevelUpLearnset, .teachableLearnset = sTyruntTeachableLearnset, .eggMoveLearnset = sTyruntEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_DAY, 39, SPECIES_TYRANTRUM}), + .evolutions = EVOLUTION({EVO_LEVEL, 39, SPECIES_TYRANTRUM, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}), }, [SPECIES_TYRANTRUM] = @@ -4070,7 +4070,7 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sAmauraLevelUpLearnset, .teachableLearnset = sAmauraTeachableLearnset, .eggMoveLearnset = sAmauraEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_NIGHT, 39, SPECIES_AURORUS}), + .evolutions = EVOLUTION({EVO_LEVEL, 39, SPECIES_AURORUS, CONDITIONS({IF_TIME, TIME_NIGHT})}), }, [SPECIES_AURORUS] = @@ -4501,8 +4501,8 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sSliggooLevelUpLearnset, .teachableLearnset = sSliggooTeachableLearnset, .formSpeciesIdTable = sSliggooFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL_RAIN, 50, SPECIES_GOODRA}, - {EVO_LEVEL_FOG, 50, SPECIES_GOODRA}), + .evolutions = EVOLUTION({EVO_LEVEL, 50, SPECIES_GOODRA, CONDITIONS({IF_WEATHER, WEATHER_RAIN})}, + {EVO_LEVEL, 50, SPECIES_GOODRA, CONDITIONS({IF_WEATHER, WEATHER_FOG})}), }, [SPECIES_GOODRA] = @@ -4640,8 +4640,9 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = .levelUpLearnset = sSliggooHisuiLevelUpLearnset, .teachableLearnset = sSliggooHisuiTeachableLearnset, .formSpeciesIdTable = sSliggooFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL_RAIN, 50, SPECIES_GOODRA_HISUI}, - {EVO_LEVEL_FOG, 50, SPECIES_GOODRA_HISUI}), + .evolutions = EVOLUTION({EVO_LEVEL, 50, SPECIES_GOODRA_HISUI, CONDITIONS({IF_WEATHER, WEATHER_RAIN})}, + {EVO_LEVEL, 50, SPECIES_GOODRA_HISUI, CONDITIONS({IF_WEATHER, WEATHER_FOG})}), + }, [SPECIES_GOODRA_HISUI] = diff --git a/src/data/pokemon/species_info/gen_7_families.h b/src/data/pokemon/species_info/gen_7_families.h index 8b1e4d369b..ff5f1a9344 100644 --- a/src/data/pokemon/species_info/gen_7_families.h +++ b/src/data/pokemon/species_info/gen_7_families.h @@ -937,7 +937,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .levelUpLearnset = sYungoosLevelUpLearnset, .teachableLearnset = sYungoosTeachableLearnset, .eggMoveLearnset = sYungoosEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_DAY, 20, SPECIES_GUMSHOOS}), + .evolutions = EVOLUTION({EVO_LEVEL, 20, SPECIES_GUMSHOOS, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}), }, [SPECIES_GUMSHOOS] = @@ -1197,7 +1197,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = ) .levelUpLearnset = sCharjabugLevelUpLearnset, .teachableLearnset = sCharjabugTeachableLearnset, - .evolutions = EVOLUTION({EVO_MAPSEC, MAPSEC_NEW_MAUVILLE, SPECIES_VIKAVOLT}, + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_VIKAVOLT, CONDITIONS({IF_IN_MAPSEC, MAPSEC_NEW_MAUVILLE})}, {EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_VIKAVOLT}, {EVO_NONE, 0, SPECIES_VIKAVOLT_TOTEM}), }, @@ -1399,7 +1399,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .levelUpLearnset = sCrabrawlerLevelUpLearnset, .teachableLearnset = sCrabrawlerTeachableLearnset, .eggMoveLearnset = sCrabrawlerEggMoveLearnset, - .evolutions = EVOLUTION({EVO_SPECIFIC_MAP, MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM, SPECIES_CRABOMINABLE}, + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_CRABOMINABLE, CONDITIONS({IF_IN_MAP, MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM})}, {EVO_ITEM, ITEM_ICE_STONE, SPECIES_CRABOMINABLE}), }, @@ -2027,8 +2027,8 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .teachableLearnset = sRockruffTeachableLearnset, .eggMoveLearnset = sRockruffEggMoveLearnset, .formSpeciesIdTable = sRockruffFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL_DAY, 25, SPECIES_LYCANROC_MIDDAY}, - {EVO_LEVEL_NIGHT, 25, SPECIES_LYCANROC_MIDNIGHT}), + .evolutions = EVOLUTION({EVO_LEVEL, 25, SPECIES_LYCANROC_MIDDAY, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}, + {EVO_LEVEL, 25, SPECIES_LYCANROC_MIDNIGHT, CONDITIONS({IF_TIME, TIME_NIGHT})}), }, [SPECIES_ROCKRUFF_OWN_TEMPO] = @@ -2090,7 +2090,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .teachableLearnset = sRockruffTeachableLearnset, .eggMoveLearnset = sRockruffEggMoveLearnset, .formSpeciesIdTable = sRockruffFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL_DUSK, 25, SPECIES_LYCANROC_DUSK}), + .evolutions = EVOLUTION({EVO_LEVEL, 25, SPECIES_LYCANROC_DUSK, CONDITIONS({IF_TIME, TIME_EVENING})}), }, [SPECIES_LYCANROC_MIDDAY] = @@ -2949,7 +2949,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .levelUpLearnset = sFomantisLevelUpLearnset, .teachableLearnset = sFomantisTeachableLearnset, .eggMoveLearnset = sFomantisEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_DAY, 34, SPECIES_LURANTIS}, + .evolutions = EVOLUTION({EVO_LEVEL, 34, SPECIES_LURANTIS, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}, {EVO_NONE, 0, SPECIES_LURANTIS_TOTEM}), }, @@ -3280,7 +3280,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .levelUpLearnset = sSalanditLevelUpLearnset, .teachableLearnset = sSalanditTeachableLearnset, .eggMoveLearnset = sSalanditEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_FEMALE, 33, SPECIES_SALAZZLE}, + .evolutions = EVOLUTION({EVO_LEVEL, 33, SPECIES_SALAZZLE, CONDITIONS({IF_GENDER, MON_FEMALE})}, {EVO_NONE, 0, SPECIES_SALAZZLE_TOTEM}), }, @@ -3677,7 +3677,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = ) .levelUpLearnset = sSteeneeLevelUpLearnset, .teachableLearnset = sSteeneeTeachableLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_STOMP, SPECIES_TSAREENA}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_TSAREENA, CONDITIONS({IF_KNOWS_MOVE, MOVE_STOMP})}), }, [SPECIES_TSAREENA] = @@ -4357,7 +4357,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, .levelUpLearnset = sTypeNullLevelUpLearnset, .teachableLearnset = sTypeNullTeachableLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP, 0, SPECIES_SILVALLY_NORMAL}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_SILVALLY_NORMAL, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), }, #define SILVALLY_SPECIES_INFO(type, _palette) \ @@ -5971,8 +5971,8 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, .levelUpLearnset = sCosmoemLevelUpLearnset, .teachableLearnset = sCosmoemTeachableLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_DAY, 53, SPECIES_SOLGALEO}, - {EVO_LEVEL_NIGHT, 53, SPECIES_LUNALA}), + .evolutions = EVOLUTION({EVO_LEVEL, 53, SPECIES_SOLGALEO, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}, + {EVO_LEVEL, 53, SPECIES_LUNALA, CONDITIONS({IF_TIME, TIME_NIGHT})}), }, [SPECIES_SOLGALEO] = @@ -7148,7 +7148,7 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, .levelUpLearnset = sPoipoleLevelUpLearnset, .teachableLearnset = sPoipoleTeachableLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_DRAGON_PULSE, SPECIES_NAGANADEL}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_NAGANADEL, CONDITIONS({IF_KNOWS_MOVE, MOVE_DRAGON_PULSE})}), }, [SPECIES_NAGANADEL] = diff --git a/src/data/pokemon/species_info/gen_8_families.h b/src/data/pokemon/species_info/gen_8_families.h index cebabca2b8..297888d9e5 100644 --- a/src/data/pokemon/species_info/gen_8_families.h +++ b/src/data/pokemon/species_info/gen_8_families.h @@ -2778,7 +2778,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = ) .levelUpLearnset = sDipplinLevelUpLearnset, .teachableLearnset = sDipplinTeachableLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_DRAGON_CHEER, SPECIES_HYDRAPPLE}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_HYDRAPPLE, CONDITIONS({IF_KNOWS_MOVE, MOVE_DRAGON_CHEER})}), }, [SPECIES_HYDRAPPLE] = @@ -3410,8 +3410,8 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .levelUpLearnset = sToxelLevelUpLearnset, .teachableLearnset = sToxelTeachableLearnset, .eggMoveLearnset = sToxelEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_NATURE_AMPED, 30, SPECIES_TOXTRICITY_AMPED}, - {EVO_LEVEL_NATURE_LOW_KEY, 30, SPECIES_TOXTRICITY_LOW_KEY}), + .evolutions = EVOLUTION({EVO_LEVEL, 30, SPECIES_TOXTRICITY_AMPED, CONDITIONS({IF_AMPED_NATURE})}, + {EVO_LEVEL, 30, SPECIES_TOXTRICITY_LOW_KEY, CONDITIONS({IF_LOW_KEY_NATURE})}), }, [SPECIES_TOXTRICITY_AMPED] = @@ -3915,7 +3915,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .levelUpLearnset = sClobbopusLevelUpLearnset, .teachableLearnset = sClobbopusTeachableLearnset, .eggMoveLearnset = sClobbopusEggMoveLearnset, - .evolutions = EVOLUTION({EVO_MOVE, MOVE_TAUNT, SPECIES_GRAPPLOCT}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_GRAPPLOCT, CONDITIONS({IF_KNOWS_MOVE, MOVE_TAUNT})}), }, [SPECIES_GRAPPLOCT] = @@ -4813,70 +4813,197 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .levelUpLearnset = sMilceryLevelUpLearnset, .teachableLearnset = sMilceryTeachableLearnset, .eggMoveLearnset = sMilceryEggMoveLearnset, - .evolutions = EVOLUTION({EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_VANILLA_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_RUBY_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_MATCHA_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_MINT_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_CARAMEL_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_RUBY_SWIRL}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_LEMON_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_SALTED_CREAM}, - {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_STRAWBERRY_SWEET, SPECIES_ALCREMIE_STRAWBERRY_RAINBOW_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_VANILLA_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_RUBY_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_MATCHA_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_MINT_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_CARAMEL_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_RUBY_SWIRL}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_LEMON_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_SALTED_CREAM}, - {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_BERRY_SWEET, SPECIES_ALCREMIE_BERRY_RAINBOW_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_VANILLA_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_RUBY_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_MATCHA_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_MINT_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_CARAMEL_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_RUBY_SWIRL}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_LEMON_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_SALTED_CREAM}, - {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_LOVE_SWEET, SPECIES_ALCREMIE_LOVE_RAINBOW_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_VANILLA_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_RUBY_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_MATCHA_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_MINT_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_CARAMEL_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_RUBY_SWIRL}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_LEMON_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_SALTED_CREAM}, - {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_STAR_SWEET, SPECIES_ALCREMIE_STAR_RAINBOW_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_VANILLA_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_RUBY_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_MATCHA_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_MINT_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_CARAMEL_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_RUBY_SWIRL}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_LEMON_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_SALTED_CREAM}, - {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_CLOVER_SWEET, SPECIES_ALCREMIE_CLOVER_RAINBOW_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_VANILLA_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_RUBY_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_MATCHA_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_MINT_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_CARAMEL_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_RUBY_SWIRL}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_LEMON_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_SALTED_CREAM}, - {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_FLOWER_SWEET, SPECIES_ALCREMIE_FLOWER_RAINBOW_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_VANILLA_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_RUBY_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_MATCHA_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_MINT_CREAM}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_CARAMEL_SWIRL}, - {EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_RUBY_SWIRL}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_LEMON_CREAM}, - {EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_SALTED_CREAM}, - {EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS, ITEM_RIBBON_SWEET, SPECIES_ALCREMIE_RIBBON_RAINBOW_SWIRL} - ), + .evolutions = EVOLUTION( + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_STRAWBERRY_VANILLA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_STRAWBERRY_RUBY_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_STRAWBERRY_MATCHA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_STRAWBERRY_MINT_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_STRAWBERRY_LEMON_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_STRAWBERRY_SALTED_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_STRAWBERRY_RUBY_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_STRAWBERRY_CARAMEL_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_EITHER, SPECIES_ALCREMIE_STRAWBERRY_RAINBOW_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_STRAWBERRY_SWEET}, + {IF_TIME, TIME_EVENING})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_BERRY_VANILLA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_BERRY_RUBY_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_BERRY_MATCHA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_BERRY_MINT_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_BERRY_LEMON_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_BERRY_SALTED_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_BERRY_RUBY_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_BERRY_CARAMEL_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_EITHER, SPECIES_ALCREMIE_BERRY_RAINBOW_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_BERRY_SWEET}, + {IF_TIME, TIME_EVENING})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_LOVE_VANILLA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_LOVE_RUBY_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_LOVE_MATCHA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_LOVE_MINT_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_LOVE_LEMON_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_LOVE_SALTED_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_LOVE_RUBY_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_LOVE_CARAMEL_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_EITHER, SPECIES_ALCREMIE_LOVE_RAINBOW_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_LOVE_SWEET}, + {IF_TIME, TIME_EVENING})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_STAR_VANILLA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_STAR_RUBY_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_STAR_MATCHA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_STAR_MINT_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_STAR_LEMON_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_STAR_SALTED_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_STAR_RUBY_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_STAR_CARAMEL_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_EITHER, SPECIES_ALCREMIE_STAR_RAINBOW_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_STAR_SWEET}, + {IF_TIME, TIME_EVENING})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_CLOVER_VANILLA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_CLOVER_RUBY_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_CLOVER_MATCHA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_CLOVER_MINT_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_CLOVER_LEMON_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_CLOVER_SALTED_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_CLOVER_RUBY_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_CLOVER_CARAMEL_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_EITHER, SPECIES_ALCREMIE_CLOVER_RAINBOW_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_CLOVER_SWEET}, + {IF_TIME, TIME_EVENING})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_FLOWER_VANILLA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_FLOWER_RUBY_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_FLOWER_MATCHA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_FLOWER_MINT_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_FLOWER_LEMON_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_FLOWER_SALTED_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_FLOWER_RUBY_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_FLOWER_CARAMEL_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_EITHER, SPECIES_ALCREMIE_FLOWER_RAINBOW_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_FLOWER_SWEET}, + {IF_TIME, TIME_EVENING})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_RIBBON_VANILLA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_RIBBON_RUBY_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_SHORT, SPECIES_ALCREMIE_RIBBON_MATCHA_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_RIBBON_MINT_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_RIBBON_LEMON_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_SHORT, SPECIES_ALCREMIE_RIBBON_SALTED_CREAM, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_NIGHT})}, + {EVO_SPIN, SPIN_CCW_LONG, SPECIES_ALCREMIE_RIBBON_RUBY_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_CW_LONG, SPECIES_ALCREMIE_RIBBON_CARAMEL_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_DAY})}, + {EVO_SPIN, SPIN_EITHER, SPECIES_ALCREMIE_RIBBON_RAINBOW_SWIRL, + CONDITIONS({IF_HOLD_ITEM, ITEM_RIBBON_SWEET}, + {IF_TIME, TIME_EVENING})} + ) }, #define ALCREMIE_MISC_INFO(color) \ @@ -5243,7 +5370,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .levelUpLearnset = sSnomLevelUpLearnset, .teachableLearnset = sSnomTeachableLearnset, .eggMoveLearnset = sSnomEggMoveLearnset, - .evolutions = EVOLUTION({EVO_FRIENDSHIP_NIGHT, 0, SPECIES_FROSMOTH}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_FROSMOTH, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD},{IF_TIME, TIME_NIGHT})}), }, [SPECIES_FROSMOTH] = @@ -7070,10 +7197,10 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .perfectIVCount = LEGENDARY_PERFECT_IV_COUNT, .levelUpLearnset = sKubfuLevelUpLearnset, .teachableLearnset = sKubfuTeachableLearnset, - .evolutions = EVOLUTION({EVO_DARK_SCROLL, 0, SPECIES_URSHIFU_SINGLE_STRIKE}, + .evolutions = EVOLUTION({EVO_SCRIPT_TRIGGER, 0, SPECIES_URSHIFU_SINGLE_STRIKE}, + {EVO_SCRIPT_TRIGGER, 1, SPECIES_URSHIFU_RAPID_STRIKE}, {EVO_ITEM, ITEM_SCROLL_OF_DARKNESS, SPECIES_URSHIFU_SINGLE_STRIKE}, - {EVO_WATER_SCROLL, 0, SPECIES_URSHIFU_RAPID_STRIKE}, - {EVO_ITEM, ITEM_SCROLL_OF_WATERS, SPECIES_URSHIFU_RAPID_STRIKE}), + {EVO_ITEM, ITEM_SCROLL_OF_WATERS, SPECIES_URSHIFU_RAPID_STRIKE}), }, [SPECIES_URSHIFU_SINGLE_STRIKE] = diff --git a/src/data/pokemon/species_info/gen_9_families.h b/src/data/pokemon/species_info/gen_9_families.h index 9e5046958a..c13944e406 100644 --- a/src/data/pokemon/species_info/gen_9_families.h +++ b/src/data/pokemon/species_info/gen_9_families.h @@ -648,8 +648,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .levelUpLearnset = sLechonkLevelUpLearnset, .teachableLearnset = sLechonkTeachableLearnset, .eggMoveLearnset = sLechonkEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_MALE, 18, SPECIES_OINKOLOGNE_M}, - {EVO_LEVEL_FEMALE, 18, SPECIES_OINKOLOGNE_F}), + .evolutions = EVOLUTION({EVO_LEVEL, 18, SPECIES_OINKOLOGNE_M, CONDITIONS({IF_GENDER, MON_MALE})}, + {EVO_LEVEL, 18, SPECIES_OINKOLOGNE_F, CONDITIONS({IF_GENDER, MON_FEMALE})}), }, [SPECIES_OINKOLOGNE_M] = @@ -1167,7 +1167,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = ) .levelUpLearnset = sPawmoLevelUpLearnset, .teachableLearnset = sPawmoTeachableLearnset, - .evolutions = EVOLUTION({EVO_OVERWORLD_STEPS, 1000, SPECIES_PAWMOT}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_PAWMOT, CONDITIONS({IF_MIN_OVERWORLD_STEPS, 1000})}), }, [SPECIES_PAWMOT] = @@ -1297,8 +1297,8 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .levelUpLearnset = sTandemausLevelUpLearnset, .teachableLearnset = sTandemausTeachableLearnset, .eggMoveLearnset = sTandemausEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_FAMILY_OF_FOUR, 25, SPECIES_MAUSHOLD_FOUR}, - {EVO_LEVEL_FAMILY_OF_THREE, 25, SPECIES_MAUSHOLD_THREE}), + .evolutions = EVOLUTION({EVO_LEVEL_BATTLE_ONLY, 25, SPECIES_MAUSHOLD_FOUR, CONDITIONS({IF_PID_MODULO_100_GT, 0})}, + {EVO_LEVEL_BATTLE_ONLY, 25, SPECIES_MAUSHOLD_THREE, CONDITIONS({IF_PID_MODULO_100_EQ, 0})}), }, [SPECIES_MAUSHOLD_THREE] = @@ -2987,7 +2987,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .levelUpLearnset = sBramblinLevelUpLearnset, .teachableLearnset = sBramblinTeachableLearnset, .eggMoveLearnset = sBramblinEggMoveLearnset, - .evolutions = EVOLUTION({EVO_OVERWORLD_STEPS, 1000, SPECIES_BRAMBLEGHAST}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_BRAMBLEGHAST, CONDITIONS({IF_MIN_OVERWORLD_STEPS, 1000})}), }, [SPECIES_BRAMBLEGHAST] = @@ -3447,7 +3447,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .levelUpLearnset = sRellorLevelUpLearnset, .teachableLearnset = sRellorTeachableLearnset, .eggMoveLearnset = sRellorEggMoveLearnset, - .evolutions = EVOLUTION({EVO_OVERWORLD_STEPS, 1000, SPECIES_RABSCA}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_RABSCA, CONDITIONS({IF_MIN_OVERWORLD_STEPS, 1000})}), }, [SPECIES_RABSCA] = @@ -4686,7 +4686,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .levelUpLearnset = sGreavardLevelUpLearnset, .teachableLearnset = sGreavardTeachableLearnset, .eggMoveLearnset = sGreavardEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL_NIGHT, 30, SPECIES_HOUNDSTONE}), + .evolutions = EVOLUTION({EVO_LEVEL, 30, SPECIES_HOUNDSTONE, CONDITIONS({IF_TIME, TIME_NIGHT})}), }, [SPECIES_HOUNDSTONE] = @@ -6343,7 +6343,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .levelUpLearnset = sGimmighoulLevelUpLearnset, .teachableLearnset = sGimmighoulTeachableLearnset, .formSpeciesIdTable = sGimmighoulFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_ITEM_COUNT_999, ITEM_GIMMIGHOUL_COIN, SPECIES_GHOLDENGO}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_GHOLDENGO, CONDITIONS({IF_BAG_ITEM_COUNT, ITEM_GIMMIGHOUL_COIN, 999})}), }, [SPECIES_GIMMIGHOUL_ROAMING] = @@ -6399,7 +6399,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .levelUpLearnset = sGimmighoulLevelUpLearnset, .teachableLearnset = sGimmighoulTeachableLearnset, .formSpeciesIdTable = sGimmighoulFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_ITEM_COUNT_999, ITEM_GIMMIGHOUL_COIN, SPECIES_GHOLDENGO}), + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_GHOLDENGO, CONDITIONS({IF_BAG_ITEM_COUNT, ITEM_GIMMIGHOUL_COIN, 999})}), }, [SPECIES_GHOLDENGO] = diff --git a/src/debug.c b/src/debug.c index 4443e004d8..2ac63e347e 100644 --- a/src/debug.c +++ b/src/debug.c @@ -1982,7 +1982,14 @@ static const u8 sWeatherNames[WEATHER_COUNT][24] = { [WEATHER_ABNORMAL] = _("ABNORMAL(NOT WORKING)"), [WEATHER_ROUTE119_CYCLE] = _("ROUTE119 CYCLE"), [WEATHER_ROUTE123_CYCLE] = _("ROUTE123 CYCLE"), + [WEATHER_FOG] = _("FOG"), }; + +const u8 *GetWeatherName(u32 weatherId) +{ + return sWeatherNames[weatherId]; +} + static const u8 sDebugText_WeatherNotDefined[] = _("NOT DEFINED!!!"); static void DebugAction_Util_Weather(u8 taskId) { diff --git a/src/evolution_scene.c b/src/evolution_scene.c index 7de57bd53c..f0c6b04bab 100644 --- a/src/evolution_scene.c +++ b/src/evolution_scene.c @@ -542,7 +542,7 @@ static void CB2_TradeEvolutionSceneUpdate(void) RunTasks(); } -static void CreateShedinja(u16 preEvoSpecies, struct Pokemon *mon) +static void CreateShedinja(u32 preEvoSpecies, u32 postEvoSpecies, struct Pokemon *mon) { u32 data = 0; u16 ball = ITEM_POKE_BALL; @@ -551,41 +551,48 @@ static void CreateShedinja(u16 preEvoSpecies, struct Pokemon *mon) if (evolutions == NULL) return; - if (evolutions[0].method == EVO_LEVEL_NINJASK && gPlayerPartyCount < PARTY_SIZE && (P_SHEDINJA_BALL < GEN_4 || CheckBagHasItem(ball, 1))) + for (u32 i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { - s32 i; - struct Pokemon *shedinja = &gPlayerParty[gPlayerPartyCount]; - - CopyMon(&gPlayerParty[gPlayerPartyCount], mon, sizeof(struct Pokemon)); - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_SPECIES, &evolutions[1].targetSpecies); - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_NICKNAME, GetSpeciesName(evolutions[1].targetSpecies)); - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_HELD_ITEM, &data); - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_MARKINGS, &data); - if (P_SHEDINJA_BALL >= GEN_4) + if (evolutions[i].method == EVO_SPLIT_FROM_EVO + && evolutions[i].param == postEvoSpecies + && gPlayerPartyCount < PARTY_SIZE + && DoesMonMeetAdditionalConditions(mon, evolutions[i].params, NULL, PARTY_SIZE, NULL, CHECK_EVO)) { - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_POKEBALL, &ball); - RemoveBagItem(ball, 1); + s32 j; + struct Pokemon *shedinja = &gPlayerParty[gPlayerPartyCount]; + + CopyMon(&gPlayerParty[gPlayerPartyCount], mon, sizeof(struct Pokemon)); + SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_SPECIES, &evolutions[i].targetSpecies); + SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_NICKNAME, GetSpeciesName(evolutions[i].targetSpecies)); + SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_HELD_ITEM, &data); + SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_MARKINGS, &data); + if (P_SHEDINJA_BALL >= GEN_4) + { + SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_POKEBALL, &ball); + RemoveBagItem(ball, 1); + } + + for (j = MON_DATA_COOL_RIBBON; j < MON_DATA_COOL_RIBBON + CONTEST_CATEGORIES_COUNT; j++) + SetMonData(&gPlayerParty[gPlayerPartyCount], j, &data); + for (j = MON_DATA_CHAMPION_RIBBON; j <= MON_DATA_WORLD_RIBBON; j++) + SetMonData(&gPlayerParty[gPlayerPartyCount], j, &data); + + SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_STATUS, &data); + data = MAIL_NONE; + SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_MAIL, &data); + + CalculateMonStats(&gPlayerParty[gPlayerPartyCount]); + CalculatePlayerPartyCount(); + + GetSetPokedexFlag(SpeciesToNationalPokedexNum(evolutions[i].targetSpecies), FLAG_SET_SEEN); + GetSetPokedexFlag(SpeciesToNationalPokedexNum(evolutions[i].targetSpecies), FLAG_SET_CAUGHT); + + if (GetMonData(shedinja, MON_DATA_SPECIES) == SPECIES_SHEDINJA + && GetMonData(shedinja, MON_DATA_LANGUAGE) == LANGUAGE_JAPANESE + && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_NINJASK) + SetMonData(shedinja, MON_DATA_NICKNAME, sText_ShedinjaJapaneseName); + } - - for (i = MON_DATA_COOL_RIBBON; i < MON_DATA_COOL_RIBBON + CONTEST_CATEGORIES_COUNT; i++) - SetMonData(&gPlayerParty[gPlayerPartyCount], i, &data); - for (i = MON_DATA_CHAMPION_RIBBON; i <= MON_DATA_WORLD_RIBBON; i++) - SetMonData(&gPlayerParty[gPlayerPartyCount], i, &data); - - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_STATUS, &data); - data = MAIL_NONE; - SetMonData(&gPlayerParty[gPlayerPartyCount], MON_DATA_MAIL, &data); - - CalculateMonStats(&gPlayerParty[gPlayerPartyCount]); - CalculatePlayerPartyCount(); - - GetSetPokedexFlag(SpeciesToNationalPokedexNum(evolutions[1].targetSpecies), FLAG_SET_SEEN); - GetSetPokedexFlag(SpeciesToNationalPokedexNum(evolutions[1].targetSpecies), FLAG_SET_CAUGHT); - - if (GetMonData(shedinja, MON_DATA_SPECIES) == SPECIES_SHEDINJA - && GetMonData(shedinja, MON_DATA_LANGUAGE) == LANGUAGE_JAPANESE - && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_NINJASK) - SetMonData(shedinja, MON_DATA_NICKNAME, sText_ShedinjaJapaneseName); } } @@ -818,12 +825,12 @@ static void Task_EvolutionScene(u8 taskId) { StopMapMusic(); Overworld_PlaySpecialMapMusic(); - } - if (!gTasks[taskId].tEvoWasStopped) - { - CreateShedinja(gTasks[taskId].tPreEvoSpecies, mon); + } + if (!gTasks[taskId].tEvoWasStopped) + CreateShedinja(gTasks[taskId].tPreEvoSpecies, gTasks[taskId].tPostEvoSpecies, mon); + DestroyTask(taskId); FreeMonSpritesGfx(); FREE_AND_SET_NULL(sEvoStructPtr); diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 413c4acfc8..027fde989a 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -729,50 +729,32 @@ static void WindUpSpinTimer(u32 direction) bool32 CanTriggerSpinEvolution() { gSpecialVar_0x8000 = EVO_NONE; + bool32 canStopEvo = TRUE; if (gPlayerSpinData.triggerEvo) { - u32 timeOfDay = GetTimeOfDay(); u32 seconds = gPlayerSpinData.VBlanksSpinning / 60; u32 direction = gPlayerSpinData.spinDirection; - if (timeOfDay == TIME_EVENING && seconds >= 10) + if (seconds >= 10) { - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS; + gSpecialVar_0x8000 = SPIN_EITHER; } - else if (timeOfDay == TIME_NIGHT) + + else if (seconds >= 5 && seconds < 10) { - if (seconds >= 5) - { - if (direction == SPIN_DIRECTION_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE; - else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE; - } - else - { - if (direction == SPIN_DIRECTION_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE; - else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE; - } + if (direction == SPIN_DIRECTION_CLOCKWISE) + gSpecialVar_0x8000 = SPIN_CW_LONG; + else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) + gSpecialVar_0x8000 = SPIN_CCW_LONG; } - else if (timeOfDay != TIME_NIGHT) + else if (seconds < 5) { - if (seconds >= 5) - { - if (direction == SPIN_DIRECTION_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE; - else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE; - } - else - { - if (direction == SPIN_DIRECTION_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE; - else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) - gSpecialVar_0x8000 = EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE; - } + if (direction == SPIN_DIRECTION_CLOCKWISE) + gSpecialVar_0x8000 = SPIN_CW_SHORT; + else if (direction == SPIN_DIRECTION_COUNTER_CLOCKWISE) + gSpecialVar_0x8000 = SPIN_CCW_SHORT; } gSpecialVar_0x8001 = FALSE; //canStopEvo + canStopEvo = FALSE; gSpecialVar_0x8002 = TRUE; //tryMultiple gPlayerSpinData.triggerEvo = FALSE; } @@ -780,7 +762,7 @@ bool32 CanTriggerSpinEvolution() { for (u32 i = 0; i < PARTY_SIZE; i++) { - u16 species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_OVERWORLD_SPECIAL, gSpecialVar_0x8000, NULL, CHECK_EVO); + u16 species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_OVERWORLD_SPECIAL, 0, NULL, &canStopEvo, CHECK_EVO); if (species != SPECIES_NONE) { return TRUE; diff --git a/src/line_break.c b/src/line_break.c index b8888f501f..6684b32375 100644 --- a/src/line_break.c +++ b/src/line_break.c @@ -14,7 +14,21 @@ void StripLineBreaks(u8 *src) } } -void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId) +u32 CountLineBreaks(u8 *src) +{ + u32 currIndex = 0; + u32 numNewLines = 0; + while (src[currIndex] != EOS) + { + if (src[currIndex] == CHAR_PROMPT_SCROLL || src[currIndex] == CHAR_NEWLINE) + numNewLines++; + currIndex++; + } + + return numNewLines; +} + +void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId, enum ToggleScrollPrompt toggleScrollPrompt) { u32 currIndex = 0; u8 *currSrc = src; @@ -24,16 +38,16 @@ void BreakStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId) { u8 replacedChar = src[currIndex + 1]; src[currIndex + 1] = EOS; - BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId); + BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId, toggleScrollPrompt); src[currIndex + 1] = replacedChar; currSrc = &src[currIndex + 1]; } currIndex++; } - BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId); + BreakSubStringAutomatic(currSrc, maxWidth, screenLines, fontId, toggleScrollPrompt); } -void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId) +void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId, enum ToggleScrollPrompt toggleScrollPrompt) { // If the string already has line breaks, don't interfere with them if (StringHasManualBreaks(src)) @@ -185,7 +199,7 @@ void BreakSubStringAutomatic(u8 *src, u32 maxWidth, u32 screenLines, u8 fontId) } } while (shouldTryAgain); //u32 currBadness = GetStringBadness(stringLines, totalLines, maxWidth); - BuildNewString(stringLines, totalLines, screenLines, src); + BuildNewString(stringLines, totalLines, screenLines, src, toggleScrollPrompt); Free(stringLines); } @@ -247,7 +261,7 @@ u32 GetStringBadness(struct StringLine *stringLines, u32 numLines, u32 maxWidth) } // Build the new string from the data stored in the StringLine structs -void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str) +void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, u8 *str, enum ToggleScrollPrompt toggleScrollPrompt) { u32 srcCharIndex = 0; for (u32 lineIndex = 0; lineIndex < numLines; lineIndex++) @@ -259,7 +273,7 @@ void BuildNewString(struct StringLine *stringLines, u32 numLines, u32 maxLines, if (lineIndex + 1 < numLines) { // Add the appropriate line break depending on line number - if (lineIndex >= maxLines - 1 && numLines > maxLines) + if (lineIndex >= maxLines - 1 && numLines > maxLines && toggleScrollPrompt == SHOW_SCROLL_PROMPT) str[srcCharIndex] = CHAR_PROMPT_SCROLL; else str[srcCharIndex] = CHAR_NEWLINE; diff --git a/src/party_menu.c b/src/party_menu.c index 2303bae000..de9398744d 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -1154,7 +1154,7 @@ static bool8 DisplayPartyPokemonDataForMoveTutorOrEvolutionItem(u8 slot) DisplayPartyPokemonDataToTeachMove(slot, ItemIdToBattleMoveId(item)); break; case 2: // Evolution stone - if (!GetMonData(currentPokemon, MON_DATA_IS_EGG) && GetEvolutionTargetSpecies(currentPokemon, EVO_MODE_ITEM_CHECK, item, NULL, DO_EVO) != SPECIES_NONE) + if (!GetMonData(currentPokemon, MON_DATA_IS_EGG) && GetEvolutionTargetSpecies(currentPokemon, EVO_MODE_ITEM_CHECK, item, NULL, NULL, CHECK_EVO) != SPECIES_NONE) return FALSE; DisplayPartyPokemonDescriptionData(slot, PARTYBOX_DESC_NO_USE); break; @@ -5625,29 +5625,25 @@ void ItemUseCB_RareCandy(u8 taskId, TaskFunc task) PlaySE(SE_SELECT); if (cannotUseEffect) { - u16 targetSpecies = SPECIES_NONE; - bool32 evoModeNormal = TRUE; + u32 targetSpecies = SPECIES_NONE; + bool32 canStopEvo = TRUE; // Resets values to 0 so other means of teaching moves doesn't overwrite levels sInitialLevel = 0; sFinalLevel = 0; - if (holdEffectParam == 0) + if (holdEffectParam == 0) // Rare Candy { - targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL, DO_EVO); - if (targetSpecies == SPECIES_NONE) - { - targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_CANT_STOP, ITEM_NONE, NULL, DO_EVO); - evoModeNormal = FALSE; - } + targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL, &canStopEvo, CHECK_EVO); } if (targetSpecies != SPECIES_NONE) { + GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL, &canStopEvo, DO_EVO); RemoveBagItem(gSpecialVar_ItemId, 1); FreePartyPointers(); gCB2_AfterEvolution = gPartyMenu.exitCallback; - BeginEvolutionScene(mon, targetSpecies, evoModeNormal, gPartyMenu.slotId); + BeginEvolutionScene(mon, targetSpecies, canStopEvo, gPartyMenu.slotId); DestroyTask(taskId); } else @@ -5821,28 +5817,24 @@ static void CB2_ReturnToPartyMenuUsingRareCandy(void) static void PartyMenuTryEvolution(u8 taskId) { struct Pokemon *mon = &gPlayerParty[gPartyMenu.slotId]; - u16 targetSpecies = SPECIES_NONE; - bool32 evoModeNormal = TRUE; + u32 targetSpecies = SPECIES_NONE; + bool32 canStopEvo = TRUE; // Resets values to 0 so other means of teaching moves doesn't overwrite levels sInitialLevel = 0; sFinalLevel = 0; - targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL, DO_EVO); - if (targetSpecies == SPECIES_NONE) - { - targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_CANT_STOP, ITEM_NONE, NULL, DO_EVO); - evoModeNormal = FALSE; - } + targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL, &canStopEvo, CHECK_EVO); if (targetSpecies != SPECIES_NONE) { + GetEvolutionTargetSpecies(mon, EVO_MODE_NORMAL, ITEM_NONE, NULL, &canStopEvo, DO_EVO); FreePartyPointers(); if (ItemId_GetFieldFunc(gSpecialVar_ItemId) == ItemUseOutOfBattle_RareCandy && gPartyMenu.menuType == PARTY_MENU_TYPE_FIELD && CheckBagHasItem(gSpecialVar_ItemId, 1)) gCB2_AfterEvolution = CB2_ReturnToPartyMenuUsingRareCandy; else gCB2_AfterEvolution = gPartyMenu.exitCallback; - BeginEvolutionScene(mon, targetSpecies, evoModeNormal, gPartyMenu.slotId); + BeginEvolutionScene(mon, targetSpecies, canStopEvo, gPartyMenu.slotId); DestroyTask(taskId); } else diff --git a/src/pokedex_plus_hgss.c b/src/pokedex_plus_hgss.c index 999bfd0b70..b007979667 100644 --- a/src/pokedex_plus_hgss.c +++ b/src/pokedex_plus_hgss.c @@ -5,6 +5,7 @@ #include "contest_effect.h" #include "data.h" #include "daycare.h" +#include "debug.h" #include "decompress.h" #include "event_data.h" #include "gpu_regs.h" @@ -12,6 +13,7 @@ #include "international_string_util.h" #include "item.h" #include "item_icon.h" +#include "line_break.h" #include "main.h" #include "malloc.h" #include "menu.h" @@ -205,54 +207,19 @@ static const u8 sText_EVO_Buttons_Decapped_PE[] = _("{DPAD_UPDOWN}Evos {A_BUTTO static const u8 sText_EVO_Name[] = _("{STR_VAR_3}:"); static const u8 sText_EVO_PreEvo[] = _("{STR_VAR_1} evolves from {STR_VAR_2}"); static const u8 sText_EVO_PreEvo_PE_Mega[] = _("{STR_VAR_1} Mega Evolves with {STR_VAR_2}"); -static const u8 sText_EVO_FRIENDSHIP[] = _("{LV}{UP_ARROW}, high friendship"); -static const u8 sText_EVO_FRIENDSHIP_DAY[] = _("{LV}{UP_ARROW}, high friendship, day"); -static const u8 sText_EVO_FRIENDSHIP_NIGHT[] = _("{LV}{UP_ARROW}, high friendship, night"); -static const u8 sText_EVO_FRIENDSHIP_MOVE_TYPE[] = _("{LV}{UP_ARROW}, high friendship, {STR_VAR_2} move"); -static const u8 sText_EVO_LEVEL[] = _("{LV}{UP_ARROW} to {STR_VAR_2}"); -static const u8 sText_EVO_TRADE[] = _("Trading"); -static const u8 sText_EVO_TRADE_ITEM[] = _("Trading, holding {STR_VAR_2}"); -static const u8 sText_EVO_ITEM[] = _("{STR_VAR_2} is used"); -static const u8 sText_EVO_LEVEL_ATK_GT_DEF[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, Atk > Def"); -static const u8 sText_EVO_LEVEL_ATK_EQ_DEF[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, Atk = Def"); -static const u8 sText_EVO_LEVEL_ATK_LT_DEF[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, Atk < Def"); static const u8 sText_EVO_LEVEL_SILCOON[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, Silcoon persona"); static const u8 sText_EVO_LEVEL_CASCOON[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, Cascoon persona"); -static const u8 sText_EVO_LEVEL_NINJASK[] = _("{LV}{UP_ARROW} to {STR_VAR_2}"); -static const u8 sText_EVO_LEVEL_SHEDINJA[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, party<6, 1x POKéBALL"); -static const u8 sText_EVO_BEAUTY[] = _("{LV}{UP_ARROW}, high beauty"); -static const u8 sText_EVO_LEVEL_FEMALE[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, is female"); -static const u8 sText_EVO_LEVEL_MALE[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, is male"); -static const u8 sText_EVO_LEVEL_NIGHT[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, night"); -static const u8 sText_EVO_LEVEL_DAY[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, day"); -static const u8 sText_EVO_LEVEL_DUSK[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, dusk (5-6PM)"); -static const u8 sText_EVO_ITEM_HOLD_DAY[] = _("{LV}{UP_ARROW}, holds {STR_VAR_2}, day"); -static const u8 sText_EVO_ITEM_HOLD_NIGHT[] = _("{LV}{UP_ARROW}, holds {STR_VAR_2}, night"); static const u8 sText_EVO_MOVE[] = _("{LV}{UP_ARROW}, knows {STR_VAR_2}"); -static const u8 sText_EVO_MAPSEC[] = _("{LV}{UP_ARROW} on {STR_VAR_2}"); -static const u8 sText_EVO_ITEM_MALE[] = _("{STR_VAR_2} used on male"); -static const u8 sText_EVO_ITEM_FEMALE[] = _("{STR_VAR_2} used on female"); static const u8 sText_EVO_LEVEL_RAIN[] = _("{LV}{UP_ARROW} to {STR_VAR_2} while raining"); -static const u8 sText_EVO_SPECIFIC_MON_IN_PARTY[] = _("{LV}{UP_ARROW} with {STR_VAR_2} in party"); -static const u8 sText_EVO_LEVEL_DARK_TYPE_MON_IN_PARTY[] = _("{LV}{UP_ARROW} with dark type in party"); static const u8 sText_EVO_TRADE_SPECIFIC_MON[] = _("Traded for {STR_VAR_2}"); -static const u8 sText_EVO_SPECIFIC_MAP[] = _("{LV}{UP_ARROW} on {STR_VAR_2}"); -static const u8 sText_EVO_LEVEL_NATURE_AMPED[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, Amped natures"); -static const u8 sText_EVO_LEVEL_NATURE_LOW_KEY[] = _("{LV}{UP_ARROW} to {STR_VAR_2}, Low Key natures"); static const u8 sText_EVO_CRITICAL_HITS[] = _("Land {STR_VAR_2} critical hits in\nsingle battle"); static const u8 sText_EVO_SCRIPT_TRIGGER_DMG[] = _("Takes at least {STR_VAR_2} HP in damage"); static const u8 sText_EVO_DARK_SCROLL[] = _("ScrllOfDrknss is used"); static const u8 sText_EVO_WATER_SCROLL[] = _("ScrollOfWatrs is used"); -static const u8 sText_EVO_ITEM_NIGHT[] = _("{STR_VAR_2} is used, night"); -static const u8 sText_EVO_ITEM_DAY[] = _("{STR_VAR_2} is used, day"); -static const u8 sText_EVO_ITEM_HOLD[] = _("{LV}{UP_ARROW}, holds {STR_VAR_2}"); static const u8 sText_EVO_USE_MOVE_TWENTY_TIMES[] = _("{LV}{UP_ARROW} after 20x {STR_VAR_2}"); static const u8 sText_EVO_RECOIL_DAMAGE_MALE[] = _("{LV}{UP_ARROW} with {STR_VAR_2} recoil, male"); static const u8 sText_EVO_RECOIL_DAMAGE_FEMALE[] = _("{LV}{UP_ARROW} with {STR_VAR_2} recoil, female"); -static const u8 sText_EVO_ITEM_COUNT_999[] = _("{LV}{UP_ARROW} with 999 {STR_VAR_2} in bag"); static const u8 sText_EVO_DEFEAT_THREE_WITH_ITEM[] = _("{LV}{UP_ARROW} defeating 3 {STR_VAR_3} holding {STR_VAR_2}"); -static const u8 sText_EVO_OVERWORLD_STEPS[] = _("{LV}{UP_ARROW} after {STR_VAR_2} steps"); -static const u8 sText_EVO_UNKNOWN[] = _("Method unknown"); static const u8 sText_EVO_NONE[] = _("{STR_VAR_1} has no evolution."); static const u8 sText_FORMS_Buttons_PE[] = _("{A_BUTTON}FORM MODE {START_BUTTON}EVOs"); @@ -314,6 +281,9 @@ static const u32 sPokedexPlusHGSS_ScreenSearchNational_Tilemap[] = INCBIN_U32("g #define POKEBALL_ROTATION_TOP 64 #define POKEBALL_ROTATION_BOTTOM (POKEBALL_ROTATION_TOP - 16) +// for evolution method listings +#define MAX_EVO_METHOD_LINES 10 + // Coordinates of the Pokémon sprite on its page (info/cry screens) #define MON_PAGE_X 48 #define MON_PAGE_Y 56 @@ -408,6 +378,7 @@ struct EvoScreenData u8 menuPos; u8 arrowSpriteId; bool8 isMega; + u32 arrowSpriteDist[10]; }; struct FromScreenData @@ -598,13 +569,13 @@ static void PrintStatsScreen_Moves_Bottom(u8 taskId); static void PrintStatsScreen_Left(u8 taskId); static void PrintStatsScreen_Abilities(u8 taskId); static void PrintInfoScreenTextWhite(const u8* str, u8 left, u8 top); -static void PrintInfoScreenTextSmall(const u8* str, u8 left, u8 top); +static void PrintInfoScreenTextSmall(const u8* str, u8 fontId, u8 left, u8 top); static void PrintInfoScreenTextSmallWhite(const u8* str, u8 left, u8 top); static void Task_LoadEvolutionScreen(u8 taskId); static void Task_HandleEvolutionScreenInput(u8 taskId); static void Task_SwitchScreensFromEvolutionScreen(u8 taskId); static void Task_ExitEvolutionScreen(u8 taskId); -static void PrintEvolutionTargetSpeciesAndMethod(u8 taskId, u16 species, u8 depth, u32 *depth_i, u32 alreadyPrintedIcons[], u32 *icon_depth_i); +static void PrintEvolutionTargetSpeciesAndMethod(u8 taskId, u16 species, u8 depth, u32 *depth_i, u32 alreadyPrintedIcons[], u32 *icon_depth_i, u32 numLines); static u8 PrintPreEvolutions(u8 taskId, u16 species); //Stat bars on scrolling screens static void TryDestroyStatBars(void); @@ -627,6 +598,12 @@ static void DestroyCategoryIcon(void); static u16 NationalPokedexNumToSpeciesHGSS(u16 nationalNum); +//Evo screen +u32 GetSpeciesNameFontId(u32 nameWidth); +u32 GetSpeciesNameWidthInChars(const u8 *speciesName); +bool32 IsSpeciesAlcremie(u32 targetSpecies); +bool32 IsItemSweet(u32 item); + //Stat bars by DizzyEgg #define TAG_STAT_BAR 4097 #define TAG_STAT_BAR_BG 4098 @@ -2658,7 +2635,7 @@ static void PrintMonDexNumAndName_2(u8 windowId, u8 fontId, const u8* str, u8 le color[0] = TEXT_COLOR_TRANSPARENT; color[1] = TEXT_DYNAMIC_COLOR_6; color[2] = TEXT_COLOR_LIGHT_GRAY; - AddTextPrinterParameterized4(windowId, fontId, left * 8 - 13, (top * 8) + 1, 0, 0, color, -1, str); + AddTextPrinterParameterized4(windowId, fontId, left * 8 - 13, (top * 8) + 1, 0, 0, color, TEXT_SKIP_DRAW, str); } // u16 ignored is passed but never used @@ -4280,12 +4257,6 @@ static void SpriteCB_SlideCaughtMonToCenter(struct Sprite *sprite) #undef tPersonalityLo #undef tPersonalityHi - - - - - - //************************************ //* * //* Print data * @@ -4309,14 +4280,14 @@ static void PrintInfoScreenTextWhite(const u8* str, u8 left, u8 top) AddTextPrinterParameterized4(0, FONT_NORMAL, left, top, 0, 0, color, TEXT_SKIP_DRAW, str); } -static void PrintInfoScreenTextSmall(const u8* str, u8 left, u8 top) +static void PrintInfoScreenTextSmall(const u8* str, u8 fontId, u8 left, u8 top) { u8 color[3]; color[0] = TEXT_COLOR_TRANSPARENT; color[1] = TEXT_DYNAMIC_COLOR_6; color[2] = TEXT_COLOR_LIGHT_GRAY; - AddTextPrinterParameterized4(0, 0, left, top, 0, 0, color, 0, str); + AddTextPrinterParameterized4(0, fontId, left, top, 0, 0, color, 0, str); } static void UNUSED PrintInfoScreenTextSmallWhite(const u8* str, u8 left, u8 top) { @@ -6079,7 +6050,7 @@ static void Task_LoadEvolutionScreen(u8 taskId) u32 iconDepth = depth; //Print evo info and icons gTasks[taskId].data[3] = 0; - PrintEvolutionTargetSpeciesAndMethod(taskId, NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum), 0, &depth, alreadyPrintedIcons, &iconDepth); + PrintEvolutionTargetSpeciesAndMethod(taskId, NationalPokedexNumToSpeciesHGSS(sPokedexListItem->dexNum), 0, &depth, alreadyPrintedIcons, &iconDepth, 0); LoadSpritePalette(&gSpritePalette_Arrow); GetSeenFlagTargetSpecies(); if (sPokedexView->sEvoScreenData.numAllEvolutions > 0 && sPokedexView->sEvoScreenData.numSeen > 0) @@ -6163,7 +6134,7 @@ static void Task_HandleEvolutionScreenInput(u8 taskId) else pos = 0; } while (!sPokedexView->sEvoScreenData.seen[pos]); - gSprites[sPokedexView->sEvoScreenData.arrowSpriteId].y = base_y + base_y_offset * pos; + gSprites[sPokedexView->sEvoScreenData.arrowSpriteId].y = sPokedexView->sEvoScreenData.arrowSpriteDist[pos] + base_y + base_y_offset * pos; sPokedexView->sEvoScreenData.menuPos = pos; } else if (JOY_NEW(DPAD_UP)) @@ -6176,7 +6147,7 @@ static void Task_HandleEvolutionScreenInput(u8 taskId) pos = max; } while (!sPokedexView->sEvoScreenData.seen[pos]); - gSprites[sPokedexView->sEvoScreenData.arrowSpriteId].y = base_y + base_y_offset * pos; + gSprites[sPokedexView->sEvoScreenData.arrowSpriteId].y = sPokedexView->sEvoScreenData.arrowSpriteDist[pos] + base_y + base_y_offset * pos; sPokedexView->sEvoScreenData.menuPos = pos; } @@ -6239,13 +6210,14 @@ static void Task_HandleEvolutionScreenInput(u8 taskId) static void HandleTargetSpeciesPrintText(u32 targetSpecies, u32 base_x, u32 base_y, u32 base_y_offset, u32 base_i) { bool32 seen = GetSetPokedexFlag(SpeciesToNationalPokedexNum(targetSpecies), FLAG_GET_SEEN); + u32 fontId = GetSpeciesNameFontId(GetSpeciesNameWidthInChars(GetSpeciesName(targetSpecies))); if (seen || !HGSS_HIDE_UNSEEN_EVOLUTION_NAMES) StringCopy(gStringVar3, GetSpeciesName(targetSpecies)); //evolution mon name else StringCopy(gStringVar3, gText_ThreeQuestionMarks); //show questionmarks instead of name StringExpandPlaceholders(gStringVar3, sText_EVO_Name); //evolution mon name - PrintInfoScreenTextSmall(gStringVar3, base_x, base_y + base_y_offset*base_i); //evolution mon name + PrintInfoScreenTextSmall(gStringVar3, fontId, base_x, base_y + base_y_offset*base_i); //evolution mon name } static void HandleTargetSpeciesPrintIcon(u8 taskId, u16 targetSpecies, u8 base_i, u8 iterations) @@ -6267,7 +6239,7 @@ static void CreateCaughtBallEvolutionScreen(u16 targetSpecies, u8 x, u8 y, u16 u else { //FillWindowPixelRect(0, PIXEL_FILL(0), x, y, 8, 16); //not sure why this was even here - PrintInfoScreenTextSmall(gText_OneDash, x+1, y-1); + PrintInfoScreenTextSmall(gText_OneDash, FONT_SMALL, x+1, y-1); } } @@ -6291,7 +6263,7 @@ static void HandlePreEvolutionSpeciesPrint(u8 taskId, u16 preSpecies, u16 specie } - PrintInfoScreenTextSmall(gStringVar3, base_x, base_y + base_y_offset*base_i); //evolution mon name + PrintInfoScreenTextSmall(gStringVar3, FONT_SMALL, base_x, base_y + base_y_offset*base_i); //evolution mon name if (base_i < 3) { @@ -6413,21 +6385,48 @@ static u8 PrintPreEvolutions(u8 taskId, u16 species) #define EVO_SCREEN_CRITS_DIGITS 1 #define EVO_SCREEN_DMG_DIGITS 2 -static void PrintEvolutionTargetSpeciesAndMethod(u8 taskId, u16 species, u8 depth, u32 *depth_i, u32 alreadyPrintedIcons[], u32 *icon_depth_i) +u32 GetSpeciesNameFontId(u32 nameWidth) +{ + if (nameWidth <= 8) + return FONT_SMALL; + else if (nameWidth > 7 && nameWidth < 11) + return FONT_SMALL;//_NARROW; + else + return FONT_SMALL;//_NARROWER; +} + +u32 GetSpeciesNameWidthInChars(const u8 *speciesName) +{ + u32 i = 0; + + while (speciesName[i] != EOS) i++; + + return i; +} + +bool32 IsSpeciesAlcremie(u32 targetSpecies) +{ + return targetSpecies >= SPECIES_ALCREMIE_STRAWBERRY_VANILLA_CREAM && targetSpecies <= SPECIES_ALCREMIE_RIBBON_RAINBOW_SWIRL; +} + +bool32 IsItemSweet(u32 item) +{ + return item >= ITEM_STRAWBERRY_SWEET && item <= ITEM_RIBBON_SWEET; +} + +static void PrintEvolutionTargetSpeciesAndMethod(u8 taskId, u16 species, u8 depth, u32 *depth_i, u32 alreadyPrintedIcons[], u32 *icon_depth_i, u32 numLines) { int i; - const struct MapHeader *mapHeader; + u32 depth_x = 4; + u32 depth_offset = 8 * (depth + 1); + int fontId; u16 targetSpecies = 0; - - u16 item; - bool8 left = TRUE; - u8 base_x = 13+8; - u8 base_x_offset = 54+8; - u8 base_y = 51; - u8 base_y_offset = 9; - u8 times = 0; - u8 depth_x = 16; + u32 base_x = 21; + u32 base_y = 51; + u32 base_y_offset = 9; + u32 times = 0; + u32 arg; // shorthand for some of the more mathy evolutions const struct Evolution *evolutions = GetSpeciesEvolutions(species); if (sPokedexView->sEvoScreenData.isMega) @@ -6435,23 +6434,28 @@ static void PrintEvolutionTargetSpeciesAndMethod(u8 taskId, u16 species, u8 dept StringCopy(gStringVar1, GetSpeciesName(species)); + sPokedexView->sEvoScreenData.arrowSpriteDist[depth] = numLines; + //If there are no evolutions print text and return if (evolutions == NULL) { if (depth == 0) { StringExpandPlaceholders(gStringVar4, sText_EVO_NONE); - PrintInfoScreenTextSmall(gStringVar4, base_x-7-7, base_y + base_y_offset*(*depth_i)); + PrintInfoScreenTextSmall(gStringVar4, FONT_SMALL, base_x-7-7, base_y + base_y_offset*(*depth_i) + numLines); } return; } //Calculate number of possible direct evolutions (e.g. Eevee has 5 but torchic has 1) for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) - { - if (evolutions[i].method != 0) - times += 1; - } + times += 1; + + if (times > 9 && species == SPECIES_MILCERY) + times = 9; + else if (times > 10) + times = 10; + gTasks[taskId].data[3] = times; sPokedexView->sEvoScreenData.numAllEvolutions += times; @@ -6462,9 +6466,18 @@ static void PrintEvolutionTargetSpeciesAndMethod(u8 taskId, u16 species, u8 dept left = !left; targetSpecies = evolutions[i].targetSpecies; + bool32 isAlcremie = IsSpeciesAlcremie(targetSpecies); + + u32 speciesNameWidthInChars = GetSpeciesNameWidthInChars(GetSpeciesName(targetSpecies)); + u32 speciesNameCharWidth = GetFontAttribute(GetSpeciesNameFontId(speciesNameWidthInChars), FONTATTR_MAX_LETTER_WIDTH); + + u32 speciesNameWidth = (speciesNameWidthInChars * speciesNameCharWidth); + u32 base_x_offset = speciesNameWidth + base_x + depth_offset; // for evo method info + u32 maxScreenWidth = 230 - base_x_offset; + sPokedexView->sEvoScreenData.targetSpecies[*depth_i] = targetSpecies; - CreateCaughtBallEvolutionScreen(targetSpecies, base_x + depth_x*depth-9, base_y + base_y_offset*(*depth_i), 0); - HandleTargetSpeciesPrintText(targetSpecies, base_x + depth_x*depth, base_y, base_y_offset, *depth_i); //evolution mon name + CreateCaughtBallEvolutionScreen(targetSpecies, base_x + depth_x*depth-9, base_y + base_y_offset*(*depth_i) + numLines, 0); + HandleTargetSpeciesPrintText(targetSpecies, base_x + depth_x*depth, base_y, base_y_offset + numLines, *depth_i); //evolution mon name for (j = 0; j < MAX_EVOLUTION_ICONS; j++) { @@ -6479,215 +6492,282 @@ static void PrintEvolutionTargetSpeciesAndMethod(u8 taskId, u16 species, u8 dept } } - switch (evolutions[i].method) + switch ((enum EvolutionMethods)evolutions[i].method) { - case EVO_FRIENDSHIP: - ConvertIntToDecimalStringN(gStringVar2, 220, STR_CONV_MODE_LEADING_ZEROS, 3); //friendship value - StringExpandPlaceholders(gStringVar4, sText_EVO_FRIENDSHIP ); - break; - case EVO_FRIENDSHIP_DAY: - StringExpandPlaceholders(gStringVar4, sText_EVO_FRIENDSHIP_DAY ); - break; - case EVO_FRIENDSHIP_NIGHT: - StringExpandPlaceholders(gStringVar4, sText_EVO_FRIENDSHIP_NIGHT ); + case EVO_SCRIPT_TRIGGER: + case EVO_NONE: + StringExpandPlaceholders(gStringVar4, COMPOUND_STRING("Unknown")); break; case EVO_LEVEL: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL ); + case EVO_LEVEL_BATTLE_ONLY: + StringCopy(gStringVar4, COMPOUND_STRING("{LV}{UP_ARROW}")); + if (evolutions[i].param > 1) + { + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEFT_ALIGN, EVO_SCREEN_LVL_DIGITS); //level + StringAppend(gStringVar4, gStringVar2); + } + if ((enum EvolutionMethods)evolutions[i].method == EVO_LEVEL_BATTLE_ONLY) + StringAppend(gStringVar4, COMPOUND_STRING(", in battle")); break; case EVO_TRADE: - StringExpandPlaceholders(gStringVar4, sText_EVO_TRADE ); - break; - case EVO_TRADE_ITEM: - item = evolutions[i].param; //item - CopyItemName(item, gStringVar2); //item - StringExpandPlaceholders(gStringVar4, sText_EVO_TRADE_ITEM ); + StringExpandPlaceholders(gStringVar4, COMPOUND_STRING("Trading")); break; case EVO_ITEM: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM ); + CopyItemName(evolutions[i].param, gStringVar2); + StringExpandPlaceholders(gStringVar4, COMPOUND_STRING("{STR_VAR_2} is used")); break; - case EVO_LEVEL_ATK_GT_DEF: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_ATK_GT_DEF ); + case EVO_SPLIT_FROM_EVO: + StringCopy(gStringVar4, COMPOUND_STRING("Splits from ")); + StringAppend(gStringVar4, GetSpeciesName(evolutions[i].param)); //mon name break; - case EVO_LEVEL_ATK_EQ_DEF: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_ATK_EQ_DEF ); + case EVO_BATTLE_END: + StringExpandPlaceholders(gStringVar4, COMPOUND_STRING("End battle")); break; - case EVO_LEVEL_ATK_LT_DEF: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_ATK_LT_DEF ); - break; - case EVO_LEVEL_SILCOON: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_SILCOON ); - break; - case EVO_LEVEL_CASCOON: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_CASCOON ); - break; - case EVO_LEVEL_NINJASK: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_NINJASK ); - break; - case EVO_LEVEL_SHEDINJA: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_SHEDINJA ); - break; - case EVO_BEAUTY: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, 3); //beauty - StringExpandPlaceholders(gStringVar4, sText_EVO_BEAUTY ); - break; - case EVO_LEVEL_FEMALE: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_FEMALE ); - break; - case EVO_LEVEL_MALE: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_MALE ); - break; - case EVO_LEVEL_NIGHT: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_NIGHT ); - break; - case EVO_LEVEL_DAY: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_DAY ); - break; - case EVO_LEVEL_DUSK: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_DUSK ); - break; - case EVO_ITEM_HOLD_DAY: - item = evolutions[i].param; //item - CopyItemName(item, gStringVar2); //item - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_HOLD_DAY ); - break; - case EVO_ITEM_HOLD_NIGHT: - item = evolutions[i].param; //item - CopyItemName(item, gStringVar2); //item - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_HOLD_NIGHT ); - break; - case EVO_MOVE: - StringCopy(gStringVar2, GetMoveName(evolutions[i].param)); - StringExpandPlaceholders(gStringVar4, sText_EVO_MOVE ); - break; - case EVO_FRIENDSHIP_MOVE_TYPE: - StringCopy(gStringVar2, gTypesInfo[evolutions[i].param].name); - StringExpandPlaceholders(gStringVar4, sText_EVO_FRIENDSHIP_MOVE_TYPE ); - break; - case EVO_MAPSEC: - StringCopy(gStringVar2, gRegionMapEntries[evolutions[i].param].name); - StringExpandPlaceholders(gStringVar4, sText_EVO_MAPSEC ); - break; - case EVO_ITEM_MALE: - item = evolutions[i].param; //item - CopyItemName(item, gStringVar2); //item - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_MALE ); - break; - case EVO_ITEM_FEMALE: - item = evolutions[i].param; //item - CopyItemName(item, gStringVar2); //item - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_FEMALE ); - break; - case EVO_LEVEL_RAIN: - //if (j == WEATHER_RAIN || j == WEATHER_RAIN_THUNDERSTORM || j == WEATHER_DOWNPOUR) - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_RAIN ); - break; - case EVO_SPECIFIC_MON_IN_PARTY: - StringCopy(gStringVar2, GetSpeciesName(evolutions[i].param)); //mon name - StringExpandPlaceholders(gStringVar4, sText_EVO_SPECIFIC_MON_IN_PARTY ); - break; - case EVO_LEVEL_DARK_TYPE_MON_IN_PARTY: - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_DARK_TYPE_MON_IN_PARTY ); - break; - case EVO_TRADE_SPECIFIC_MON: - StringCopy(gStringVar2, GetSpeciesName(evolutions[i].param)); //mon name - StringExpandPlaceholders(gStringVar4, sText_EVO_TRADE_SPECIFIC_MON ); - break; - case EVO_SPECIFIC_MAP: - mapHeader = Overworld_GetMapHeaderByGroupAndId(evolutions[i].param >> 8, evolutions[i].param & 0xFF); - GetMapName(gStringVar2, mapHeader->regionMapSectionId, 0); - StringExpandPlaceholders(gStringVar4, sText_EVO_SPECIFIC_MAP ); - break; - case EVO_LEVEL_NATURE_AMPED: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_NATURE_AMPED); - break; - case EVO_LEVEL_NATURE_LOW_KEY: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_LVL_DIGITS); //level - StringExpandPlaceholders(gStringVar4, sText_EVO_LEVEL_NATURE_LOW_KEY); - break; - case EVO_CRITICAL_HITS: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_CRITS_DIGITS); //crits - StringExpandPlaceholders(gStringVar4, sText_EVO_CRITICAL_HITS); - break; - case EVO_SCRIPT_TRIGGER_DMG: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, EVO_SCREEN_DMG_DIGITS); //damage - StringExpandPlaceholders(gStringVar4, sText_EVO_SCRIPT_TRIGGER_DMG); - break; - case EVO_DARK_SCROLL: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringExpandPlaceholders(gStringVar4, sText_EVO_DARK_SCROLL ); - break; - case EVO_WATER_SCROLL: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringExpandPlaceholders(gStringVar4, sText_EVO_WATER_SCROLL ); - break; - case EVO_ITEM_NIGHT: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_NIGHT ); - break; - case EVO_ITEM_DAY: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_DAY ); - break; - case EVO_ITEM_HOLD: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_HOLD ); - break; - case EVO_USE_MOVE_TWENTY_TIMES: - StringCopy(gStringVar2, GetMoveName(evolutions[i].param)); - StringExpandPlaceholders(gStringVar4, sText_EVO_USE_MOVE_TWENTY_TIMES ); - break; - case EVO_RECOIL_DAMAGE_MALE: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, 3); - StringExpandPlaceholders(gStringVar4, sText_EVO_RECOIL_DAMAGE_MALE); - break; - case EVO_RECOIL_DAMAGE_FEMALE: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, 3); - StringExpandPlaceholders(gStringVar4, sText_EVO_RECOIL_DAMAGE_FEMALE); - break; - case EVO_ITEM_COUNT_999: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringExpandPlaceholders(gStringVar4, sText_EVO_ITEM_COUNT_999); - break; - case EVO_DEFEAT_THREE_WITH_ITEM: - item = evolutions[i].param; - CopyItemName(item, gStringVar2); - StringCopy(gStringVar3, GetSpeciesName(species)); - StringExpandPlaceholders(gStringVar4, sText_EVO_DEFEAT_THREE_WITH_ITEM); - break; - case EVO_OVERWORLD_STEPS: - ConvertIntToDecimalStringN(gStringVar2, evolutions[i].param, STR_CONV_MODE_LEADING_ZEROS, 4); - StringExpandPlaceholders(gStringVar4, sText_EVO_OVERWORLD_STEPS); - break; - default: - StringExpandPlaceholders(gStringVar4, sText_EVO_UNKNOWN); + case EVO_SPIN: + StringCopy(gStringVar4, COMPOUND_STRING("Spin ")); + if (evolutions[i].param == SPIN_CW_SHORT) + StringAppend(gStringVar4, COMPOUND_STRING("CW <5s")); + else if (evolutions[i].param == SPIN_CW_LONG) + StringAppend(gStringVar4, COMPOUND_STRING("CW >5s")); + else if (evolutions[i].param == SPIN_CCW_SHORT) + StringAppend(gStringVar4, COMPOUND_STRING("CCW <5s")); + else if (evolutions[i].param == SPIN_CCW_LONG) + StringAppend(gStringVar4, COMPOUND_STRING("CCW >5s")); + else + StringAppend(gStringVar4, COMPOUND_STRING("CW/CCW >10s")); break; }//Switch end - PrintInfoScreenTextSmall(gStringVar4, base_x + depth_x*depth+base_x_offset, base_y + base_y_offset*(*depth_i)); //Print actual instructions + // Check for additional conditions. Skips if there's no additional conditions. + for (j = 0; evolutions[i].params != NULL && evolutions[i].params[j].condition != CONDITIONS_END; j++) + { + if (j == 0) + { + StringAppend(gStringVar4, COMPOUND_STRING(", ")); + } + + switch((enum EvolutionConditions)evolutions[i].params[j].condition) + { + // Gen 2 + case IF_GENDER: + switch(evolutions[i].params[j].arg1) + { + case MON_MALE: StringAppend(gStringVar4, COMPOUND_STRING("Male")); break; + case MON_FEMALE: StringAppend(gStringVar4, COMPOUND_STRING("Female")); break; + } + break; + case IF_MIN_FRIENDSHIP: + StringAppend(gStringVar4, COMPOUND_STRING("{UP_ARROW_2}friendship")); + break; + case IF_ATK_GT_DEF: + StringAppend(gStringVar4, COMPOUND_STRING("Atk > Def")); + break; + case IF_ATK_EQ_DEF: + StringAppend(gStringVar4, COMPOUND_STRING("Atk = Def")); + break; + case IF_ATK_LT_DEF: + StringAppend(gStringVar4, COMPOUND_STRING("Atk < Def")); + break; + case IF_TIME: + switch(evolutions[i].params[j].arg1) + { + case TIME_MORNING: StringAppend(gStringVar4, COMPOUND_STRING("Morning")); break; + case TIME_DAY: StringAppend(gStringVar4, COMPOUND_STRING("Day")); break; + case TIME_EVENING: StringAppend(gStringVar4, COMPOUND_STRING("Evening")); break; + case TIME_NIGHT: StringAppend(gStringVar4, COMPOUND_STRING("Night")); break; + } + break; + case IF_NOT_TIME: + switch(evolutions[i].params[j].arg1) + { + case TIME_MORNING: StringAppend(gStringVar4, COMPOUND_STRING("NOT Morning")); break; + case TIME_DAY: StringAppend(gStringVar4, COMPOUND_STRING("NOT Day")); break; + case TIME_EVENING: StringAppend(gStringVar4, COMPOUND_STRING("NOT Evening")); break; + case TIME_NIGHT: StringAppend(gStringVar4, COMPOUND_STRING("Day")); break; // More intuitive than "NOT Night" + } + break; + case IF_HOLD_ITEM: + StringAppend(gStringVar4, COMPOUND_STRING("holds ")); + if (isAlcremie && IsItemSweet(evolutions[i].params[j].arg1)) + { + StringAppend(gStringVar4, COMPOUND_STRING("Sweet")); //item + } + else + { + CopyItemName(evolutions[i].params[j].arg1, gStringVar2); //item + StringAppend(gStringVar4, gStringVar2); + } + break; + // Gen 3 + case IF_PID_UPPER_MODULO_10_GT: + case IF_PID_UPPER_MODULO_10_EQ: + case IF_PID_UPPER_MODULO_10_LT: + arg = evolutions[i].params[j].arg1; + if ((enum EvolutionConditions)evolutions[i].params[j].condition == IF_PID_UPPER_MODULO_10_GT + && arg < 10 && arg >= 0) + arg = 9 - arg; + else if ((enum EvolutionConditions)evolutions[i].params[j].condition == IF_PID_UPPER_MODULO_10_EQ + && arg < 10 && arg >= 0) + arg = 1; + ConvertIntToDecimalStringN(gStringVar2, arg * 10, STR_CONV_MODE_LEFT_ALIGN, 3); + StringAppend(gStringVar4, COMPOUND_STRING("random %")); + StringAppend(gStringVar4, gStringVar2); + break; + case IF_MIN_BEAUTY: + StringAppend(gStringVar4, COMPOUND_STRING("{UP_ARROW_2}beauty")); + break; + case IF_MIN_COOLNESS: + StringAppend(gStringVar4, COMPOUND_STRING("{UP_ARROW_2}coolness")); + break; + case IF_MIN_SMARTNESS: + StringAppend(gStringVar4, COMPOUND_STRING("{UP_ARROW_2}smartness")); + break; + case IF_MIN_TOUGHNESS: + StringAppend(gStringVar4, COMPOUND_STRING("{UP_ARROW_2}toughness")); + break; + case IF_MIN_CUTENESS: + StringAppend(gStringVar4, COMPOUND_STRING("{UP_ARROW_2}cuteness")); + break; + // Gen 4 + case IF_SPECIES_IN_PARTY: + StringAppend(gStringVar4, GetSpeciesName(evolutions[i].params[j].arg1)); //mon name + StringAppend(gStringVar4, COMPOUND_STRING(" in party")); + break; + case IF_IN_MAPSEC: + StringAppend(gStringVar4, COMPOUND_STRING("in ")); + StringCopy(gStringVar2, gRegionMapEntries[evolutions[i].params[j].arg1].name); + StringAppend(gStringVar4, gStringVar2); + break; + case IF_IN_MAP: + StringAppend(gStringVar4, COMPOUND_STRING("in ")); + GetMapName(gStringVar2, Overworld_GetMapHeaderByGroupAndId(evolutions[i].params[j].arg1 >> 8, evolutions[i].params[j].arg1 & 0xFF)->regionMapSectionId, 0); + StringAppend(gStringVar4, gStringVar2); + break; + case IF_KNOWS_MOVE: + StringAppend(gStringVar4, COMPOUND_STRING("knows ")); + StringAppend(gStringVar4, GetMoveName(evolutions[i].params[j].arg1)); + break; + // Gen 5 + case IF_TRADE_PARTNER_SPECIES: + StringAppend(gStringVar4, COMPOUND_STRING("traded with ")); + StringAppend(gStringVar4, GetSpeciesName(evolutions[i].params[j].arg1)); + break; + // Gen 6 + case IF_TYPE_IN_PARTY: + StringAppend(gStringVar4, gTypesInfo[evolutions[i].params[j].arg1].name); //type name + StringAppend(gStringVar4, COMPOUND_STRING("-type in party")); + break; + case IF_WEATHER: + StringAppend(gStringVar4, COMPOUND_STRING("weather ")); + StringAppend(gStringVar4, GetWeatherName(evolutions[i].params[j].arg1)); + break; + case IF_KNOWS_MOVE_TYPE: + StringAppend(gStringVar4, gTypesInfo[evolutions[i].params[j].arg1].name); + StringAppend(gStringVar4, COMPOUND_STRING(" move")); + break; + // Gen 8 + case IF_NATURE: + StringCopy(gStringVar2, gNaturesInfo[evolutions[i].params[j].arg1].name); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" nature")); + break; + case IF_AMPED_NATURE: + StringAppend(gStringVar4, COMPOUND_STRING("amped natures")); + break; + case IF_LOW_KEY_NATURE: + StringAppend(gStringVar4, COMPOUND_STRING("low-Key natures")); + break; + case IF_RECOIL_DAMAGE_GE: + StringAppend(gStringVar4, COMPOUND_STRING("takes >= ")); + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].params[j].arg1, STR_CONV_MODE_LEFT_ALIGN, 3); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" recoil dmg")); + break; + case IF_CURRENT_DAMAGE_GE: + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].params[j].arg1, STR_CONV_MODE_LEFT_ALIGN, 3); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" current dmg")); + break; + case IF_CRITICAL_HITS_GE: + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].params[j].arg1, STR_CONV_MODE_LEFT_ALIGN, 2); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" critical hits")); + break; + case IF_USED_MOVE_X_TIMES: + StringAppend(gStringVar4, COMPOUND_STRING("use move ")); + StringAppend(gStringVar4, GetMoveName(evolutions[i].params[j].arg1)); + StringAppend(gStringVar4, COMPOUND_STRING(" ")); + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].params[j].arg2, STR_CONV_MODE_LEFT_ALIGN, 3); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" times")); + break; + // Gen 9 + case IF_DEFEAT_X_WITH_ITEMS: + StringAppend(gStringVar4, COMPOUND_STRING("defeat ")); + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].params[j].arg3, STR_CONV_MODE_LEFT_ALIGN, 3); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" ")); + StringAppend(gStringVar4, GetSpeciesName(evolutions[i].params[j].arg1)); + StringAppend(gStringVar4, COMPOUND_STRING(" that hold ")); + CopyItemName(evolutions[i].params[j].arg2, gStringVar2); + StringAppend(gStringVar4, gStringVar2); + break; + case IF_PID_MODULO_100_GT: + case IF_PID_MODULO_100_EQ: + case IF_PID_MODULO_100_LT: + arg = evolutions[i].params[j].arg1; + if ((enum EvolutionConditions)evolutions[i].params[j].condition == IF_PID_MODULO_100_GT + && arg < 100 && arg >= 0) + arg = 99 - arg; + else if ((enum EvolutionConditions)evolutions[i].params[j].condition == IF_PID_MODULO_100_EQ + && arg < 100 && arg >= 0) + arg = 1; + ConvertIntToDecimalStringN(gStringVar2, arg, STR_CONV_MODE_LEFT_ALIGN, 3); + StringAppend(gStringVar4, COMPOUND_STRING("%")); + StringAppend(gStringVar4, gStringVar2); + break; + case IF_MIN_OVERWORLD_STEPS: + StringAppend(gStringVar4, COMPOUND_STRING("after ")); + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].params[j].arg1, STR_CONV_MODE_LEFT_ALIGN, 4); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" steps")); + break; + case IF_BAG_ITEM_COUNT: + ConvertIntToDecimalStringN(gStringVar2, evolutions[i].params[j].arg2, STR_CONV_MODE_LEFT_ALIGN, 3); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" ")); + CopyItemNameHandlePlural(evolutions[i].params[j].arg1, gStringVar2, evolutions[i].params[j].arg2); + StringAppend(gStringVar4, gStringVar2); + StringAppend(gStringVar4, COMPOUND_STRING(" in bag")); + break; + case CONDITIONS_END: + break; + } + + if (evolutions[i].params[j+1].condition != CONDITIONS_END) + { + StringAppend(gStringVar4, COMPOUND_STRING(", ")); + } + } + + if (isAlcremie) + fontId = FONT_NARROWER; + else + fontId = GetFontIdToFit(gStringVar4, FONT_SMALL, 0, maxScreenWidth); + + u32 fontHeight = GetFontAttribute(fontId, FONTATTR_MAX_LETTER_HEIGHT); + + StringAppend(gStringVar4, COMPOUND_STRING(".")); + BreakStringAutomatic(gStringVar4, maxScreenWidth, MAX_EVO_METHOD_LINES, fontId, HIDE_SCROLL_PROMPT); + + PrintInfoScreenTextSmall(gStringVar4, fontId, base_x_offset, base_y + base_y_offset*(*depth_i) + numLines); //Print actual instructions (*depth_i)++; - PrintEvolutionTargetSpeciesAndMethod(taskId, targetSpecies, depth+1, depth_i, alreadyPrintedIcons, icon_depth_i); + + numLines = CountLineBreaks(gStringVar4) * fontHeight; + + sPokedexView->sEvoScreenData.arrowSpriteDist[depth + 1] = numLines; + + PrintEvolutionTargetSpeciesAndMethod(taskId, targetSpecies, depth+1, depth_i, alreadyPrintedIcons, icon_depth_i, numLines); }//For loop end } @@ -6995,7 +7075,7 @@ static void PrintForms(u8 taskId, u16 species) if (times == 0) { StringExpandPlaceholders(gStringVar4, sText_FORMS_NONE); - PrintInfoScreenTextSmall(gStringVar4, base_x, base_y + base_y_offset*times); + PrintInfoScreenTextSmall(gStringVar4, FONT_SMALL, base_x, base_y + base_y_offset*times); } } diff --git a/src/pokemon.c b/src/pokemon.c index d480701a3e..de9893f6bd 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -16,6 +16,7 @@ #include "event_data.h" #include "event_object_movement.h" #include "evolution_scene.h" +#include "field_player_avatar.h" #include "field_specials.h" #include "field_weather.h" #include "graphics.h" @@ -4069,11 +4070,13 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov case 7: // ITEM4_EVO_STONE { - u16 targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_ITEM_USE, item, NULL, DO_EVO); + bool32 canStopEvo = TRUE; + u32 targetSpecies = GetEvolutionTargetSpecies(mon, EVO_MODE_ITEM_USE, item, NULL, &canStopEvo, CHECK_EVO); if (targetSpecies != SPECIES_NONE) { - BeginEvolutionScene(mon, targetSpecies, FALSE, partyIndex); + GetEvolutionTargetSpecies(mon, EVO_MODE_ITEM_USE, item, NULL, &canStopEvo, DO_EVO); + BeginEvolutionScene(mon, targetSpecies, canStopEvo, partyIndex); return FALSE; } } @@ -4461,25 +4464,24 @@ u32 GetGMaxTargetSpecies(u32 species) return species; } -u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 evolutionItem, struct Pokemon *tradePartner, enum StartEvo prepareEvo) +bool32 DoesMonMeetAdditionalConditions(struct Pokemon *mon, const struct EvolutionParam *params, struct Pokemon *tradePartner, u32 partyId, bool32 *canStopEvo, enum EvoState evoState) { - int i, j; - u16 targetSpecies = SPECIES_NONE; - u16 species = GetMonData(mon, MON_DATA_SPECIES, 0); - u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); + u32 i, j; + u32 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM); + u32 gender = GetMonGender(mon); + u32 friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); + u32 attack = GetMonData(mon, MON_DATA_ATK, 0); + u32 defense = GetMonData(mon, MON_DATA_DEF, 0); u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0); - u8 level; - u16 friendship; - u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0); u16 upperPersonality = personality >> 16; - enum ItemHoldEffect holdEffect; - u32 currentMap, partnerSpecies, partnerHeldItem, partnerHoldEffect; - bool32 consumeItem = FALSE; - u16 evolutionTracker = GetMonData(mon, MON_DATA_EVOLUTION_TRACKER, 0); - const struct Evolution *evolutions = GetSpeciesEvolutions(species); - - if (evolutions == NULL) - return SPECIES_NONE; + u32 weather = GetCurrentWeather(); + u32 nature = GetNature(mon); + bool32 removeHoldItem = FALSE; + u32 removeBagItem = ITEM_NONE; + u32 removeBagItemCount = 0; + u32 evolutionTracker = GetMonData(mon, MON_DATA_EVOLUTION_TRACKER, 0); + u32 partnerSpecies, partnerHeldItem; + enum ItemHoldEffect partnerHoldEffect; if (tradePartner != NULL) { @@ -4502,6 +4504,289 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 partnerHoldEffect = HOLD_EFFECT_NONE; } + // Check for additional conditions (only if the primary method passes). Skips if there's no additional conditions. + for (i = 0; params != NULL && params[i].condition != CONDITIONS_END; i++) + { + enum EvolutionConditions condition = params[i].condition; + u32 currentCondition = FALSE; + + switch(condition) + { + // Gen 2 + case IF_GENDER: + if (gender == GetMonGender(mon)) + currentCondition = TRUE; + break; + case IF_MIN_FRIENDSHIP: + if (friendship >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_ATK_GT_DEF: + if (attack > defense) + currentCondition = TRUE; + break; + case IF_ATK_EQ_DEF: + if (attack == defense) + currentCondition = TRUE; + break; + case IF_ATK_LT_DEF: + if (attack < defense) + currentCondition = TRUE; + break; + case IF_TIME: + if (GetTimeOfDay() == params[i].arg1) + currentCondition = TRUE; + + break; + case IF_NOT_TIME: + if (GetTimeOfDay() != params[i].arg1) + currentCondition = TRUE; + break; + case IF_HOLD_ITEM: + if (heldItem == params[i].arg1) + { + currentCondition = TRUE; + removeHoldItem = TRUE; + } + break; + // Gen 3 + case IF_PID_UPPER_MODULO_10_GT: + if ((upperPersonality % 10) > params[i].arg1) + currentCondition = TRUE; + break; + case IF_PID_UPPER_MODULO_10_EQ: + if ((upperPersonality % 10) == params[i].arg1) + currentCondition = TRUE; + break; + case IF_PID_UPPER_MODULO_10_LT: + if ((upperPersonality % 10) < params[i].arg1) + currentCondition = TRUE; + break; + case IF_MIN_BEAUTY: + u32 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0); + if (beauty >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_MIN_COOLNESS: + u32 coolness = GetMonData(mon, MON_DATA_COOL, 0); + if (coolness >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_MIN_SMARTNESS: + // remember that even though it's called "Smart/Smartness" here, + // from gen 6 and up it's known as "Clever/Cleverness." + u32 smartness = GetMonData(mon, MON_DATA_SMART, 0); + if (smartness >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_MIN_TOUGHNESS: + u32 toughness = GetMonData(mon, MON_DATA_TOUGH, 0); + if (toughness >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_MIN_CUTENESS: + u32 cuteness = GetMonData(mon, MON_DATA_CUTE, 0); + if (cuteness >= params[i].arg1) + currentCondition = TRUE; + break; + // Gen 4 + case IF_SPECIES_IN_PARTY: + for (j = 0; j < PARTY_SIZE; j++) + { + if (GetMonData(&gPlayerParty[j], MON_DATA_SPECIES, NULL) == params[i].arg1) + { + currentCondition = TRUE; + break; + } + } + break; + case IF_IN_MAP: + if (params[i].arg1 == ((gSaveBlock1Ptr->location.mapGroup) << 8 | gSaveBlock1Ptr->location.mapNum)) + currentCondition = TRUE; + break; + case IF_IN_MAPSEC: + if (gMapHeader.regionMapSectionId == params[i].arg1) + currentCondition = TRUE; + break; + case IF_KNOWS_MOVE: + if (MonKnowsMove(mon, params[i].arg1)) + currentCondition = TRUE; + break; + // Gen 5 + case IF_TRADE_PARTNER_SPECIES: + if (params[i].arg1 == partnerSpecies && partnerHoldEffect != HOLD_EFFECT_PREVENT_EVOLVE) + currentCondition = TRUE; + break; + // Gen 6 + case IF_TYPE_IN_PARTY: + for (j = 0; j < PARTY_SIZE; j++) + { + u16 currSpecies = GetMonData(&gPlayerParty[j], MON_DATA_SPECIES, NULL); + if (gSpeciesInfo[currSpecies].types[0] == params[i].arg1 + || gSpeciesInfo[currSpecies].types[1] == params[i].arg1) + { + currentCondition = TRUE; + break; + } + } + break; + case IF_WEATHER: + if (params[i].arg1 == WEATHER_RAIN) + { + if (weather == WEATHER_RAIN || weather == WEATHER_RAIN_THUNDERSTORM || weather == WEATHER_DOWNPOUR) + currentCondition = TRUE; + } + else if (params[i].arg1 == WEATHER_FOG) + { + if (weather == WEATHER_FOG_DIAGONAL || weather == WEATHER_FOG_HORIZONTAL) + currentCondition = TRUE; + } + else if (weather == params[i].arg1) + { + currentCondition = TRUE; + } + + break; + case IF_KNOWS_MOVE_TYPE: + for (j = 0; j < MAX_MON_MOVES; j++) + { + if (GetMoveType(GetMonData(mon, MON_DATA_MOVE1 + j, NULL)) == params[i].arg1) + { + currentCondition = TRUE; + break; + } + } + break; + // Gen 8 + case IF_NATURE: + if (nature == params[i].arg1) + currentCondition = TRUE; + break; + case IF_AMPED_NATURE: + switch (nature) + { + case NATURE_HARDY: + case NATURE_BRAVE: + case NATURE_ADAMANT: + case NATURE_NAUGHTY: + case NATURE_DOCILE: + case NATURE_IMPISH: + case NATURE_LAX: + case NATURE_HASTY: + case NATURE_JOLLY: + case NATURE_NAIVE: + case NATURE_RASH: + case NATURE_SASSY: + case NATURE_QUIRKY: + currentCondition = TRUE; + break; + } + break; + case IF_LOW_KEY_NATURE: + switch (nature) + { + case NATURE_LONELY: + case NATURE_BOLD: + case NATURE_RELAXED: + case NATURE_TIMID: + case NATURE_SERIOUS: + case NATURE_MODEST: + case NATURE_MILD: + case NATURE_QUIET: + case NATURE_BASHFUL: + case NATURE_CALM: + case NATURE_GENTLE: + case NATURE_CAREFUL: + currentCondition = TRUE; + break; + } + break; + case IF_RECOIL_DAMAGE_GE: + if (evolutionTracker >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_CURRENT_DAMAGE_GE: + { + u32 currentHp = GetMonData(mon, MON_DATA_HP, NULL); + if (currentHp != 0 && (GetMonData(mon, MON_DATA_MAX_HP, NULL) - currentHp >= params[i].arg1)) + currentCondition = TRUE; + break; + } + case IF_CRITICAL_HITS_GE: + if (partyId != PARTY_SIZE && gPartyCriticalHits[partyId] >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_USED_MOVE_X_TIMES: + if (evolutionTracker >= params[i].arg2) + currentCondition = TRUE; + // Gen 9 + case IF_DEFEAT_X_WITH_ITEMS: + if (evolutionTracker >= params[i].arg3) + currentCondition = TRUE; + break; + case IF_PID_MODULO_100_GT: + if ((personality % 100) > params[i].arg1) + currentCondition = TRUE; + break; + case IF_PID_MODULO_100_EQ: + if ((personality % 100) == params[i].arg1) + currentCondition = TRUE; + break; + case IF_PID_MODULO_100_LT: + if ((personality % 100) < params[i].arg1) + currentCondition = TRUE; + break; + case IF_MIN_OVERWORLD_STEPS: + if (mon == GetFirstLiveMon() && gFollowerSteps >= params[i].arg1) + currentCondition = TRUE; + break; + case IF_BAG_ITEM_COUNT: + if (CheckBagHasItem(params[i].arg1, params[i].arg2)) + { + currentCondition = TRUE; + removeBagItem = params[i].arg1; + removeBagItemCount = params[i].arg2; + if (canStopEvo != NULL) + *canStopEvo = FALSE; + } + break; + case CONDITIONS_END: + break; + } + + // check if an evolution is about to happen and items should be removed + if (evoState == DO_EVO) + { + if (removeHoldItem) + { + u32 heldItem = ITEM_NONE; + SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); + } + + if (removeBagItem != ITEM_NONE) + RemoveBagItem(removeBagItem, removeBagItemCount); + } + + if (currentCondition == FALSE) + return FALSE; + } + + return TRUE; +} + +u32 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 evolutionItem, struct Pokemon *tradePartner, bool32 *canStopEvo, enum EvoState evoState) +{ + int i; + u32 targetSpecies = SPECIES_NONE; + u32 species = GetMonData(mon, MON_DATA_SPECIES, 0); + u32 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0); + u32 level = GetMonData(mon, MON_DATA_LEVEL, 0); + u32 holdEffect; + const struct Evolution *evolutions = GetSpeciesEvolutions(species); + + if (evolutions == NULL) + return SPECIES_NONE; + if (heldItem == ITEM_ENIGMA_BERRY_E_READER) #if FREE_ENIGMA_BERRY == FALSE holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect; @@ -4521,271 +4806,31 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 { case EVO_MODE_NORMAL: case EVO_MODE_BATTLE_ONLY: - level = GetMonData(mon, MON_DATA_LEVEL, 0); - friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); - for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { + bool32 conditionsMet = FALSE; if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) continue; + // Check main primary evolution method switch (evolutions[i].method) { - case EVO_FRIENDSHIP: - if (friendship >= FRIENDSHIP_EVO_THRESHOLD) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_FRIENDSHIP_DAY: - if (GetTimeOfDay() != TIME_NIGHT && friendship >= FRIENDSHIP_EVO_THRESHOLD) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_DAY: - if (GetTimeOfDay() != TIME_NIGHT && evolutions[i].param <= level) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_FRIENDSHIP_NIGHT: - if (GetTimeOfDay() == TIME_NIGHT && friendship >= FRIENDSHIP_EVO_THRESHOLD) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_NIGHT: - if (GetTimeOfDay() == TIME_NIGHT && evolutions[i].param <= level) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_ITEM_HOLD_NIGHT: - if (GetTimeOfDay() == TIME_NIGHT && heldItem == evolutions[i].param) - { - targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; - } - break; - case EVO_ITEM_HOLD_DAY: - if (GetTimeOfDay() != TIME_NIGHT && heldItem == evolutions[i].param) - { - targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; - } - break; - case EVO_LEVEL_DUSK: - if (GetTimeOfDay() == TIME_EVENING && evolutions[i].param <= level) - targetSpecies = evolutions[i].targetSpecies; - break; case EVO_LEVEL: if (evolutions[i].param <= level) - targetSpecies = evolutions[i].targetSpecies; + conditionsMet = TRUE; break; - case EVO_LEVEL_FEMALE: - if (evolutions[i].param <= level && GetMonGender(mon) == MON_FEMALE) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_MALE: - if (evolutions[i].param <= level && GetMonGender(mon) == MON_MALE) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_ATK_GT_DEF: - if (evolutions[i].param <= level) - if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0)) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_ATK_EQ_DEF: - if (evolutions[i].param <= level) - if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0)) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_ATK_LT_DEF: - if (evolutions[i].param <= level) - if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0)) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_SILCOON: - if (evolutions[i].param <= level && (upperPersonality % 10) <= 4) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_CASCOON: - if (evolutions[i].param <= level && (upperPersonality % 10) > 4) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_NINJASK: - if (evolutions[i].param <= level) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_FAMILY_OF_FOUR: - if (mode == EVO_MODE_BATTLE_ONLY && evolutions[i].param <= level && (personality % 100) != 0) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_FAMILY_OF_THREE: - if (mode == EVO_MODE_BATTLE_ONLY && evolutions[i].param <= level && (personality % 100) == 0) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_BEAUTY: - if (evolutions[i].param <= beauty) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_MOVE: - if (MonKnowsMove(mon, evolutions[i].param)) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_MOVE_TWO_SEGMENT: - if (MonKnowsMove(mon, evolutions[i].param) && (personality % 100) != 0) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_MOVE_THREE_SEGMENT: - if (MonKnowsMove(mon, evolutions[i].param) && (personality % 100) == 0) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_FRIENDSHIP_MOVE_TYPE: - if (friendship >= FRIENDSHIP_EVO_THRESHOLD) - { - for (j = 0; j < MAX_MON_MOVES; j++) - { - if (GetMoveType(GetMonData(mon, MON_DATA_MOVE1 + j, NULL)) == evolutions[i].param) - { - targetSpecies = evolutions[i].targetSpecies; - break; - } - } - } - break; - case EVO_SPECIFIC_MON_IN_PARTY: - for (j = 0; j < PARTY_SIZE; j++) - { - if (GetMonData(&gPlayerParty[j], MON_DATA_SPECIES, NULL) == evolutions[i].param) - { - targetSpecies = evolutions[i].targetSpecies; - break; - } - } - break; - case EVO_LEVEL_DARK_TYPE_MON_IN_PARTY: - if (evolutions[i].param <= level) - { - for (j = 0; j < PARTY_SIZE; j++) - { - u16 currSpecies = GetMonData(&gPlayerParty[j], MON_DATA_SPECIES, NULL); - if (gSpeciesInfo[currSpecies].types[0] == TYPE_DARK - || gSpeciesInfo[currSpecies].types[1] == TYPE_DARK) - { - targetSpecies = evolutions[i].targetSpecies; - break; - } - } - } - break; - case EVO_LEVEL_RAIN: - j = GetCurrentWeather(); - if (evolutions[i].param <= level - && (j == WEATHER_RAIN || j == WEATHER_RAIN_THUNDERSTORM || j == WEATHER_DOWNPOUR)) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_FOG: - j = GetCurrentWeather(); - if (evolutions[i].param <= level - && (j == WEATHER_FOG_HORIZONTAL || j == WEATHER_FOG_DIAGONAL)) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_MAPSEC: - if (gMapHeader.regionMapSectionId == evolutions[i].param) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_SPECIFIC_MAP: - currentMap = ((gSaveBlock1Ptr->location.mapGroup) << 8 | gSaveBlock1Ptr->location.mapNum); - if (currentMap == evolutions[i].param) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_LEVEL_NATURE_AMPED: - if (evolutions[i].param <= level) - { - u8 nature = GetNature(mon); - switch (nature) - { - case NATURE_HARDY: - case NATURE_BRAVE: - case NATURE_ADAMANT: - case NATURE_NAUGHTY: - case NATURE_DOCILE: - case NATURE_IMPISH: - case NATURE_LAX: - case NATURE_HASTY: - case NATURE_JOLLY: - case NATURE_NAIVE: - case NATURE_RASH: - case NATURE_SASSY: - case NATURE_QUIRKY: - targetSpecies = evolutions[i].targetSpecies; - break; - } - } - break; - case EVO_LEVEL_NATURE_LOW_KEY: - if (evolutions[i].param <= level) - { - u8 nature = GetNature(mon); - switch (nature) - { - case NATURE_LONELY: - case NATURE_BOLD: - case NATURE_RELAXED: - case NATURE_TIMID: - case NATURE_SERIOUS: - case NATURE_MODEST: - case NATURE_MILD: - case NATURE_QUIET: - case NATURE_BASHFUL: - case NATURE_CALM: - case NATURE_GENTLE: - case NATURE_CAREFUL: - targetSpecies = evolutions[i].targetSpecies; - break; - } - } - break; - case EVO_ITEM_HOLD: - if (heldItem == evolutions[i].param) - { - targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; - } - break; - case EVO_USE_MOVE_TWENTY_TIMES: - if (evolutionTracker >= 20) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_RECOIL_DAMAGE_MALE: - if (evolutionTracker >= evolutions[i].param && GetMonGender(mon) == MON_MALE) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_RECOIL_DAMAGE_FEMALE: - if (evolutionTracker >= evolutions[i].param && GetMonGender(mon) == MON_FEMALE) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_DEFEAT_THREE_WITH_ITEM: - if (evolutionTracker >= 3) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_OVERWORLD_STEPS: - if (mon == GetFirstLiveMon() && gFollowerSteps >= evolutions[i].param) - targetSpecies = evolutions[i].targetSpecies; + case EVO_LEVEL_BATTLE_ONLY: + if (mode == EVO_MODE_BATTLE_ONLY && evolutions[i].param <= level) + conditionsMet = TRUE; break; } - } - break; - case EVO_MODE_CANT_STOP: - level = GetMonData(mon, MON_DATA_LEVEL, 0); - friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0); - for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) - { - if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) - continue; - - switch (evolutions[i].method) + if (conditionsMet && DoesMonMeetAdditionalConditions(mon, evolutions[i].params, NULL, PARTY_SIZE, canStopEvo, evoState)) { - case EVO_ITEM_COUNT_999: - if (CheckBagHasItem(evolutions[i].param, 999)) - { - targetSpecies = evolutions[i].targetSpecies; - if (prepareEvo == DO_EVO) - RemoveBagItem(evolutions[i].param, 999); - } + // All checks passed, so stop checking the rest of the evolutions. + // This is different from vanilla where the loop continues. + // If you have overlapping evolutions, put the ones you want to happen first on top of the list. + targetSpecies = evolutions[i].targetSpecies; break; } } @@ -4793,25 +4838,24 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 case EVO_MODE_TRADE: for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { + bool32 conditionsMet = FALSE; if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) continue; switch (evolutions[i].method) { case EVO_TRADE: + conditionsMet = TRUE; + break; + } + + if (conditionsMet && DoesMonMeetAdditionalConditions(mon, evolutions[i].params, tradePartner, PARTY_SIZE, canStopEvo, evoState)) + { + // All checks passed, so stop checking the rest of the evolutions. + // This is different from vanilla where the loop continues. + // If you have overlapping evolutions, put the ones you want to happen first on top of the list. targetSpecies = evolutions[i].targetSpecies; break; - case EVO_TRADE_ITEM: - if (evolutions[i].param == heldItem) - { - targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; - } - break; - case EVO_TRADE_SPECIFIC_MON: - if (evolutions[i].param == partnerSpecies && partnerHoldEffect != HOLD_EFFECT_PREVENT_EVOLVE) - targetSpecies = evolutions[i].targetSpecies; - break; } } break; @@ -4819,6 +4863,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 case EVO_MODE_ITEM_CHECK: for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { + bool32 conditionMet = FALSE; if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) continue; @@ -4826,23 +4871,18 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 { case EVO_ITEM: if (evolutions[i].param == evolutionItem) - targetSpecies = evolutions[i].targetSpecies; + conditionMet = TRUE; break; - case EVO_ITEM_FEMALE: - if (GetMonGender(mon) == MON_FEMALE && evolutions[i].param == evolutionItem) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_ITEM_MALE: - if (GetMonGender(mon) == MON_MALE && evolutions[i].param == evolutionItem) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_ITEM_NIGHT: - if (GetTimeOfDay() == TIME_NIGHT && evolutions[i].param == evolutionItem) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_ITEM_DAY: - if (GetTimeOfDay() != TIME_NIGHT && evolutions[i].param == evolutionItem) - targetSpecies = evolutions[i].targetSpecies; + } + + if (conditionMet && DoesMonMeetAdditionalConditions(mon, evolutions[i].params, NULL, PARTY_SIZE, canStopEvo, evoState)) + { + // All checks passed, so stop checking the rest of the evolutions. + // This is different from vanilla where the loop continues. + // If you have overlapping evolutions, put the ones you want to happen first on top of the list. + targetSpecies = evolutions[i].targetSpecies; + if (canStopEvo != NULL) + *canStopEvo = FALSE; break; } } @@ -4851,14 +4891,23 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 case EVO_MODE_BATTLE_SPECIAL: for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { + bool32 conditionsMet = FALSE; if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) continue; switch (evolutions[i].method) { - case EVO_CRITICAL_HITS: - if (gPartyCriticalHits[evolutionItem] >= evolutions[i].param) - targetSpecies = evolutions[i].targetSpecies; + case EVO_BATTLE_END: + conditionsMet = TRUE; + break; + } + + if (conditionsMet && DoesMonMeetAdditionalConditions(mon, evolutions[i].params, NULL, evolutionItem, canStopEvo, evoState)) + { + // All checks passed, so stop checking the rest of the evolutions. + // This is different from vanilla where the loop continues. + // If you have overlapping evolutions, put the ones you want to happen first on top of the list. + targetSpecies = evolutions[i].targetSpecies; break; } } @@ -4867,50 +4916,33 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 case EVO_MODE_OVERWORLD_SPECIAL: for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { + bool32 conditionsMet = FALSE; if (SanitizeSpeciesId(evolutions[i].targetSpecies) == SPECIES_NONE) continue; switch (evolutions[i].method) { - case EVO_SCRIPT_TRIGGER_DMG: - { - u16 currentHp = GetMonData(mon, MON_DATA_HP, NULL); - if (evolutionItem == EVO_SCRIPT_TRIGGER_DMG - && currentHp != 0 - && (GetMonData(mon, MON_DATA_MAX_HP, NULL) - currentHp >= evolutions[i].param)) - targetSpecies = evolutions[i].targetSpecies; + case EVO_SCRIPT_TRIGGER: + case EVO_SPIN: + if (gSpecialVar_0x8000 == evolutions[i].param) + conditionsMet = TRUE; + break; } - case EVO_DARK_SCROLL: - if (evolutionItem == EVO_DARK_SCROLL) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_WATER_SCROLL: - if (evolutionItem == EVO_WATER_SCROLL) - targetSpecies = evolutions[i].targetSpecies; - break; - case EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_DAY_LESS_THAN_5_SECS_COUNTER_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_NIGHT_LESS_THAN_5_SECS_COUNTER_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_DAY_MORE_THAN_5_SECS_COUNTER_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_NIGHT_MORE_THAN_5_SECS_COUNTER_CLOCKWISE: - case EVO_ITEM_HOLD_SPIN_DUSK_MORE_THAN_10_SECS: - if (evolutions[i].param == heldItem && evolutionItem == evolutions[i].method) - { - targetSpecies = evolutions[i].targetSpecies; - consumeItem = TRUE; - } + if (conditionsMet && DoesMonMeetAdditionalConditions(mon, evolutions[i].params, NULL, PARTY_SIZE, canStopEvo, evoState)) + { + // All checks passed, so stop checking the rest of the evolutions. + // This is different from vanilla where the loop continues. + // If you have overlapping evolutions, put the ones you want to happen first on top of the list. + targetSpecies = evolutions[i].targetSpecies; break; } } break; } - // Pikachu, Meowth, and Eevee cannot evolve if they have the + // Pikachu, Meowth, Eevee and Duraludon cannot evolve if they have the // Gigantamax Factor. We assume that is because their evolutions // do not have a Gigantamax Form. if (GetMonData(mon, MON_DATA_GIGANTAMAX_FACTOR, NULL) @@ -4920,12 +4952,6 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, enum EvolutionMode mode, u16 return SPECIES_NONE; } - if (consumeItem && prepareEvo == DO_EVO) - { - heldItem = ITEM_NONE; - SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem); - } - return targetSpecies; } @@ -6745,20 +6771,22 @@ void RemoveIVIndexFromList(u8 *ivs, u8 selectedIv) void TrySpecialOverworldEvo(void) { u8 i; - u8 evoMethod = gSpecialVar_0x8000; - u16 canStopEvo = gSpecialVar_0x8001; + bool32 canStopEvo = gSpecialVar_0x8001; u16 tryMultiple = gSpecialVar_0x8002; for (i = 0; i < PARTY_SIZE; i++) { - u16 targetSpecies = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_OVERWORLD_SPECIAL, evoMethod, SPECIES_NONE, DO_EVO); + u32 targetSpecies = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_OVERWORLD_SPECIAL, 0, NULL, &canStopEvo, CHECK_EVO); + if (targetSpecies != SPECIES_NONE && !(sTriedEvolving & (1u << i))) { + GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_OVERWORLD_SPECIAL, 0, NULL, &canStopEvo, DO_EVO); sTriedEvolving |= 1u << i; if(gMain.callback2 == TrySpecialOverworldEvo) // This fixes small graphics glitches. EvolutionScene(&gPlayerParty[i], targetSpecies, canStopEvo, i); else BeginEvolutionScene(&gPlayerParty[i], targetSpecies, canStopEvo, i); + if (tryMultiple) gCB2_AfterEvolution = TrySpecialOverworldEvo; else diff --git a/src/trade.c b/src/trade.c index 693f295e7d..2213211922 100644 --- a/src/trade.c +++ b/src/trade.c @@ -3410,7 +3410,7 @@ enum { static bool8 DoTradeAnim_Cable(void) { - u16 evoTarget; + u32 evoTarget; switch (sTradeAnim->state) { @@ -3846,9 +3846,12 @@ static bool8 DoTradeAnim_Cable(void) case STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution TradeMons(gSpecialVar_0x8005, 0); gCB2_AfterEvolution = CB2_InGameTrade; - evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], DO_EVO); + evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], NULL, CHECK_EVO); if (evoTarget != SPECIES_NONE) + { + GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], NULL, DO_EVO); TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + } sTradeAnim->state++; break; case STATE_FADE_OUT_END: @@ -3883,7 +3886,7 @@ static bool8 DoTradeAnim_Cable(void) static bool8 DoTradeAnim_Wireless(void) { - u16 evoTarget; + u32 evoTarget; switch (sTradeAnim->state) { @@ -4343,9 +4346,13 @@ static bool8 DoTradeAnim_Wireless(void) case STATE_TRY_EVOLUTION: // Only if in-game trade, link trades use CB2_TryLinkTradeEvolution TradeMons(gSpecialVar_0x8005, 0); gCB2_AfterEvolution = CB2_InGameTrade; - evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], DO_EVO); + evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], NULL, CHECK_EVO); if (evoTarget != SPECIES_NONE) + { + GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], NULL, DO_EVO); TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + } + sTradeAnim->state++; break; case STATE_FADE_OUT_END: @@ -4377,7 +4384,7 @@ static bool8 DoTradeAnim_Wireless(void) // In-game trades resolve evolution during the trade sequence, in STATE_TRY_EVOLUTION static void CB2_TryLinkTradeEvolution(void) { - u16 evoTarget; + u32 evoTarget; switch (gMain.state) { case 0: @@ -4386,9 +4393,12 @@ static void CB2_TryLinkTradeEvolution(void) break; case 4: gCB2_AfterEvolution = CB2_SaveAndEndTrade; - evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], DO_EVO); + evoTarget = GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], NULL, CHECK_EVO); if (evoTarget != SPECIES_NONE) + { + GetEvolutionTargetSpecies(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], EVO_MODE_TRADE, ITEM_NONE, &gPlayerParty[gSelectedTradeMonPositions[TRADE_PARTNER]], NULL, DO_EVO); TradeEvolutionScene(&gPlayerParty[gSelectedTradeMonPositions[TRADE_PLAYER]], evoTarget, sTradeAnim->monSpriteIds[TRADE_PARTNER], gSelectedTradeMonPositions[TRADE_PLAYER]); + } else if (IsWirelessTrade()) SetMainCallback2(CB2_SaveAndEndWirelessTrade); else diff --git a/test/species.c b/test/species.c index 2d702b6c45..06351f179e 100644 --- a/test/species.c +++ b/test/species.c @@ -98,10 +98,10 @@ TEST("Form change targets have the appropriate species flags") TEST("No species has two evolutions that use the evolution tracker") { - u32 i; + u32 i, j; u32 species = SPECIES_NONE; u32 evolutionTrackerEvolutions; - bool32 hasGenderBasedRecoil; + bool32 hasRecoilEvo; const struct Evolution *evolutions; for (i = 0; i < NUM_SPECIES; i++) @@ -110,24 +110,28 @@ TEST("No species has two evolutions that use the evolution tracker") } evolutionTrackerEvolutions = 0; - hasGenderBasedRecoil = FALSE; + hasRecoilEvo = FALSE; evolutions = GetSpeciesEvolutions(species); for (i = 0; evolutions[i].method != EVOLUTIONS_END; i++) { - if (evolutions[i].method == EVO_USE_MOVE_TWENTY_TIMES - || evolutions[i].method == EVO_DEFEAT_THREE_WITH_ITEM - ) - evolutionTrackerEvolutions++; - - if (evolutions[i].method == EVO_RECOIL_DAMAGE_MALE - || evolutions[i].method == EVO_RECOIL_DAMAGE_FEMALE) + if (evolutions[i].params == NULL) + continue; + for (j = 0; evolutions[i].params[j].condition != CONDITIONS_END; j++) { - // Special handling for these since they can be combined as the evolution tracker field is used for the same purpose - if (!hasGenderBasedRecoil) - { - hasGenderBasedRecoil = TRUE; + if (evolutions[i].params[j].condition == IF_USED_MOVE_X_TIMES + || evolutions[i].params[j].condition == IF_DEFEAT_X_WITH_ITEMS + ) evolutionTrackerEvolutions++; + + if (evolutions[i].params[j].condition == IF_RECOIL_DAMAGE_GE) + { + // Special handling for these since they can be combined as the evolution tracker field is used for the same purpose + if (!hasRecoilEvo) + { + hasRecoilEvo = TRUE; + evolutionTrackerEvolutions++; + } } } }