mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 11:44:17 +01:00
2efbd5f549
Fix some incorrect fieldmap names
1006 lines
33 KiB
C
1006 lines
33 KiB
C
#include "global.h"
|
|
#include "battle_setup.h"
|
|
#include "bike.h"
|
|
#include "coord_event_weather.h"
|
|
#include "daycare.h"
|
|
#include "faraway_island.h"
|
|
#include "event_data.h"
|
|
#include "event_object_movement.h"
|
|
#include "event_scripts.h"
|
|
#include "fieldmap.h"
|
|
#include "field_control_avatar.h"
|
|
#include "field_player_avatar.h"
|
|
#include "field_poison.h"
|
|
#include "field_screen_effect.h"
|
|
#include "field_specials.h"
|
|
#include "fldeff_misc.h"
|
|
#include "item_menu.h"
|
|
#include "link.h"
|
|
#include "match_call.h"
|
|
#include "metatile_behavior.h"
|
|
#include "overworld.h"
|
|
#include "pokemon.h"
|
|
#include "safari_zone.h"
|
|
#include "script.h"
|
|
#include "secret_base.h"
|
|
#include "sound.h"
|
|
#include "start_menu.h"
|
|
#include "trainer_see.h"
|
|
#include "trainer_hill.h"
|
|
#include "wild_encounter.h"
|
|
#include "constants/event_bg.h"
|
|
#include "constants/event_objects.h"
|
|
#include "constants/field_poison.h"
|
|
#include "constants/map_types.h"
|
|
#include "constants/songs.h"
|
|
#include "constants/trainer_hill.h"
|
|
|
|
static EWRAM_DATA u8 sWildEncounterImmunitySteps = 0;
|
|
static EWRAM_DATA u16 sPreviousPlayerMetatileBehavior = 0;
|
|
|
|
u8 gSelectedObjectEvent;
|
|
|
|
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 *GetInteractedObjectEventScript(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 TryArrowWarp(struct MapPosition *, u16, u8);
|
|
static bool8 IsWarpMetatileBehavior(u16);
|
|
static bool8 IsArrowWarpMetatileBehavior(u16, u8);
|
|
static s8 GetWarpEventAtMapPosition(struct MapHeader *, struct MapPosition *);
|
|
static void SetupWarp(struct MapHeader *, s8, struct MapPosition *);
|
|
static bool8 TryDoorWarp(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 UpdateFriendshipStepCounter(void);
|
|
static bool8 UpdatePoisonStepCounter(void);
|
|
|
|
void FieldClearPlayerInput(struct FieldInput *input)
|
|
{
|
|
input->pressedAButton = FALSE;
|
|
input->checkStandardWildEncounter = FALSE;
|
|
input->pressedStartButton = FALSE;
|
|
input->pressedSelectButton = FALSE;
|
|
input->heldDirection = FALSE;
|
|
input->heldDirection2 = 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() != PLAYER_SPEED_FASTEST)
|
|
{
|
|
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->heldDirection = TRUE;
|
|
input->heldDirection2 = 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 ProcessPlayerFieldInput(struct FieldInput *input)
|
|
{
|
|
struct MapPosition position;
|
|
u8 playerDirection;
|
|
u16 metatileBehavior;
|
|
|
|
gSpecialVar_LastTalked = 0;
|
|
gSelectedObjectEvent = 0;
|
|
|
|
playerDirection = GetPlayerFacingDirection();
|
|
GetPlayerPosition(&position);
|
|
metatileBehavior = MapGridGetMetatileBehaviorAt(position.x, position.y);
|
|
|
|
if (CheckForTrainersWantingBattle() == TRUE)
|
|
return TRUE;
|
|
|
|
if (TryRunOnFrameMapScript() == TRUE)
|
|
return TRUE;
|
|
|
|
if (input->pressedBButton && TrySetupDiveEmergeScript() == TRUE)
|
|
return TRUE;
|
|
if (input->tookStep)
|
|
{
|
|
IncrementGameStat(GAME_STAT_STEPS);
|
|
IncrementBirthIslandRockStepCount();
|
|
if (TryStartStepBasedScript(&position, metatileBehavior, playerDirection) == TRUE)
|
|
return TRUE;
|
|
}
|
|
if (input->checkStandardWildEncounter && CheckStandardWildEncounter(metatileBehavior) == TRUE)
|
|
return TRUE;
|
|
if (input->heldDirection && input->dpadDirection == playerDirection)
|
|
{
|
|
if (TryArrowWarp(&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->heldDirection2 && input->dpadDirection == playerDirection)
|
|
{
|
|
if (TryDoorWarp(&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->elevation = PlayerGetElevation();
|
|
}
|
|
|
|
static void GetInFrontOfPlayerPosition(struct MapPosition *position)
|
|
{
|
|
s16 x, y;
|
|
|
|
GetXYCoordsOneStepInFrontOfPlayer(&position->x, &position->y);
|
|
PlayerGetDestCoords(&x, &y);
|
|
if (MapGridGetElevationAt(x, y) != 0)
|
|
position->elevation = PlayerGetElevation();
|
|
else
|
|
position->elevation = 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 != LittlerootTown_BrendansHouse_2F_EventScript_PC
|
|
&& script != LittlerootTown_MaysHouse_2F_EventScript_PC
|
|
&& script != SecretBase_EventScript_PC
|
|
&& script != SecretBase_EventScript_RecordMixingPC
|
|
&& script != SecretBase_EventScript_DollInteract
|
|
&& script != SecretBase_EventScript_CushionInteract
|
|
&& 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 = GetInteractedObjectEventScript(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 objectEventId;
|
|
s32 i;
|
|
|
|
if (!MetatileBehavior_IsCounter(MapGridGetMetatileBehaviorAt(position->x, position->y)))
|
|
objectEventId = GetObjectEventIdByPosition(position->x, position->y, position->elevation);
|
|
else
|
|
objectEventId = GetObjectEventIdByPosition(position->x + gDirectionToVectors[direction].x, position->y + gDirectionToVectors[direction].y, position->elevation);
|
|
|
|
if (objectEventId == OBJECT_EVENTS_COUNT || gObjectEvents[objectEventId].localId == OBJ_EVENT_ID_PLAYER)
|
|
return NULL;
|
|
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
if (gLinkPlayerObjectEvents[i].active == TRUE && gLinkPlayerObjectEvents[i].objEventId == objectEventId)
|
|
return NULL;
|
|
}
|
|
|
|
gSelectedObjectEvent = objectEventId;
|
|
gSpecialVar_LastTalked = gObjectEvents[objectEventId].localId;
|
|
gSpecialVar_Facing = direction;
|
|
return GetObjectEventScriptPointerByObjectEventId(objectEventId);
|
|
}
|
|
|
|
static const u8 *GetInteractedObjectEventScript(struct MapPosition *position, u8 metatileBehavior, u8 direction)
|
|
{
|
|
u8 objectEventId;
|
|
const u8 *script;
|
|
|
|
objectEventId = GetObjectEventIdByPosition(position->x, position->y, position->elevation);
|
|
if (objectEventId == OBJECT_EVENTS_COUNT || gObjectEvents[objectEventId].localId == OBJ_EVENT_ID_PLAYER)
|
|
{
|
|
if (MetatileBehavior_IsCounter(metatileBehavior) != TRUE)
|
|
return NULL;
|
|
|
|
// Look for an object event on the other side of the counter.
|
|
objectEventId = GetObjectEventIdByPosition(position->x + gDirectionToVectors[direction].x, position->y + gDirectionToVectors[direction].y, position->elevation);
|
|
if (objectEventId == OBJECT_EVENTS_COUNT || gObjectEvents[objectEventId].localId == OBJ_EVENT_ID_PLAYER)
|
|
return NULL;
|
|
}
|
|
|
|
gSelectedObjectEvent = objectEventId;
|
|
gSpecialVar_LastTalked = gObjectEvents[objectEventId].localId;
|
|
gSpecialVar_Facing = direction;
|
|
|
|
if (InTrainerHill() == TRUE)
|
|
script = GetTrainerHillTrainerScript();
|
|
else
|
|
script = GetObjectEventScriptPointerByObjectEventId(objectEventId);
|
|
|
|
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 - MAP_OFFSET, position->y - MAP_OFFSET, position->elevation);
|
|
|
|
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 (TrySetCurSecretBase())
|
|
return SecretBase_EventScript_CheckEntrance;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
return bgEvent->bgUnion.script;
|
|
}
|
|
|
|
static const u8 *GetInteractedMetatileScript(struct MapPosition *position, u8 metatileBehavior, u8 direction)
|
|
{
|
|
s8 elevation;
|
|
|
|
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_IsSkyPillarClosedDoor(metatileBehavior) == TRUE)
|
|
return SkyPillar_Outside_EventScript_ClosedDoor;
|
|
if (MetatileBehavior_IsCableBoxResults1(metatileBehavior) == TRUE)
|
|
return EventScript_CableBoxResults;
|
|
if (MetatileBehavior_IsPokeblockFeeder(metatileBehavior) == TRUE)
|
|
return EventScript_PokeBlockFeeder;
|
|
if (MetatileBehavior_IsTrickHousePuzzleDoor(metatileBehavior) == TRUE)
|
|
return Route110_TrickHousePuzzle_EventScript_Door;
|
|
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_EmptyTrashCan;
|
|
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;
|
|
|
|
elevation = position->elevation;
|
|
if (elevation == MapGridGetElevationAt(position->x, position->y))
|
|
{
|
|
if (MetatileBehavior_IsSecretBasePC(metatileBehavior) == TRUE)
|
|
return SecretBase_EventScript_PC;
|
|
if (MetatileBehavior_IsRecordMixingSecretBasePC(metatileBehavior) == TRUE)
|
|
return SecretBase_EventScript_RecordMixingPC;
|
|
if (MetatileBehavior_IsSecretBaseSandOrnament(metatileBehavior) == TRUE)
|
|
return SecretBase_EventScript_SandOrnament;
|
|
if (MetatileBehavior_IsSecretBaseShieldOrToyTV(metatileBehavior) == TRUE)
|
|
return SecretBase_EventScript_ShieldOrToyTV;
|
|
if (MetatileBehavior_IsSecretBaseDecorationBase(metatileBehavior) == TRUE)
|
|
{
|
|
CheckInteractedWithFriendsFurnitureBottom();
|
|
return NULL;
|
|
}
|
|
if (MetatileBehavior_HoldsLargeDecoration(metatileBehavior) == TRUE)
|
|
{
|
|
CheckInteractedWithFriendsFurnitureMiddle();
|
|
return NULL;
|
|
}
|
|
if (MetatileBehavior_HoldsSmallDecoration(metatileBehavior) == TRUE)
|
|
{
|
|
CheckInteractedWithFriendsFurnitureTop();
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (MetatileBehavior_IsSecretBasePoster(metatileBehavior) == TRUE)
|
|
{
|
|
CheckInteractedWithFriendsPosterDecor();
|
|
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 - MAP_OFFSET, position->y - MAP_OFFSET, position->elevation);
|
|
|
|
if (script == NULL)
|
|
return FALSE;
|
|
ScriptContext1_SetupScript(script);
|
|
return TRUE;
|
|
}
|
|
|
|
static bool8 TryStartMiscWalkingScripts(u16 metatileBehavior)
|
|
{
|
|
s16 x, y;
|
|
|
|
if (MetatileBehavior_IsCrackedFloorHole(metatileBehavior))
|
|
{
|
|
ScriptContext1_SetupScript(EventScript_FallDownHole);
|
|
return TRUE;
|
|
}
|
|
else if (MetatileBehavior_IsBattlePyramidWarp(metatileBehavior))
|
|
{
|
|
ScriptContext1_SetupScript(BattlePyramid_WarpToNextFloor);
|
|
return TRUE;
|
|
}
|
|
else if (MetatileBehavior_IsSecretBaseGlitterMat(metatileBehavior) == TRUE)
|
|
{
|
|
DoSecretBaseGlitterMatSparkle();
|
|
return FALSE;
|
|
}
|
|
else if (MetatileBehavior_IsSecretBaseSoundMat(metatileBehavior) == TRUE)
|
|
{
|
|
PlayerGetDestCoords(&x, &y);
|
|
PlaySecretBaseMusicNoteMatSound(MapGridGetMetatileIdAt(x, y));
|
|
return FALSE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 TryStartStepCountScript(u16 metatileBehavior)
|
|
{
|
|
if (InUnionRoom() == TRUE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
IncrementRematchStepCounter();
|
|
UpdateFriendshipStepCounter();
|
|
UpdateFarawayIslandStepCounter();
|
|
|
|
if (!(gPlayerAvatar.flags & PLAYER_AVATAR_FLAG_FORCED_MOVE) && !MetatileBehavior_IsForcedMovementTile(metatileBehavior))
|
|
{
|
|
if (UpdatePoisonStepCounter() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(EventScript_FieldPoison);
|
|
return TRUE;
|
|
}
|
|
if (ShouldEggHatch())
|
|
{
|
|
IncrementGameStat(GAME_STAT_HATCHED_EGGS);
|
|
ScriptContext1_SetupScript(EventScript_EggHatch);
|
|
return TRUE;
|
|
}
|
|
if (AbnormalWeatherHasExpired() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(AbnormalWeather_EventScript_EndEventAndCleanup_1);
|
|
return TRUE;
|
|
}
|
|
if (ShouldDoBrailleRegicePuzzle() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(IslandCave_EventScript_OpenRegiEntrance);
|
|
return TRUE;
|
|
}
|
|
if (ShouldDoWallyCall() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(MauvilleCity_EventScript_RegisterWallyCall);
|
|
return TRUE;
|
|
}
|
|
if (ShouldDoScottFortreeCall() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(Route119_EventScript_ScottWonAtFortreeGymCall);
|
|
return TRUE;
|
|
}
|
|
if (ShouldDoScottBattleFrontierCall() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(LittlerootTown_ProfessorBirchsLab_EventScript_ScottAboardSSTidalCall);
|
|
return TRUE;
|
|
}
|
|
if (ShouldDoRoxanneCall() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(RustboroCity_Gym_EventScript_RegisterRoxanne);
|
|
return TRUE;
|
|
}
|
|
if (ShouldDoRivalRayquazaCall() == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(MossdeepCity_SpaceCenter_2F_EventScript_RivalRayquazaCall);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (SafariZoneTakeStep() == TRUE)
|
|
return TRUE;
|
|
if (CountSSTidalStep(1) == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(SSTidalCorridor_EventScript_ReachedStepCount);
|
|
return TRUE;
|
|
}
|
|
if (TryStartMatchCall())
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
// Unused
|
|
static void ClearFriendshipStepCounter(void)
|
|
{
|
|
VarSet(VAR_FRIENDSHIP_STEP_COUNTER, 0);
|
|
}
|
|
|
|
static void UpdateFriendshipStepCounter(void)
|
|
{
|
|
u16 *ptr = GetVarPointer(VAR_FRIENDSHIP_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 FLDPSN_NONE:
|
|
return FALSE;
|
|
case FLDPSN_PSN:
|
|
return FALSE;
|
|
case FLDPSN_FNT:
|
|
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 TryArrowWarp(struct MapPosition *position, u16 metatileBehavior, u8 direction)
|
|
{
|
|
s8 warpEventId = GetWarpEventAtMapPosition(&gMapHeader, position);
|
|
|
|
if (IsArrowWarpMetatileBehavior(metatileBehavior, direction) == TRUE && warpEventId != WARP_ID_NONE)
|
|
{
|
|
StoreInitialPlayerAvatarState();
|
|
SetupWarp(&gMapHeader, warpEventId, position);
|
|
DoWarp();
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool8 TryStartWarpEventScript(struct MapPosition *position, u16 metatileBehavior)
|
|
{
|
|
s8 warpEventId = GetWarpEventAtMapPosition(&gMapHeader, position);
|
|
|
|
if (warpEventId != WARP_ID_NONE && IsWarpMetatileBehavior(metatileBehavior) == TRUE)
|
|
{
|
|
StoreInitialPlayerAvatarState();
|
|
SetupWarp(&gMapHeader, warpEventId, position);
|
|
if (MetatileBehavior_IsEscalator(metatileBehavior) == TRUE)
|
|
{
|
|
DoEscalatorWarp(metatileBehavior);
|
|
return TRUE;
|
|
}
|
|
if (MetatileBehavior_IsLavaridgeB1FWarp(metatileBehavior) == TRUE)
|
|
{
|
|
DoLavaridgeGymB1FWarp();
|
|
return TRUE;
|
|
}
|
|
if (MetatileBehavior_IsLavaridge1FWarp(metatileBehavior) == TRUE)
|
|
{
|
|
DoLavaridgeGym1FWarp();
|
|
return TRUE;
|
|
}
|
|
if (MetatileBehavior_IsAquaHideoutWarp(metatileBehavior) == TRUE)
|
|
{
|
|
DoTeleportTileWarp();
|
|
return TRUE;
|
|
}
|
|
if (MetatileBehavior_IsUnionRoomWarp(metatileBehavior) == TRUE)
|
|
{
|
|
DoSpinExitWarp();
|
|
return TRUE;
|
|
}
|
|
if (MetatileBehavior_IsMtPyreHole(metatileBehavior) == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(EventScript_FallDownHoleMtPyre);
|
|
return TRUE;
|
|
}
|
|
if (MetatileBehavior_IsMossdeepGymWarp(metatileBehavior) == TRUE)
|
|
{
|
|
DoMossdeepGymWarp();
|
|
return TRUE;
|
|
}
|
|
DoWarp();
|
|
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_IsUnionRoomWarp(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 - MAP_OFFSET, position->y - MAP_OFFSET, position->elevation);
|
|
}
|
|
|
|
static void SetupWarp(struct MapHeader *unused, s8 warpEventId, struct MapPosition *position)
|
|
{
|
|
const struct WarpEvent *warpEvent;
|
|
|
|
u8 trainerHillMapId = GetCurrentTrainerHillMapId();
|
|
|
|
if (trainerHillMapId)
|
|
{
|
|
if (trainerHillMapId == GetNumFloorsInTrainerHillChallenge())
|
|
{
|
|
if (warpEventId == 0)
|
|
warpEvent = &gMapHeader.events->warps[0];
|
|
else
|
|
warpEvent = SetWarpDestinationTrainerHill4F();
|
|
}
|
|
else if (trainerHillMapId == TRAINER_HILL_ROOF)
|
|
{
|
|
warpEvent = SetWarpDestinationTrainerHillFinalFloor(warpEventId);
|
|
}
|
|
else
|
|
{
|
|
warpEvent = &gMapHeader.events->warps[warpEventId];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
warpEvent = &gMapHeader.events->warps[warpEventId];
|
|
}
|
|
|
|
if (warpEvent->mapNum == MAP_NUM(NONE))
|
|
{
|
|
SetWarpDestinationToDynamicWarp(warpEvent->warpId);
|
|
}
|
|
else
|
|
{
|
|
const struct MapHeader *mapHeader;
|
|
|
|
SetWarpDestinationToMapWarp(warpEvent->mapGroup, warpEvent->mapNum, warpEvent->warpId);
|
|
UpdateEscapeWarp(position->x, position->y);
|
|
mapHeader = Overworld_GetMapHeaderByGroupAndId(warpEvent->mapGroup, warpEvent->mapNum);
|
|
if (mapHeader->events->warps[warpEvent->warpId].mapNum == MAP_NUM(NONE))
|
|
SetDynamicWarp(mapHeader->events->warps[warpEventId].warpId, gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum, warpEventId);
|
|
}
|
|
}
|
|
|
|
static bool8 TryDoorWarp(struct MapPosition *position, u16 metatileBehavior, u8 direction)
|
|
{
|
|
s8 warpEventId;
|
|
|
|
if (direction == DIR_NORTH)
|
|
{
|
|
if (MetatileBehavior_IsOpenSecretBaseDoor(metatileBehavior) == TRUE)
|
|
{
|
|
WarpIntoSecretBase(position, gMapHeader.events);
|
|
return TRUE;
|
|
}
|
|
|
|
if (MetatileBehavior_IsWarpDoor(metatileBehavior) == TRUE)
|
|
{
|
|
warpEventId = GetWarpEventAtMapPosition(&gMapHeader, position);
|
|
if (warpEventId != WARP_ID_NONE && IsWarpMetatileBehavior(metatileBehavior) == TRUE)
|
|
{
|
|
StoreInitialPlayerAvatarState();
|
|
SetupWarp(&gMapHeader, warpEventId, position);
|
|
DoDoorWarp();
|
|
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 WARP_ID_NONE;
|
|
}
|
|
|
|
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 - MAP_OFFSET, position->y - MAP_OFFSET, position->elevation);
|
|
}
|
|
|
|
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 TryDoDiveWarp(struct MapPosition *position, u16 metatileBehavior)
|
|
{
|
|
if (gMapHeader.mapType == MAP_TYPE_UNDERWATER && !MetatileBehavior_IsUnableToEmerge(metatileBehavior))
|
|
{
|
|
if (SetDiveWarpEmerge(position->x - MAP_OFFSET, position->y - MAP_OFFSET))
|
|
{
|
|
StoreInitialPlayerAvatarState();
|
|
DoDiveWarp();
|
|
PlaySE(SE_M_DIVE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (MetatileBehavior_IsDiveable(metatileBehavior) == TRUE)
|
|
{
|
|
if (SetDiveWarpDive(position->x - MAP_OFFSET, position->y - MAP_OFFSET))
|
|
{
|
|
StoreInitialPlayerAvatarState();
|
|
DoDiveWarp();
|
|
PlaySE(SE_M_DIVE);
|
|
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 - MAP_OFFSET, y - MAP_OFFSET) == TRUE)
|
|
return 1;
|
|
}
|
|
else if (MetatileBehavior_IsDiveable(metatileBehavior) == TRUE)
|
|
{
|
|
if (SetDiveWarpDive(x - MAP_OFFSET, y - MAP_OFFSET) == TRUE)
|
|
return 2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
const u8 *GetObjectEventScriptPointerPlayerFacing(void)
|
|
{
|
|
u8 direction;
|
|
struct MapPosition position;
|
|
|
|
direction = GetPlayerMovementDirection();
|
|
GetInFrontOfPlayerPosition(&position);
|
|
return GetInteractedObjectEventScript(&position, MapGridGetMetatileBehaviorAt(position.x, position.y), direction);
|
|
}
|
|
|
|
int SetCableClubWarp(void)
|
|
{
|
|
struct MapPosition position;
|
|
|
|
GetPlayerMovementDirection(); //unnecessary
|
|
GetPlayerPosition(&position);
|
|
MapGridGetMetatileBehaviorAt(position.x, position.y); //unnecessary
|
|
SetupWarp(&gMapHeader, GetWarpEventAtMapPosition(&gMapHeader, &position), &position);
|
|
return 0;
|
|
}
|