-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Trainer Scripts
Credit to ghoulslash. Pull from his repo 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)
1. Open src/trainer_see.c. Find the function CheckForTrainersWantingBattle
. Modify it to the following:
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:
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. Somewhere, add the function GetObjectEventTrainerSightFlagByObjectEventId
:
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. Add u16 GetObjectEventTrainerSightFlagByObjectEventId(u8 objEventId);
somewhere in the file.
add #define TRAINER_TYPE_RUN_SCRIPT 4
to include/constants/trainer_types.h
Open data/scripts/trainer_script.inc and add the following to the bottom
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
Open src/script.c and add the following function:
### How to Set Up: