summaryrefslogtreecommitdiff
path: root/src/field_control_avatar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/field_control_avatar.c')
-rw-r--r--src/field_control_avatar.c1058
1 files changed, 1058 insertions, 0 deletions
diff --git a/src/field_control_avatar.c b/src/field_control_avatar.c
new file mode 100644
index 000000000..fef403c04
--- /dev/null
+++ b/src/field_control_avatar.c
@@ -0,0 +1,1058 @@
+#include "global.h"
+#include "battle_setup.h"
+#include "battle_frontier_1.h"
+#include "bike.h"
+#include "coord_event_weather.h"
+#include "daycare.h"
+#include "event_data.h"
+#include "event_object_movement.h"
+#include "fieldmap.h"
+#include "field_control_avatar.h"
+#include "field_fadetransition.h"
+#include "field_player_avatar.h"
+#include "field_poison.h"
+#include "field_screen.h"
+#include "field_specials.h"
+#include "fldeff_80F9BCC.h"
+#include "item_menu.h"
+#include "link.h"
+#include "metatile_behavior.h"
+#include "overworld.h"
+#include "pokemon.h"
+#include "pokenav.h"
+#include "safari_zone.h"
+#include "script.h"
+#include "secret_base.h"
+#include "sound.h"
+#include "start_menu.h"
+#include "trainer_see.h"
+#include "wild_encounter.h"
+#include "constants/bg_event_constants.h"
+#include "constants/map_types.h"
+#include "constants/songs.h"
+
+static EWRAM_DATA u8 sWildEncounterImmunitySteps = 0;
+static EWRAM_DATA u16 sPreviousPlayerMetatileBehavior = 0;
+
+u8 gSelectedEventObject;
+
+//scripts
+extern const u8 EventScript_PlayerPCMale[];
+extern const u8 EventScript_PlayerPCFemale[];
+extern const u8 EventScript_SecretBasePC[];
+extern const u8 EventScript_RecordMixingSecretBasePC[];
+extern const u8 EventScript_SecretPower1[];
+extern const u8 EventScript_SecretPower2[];
+extern const u8 EventScript_PC[];
+extern const u8 EventScript_TestSignpostMsg[];
+extern const u8 EventScript_HiddenItemScript[];
+extern const u8 EventScript_2759F1[];
+extern const u8 EventScript_TV[];
+extern const u8 EventScript_ClosedSootopolisDoor[];
+extern const u8 SkyPillar_Outside_EventScript_2393F9[];
+extern const u8 EventScript_CableBoxResults[];
+extern const u8 EventScript_2A4BAC[];
+extern const u8 Route110_TrickHouseEntrance_EventScript_26A22A[];
+extern const u8 EventScript_RegionMap[];
+extern const u8 EventScript_RunningShoesManual[];
+extern const u8 EventScript_PictureBookShelf[];
+extern const u8 EventScript_BookShelf[];
+extern const u8 EventScript_PokemonCenterBookshelf[];
+extern const u8 EventScript_Vase[];
+extern const u8 EventScript_TrashCan[];
+extern const u8 EventScript_ShopShelf[];
+extern const u8 EventScript_Blueprint[];
+extern const u8 EventScript_WirelessBoxResults[];
+extern const u8 EventScript_CableBoxResults[];
+extern const u8 EventScript_Questionnaire[];
+extern const u8 EventScript_TrainerHillTimer[];
+extern const u8 EventScript_SecretBaseSandOrnament[];
+extern const u8 EventScript_SecretBaseShieldOrToyTV[];
+extern const u8 EventScript_UseSurf[];
+extern const u8 EventScript_UseWaterfall[];
+extern const u8 EventScript_CannotUseWaterfall[];
+extern const u8 EventScript_UseDive[];
+extern const u8 EventScript_UseDiveUnderwater[];
+extern const u8 EventScript_FallDownHole[];
+extern const u8 BattleFrontier_BattlePyramidEmptySquare_EventScript_252BE8[];
+extern const u8 EventScript_Poison[];
+extern const u8 EventScript_EggHatch[];
+extern const u8 gUnknown_08273D1F[];
+extern const u8 IslandCave_EventScript_238EAF[];
+extern const u8 MauvilleCity_EventScript_1DF7BA[];
+extern const u8 Route119_EventScript_1F49EC[];
+extern const u8 LittlerootTown_ProfessorBirchsLab_EventScript_1FA4D6[];
+extern const u8 RustboroCity_Gym_EventScript_21307B[];
+extern const u8 MossdeepCity_SpaceCenter_2F_EventScript_224175[];
+extern const u8 SSTidalCorridor_EventScript_23C050[];
+extern const u8 gUnknown_082A8350[];
+
+static void GetPlayerPosition(struct MapPosition *);
+static void GetInFrontOfPlayerPosition(struct MapPosition *);
+static u16 GetPlayerCurMetatileBehavior(int);
+static bool8 TryStartInteractionScript(struct MapPosition*, u16, u8);
+static const u8 *GetInteractionScript(struct MapPosition*, u8, u8);
+static const u8 *GetInteractedEventObjectScript(struct MapPosition *, u8, u8);
+static const u8 *GetInteractedBackgroundEventScript(struct MapPosition *, u8, u8);
+static const u8 *GetInteractedMetatileScript(struct MapPosition *, u8, u8);
+static const u8 *GetInteractedWaterScript(struct MapPosition *, u8, u8);
+static bool32 TrySetupDiveDownScript(void);
+static bool32 TrySetupDiveEmergeScript(void);
+static bool8 TryStartStepBasedScript(struct MapPosition *, u16, u16);
+static bool8 CheckStandardWildEncounter(u16);
+static bool8 mapheader_run_first_tag2_script_list_match_conditionally(struct MapPosition *, u16, u8);
+static bool8 IsWarpMetatileBehavior(u16);
+static bool8 IsArrowWarpMetatileBehavior(u16, u8);
+static s8 GetWarpEventAtMapPosition(struct MapHeader *, struct MapPosition *);
+static void sub_809CEB0(struct MapHeader *, s8, struct MapPosition *);
+static bool8 map_warp_consider_2_to_inside(struct MapPosition *, u16, u8);
+static s8 GetWarpEventAtPosition(struct MapHeader *, u16, u16, u8);
+static u8 *GetCoordEventScriptAtPosition(struct MapHeader *, u16, u16, u8);
+static struct BgEvent *GetBackgroundEventAtPosition(struct MapHeader *, u16, u16, u8);
+static bool8 TryStartCoordEventScript(struct MapPosition *);
+static bool8 TryStartWarpEventScript(struct MapPosition *, u16);
+static bool8 TryStartMiscWalkingScripts(u16);
+static bool8 TryStartStepCountScript(u16);
+static void UpdateHappinessStepCounter(void);
+static bool8 UpdatePoisonStepCounter(void);
+
+void FieldClearPlayerInput(struct FieldInput *input)
+{
+ input->pressedAButton = FALSE;
+ input->checkStandardWildEncounter = FALSE;
+ input->pressedStartButton = FALSE;
+ input->pressedSelectButton = FALSE;
+ input->input_field_0_4 = FALSE;
+ input->input_field_0_5 = FALSE;
+ input->tookStep = FALSE;
+ input->pressedBButton = FALSE;
+ input->input_field_1_0 = FALSE;
+ input->input_field_1_1 = FALSE;
+ input->input_field_1_2 = FALSE;
+ input->input_field_1_3 = FALSE;
+ input->dpadDirection = 0;
+}
+
+void FieldGetPlayerInput(struct FieldInput *input, u16 newKeys, u16 heldKeys)
+{
+ u8 tileTransitionState = gPlayerAvatar.tileTransitionState;
+ u8 runningState = gPlayerAvatar.runningState;
+ bool8 forcedMove = MetatileBehavior_IsForcedMovementTile(GetPlayerCurMetatileBehavior(runningState));
+
+ if ((tileTransitionState == T_TILE_CENTER && forcedMove == FALSE) || tileTransitionState == T_NOT_MOVING)
+ {
+ if (GetPlayerSpeed() != 4)
+ {
+ if (newKeys & START_BUTTON)
+ input->pressedStartButton = TRUE;
+ if (newKeys & SELECT_BUTTON)
+ input->pressedSelectButton = TRUE;
+ if (newKeys & A_BUTTON)
+ input->pressedAButton = TRUE;
+ if (newKeys & B_BUTTON)
+ input->pressedBButton = TRUE;
+ }
+
+ if (heldKeys & (DPAD_UP | DPAD_DOWN | DPAD_LEFT | DPAD_RIGHT))
+ {
+ input->input_field_0_4 = TRUE;
+ input->input_field_0_5 = TRUE;
+ }
+ }
+
+ if (forcedMove == FALSE)
+ {
+ if (tileTransitionState == T_TILE_CENTER && runningState == MOVING)
+ input->tookStep = TRUE;
+ if (forcedMove == FALSE && tileTransitionState == T_TILE_CENTER)
+ input->checkStandardWildEncounter = TRUE;
+ }
+
+ if (heldKeys & DPAD_UP)
+ input->dpadDirection = DIR_NORTH;
+ else if (heldKeys & DPAD_DOWN)
+ input->dpadDirection = DIR_SOUTH;
+ else if (heldKeys & DPAD_LEFT)
+ input->dpadDirection = DIR_WEST;
+ else if (heldKeys & DPAD_RIGHT)
+ input->dpadDirection = DIR_EAST;
+}
+
+int sub_809C014(struct FieldInput *input)
+{
+ struct MapPosition position;
+ u8 playerDirection;
+ u16 metatileBehavior;
+
+ gSpecialVar_LastTalked = 0;
+ gSelectedEventObject = 0;
+
+ playerDirection = GetPlayerFacingDirection();
+ GetPlayerPosition(&position);
+ metatileBehavior = MapGridGetMetatileBehaviorAt(position.x, position.y);
+
+ if (CheckForTrainersWantingBattle() == TRUE)
+ return TRUE;
+
+ if (mapheader_run_first_tag2_script_list_match() == 1)
+ return TRUE;
+
+ if (input->pressedBButton && TrySetupDiveEmergeScript() == TRUE)
+ return TRUE;
+ if (input->tookStep)
+ {
+ IncrementGameStat(GAME_STAT_STEPS);
+ increment_var_x4026_on_birth_island_modulo_100();
+ if (TryStartStepBasedScript(&position, metatileBehavior, playerDirection) == TRUE)
+ return TRUE;
+ }
+ if (input->checkStandardWildEncounter && CheckStandardWildEncounter(metatileBehavior) == TRUE)
+ return TRUE;
+ if (input->input_field_0_4 && input->dpadDirection == playerDirection)
+ {
+ if (mapheader_run_first_tag2_script_list_match_conditionally(&position, metatileBehavior, playerDirection) == TRUE)
+ return TRUE;
+ }
+
+ GetInFrontOfPlayerPosition(&position);
+ metatileBehavior = MapGridGetMetatileBehaviorAt(position.x, position.y);
+ if (input->pressedAButton && TryStartInteractionScript(&position, metatileBehavior, playerDirection) == TRUE)
+ return TRUE;
+
+ if (input->input_field_0_5 && input->dpadDirection == playerDirection)
+ {
+ if (map_warp_consider_2_to_inside(&position, metatileBehavior, playerDirection) == TRUE)
+ return TRUE;
+ }
+ if (input->pressedAButton && TrySetupDiveDownScript() == TRUE)
+ return TRUE;
+ if (input->pressedStartButton)
+ {
+ PlaySE(SE_WIN_OPEN);
+ ShowStartMenu();
+ return TRUE;
+ }
+ if (input->pressedSelectButton && UseRegisteredKeyItemOnField() == TRUE)
+ return TRUE;
+
+ return FALSE;
+}
+
+static void GetPlayerPosition(struct MapPosition *position)
+{
+ PlayerGetDestCoords(&position->x, &position->y);
+ position->height = PlayerGetZCoord();
+}
+
+static void GetInFrontOfPlayerPosition(struct MapPosition *position)
+{
+ s16 x, y;
+
+ GetXYCoordsOneStepInFrontOfPlayer(&position->x, &position->y);
+ PlayerGetDestCoords(&x, &y);
+ if (MapGridGetZCoordAt(x, y) != 0)
+ position->height = PlayerGetZCoord();
+ else
+ position->height = 0;
+}
+
+static u16 GetPlayerCurMetatileBehavior(int runningState)
+{
+ s16 x, y;
+
+ PlayerGetDestCoords(&x, &y);
+ return MapGridGetMetatileBehaviorAt(x, y);
+}
+
+static bool8 TryStartInteractionScript(struct MapPosition *position, u16 metatileBehavior, u8 direction)
+{
+ const u8 *script = GetInteractionScript(position, metatileBehavior, direction);
+ if (script == NULL)
+ return FALSE;
+
+ // Don't play interaction sound for certain scripts.
+ if (script != EventScript_PlayerPCMale
+ && script != EventScript_PlayerPCFemale
+ && script != EventScript_SecretBasePC
+ && script != EventScript_RecordMixingSecretBasePC
+ && script != EventScript_SecretPower1
+ && script != EventScript_SecretPower2
+ && script != EventScript_PC)
+ PlaySE(SE_SELECT);
+
+ ScriptContext1_SetupScript(script);
+ return TRUE;
+}
+
+static const u8 *GetInteractionScript(struct MapPosition *position, u8 metatileBehavior, u8 direction)
+{
+ const u8 *script = GetInteractedEventObjectScript(position, metatileBehavior, direction);
+ if (script != NULL)
+ return script;
+
+ script = GetInteractedBackgroundEventScript(position, metatileBehavior, direction);
+ if (script != NULL)
+ return script;
+
+ script = GetInteractedMetatileScript(position, metatileBehavior, direction);
+ if (script != NULL)
+ return script;
+
+ script = GetInteractedWaterScript(position, metatileBehavior, direction);
+ if (script != NULL)
+ return script;
+
+ return NULL;
+}
+
+const u8 *GetInteractedLinkPlayerScript(struct MapPosition *position, u8 metatileBehavior, u8 direction)
+{
+ u8 eventObjectId;
+ s32 i;
+
+ if (!MetatileBehavior_IsCounter(MapGridGetMetatileBehaviorAt(position->x, position->y)))
+ eventObjectId = GetEventObjectIdByXYZ(position->x, position->y, position->height);
+ else
+ eventObjectId = GetEventObjectIdByXYZ(position->x + gDirectionToVectors[direction].x, position->y + gDirectionToVectors[direction].y, position->height);
+
+ if (eventObjectId == 16 || gEventObjects[eventObjectId].localId == 0xFF)
+ return NULL;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (gLinkPlayerEventObjects[i].active == TRUE && gLinkPlayerEventObjects[i].eventObjId == eventObjectId)
+ return NULL;
+ }
+
+ gSelectedEventObject = eventObjectId;
+ gSpecialVar_LastTalked = gEventObjects[eventObjectId].localId;
+ gSpecialVar_Facing = direction;
+ return GetEventObjectScriptPointerByEventObjectId(eventObjectId);
+}
+
+static const u8 *GetInteractedEventObjectScript(struct MapPosition *position, u8 metatileBehavior, u8 direction)
+{
+ u8 eventObjectId;
+ const u8 *script;
+
+ eventObjectId = GetEventObjectIdByXYZ(position->x, position->y, position->height);
+ if (eventObjectId == 16 || gEventObjects[eventObjectId].localId == 0xFF)
+ {
+ if (MetatileBehavior_IsCounter(metatileBehavior) != TRUE)
+ return NULL;
+
+ // Look for an event object on the other side of the counter.
+ eventObjectId = GetEventObjectIdByXYZ(position->x + gDirectionToVectors[direction].x, position->y + gDirectionToVectors[direction].y, position->height);
+ if (eventObjectId == 16 || gEventObjects[eventObjectId].localId == 0xFF)
+ return NULL;
+ }
+
+ gSelectedEventObject = eventObjectId;
+ gSpecialVar_LastTalked = gEventObjects[eventObjectId].localId;
+ gSpecialVar_Facing = direction;
+
+ if (InTrainerHill() == TRUE)
+ {
+ script = sub_81D62AC();
+ }
+ else
+ {
+ script = GetEventObjectScriptPointerByEventObjectId(eventObjectId);
+ }
+ script = GetRamScript(gSpecialVar_LastTalked, script);
+ return script;
+}
+
+static const u8 *GetInteractedBackgroundEventScript(struct MapPosition *position, u8 metatileBehavior, u8 direction)
+{
+ struct BgEvent *bgEvent = GetBackgroundEventAtPosition(&gMapHeader, position->x - 7, position->y - 7, position->height);
+
+ if (bgEvent == NULL)
+ return NULL;
+ if (bgEvent->bgUnion.script == NULL)
+ return EventScript_TestSignpostMsg;
+
+ switch (bgEvent->kind)
+ {
+ case BG_EVENT_PLAYER_FACING_ANY:
+ default:
+ return bgEvent->bgUnion.script;
+ case BG_EVENT_PLAYER_FACING_NORTH:
+ if (direction != DIR_NORTH)
+ return NULL;
+ break;
+ case BG_EVENT_PLAYER_FACING_SOUTH:
+ if (direction != DIR_SOUTH)
+ return NULL;
+ break;
+ case BG_EVENT_PLAYER_FACING_EAST:
+ if (direction != DIR_EAST)
+ return NULL;
+ break;
+ case BG_EVENT_PLAYER_FACING_WEST:
+ if (direction != DIR_WEST)
+ return NULL;
+ break;
+ case 5:
+ case 6:
+ case BG_EVENT_HIDDEN_ITEM:
+ gSpecialVar_0x8004 = ((u32)bgEvent->bgUnion.script >> 16) + FLAG_HIDDEN_ITEMS_START;
+ gSpecialVar_0x8005 = (u32)bgEvent->bgUnion.script;
+ if (FlagGet(gSpecialVar_0x8004) == TRUE)
+ return NULL;
+ return EventScript_HiddenItemScript;
+ case BG_EVENT_SECRET_BASE:
+ if (direction == DIR_NORTH)
+ {
+ gSpecialVar_0x8004 = bgEvent->bgUnion.secretBaseId;
+ if (sub_80E9680())
+ return EventScript_2759F1;
+ }
+ return NULL;
+ }
+
+ return bgEvent->bgUnion.script;
+}
+
+static const u8 *GetInteractedMetatileScript(struct MapPosition *position, u8 metatileBehavior, u8 direction)
+{
+ s8 height;
+
+ if (MetatileBehavior_IsPlayerFacingTVScreen(metatileBehavior, direction) == TRUE)
+ return EventScript_TV;
+ if (MetatileBehavior_IsPC(metatileBehavior) == TRUE)
+ return EventScript_PC;
+ if (MetatileBehavior_IsClosedSootopolisDoor(metatileBehavior) == TRUE)
+ return EventScript_ClosedSootopolisDoor;
+ if (MetatileBehavior_IsUnknownClosedDoor(metatileBehavior) == TRUE)
+ return SkyPillar_Outside_EventScript_2393F9;
+ if (MetatileBehavior_IsCableBoxResults1(metatileBehavior) == TRUE)
+ return EventScript_CableBoxResults;
+ if (MetatileBehavior_IsPokeblockFeeder(metatileBehavior) == TRUE)
+ return EventScript_2A4BAC;
+ if (MetatileBehavior_IsTrickHousePuzzleDoor(metatileBehavior) == TRUE)
+ return Route110_TrickHouseEntrance_EventScript_26A22A;
+ if (MetatileBehavior_IsRegionMap(metatileBehavior) == TRUE)
+ return EventScript_RegionMap;
+ if (MetatileBehavior_IsRunningShoesManual(metatileBehavior) == TRUE)
+ return EventScript_RunningShoesManual;
+ if (MetatileBehavior_IsPictureBookShelf(metatileBehavior) == TRUE)
+ return EventScript_PictureBookShelf;
+ if (MetatileBehavior_IsBookShelf(metatileBehavior) == TRUE)
+ return EventScript_BookShelf;
+ if (MetatileBehavior_IsPokeCenterBookShelf(metatileBehavior) == TRUE)
+ return EventScript_PokemonCenterBookshelf;
+ if (MetatileBehavior_IsVase(metatileBehavior) == TRUE)
+ return EventScript_Vase;
+ if (MetatileBehavior_IsTrashCan(metatileBehavior) == TRUE)
+ return EventScript_TrashCan;
+ if (MetatileBehavior_IsShopShelf(metatileBehavior) == TRUE)
+ return EventScript_ShopShelf;
+ if (MetatileBehavior_IsBlueprint(metatileBehavior) == TRUE)
+ return EventScript_Blueprint;
+ if (MetatileBehavior_IsPlayerFacingWirelessBoxResults(metatileBehavior, direction) == TRUE)
+ return EventScript_WirelessBoxResults;
+ if (MetatileBehavior_IsCableBoxResults2(metatileBehavior, direction) == TRUE)
+ return EventScript_CableBoxResults;
+ if (MetatileBehavior_IsQuestionnaire(metatileBehavior) == TRUE)
+ return EventScript_Questionnaire;
+ if (MetatileBehavior_IsTrainerHillTimer(metatileBehavior) == TRUE)
+ return EventScript_TrainerHillTimer;
+
+ height = position->height;
+ if (height == MapGridGetZCoordAt(position->x, position->y))
+ {
+ if (MetatileBehavior_IsSecretBasePC(metatileBehavior) == TRUE)
+ return EventScript_SecretBasePC;
+ if (MetatileBehavior_IsRecordMixingSecretBasePC(metatileBehavior) == TRUE)
+ return EventScript_RecordMixingSecretBasePC;
+ if (MetatileBehavior_IsSecretBaseSandOrnament(metatileBehavior) == TRUE)
+ return EventScript_SecretBaseSandOrnament;
+ if (MetatileBehavior_IsSecretBaseShieldOrToyTV(metatileBehavior) == TRUE)
+ return EventScript_SecretBaseShieldOrToyTV;
+ if (MetatileBehavior_IsMB_C6(metatileBehavior) == TRUE)
+ {
+ sub_80EB56C();
+ return NULL;
+ }
+ if (MetatileBehavior_IsLargeMatCenter(metatileBehavior) == TRUE)
+ {
+ sub_80EB9E0();
+ return NULL;
+ }
+ if (MetatileBehavior_IsSecretBaseLargeMatEdge(metatileBehavior) == TRUE)
+ {
+ sub_80EBB28();
+ return NULL;
+ }
+ }
+ else if (MetatileBehavior_IsSecretBasePoster(metatileBehavior) == TRUE)
+ {
+ sub_80EB498();
+ return NULL;
+ }
+
+ return NULL;
+}
+
+static const u8 *GetInteractedWaterScript(struct MapPosition *unused1, u8 metatileBehavior, u8 direction)
+{
+ if (FlagGet(FLAG_BADGE05_GET) == TRUE && PartyHasMonWithSurf() == TRUE && IsPlayerFacingSurfableFishableWater() == TRUE)
+ return EventScript_UseSurf;
+
+ if (MetatileBehavior_IsWaterfall(metatileBehavior) == TRUE)
+ {
+ if (FlagGet(FLAG_BADGE08_GET) == TRUE && IsPlayerSurfingNorth() == TRUE)
+ return EventScript_UseWaterfall;
+ else
+ return EventScript_CannotUseWaterfall;
+ }
+ return NULL;
+}
+
+static bool32 TrySetupDiveDownScript(void)
+{
+ if (FlagGet(FLAG_BADGE07_GET) && TrySetDiveWarp() == 2)
+ {
+ ScriptContext1_SetupScript(EventScript_UseDive);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool32 TrySetupDiveEmergeScript(void)
+{
+ if (FlagGet(FLAG_BADGE07_GET) && gMapHeader.mapType == MAP_TYPE_UNDERWATER && TrySetDiveWarp() == 1)
+ {
+ ScriptContext1_SetupScript(EventScript_UseDiveUnderwater);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 TryStartStepBasedScript(struct MapPosition *position, u16 metatileBehavior, u16 direction)
+{
+ if (TryStartCoordEventScript(position) == TRUE)
+ return TRUE;
+ if (TryStartWarpEventScript(position, metatileBehavior) == TRUE)
+ return TRUE;
+ if (TryStartMiscWalkingScripts(metatileBehavior) == TRUE)
+ return TRUE;
+ if (TryStartStepCountScript(metatileBehavior) == TRUE)
+ return TRUE;
+ if (UpdateRepelCounter() == TRUE)
+ return TRUE;
+ return FALSE;
+}
+
+static bool8 TryStartCoordEventScript(struct MapPosition *position)
+{
+ u8 *script = GetCoordEventScriptAtPosition(&gMapHeader, position->x - 7, position->y - 7, position->height);
+
+ if (script == NULL)
+ return FALSE;
+ ScriptContext1_SetupScript(script);
+ return TRUE;
+}
+
+static bool8 TryStartMiscWalkingScripts(u16 metatileBehavior)
+{
+ s16 x;
+ s16 y;
+
+ if (MetatileBehavior_IsCrackedFloorHole(metatileBehavior))
+ {
+ ScriptContext1_SetupScript(EventScript_FallDownHole);
+ return TRUE;
+ }
+ else if (MetatileBehavior_IsBattlePyramidWarp(metatileBehavior))
+ {
+ ScriptContext1_SetupScript(BattleFrontier_BattlePyramidEmptySquare_EventScript_252BE8);
+ return TRUE;
+ }
+ else if (MetatileBehavior_IsSecretBaseGlitterMat(metatileBehavior) == TRUE)
+ {
+ sub_80FA9D0();
+ return FALSE;
+ }
+ else if (MetatileBehavior_IsSecretBaseSoundMat(metatileBehavior) == TRUE)
+ {
+ PlayerGetDestCoords(&x, &y);
+ sub_80FA970(MapGridGetMetatileIdAt(x, y));
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static bool8 TryStartStepCountScript(u16 metatileBehavior)
+{
+ if (InUnionRoom() == TRUE)
+ {
+ return FALSE;
+ }
+
+ IncrementRematchStepCounter();
+ UpdateHappinessStepCounter();
+ sub_81D4998();
+
+ if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_6) && !MetatileBehavior_IsForcedMovementTile(metatileBehavior))
+ {
+ if (UpdatePoisonStepCounter() == TRUE)
+ {
+ ScriptContext1_SetupScript(EventScript_Poison);
+ return TRUE;
+ }
+ if (ShouldEggHatch())
+ {
+ IncrementGameStat(GAME_STAT_HATCHED_EGGS);
+ ScriptContext1_SetupScript(EventScript_EggHatch);
+ return TRUE;
+ }
+ if (sub_813B3B0() == TRUE)
+ {
+ ScriptContext1_SetupScript(gUnknown_08273D1F);
+ return TRUE;
+ }
+ if (ShouldDoBrailleRegicePuzzle() == TRUE)
+ {
+ ScriptContext1_SetupScript(IslandCave_EventScript_238EAF);
+ return TRUE;
+ }
+ if (is_tile_that_overrides_player_control() == TRUE)
+ {
+ ScriptContext1_SetupScript(MauvilleCity_EventScript_1DF7BA);
+ return TRUE;
+ }
+ if (sub_8138120() == TRUE)
+ {
+ ScriptContext1_SetupScript(Route119_EventScript_1F49EC);
+ return TRUE;
+ }
+ if (sub_8138168() == TRUE)
+ {
+ ScriptContext1_SetupScript(LittlerootTown_ProfessorBirchsLab_EventScript_1FA4D6);
+ return TRUE;
+ }
+ if (sub_81381B0() == TRUE)
+ {
+ ScriptContext1_SetupScript(RustboroCity_Gym_EventScript_21307B);
+ return TRUE;
+ }
+ if (sub_81381F8() == TRUE)
+ {
+ ScriptContext1_SetupScript(MossdeepCity_SpaceCenter_2F_EventScript_224175);
+ return TRUE;
+ }
+ }
+
+ if (SafariZoneTakeStep() == TRUE)
+ return TRUE;
+ if (CountSSTidalStep(1) == TRUE)
+ {
+ ScriptContext1_SetupScript(SSTidalCorridor_EventScript_23C050);
+ return TRUE;
+ }
+ if (sub_8196034())
+ return TRUE;
+ return FALSE;
+}
+
+void Unref_ClearHappinessStepCounter(void)
+{
+ VarSet(VAR_HAPPINESS_STEP_COUNTER, 0);
+}
+
+static void UpdateHappinessStepCounter(void)
+{
+ u16 *ptr = GetVarPointer(VAR_HAPPINESS_STEP_COUNTER);
+ int i;
+
+ (*ptr)++;
+ (*ptr) %= 128;
+ if (*ptr == 0)
+ {
+ struct Pokemon *mon = gPlayerParty;
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ AdjustFriendship(mon, FRIENDSHIP_EVENT_WALKING);
+ mon++;
+ }
+ }
+}
+
+void ClearPoisonStepCounter(void)
+{
+ VarSet(VAR_POISON_STEP_COUNTER, 0);
+}
+
+static bool8 UpdatePoisonStepCounter(void)
+{
+ u16 *ptr;
+
+ if (gMapHeader.mapType != MAP_TYPE_SECRET_BASE)
+ {
+ ptr = GetVarPointer(VAR_POISON_STEP_COUNTER);
+ (*ptr)++;
+ (*ptr) %= 4;
+ if (*ptr == 0)
+ {
+ switch (DoPoisonFieldEffect())
+ {
+ case 0:
+ return FALSE;
+ case 1:
+ return FALSE;
+ case 2:
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+void RestartWildEncounterImmunitySteps(void)
+{
+ // Starts at 0 and counts up to 4 steps.
+ sWildEncounterImmunitySteps = 0;
+}
+
+static bool8 CheckStandardWildEncounter(u16 metatileBehavior)
+{
+ if (sWildEncounterImmunitySteps < 4)
+ {
+ sWildEncounterImmunitySteps++;
+ sPreviousPlayerMetatileBehavior = metatileBehavior;
+ return FALSE;
+ }
+
+ if (StandardWildEncounter(metatileBehavior, sPreviousPlayerMetatileBehavior) == TRUE)
+ {
+ sWildEncounterImmunitySteps = 0;
+ sPreviousPlayerMetatileBehavior = metatileBehavior;
+ return TRUE;
+ }
+
+ sPreviousPlayerMetatileBehavior = metatileBehavior;
+ return FALSE;
+}
+
+static bool8 mapheader_run_first_tag2_script_list_match_conditionally(struct MapPosition *position, u16 metatileBehavior, u8 direction)
+{
+ s8 warpEventId = GetWarpEventAtMapPosition(&gMapHeader, position);
+
+ if (IsArrowWarpMetatileBehavior(metatileBehavior, direction) == TRUE && warpEventId != -1)
+ {
+ StoreInitialPlayerAvatarState();
+ sub_809CEB0(&gMapHeader, warpEventId, position);
+ sub_80AF734();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 TryStartWarpEventScript(struct MapPosition *position, u16 metatileBehavior)
+{
+ s8 warpEventId = GetWarpEventAtMapPosition(&gMapHeader, position);
+
+ if (warpEventId != -1 && IsWarpMetatileBehavior(metatileBehavior) == TRUE)
+ {
+ StoreInitialPlayerAvatarState();
+ sub_809CEB0(&gMapHeader, warpEventId, position);
+ if (MetatileBehavior_IsEscalator(metatileBehavior) == TRUE)
+ {
+ sub_80AF80C(metatileBehavior);
+ return TRUE;
+ }
+ if (MetatileBehavior_IsLavaridgeB1FWarp(metatileBehavior) == TRUE)
+ {
+ sub_80AF828();
+ return TRUE;
+ }
+ if (MetatileBehavior_IsLavaridge1FWarp(metatileBehavior) == TRUE)
+ {
+ sub_80AF838();
+ return TRUE;
+ }
+ if (MetatileBehavior_IsAquaHideoutWarp(metatileBehavior) == TRUE)
+ {
+ sub_80AF848();
+ return TRUE;
+ }
+ if (MetatileBehavior_IsWarpOrBridge(metatileBehavior) == TRUE)
+ {
+ sub_80B0268();
+ return TRUE;
+ }
+ if (MetatileBehavior_IsMtPyreHole(metatileBehavior) == TRUE)
+ {
+ ScriptContext1_SetupScript(gUnknown_082A8350);
+ return TRUE;
+ }
+ if (MetatileBehavior_IsMossdeepGymWarp(metatileBehavior) == TRUE)
+ {
+ sub_80AF87C();
+ return TRUE;
+ }
+ sub_80AF734();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool8 IsWarpMetatileBehavior(u16 metatileBehavior)
+{
+ if (MetatileBehavior_IsWarpDoor(metatileBehavior) != TRUE
+ && MetatileBehavior_IsLadder(metatileBehavior) != TRUE
+ && MetatileBehavior_IsEscalator(metatileBehavior) != TRUE
+ && MetatileBehavior_IsNonAnimDoor(metatileBehavior) != TRUE
+ && MetatileBehavior_IsLavaridgeB1FWarp(metatileBehavior) != TRUE
+ && MetatileBehavior_IsLavaridge1FWarp(metatileBehavior) != TRUE
+ && MetatileBehavior_IsAquaHideoutWarp(metatileBehavior) != TRUE
+ && MetatileBehavior_IsMtPyreHole(metatileBehavior) != TRUE
+ && MetatileBehavior_IsMossdeepGymWarp(metatileBehavior) != TRUE
+ && MetatileBehavior_IsWarpOrBridge(metatileBehavior) != TRUE)
+ return FALSE;
+ return TRUE;
+}
+
+static bool8 IsArrowWarpMetatileBehavior(u16 metatileBehavior, u8 direction)
+{
+ switch (direction)
+ {
+ case DIR_NORTH:
+ return MetatileBehavior_IsNorthArrowWarp(metatileBehavior);
+ case DIR_SOUTH:
+ return MetatileBehavior_IsSouthArrowWarp(metatileBehavior);
+ case DIR_WEST:
+ return MetatileBehavior_IsWestArrowWarp(metatileBehavior);
+ case DIR_EAST:
+ return MetatileBehavior_IsEastArrowWarp(metatileBehavior);
+ }
+ return FALSE;
+}
+
+static s8 GetWarpEventAtMapPosition(struct MapHeader *mapHeader, struct MapPosition *position)
+{
+ return GetWarpEventAtPosition(mapHeader, position->x - 7, position->y - 7, position->height);
+}
+
+static void sub_809CEB0(struct MapHeader *unused, s8 warpEventId, struct MapPosition *position)
+{
+ const struct WarpEvent *warpEvent;
+
+ u8 trainerHillMapId = GetCurrentTrainerHillMapId();
+
+ if (trainerHillMapId)
+ {
+ if (trainerHillMapId == sub_81D6490())
+ {
+ if (warpEventId == 0)
+ {
+ warpEvent = &gMapHeader.events->warps[0];
+ }
+ else
+ {
+ warpEvent = sub_81D6120();
+ }
+ }
+ else if (trainerHillMapId == 5)
+ {
+ warpEvent = sub_81D6134(warpEventId);
+ }
+ else
+ {
+ warpEvent = &gMapHeader.events->warps[warpEventId];
+ }
+ }
+ else
+ {
+ warpEvent = &gMapHeader.events->warps[warpEventId];
+ }
+
+ if (warpEvent->mapNum == 0x7F)
+ {
+ copy_saved_warp2_bank_and_enter_x_to_warp1(warpEvent->warpId);
+ }
+ else
+ {
+ const struct MapHeader *mapHeader;
+
+ warp1_set_2(warpEvent->mapGroup, warpEvent->mapNum, warpEvent->warpId);
+ sub_8084D5C(position->x, position->y);
+ mapHeader = Overworld_GetMapHeaderByGroupAndId(warpEvent->mapGroup, warpEvent->mapNum);
+ if (mapHeader->events->warps[warpEvent->warpId].mapNum == 0x7F)
+ saved_warp2_set(mapHeader->events->warps[warpEventId].warpId, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, warpEventId);
+ }
+}
+
+static bool8 map_warp_consider_2_to_inside(struct MapPosition *position, u16 metatileBehavior, u8 direction)
+{
+ s8 warpEventId;
+
+ if (direction == DIR_NORTH)
+ {
+ if (MetatileBehavior_IsOpenSecretBaseDoor(metatileBehavior) == TRUE)
+ {
+ sub_80E9668(position, gMapHeader.events);
+ return TRUE;
+ }
+ if (MetatileBehavior_IsWarpDoor(metatileBehavior) == TRUE)
+ {
+ warpEventId = GetWarpEventAtMapPosition(&gMapHeader, position);
+ if (warpEventId != -1 && IsWarpMetatileBehavior(metatileBehavior) == TRUE)
+ {
+ StoreInitialPlayerAvatarState();
+ sub_809CEB0(&gMapHeader, warpEventId, position);
+ sub_80AF7D0();
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+static s8 GetWarpEventAtPosition(struct MapHeader *mapHeader, u16 x, u16 y, u8 elevation)
+{
+ s32 i;
+ struct WarpEvent *warpEvent = mapHeader->events->warps;
+ u8 warpCount = mapHeader->events->warpCount;
+
+ for (i = 0; i < warpCount; i++, warpEvent++)
+ {
+ if ((u16)warpEvent->x == x && (u16)warpEvent->y == y)
+ {
+ if (warpEvent->elevation == elevation || warpEvent->elevation == 0)
+ return i;
+ }
+ }
+ return -1;
+}
+
+static u8 *TryRunCoordEventScript(struct CoordEvent *coordEvent)
+{
+ if (coordEvent != NULL)
+ {
+ if (coordEvent->script == NULL)
+ {
+ DoCoordEventWeather(coordEvent->trigger);
+ return NULL;
+ }
+ if (coordEvent->trigger == 0)
+ {
+ ScriptContext2_RunNewScript(coordEvent->script);
+ return NULL;
+ }
+ if (VarGet(coordEvent->trigger) == (u8)coordEvent->index)
+ return coordEvent->script;
+ }
+ return NULL;
+}
+
+static u8 *GetCoordEventScriptAtPosition(struct MapHeader *mapHeader, u16 x, u16 y, u8 elevation)
+{
+ s32 i;
+ struct CoordEvent *coordEvents = mapHeader->events->coordEvents;
+ u8 coordEventCount = mapHeader->events->coordEventCount;
+
+ for (i = 0; i < coordEventCount; i++)
+ {
+ if ((u16)coordEvents[i].x == x && (u16)coordEvents[i].y == y)
+ {
+ if (coordEvents[i].elevation == elevation || coordEvents[i].elevation == 0)
+ {
+ u8 *script = TryRunCoordEventScript(&coordEvents[i]);
+ if (script != NULL)
+ return script;
+ }
+ }
+ }
+ return NULL;
+}
+
+u8 *GetCoordEventScriptAtMapPosition(struct MapPosition *position)
+{
+ return GetCoordEventScriptAtPosition(&gMapHeader, position->x - 7, position->y - 7, position->height);
+}
+
+static struct BgEvent *GetBackgroundEventAtPosition(struct MapHeader *mapHeader, u16 x, u16 y, u8 elevation)
+{
+ u8 i;
+ struct BgEvent *bgEvents = mapHeader->events->bgEvents;
+ u8 bgEventCount = mapHeader->events->bgEventCount;
+
+ for (i = 0; i < bgEventCount; i++)
+ {
+ if ((u16)bgEvents[i].x == x && (u16)bgEvents[i].y == y)
+ {
+ if (bgEvents[i].elevation == elevation || bgEvents[i].elevation == 0)
+ return &bgEvents[i];
+ }
+ }
+ return NULL;
+}
+
+bool8 dive_warp(struct MapPosition *position, u16 metatileBehavior)
+{
+ if (gMapHeader.mapType == MAP_TYPE_UNDERWATER && !MetatileBehavior_IsUnableToEmerge(metatileBehavior))
+ {
+ if (SetDiveWarpEmerge(position->x - 7, position->y - 7))
+ {
+ StoreInitialPlayerAvatarState();
+ sp13E_warp_to_last_warp();
+ PlaySE(SE_W291);
+ return TRUE;
+ }
+ }
+ else if (MetatileBehavior_IsDiveable(metatileBehavior) == TRUE)
+ {
+ if (SetDiveWarpDive(position->x - 7, position->y - 7))
+ {
+ StoreInitialPlayerAvatarState();
+ sp13E_warp_to_last_warp();
+ PlaySE(SE_W291);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+u8 TrySetDiveWarp(void)
+{
+ s16 x, y;
+ u8 metatileBehavior;
+
+ PlayerGetDestCoords(&x, &y);
+ metatileBehavior = MapGridGetMetatileBehaviorAt(x, y);
+ if (gMapHeader.mapType == MAP_TYPE_UNDERWATER && !MetatileBehavior_IsUnableToEmerge(metatileBehavior))
+ {
+ if (SetDiveWarpEmerge(x - 7, y - 7) == TRUE)
+ return 1;
+ }
+ else if (MetatileBehavior_IsDiveable(metatileBehavior) == TRUE)
+ {
+ if (SetDiveWarpDive(x - 7, y - 7) == TRUE)
+ return 2;
+ }
+ return 0;
+}
+
+const u8 *GetEventObjectScriptPointerPlayerFacing(void)
+{
+ u8 direction;
+ struct MapPosition position;
+
+ direction = GetPlayerMovementDirection();
+ GetInFrontOfPlayerPosition(&position);
+ return GetInteractedEventObjectScript(&position, MapGridGetMetatileBehaviorAt(position.x, position.y), direction);
+}
+
+int SetCableClubWarp(void)
+{
+ struct MapPosition position;
+
+ GetPlayerMovementDirection(); //unnecessary
+ GetPlayerPosition(&position);
+ MapGridGetMetatileBehaviorAt(position.x, position.y); //unnecessary
+ sub_809CEB0(&gMapHeader, GetWarpEventAtMapPosition(&gMapHeader, &position), &position);
+ return 0;
+}