diff options
author | ghoulslash <41651341+ghoulslash@users.noreply.github.com> | 2020-07-03 12:07:38 -0600 |
---|---|---|
committer | ghoulslash <41651341+ghoulslash@users.noreply.github.com> | 2020-07-03 12:07:38 -0600 |
commit | 8bb58bca4c4e58c5a9692e343814fc45136b0498 (patch) | |
tree | 0dfe66ef7f788f663c49a08cc8159e183130b16f | |
parent | 680dcede740fc8c678111e61e6bf81b1d6eb4d93 (diff) |
Created Trainer Scripts (markdown)
-rw-r--r-- | Trainer-Scripts.md | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/Trainer-Scripts.md b/Trainer-Scripts.md new file mode 100644 index 0000000..4adae6c --- /dev/null +++ b/Trainer-Scripts.md @@ -0,0 +1,191 @@ +## Run Script On Trainer Sight + +Credit to ghoulslash. Pull from his [repo](https://github.com/ghoulslash/pokeemerald/tree/trainer_see_scripts) or follow the guide below. + +Default Pokemon Trainers require the first script command to be trainerbattle to function correctly. This feature allows you to run any script while including the "trainer spotting" effect (see the bottom of the page for an example) + +### Modify Trainer Sight +**1. Open [src/trainer_see.c](../blob/master/src/trainer_see.c).** Find the function `CheckForTrainersWantingBattle`. Modify it to the following: +```c +bool8 CheckForTrainersWantingBattle(void) +{ + u8 i; + u8 numTrainers; + + gNoOfApproachingTrainers = 0; + gApproachingTrainerId = 0; + + for (i = 0; i < OBJECT_EVENTS_COUNT; i++) + { + if (!gObjectEvents[i].active) + continue; + + if (gObjectEvents[i].trainerType == TRAINER_TYPE_NONE || gObjectEvents[i].trainerType == TRAINER_TYPE_SEE_ALL_DIRECTIONS) + continue; + + numTrainers = CheckTrainer(i); + if (numTrainers == 0xFF) //run script + break; + + if (numTrainers == 2) + break; + + if (numTrainers == 0) + continue; + + if (gNoOfApproachingTrainers > 1) + break; + if (GetMonsStateToDoubles_2() != 0) // one trainer found and cant have a double battle + break; + } + + if (numTrainers == 0xFF) + { + u8 objectEventId = gApproachingTrainers[gNoOfApproachingTrainers - 1].objectEventId; + + gSelectedObjectEvent = objectEventId; + gSpecialVar_LastTalked = gObjectEvents[objectEventId].localId; + ScriptContext1_SetupScript(EventScript_ObjectApproachPlayer); + ScriptContext2_Enable(); + return TRUE; + } + + if (gNoOfApproachingTrainers == 1) + { + ResetTrainerOpponentIds(); + ConfigureAndSetUpOneTrainerBattle(gApproachingTrainers[gNoOfApproachingTrainers - 1].objectEventId, + gApproachingTrainers[gNoOfApproachingTrainers - 1].trainerScriptPtr); + gTrainerApproachedPlayer = TRUE; + return TRUE; + } + else if (gNoOfApproachingTrainers == 2) + { + ResetTrainerOpponentIds(); + for (i = 0; i < gNoOfApproachingTrainers; i++, gApproachingTrainerId++) + { + ConfigureTwoTrainersBattle(gApproachingTrainers[i].objectEventId, + gApproachingTrainers[i].trainerScriptPtr); + } + SetUpTwoTrainersBattle(); + gApproachingTrainerId = 0; + gTrainerApproachedPlayer = TRUE; + return TRUE; + } + else + { + gTrainerApproachedPlayer = FALSE; + return FALSE; + } +} +``` + +**2. Next, find `CheckTrainer` and change it to:** +```c +static u8 CheckTrainer(u8 objectEventId) +{ + const u8 *scriptPtr; + u8 ret = 1; + u8 approachDistance; + u16 scriptFlag = GetObjectEventTrainerSightFlagByObjectEventId(objectEventId); + + if (InTrainerHill() == TRUE) + scriptPtr = GetTrainerHillTrainerScript(); + else + scriptPtr = GetObjectEventScriptPointerByObjectEventId(objectEventId); + + if (InBattlePyramid()) + { + if (GetBattlePyramidTrainerFlag(objectEventId)) + return 0; + } + else if (InTrainerHill() == TRUE) + { + if (GetHillTrainerFlag(objectEventId)) + return 0; + } + else + { + if (GetTrainerFlagFromScriptPointer(scriptPtr)) + return 0; + } + + approachDistance = GetTrainerApproachDistance(&gObjectEvents[objectEventId]); + + if (approachDistance != 0) + { + if (scriptFlag >= TRAINER_TYPE_RUN_SCRIPT) + { + if (!FlagGet(scriptFlag) && scriptPtr != NULL) + { + // TRAINER_TYPE_RUN_SCRIPT + FlagSet(scriptFlag); + ret = 0xFF; + } + else + { + return 0; + } + } + else + { + if (scriptPtr[1] == TRAINER_BATTLE_DOUBLE + || scriptPtr[1] == TRAINER_BATTLE_REMATCH_DOUBLE + || scriptPtr[1] == TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE) + { + if (GetMonsStateToDoubles_2() != 0) + return 0; + + ret = 2; + } + } + + gApproachingTrainers[gNoOfApproachingTrainers].objectEventId = objectEventId; + gApproachingTrainers[gNoOfApproachingTrainers].trainerScriptPtr = scriptPtr; + gApproachingTrainers[gNoOfApproachingTrainers].radius = approachDistance; + TrainerApproachPlayer(&gObjectEvents[objectEventId], approachDistance - 1); + gNoOfApproachingTrainers++; + + return ret; + } + + return 0; +} +``` + +**4. Create the function `GetObjectEventTrainerSightFlagByObjectEventId`** +First, open [src/event_object_movement.c](../blob/master/src/event_object_movement.c). Somewhere, add the function `GetObjectEventTrainerSightFlagByObjectEventId`: +```c +u16 GetObjectEventTrainerSightFlagByObjectEventId(u8 objEventId) +{ + // ideally, would use a the last two bytes of the object event template + return GetObjectEventTemplateByLocalIdAndMap(gObjectEvents[objEventId].localId, gObjectEvents[objEventId].mapNum, gObjectEvents[objEventId].mapGroup)->trainerType; +} +``` + +Next, define the new function in [include/event_object_movement.h](../blob/master/include/event_object_movement.h). Add `u16 GetObjectEventTrainerSightFlagByObjectEventId(u8 objEventId);` somewhere in the file. + +### Define TRAINER_TYPE_RUN_SCRIPT +add `#define TRAINER_TYPE_RUN_SCRIPT 4` to [include/constants/trainer_types.h](../blob/master/include/constants/trainer_types.h) + + +### Make a new approach script +Open [data/scripts/trainer_script.inc](../blob/master/data/scripts/trainer_script.inc) and add the following to the bottom +```c +EventScript_ObjectApproachPlayer:: + lock + special EndTrainerApproach + waitstate + gotonative LoadTrainerObjectScript + end + +``` + +`gotonative LoadTrainerObjectScript` will allow us to dynamically branch to our objects own script. + +Next, add `extern const u8 EventScript_ObjectApproachPlayer[];` somewhere to [include/event_scripts.h](../blob/master/include/event_scripts.h) + +### Create `LoadTrainerObjectScript` +Open [src/script.c](../blob/master/src/script.c) and add the following function: +``` + +### How to Set Up: |