From e5b2492b8d0b1f6005ff0761f84ab10e8352acb2 Mon Sep 17 00:00:00 2001 From: FosterProgramming Date: Wed, 25 Feb 2026 21:10:57 +0100 Subject: [PATCH] createmon uses enum Pokeball instead of Item (#9281) Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- data/event_scripts.s | 1 + include/constants/pokeball.h | 37 +++++++++ include/pokeball.h | 33 +------- .../1.15/givemon_balls_typechange.py | 82 +++++++++++++++++++ src/script_pokemon_util.c | 20 ++--- test/pokemon.c | 6 +- 6 files changed, 134 insertions(+), 45 deletions(-) create mode 100644 include/constants/pokeball.h create mode 100644 migration_scripts/1.15/givemon_balls_typechange.py diff --git a/data/event_scripts.s b/data/event_scripts.s index ede31a6dfc..ae21d4b67c 100644 --- a/data/event_scripts.s +++ b/data/event_scripts.s @@ -50,6 +50,7 @@ #include "constants/moves.h" #include "constants/mystery_gift.h" #include "constants/party_menu.h" +#include "constants/pokeball.h" #include "constants/pokedex.h" #include "constants/pokemon.h" #include "constants/rtc.h" diff --git a/include/constants/pokeball.h b/include/constants/pokeball.h new file mode 100644 index 0000000000..e7ad93d651 --- /dev/null +++ b/include/constants/pokeball.h @@ -0,0 +1,37 @@ +#ifndef GUARD_CONSTANTS_POKEBALL_H +#define GUARD_CONSTANTS_POKEBALL_H + +enum PokeBall +{ + BALL_STRANGE = 0, + BALL_POKE = 1, + BALL_GREAT = 2, + BALL_ULTRA = 3, + BALL_MASTER = 4, + BALL_PREMIER = 5, + BALL_HEAL = 6, + BALL_NET = 7, + BALL_NEST = 8, + BALL_DIVE = 9, + BALL_DUSK = 10, + BALL_TIMER = 11, + BALL_QUICK = 12, + BALL_REPEAT = 13, + BALL_LUXURY = 14, + BALL_LEVEL = 15, + BALL_LURE = 16, + BALL_MOON = 17, + BALL_FRIEND = 18, + BALL_LOVE = 19, + BALL_FAST = 20, + BALL_HEAVY = 21, + BALL_DREAM = 22, + BALL_SAFARI = 23, + BALL_SPORT = 24, + BALL_PARK = 25, + BALL_BEAST = 26, + BALL_CHERISH = 27, + POKEBALL_COUNT +}; + +#endif // GUARD_CONSTANTS_POKEBALL_H diff --git a/include/pokeball.h b/include/pokeball.h index 8052df4620..1caf478afa 100644 --- a/include/pokeball.h +++ b/include/pokeball.h @@ -1,38 +1,7 @@ #ifndef GUARD_POKEBALL_H #define GUARD_POKEBALL_H -enum PokeBall -{ - BALL_STRANGE = 0, - BALL_POKE = 1, - BALL_GREAT = 2, - BALL_ULTRA = 3, - BALL_MASTER = 4, - BALL_PREMIER = 5, - BALL_HEAL = 6, - BALL_NET = 7, - BALL_NEST = 8, - BALL_DIVE = 9, - BALL_DUSK = 10, - BALL_TIMER = 11, - BALL_QUICK = 12, - BALL_REPEAT = 13, - BALL_LUXURY = 14, - BALL_LEVEL = 15, - BALL_LURE = 16, - BALL_MOON = 17, - BALL_FRIEND = 18, - BALL_LOVE = 19, - BALL_FAST = 20, - BALL_HEAVY = 21, - BALL_DREAM = 22, - BALL_SAFARI = 23, - BALL_SPORT = 24, - BALL_PARK = 25, - BALL_BEAST = 26, - BALL_CHERISH = 27, - POKEBALL_COUNT -}; +#include "constants/pokeball.h" enum { BALL_AFFINE_ANIM_0, diff --git a/migration_scripts/1.15/givemon_balls_typechange.py b/migration_scripts/1.15/givemon_balls_typechange.py new file mode 100644 index 0000000000..b64bd8b82c --- /dev/null +++ b/migration_scripts/1.15/givemon_balls_typechange.py @@ -0,0 +1,82 @@ +from itertools import chain + +import glob +import os +import re +import shutil + +item_to_ball = { + "ITEM_STRANGE_BALL": "BALL_STRANGE", + "ITEM_POKE_BALL": "BALL_POKE", + "ITEM_GREAT_BALL": "BALL_GREAT", + "ITEM_ULTRA_BALL": "BALL_ULTRA", + "ITEM_MASTER_BALL": "BALL_MASTER", + "ITEM_PREMIER_BALL": "BALL_PREMIER", + "ITEM_HEAL_BALL": "BALL_HEAL", + "ITEM_NET_BALL": "BALL_NET", + "ITEM_NEST_BALL": "BALL_NEST", + "ITEM_DIVE_BALL": "BALL_DIVE", + "ITEM_DUSK_BALL": "BALL_DUSK", + "ITEM_TIMER_BALL": "BALL_TIMER", + "ITEM_QUICK_BALL": "BALL_QUICK", + "ITEM_REPEAT_BALL": "BALL_REPEAT", + "ITEM_LUXURY_BALL": "BALL_LUXURY", + "ITEM_LEVEL_BALL": "BALL_LEVEL", + "ITEM_LURE_BALL": "BALL_LURE", + "ITEM_MOON_BALL": "BALL_MOON", + "ITEM_FRIEND_BALL": "BALL_FRIEND", + "ITEM_LOVE_BALL": "BALL_LOVE", + "ITEM_FAST_BALL": "BALL_FAST", + "ITEM_HEAVY_BALL": "BALL_HEAVY", + "ITEM_DREAM_BALL": "BALL_DREAM", + "ITEM_SAFARI_BALL": "BALL_SAFARI", + "ITEM_SPORT_BALL": "BALL_SPORT", + "ITEM_PARK_BALL": "BALL_PARK", + "ITEM_BEAST_BALL": "BALL_BEAST", + "ITEM_CHERISH_BALL": "BALL_CHERISH", +} + +INCFILE_CREATEMON_PAT = re.compile(r"\s*(createmon|givemon)") +BALL_ARG_PAT = re.compile(r"ball=(\w+)") +ARG_PAT = re.compile(r"[A-Z_]+") + +def parse_createmon(line, command): + ball_arg = BALL_ARG_PAT.search(line) + if ball_arg: + item = ball_arg.group(1) + if item not in item_to_ball: + print("unrecognized item:" + item) + quit() + return line.replace(item, item_to_ball[item]) + args = line.split(',') + if command == "createmon": + arg_num = 5 + else: + arg_num = 3 + if len(args) < (arg_num + 1): + return line + arg = ARG_PAT.match(args[arg_num].strip()) + if arg: + item = arg.group(0) + if item not in item_to_ball: + print("unrecognized item:" + item) + quit() + return line.replace(item, item_to_ball[item]) + return line + + +for inc_fname in chain(glob.glob("./data/scripts/*.inc"), glob.glob("./data/maps/*/scripts.inc")): + new_lines = [] + with open(inc_fname, "r") as inc_fp: + lines = inc_fp.readlines() + for line in lines: + command = INCFILE_CREATEMON_PAT.search(line) + if command: + #print(inc_fname, line) + new_line = parse_createmon(line, command.group(0)) + new_lines.append(new_line) + else: + new_lines.append(line) + with open(inc_fname, 'w+') as file: + for line in new_lines: + file.write(line) diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index b6cee10c2c..1415614643 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -511,17 +511,17 @@ u32 ScriptGiveMon(u16 species, u8 level, enum Item item) void ScrCmd_createmon(struct ScriptContext *ctx) { - u8 side = ScriptReadByte(ctx); - u8 slot = ScriptReadByte(ctx); - u16 species = VarGet(ScriptReadHalfword(ctx)); - u8 level = VarGet(ScriptReadHalfword(ctx)); + u8 side = ScriptReadByte(ctx); + u8 slot = ScriptReadByte(ctx); + u16 species = VarGet(ScriptReadHalfword(ctx)); + u8 level = VarGet(ScriptReadHalfword(ctx)); - u32 flags = ScriptReadWord(ctx); - enum Item item = PARSE_FLAG(0, ITEM_NONE); - u8 ball = PARSE_FLAG(1, ITEM_POKE_BALL); - u8 nature = PARSE_FLAG(2, NATURE_RANDOM); - u8 abilityNum = PARSE_FLAG(3, NUM_ABILITY_PERSONALITY); - u8 gender = PARSE_FLAG(4, MON_GENDER_RANDOM); + u32 flags = ScriptReadWord(ctx); + enum Item item = PARSE_FLAG(0, ITEM_NONE); + enum PokeBall ball = PARSE_FLAG(1, BALL_POKE); + u8 nature = PARSE_FLAG(2, NATURE_RANDOM); + u8 abilityNum = PARSE_FLAG(3, NUM_ABILITY_PERSONALITY); + u8 gender = PARSE_FLAG(4, MON_GENDER_RANDOM); u32 i; u16 evs[NUM_STATS]; diff --git a/test/pokemon.c b/test/pokemon.c index 89223b0c00..c03376858e 100644 --- a/test/pokemon.c +++ b/test/pokemon.c @@ -365,7 +365,7 @@ TEST("givemon [all]") ZeroPlayerPartyMons(); RUN_OVERWORLD_SCRIPT( - givemon SPECIES_WOBBUFFET, 100, item=ITEM_LEFTOVERS, ball=ITEM_MASTER_BALL, nature=NATURE_BOLD, abilityNum=2, gender=MON_MALE, hpEv=1, atkEv=2, defEv=3, speedEv=4, spAtkEv=5, spDefEv=6, hpIv=7, atkIv=8, defIv=9, speedIv=10, spAtkIv=11, spDefIv=12, move1=MOVE_SCRATCH, move2=MOVE_SPLASH, move3=MOVE_CELEBRATE, move4=MOVE_EXPLOSION, shinyMode=SHINY_MODE_ALWAYS, gmaxFactor=TRUE, teraType=TYPE_FIRE, dmaxLevel=7; + givemon SPECIES_WOBBUFFET, 100, item=ITEM_LEFTOVERS, ball=BALL_MASTER, nature=NATURE_BOLD, abilityNum=2, gender=MON_MALE, hpEv=1, atkEv=2, defEv=3, speedEv=4, spAtkEv=5, spDefEv=6, hpIv=7, atkIv=8, defIv=9, speedIv=10, spAtkIv=11, spDefIv=12, move1=MOVE_SCRATCH, move2=MOVE_SPLASH, move3=MOVE_CELEBRATE, move4=MOVE_EXPLOSION, shinyMode=SHINY_MODE_ALWAYS, gmaxFactor=TRUE, teraType=TYPE_FIRE, dmaxLevel=7; ); EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET); @@ -404,7 +404,7 @@ TEST("givemon [vars]") VarSet(VAR_TEMP_C, SPECIES_WOBBUFFET); VarSet(VAR_TEMP_D, 100); VarSet(VAR_0x8000, ITEM_LEFTOVERS); - VarSet(VAR_0x8001, ITEM_MASTER_BALL); + VarSet(VAR_0x8001, BALL_MASTER); VarSet(VAR_0x8002, NATURE_BOLD); VarSet(VAR_0x8003, 2); VarSet(VAR_0x8004, MON_MALE); @@ -544,7 +544,7 @@ TEST("CalculateMonStats") ZeroPlayerPartyMons(); RUN_OVERWORLD_SCRIPT( - givemon SPECIES_WOBBUFFET, 100, item=ITEM_LEFTOVERS, ball=ITEM_MASTER_BALL, nature=NATURE_BOLD, abilityNum=2, gender=MON_MALE, hpEv=1, atkEv=2, defEv=3, speedEv=4, spAtkEv=5, spDefEv=6, hpIv=7, atkIv=8, defIv=9, speedIv=10, spAtkIv=11, spDefIv=12, move1=MOVE_SCRATCH, move2=MOVE_SPLASH, move3=MOVE_CELEBRATE, move4=MOVE_EXPLOSION, shinyMode=SHINY_MODE_ALWAYS, gmaxFactor=TRUE, teraType=TYPE_FIRE, dmaxLevel=7; + givemon SPECIES_WOBBUFFET, 100, item=ITEM_LEFTOVERS, ball=BALL_MASTER, nature=NATURE_BOLD, abilityNum=2, gender=MON_MALE, hpEv=1, atkEv=2, defEv=3, speedEv=4, spAtkEv=5, spDefEv=6, hpIv=7, atkIv=8, defIv=9, speedIv=10, spAtkIv=11, spDefIv=12, move1=MOVE_SCRATCH, move2=MOVE_SPLASH, move3=MOVE_CELEBRATE, move4=MOVE_EXPLOSION, shinyMode=SHINY_MODE_ALWAYS, gmaxFactor=TRUE, teraType=TYPE_FIRE, dmaxLevel=7; ); EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_MAX_HP), 497);