diff --git a/Makefile b/Makefile index 8e5259ad1e..fa2420e105 100644 --- a/Makefile +++ b/Makefile @@ -195,10 +195,18 @@ ALL_LEARNABLES_JSON := $(LEARNSET_HELPERS_BUILD_DIR)/all_learnables.json WILD_ENCOUNTERS_TOOL_DIR := $(TOOLS_DIR)/wild_encounters AUTO_GEN_TARGETS += $(DATA_SRC_SUBDIR)/wild_encounters.h +MISC_TOOL_DIR := $(TOOLS_DIR)/misc +AUTO_GEN_TARGETS += $(INCLUDE_DIRS)/constants/script_commands.h + $(DATA_SRC_SUBDIR)/wild_encounters.h: $(DATA_SRC_SUBDIR)/wild_encounters.json $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py $(INCLUDE_DIRS)/config/overworld.h $(INCLUDE_DIRS)/config/dexnav.h python3 $(WILD_ENCOUNTERS_TOOL_DIR)/wild_encounters_to_header.py > $@ +$(INCLUDE_DIRS)/constants/script_commands.h: $(MISC_TOOL_DIR)/make_scr_cmd_constants.py $(DATA_ASM_SUBDIR)/script_cmd_table.inc + python3 $(MISC_TOOL_DIR)/make_scr_cmd_constants.py + $(C_BUILDDIR)/wild_encounter.o: c_dep += $(DATA_SRC_SUBDIR)/wild_encounters.h +$(C_BUILDDIR)/trainer_see.o: c_dep += $(INCLUDE_DIRS)/constants/script_commands.h +$(C_BUILDDIR)/vs_seeker.o: c_dep += $(INCLUDE_DIRS)/constants/script_commands.h PERL := perl SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c diff --git a/include/battle_setup.h b/include/battle_setup.h index 1605345260..1323971f67 100644 --- a/include/battle_setup.h +++ b/include/battle_setup.h @@ -73,6 +73,7 @@ void ConfigureAndSetUpOneTrainerBattle(u8 trainerObjEventId, const u8 *trainerSc void ConfigureTwoTrainersBattle(u8 trainerObjEventId, const u8 *trainerScript); void SetUpTwoTrainersBattle(void); bool32 GetTrainerFlagFromScriptPointer(const u8 *data); +bool32 GetRematchFromScriptPointer(const u8 *data); void SetTrainerFacingDirection(void); u8 GetTrainerBattleMode(void); bool8 GetTrainerFlag(void); diff --git a/src/battle_setup.c b/src/battle_setup.c index a6d833c417..1103818c05 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -1125,6 +1125,13 @@ bool32 GetTrainerFlagFromScriptPointer(const u8 *data) TrainerBattleParameter *temp = (TrainerBattleParameter*)(data + OPCODE_OFFSET); return FlagGet(TRAINER_FLAGS_START + temp->params.opponentA); } + +bool32 GetRematchFromScriptPointer(const u8 *data) +{ + TrainerBattleParameter *temp = (TrainerBattleParameter*)(data + OPCODE_OFFSET); + return ShouldTryRematchBattleForTrainerId(temp->params.opponentA); +} + #undef OPCODE_OFFSET // Set trainer's movement type so they stop and remain facing that direction diff --git a/src/trainer_see.c b/src/trainer_see.c index 54ea4ebf22..2ec23dfa4f 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -19,6 +19,7 @@ #include "constants/event_objects.h" #include "constants/event_object_movement.h" #include "constants/field_effects.h" +#include "constants/script_commands.h" #include "constants/trainer_types.h" // this file's functions @@ -447,7 +448,7 @@ static u8 CheckTrainer(u8 objectEventId) struct ScriptContext ctx; if (RunScriptImmediatelyUntilEffect(SCREFF_V1 | SCREFF_SAVE | SCREFF_HARDWARE | SCREFF_TRAINERBATTLE, trainerBattlePtr, &ctx)) { - if (*ctx.scriptPtr == 0x5c) // trainerbattle + if (*ctx.scriptPtr == SCR_OP_TRAINERBATTLE) trainerBattlePtr = ctx.scriptPtr; else trainerBattlePtr = NULL; @@ -471,7 +472,18 @@ static u8 CheckTrainer(u8 objectEventId) else if (trainerBattlePtr) { if (GetTrainerFlagFromScriptPointer(trainerBattlePtr)) - return 0; + { + //If there is a rematch, we want to trigger the approach sequence + if (GetRematchFromScriptPointer(trainerBattlePtr)) + { + trainerBattlePtr = NULL; + numTrainers = 0xFF; + } + else + { + return 0; + } + } } else { diff --git a/src/vs_seeker.c b/src/vs_seeker.c index 8669ca3f47..1fcf5fdfcc 100644 --- a/src/vs_seeker.c +++ b/src/vs_seeker.c @@ -28,6 +28,7 @@ #include "constants/items.h" #include "constants/maps.h" #include "constants/songs.h" +#include "constants/script_commands.h" #include "constants/trainer_types.h" #include "constants/field_effects.h" @@ -718,12 +719,12 @@ static u16 GetTrainerFlagFromScript(const u8 *script) u16 trainerFlag; switch (script[0]) { - case 0x5c: + case SCR_OP_TRAINERBATTLE: script += 3; trainerFlag = script[0]; trainerFlag |= script[1] << 8; break; - case 0x23: + case SCR_OP_CALLNATIVE: u32 callnativeFunc = (((((script[4] << 8) + script[3]) << 8) + script[2]) << 8) + script[1]; if (callnativeFunc == ((u32)NativeVsSeekerRematchId | 0xA000000)) // | 0xA000000 corresponds to the request_effects=1 version of the function { diff --git a/tools/misc/make_scr_cmd_constants.py b/tools/misc/make_scr_cmd_constants.py new file mode 100644 index 0000000000..d158dfcf8a --- /dev/null +++ b/tools/misc/make_scr_cmd_constants.py @@ -0,0 +1,25 @@ +import re + +SCR_CMD_PAT = re.compile(r"\tscript_cmd_table_entry (\w+)\s+\w+,\s+[\w=]+\s+@( 0x[0-9a-f]+)") + +def main(): + output = [ + "//", + "// DO NOT MODIFY THIS FILE! It is auto-generated by tools/misc/make_scr_cmd_constants.py", + "//", + "#ifndef GUARD_SCR_CMD_CONSTANTS_H", + "#define GUARD_SCR_CMD_CONSTANTS_H\n", + ] + + with open("data/script_cmd_table.inc", "r") as f: + for line in f.readlines(): + if match := re.match(SCR_CMD_PAT, line): + new_line = "#define " + match.group(1) + match.group(2) + output.append(new_line) + + output.append("\n#endif // GUARD_SCR_CMD_CONSTANTS_H\n") + with open("include/constants/script_commands.h", "w+") as f: + f.write('\n'.join(output)) + +if __name__ == "__main__": + main() \ No newline at end of file