mirror of
https://github.com/pret/pokeruby.git
synced 2026-04-26 00:13:40 -05:00
2763 lines
68 KiB
C
2763 lines
68 KiB
C
#include "global.h"
|
|
#include "overworld.h"
|
|
#include "battle_setup.h"
|
|
#include "berry.h"
|
|
#include "cable_club.h"
|
|
#include "clock.h"
|
|
#include "constants/map_types.h"
|
|
#include "constants/maps.h"
|
|
#include "constants/songs.h"
|
|
#include "constants/species.h"
|
|
#include "contest_util.h"
|
|
#include "event_data.h"
|
|
#include "event_object_movement.h"
|
|
#include "field_camera.h"
|
|
#include "field_control_avatar.h"
|
|
#include "field_effect.h"
|
|
#include "field_fadetransition.h"
|
|
#include "field_message_box.h"
|
|
#include "field_player_avatar.h"
|
|
#include "field_screen_effect.h"
|
|
#include "field_special_scene.h"
|
|
#include "field_specials.h"
|
|
#include "field_tasks.h"
|
|
#include "field_weather.h"
|
|
#include "fieldmap.h"
|
|
#include "fldeff_flash.h"
|
|
#include "heal_location.h"
|
|
#include "link.h"
|
|
#include "load_save.h"
|
|
#include "m4a.h"
|
|
#include "main.h"
|
|
#include "map_name_popup.h"
|
|
#include "menu.h"
|
|
#include "metatile_behavior.h"
|
|
#include "new_game.h"
|
|
#include "palette.h"
|
|
#include "play_time.h"
|
|
#include "random.h"
|
|
#include "roamer.h"
|
|
#include "rotating_gate.h"
|
|
#include "safari_zone.h"
|
|
#include "scanline_effect.h"
|
|
#include "script.h"
|
|
#include "secret_base.h"
|
|
#include "sound.h"
|
|
#include "start_menu.h"
|
|
#include "task.h"
|
|
#include "tileset_anim.h"
|
|
#include "time_events.h"
|
|
#include "tv.h"
|
|
#include "wild_encounter.h"
|
|
|
|
#ifdef SAPPHIRE
|
|
#define LEGENDARY_MUSIC MUS_WEATHER_KYOGRE // Heavy Rain
|
|
#else
|
|
#define LEGENDARY_MUSIC MUS_WEATHER_GROUDON // Drought
|
|
#endif
|
|
|
|
extern u8 gUnknown_020297ED;
|
|
extern u16 gTotalCameraPixelOffsetY;
|
|
extern u16 gTotalCameraPixelOffsetX;
|
|
|
|
extern u8 EventScript_WhiteOut[];
|
|
extern u8 EventScript_ResetMrBriney[];
|
|
extern u8 SingleBattleColosseum_EventScript_1A436F[];
|
|
extern u8 SingleBattleColosseum_EventScript_1A4379[];
|
|
extern u8 DoubleBattleColosseum_EventScript_1A4383[];
|
|
extern u8 DoubleBattleColosseum_EventScript_1A439E[];
|
|
extern u8 DoubleBattleColosseum_EventScript_1A43B9[];
|
|
extern u8 DoubleBattleColosseum_EventScript_1A43D4[];
|
|
extern u8 TradeCenter_EventScript_1A43F0[];
|
|
extern u8 TradeCenter_EventScript_1A43FA[];
|
|
extern u8 RecordCorner_EventScript_1A4418[];
|
|
extern u8 RecordCorner_EventScript_1A442D[];
|
|
extern u8 RecordCorner_EventScript_1A4442[];
|
|
extern u8 RecordCorner_EventScript_1A4457[];
|
|
extern u8 TradeRoom_ReadTrainerCard1[];
|
|
extern u8 TradeRoom_ReadTrainerCard2[];
|
|
extern u8 TradeRoom_TooBusyToNotice[];
|
|
extern u8 TradeRoom_PromptToCancelLink[];
|
|
extern u8 TradeRoom_TerminateLink[];
|
|
extern u8 gUnknown_081A4508[];
|
|
|
|
extern struct MapLayout * const gMapLayouts[];
|
|
extern struct MapHeader * const * const gMapGroups[];
|
|
extern s32 gMaxFlashLevel;
|
|
|
|
u16 word_3004858;
|
|
void (*gFieldCallback)(void);
|
|
u8 gUnknown_03004860;
|
|
u8 gFieldLinkPlayerCount;
|
|
|
|
EWRAM_DATA struct WarpData gLastUsedWarp = {0};
|
|
EWRAM_DATA struct WarpData gWarpDestination = {0};
|
|
EWRAM_DATA struct WarpData gFixedDiveWarp = {0};
|
|
EWRAM_DATA struct WarpData gFixedHoleWarp = {0};
|
|
EWRAM_DATA struct InitialPlayerAvatarState gInitialPlayerAvatarState = {0};
|
|
EWRAM_DATA static u16 sAmbientCrySpecies = 0;
|
|
EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE;
|
|
EWRAM_DATA struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4] = {0};
|
|
|
|
static u8 gUnknown_03000580[4];
|
|
static u16 (*gUnknown_03000584)(u32);
|
|
static u8 gUnknown_03000588;
|
|
|
|
static void CB2_Overworld(void);
|
|
static u8 GetAdjustedInitialTransitionFlags(struct InitialPlayerAvatarState*, u16, u8);
|
|
static u8 GetAdjustedInitialDirection(struct InitialPlayerAvatarState*, u8, u16, u8);
|
|
static bool32 sub_805483C(u8*);
|
|
static void c2_80567AC(void);
|
|
static void Overworld_ResetStateAfterWhiteOut(void);
|
|
static void InitOverworldGraphicsRegisters(void);
|
|
static void ChooseAmbientCrySpecies(void);
|
|
static void SetFieldVBlankCallback(void);
|
|
static void VBlankCB_Field(void);
|
|
static void SpawnLinkPlayerObjectEvent(u8, s16, s16, u8);
|
|
static void InitLinkPlayerObjectEventPos(struct ObjectEvent *, s16, s16);
|
|
static u8 GetLinkPlayerIdAt(s16, s16);
|
|
static u8 npc_something3(u8, u8);
|
|
static u8 LinkPlayerDetectCollision(u8, u8, s16, s16);
|
|
static void CreateLinkPlayerSprite(u8);
|
|
static void SpriteCB_LinkPlayer(struct Sprite *);
|
|
static u16 sub_8055758(const u8 *);
|
|
static void sub_8055808(const u8 *);
|
|
static void sub_8055840(const u8 *);
|
|
|
|
static const struct WarpData sDummyWarpData =
|
|
{
|
|
.mapGroup = -1,
|
|
.mapNum = -1,
|
|
.warpId = -1,
|
|
.x = -1,
|
|
.y = -1,
|
|
};
|
|
|
|
static const u8 sUnusedData[] =
|
|
{
|
|
0xB0, 0x04, 0x00, 0x00,
|
|
0x10, 0x0E, 0x00, 0x00,
|
|
0xB0, 0x04, 0x00, 0x00,
|
|
0x60, 0x09, 0x00, 0x00,
|
|
0x32, 0x00, 0x00, 0x00,
|
|
0x50, 0x00, 0x00, 0x00,
|
|
0xD4, 0xFF, 0xFF, 0xFF,
|
|
0x2C, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
const struct UCoords32 gDirectionToVectors[] =
|
|
{
|
|
{ 0, 0}, // DIR_NONE
|
|
{ 0, 1}, // DIR_SOUTH
|
|
{ 0, -1}, // DIR_NORTH
|
|
{-1, 0}, // DIR_WEST
|
|
{ 1, 0}, // DIR_EAST
|
|
{-1, 1}, // DIR_SOUTHWEST
|
|
{ 1, 1}, // DIR_SOUTHEAST
|
|
{-1, -1}, // DIR_NORTHWEST
|
|
{ 1, -1}, // DIR_NORTHEAST
|
|
};
|
|
|
|
static const struct ScanlineEffectParams sFlashEffectParams =
|
|
{
|
|
(void *)REG_ADDR_WIN0H,
|
|
((DMA_ENABLE | DMA_START_HBLANK | DMA_REPEAT | DMA_DEST_RELOAD) << 16) | 1,
|
|
1,
|
|
0,
|
|
};
|
|
|
|
static u8 sub_8055C68(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8);
|
|
static u8 sub_8055C88(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8);
|
|
static u8 sub_8055C8C(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8);
|
|
|
|
static u8 (*const gUnknown_082166A0[])(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8) =
|
|
{
|
|
sub_8055C68,
|
|
sub_8055C88,
|
|
sub_8055C8C,
|
|
};
|
|
|
|
static u8 sub_8055CAC(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8);
|
|
static u8 sub_8055CB0(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8);
|
|
static u8 sub_8055D18(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8);
|
|
|
|
static u8 (*const gUnknown_082166AC[])(struct LinkPlayerObjectEvent *, struct ObjectEvent *, u8) =
|
|
{
|
|
sub_8055CAC,
|
|
sub_8055CB0,
|
|
sub_8055CB0,
|
|
sub_8055CB0,
|
|
sub_8055CB0,
|
|
sub_8055CAC,
|
|
sub_8055CAC,
|
|
sub_8055D18,
|
|
sub_8055D18,
|
|
sub_8055D18,
|
|
sub_8055D18,
|
|
};
|
|
|
|
static void sub_8055D30(struct LinkPlayerObjectEvent *, struct ObjectEvent *);
|
|
static void sub_8055D38(struct LinkPlayerObjectEvent *, struct ObjectEvent *);
|
|
|
|
static void (*const gUnknown_082166D8[])(struct LinkPlayerObjectEvent *, struct ObjectEvent *) =
|
|
{
|
|
sub_8055D30,
|
|
sub_8055D38,
|
|
};
|
|
|
|
|
|
static void DoWhiteOut(void)
|
|
{
|
|
ScriptContext2_RunNewScript(EventScript_WhiteOut);
|
|
gSaveBlock1.money /= 2;
|
|
ScrSpecial_HealPlayerParty();
|
|
Overworld_ResetStateAfterWhiteOut();
|
|
Overworld_SetWarpDestToLastHealLoc();
|
|
WarpIntoMap();
|
|
}
|
|
|
|
void Overworld_ResetStateAfterFly(void)
|
|
{
|
|
ResetInitialPlayerAvatarState();
|
|
FlagClear(FLAG_SYS_CYCLING_ROAD);
|
|
FlagClear(FLAG_SYS_CRUISE_MODE);
|
|
FlagClear(FLAG_SYS_SAFARI_MODE);
|
|
FlagClear(FLAG_SYS_USE_STRENGTH);
|
|
FlagClear(FLAG_SYS_USE_FLASH);
|
|
}
|
|
|
|
void Overworld_ResetStateAfterTeleport(void)
|
|
{
|
|
ResetInitialPlayerAvatarState();
|
|
FlagClear(FLAG_SYS_CYCLING_ROAD);
|
|
FlagClear(FLAG_SYS_CRUISE_MODE);
|
|
FlagClear(FLAG_SYS_SAFARI_MODE);
|
|
FlagClear(FLAG_SYS_USE_STRENGTH);
|
|
FlagClear(FLAG_SYS_USE_FLASH);
|
|
ScriptContext2_RunNewScript(EventScript_ResetMrBriney);
|
|
}
|
|
|
|
void Overworld_ResetStateAfterDigEscRope(void)
|
|
{
|
|
ResetInitialPlayerAvatarState();
|
|
FlagClear(FLAG_SYS_CYCLING_ROAD);
|
|
FlagClear(FLAG_SYS_CRUISE_MODE);
|
|
FlagClear(FLAG_SYS_SAFARI_MODE);
|
|
FlagClear(FLAG_SYS_USE_STRENGTH);
|
|
FlagClear(FLAG_SYS_USE_FLASH);
|
|
}
|
|
|
|
static void Overworld_ResetStateAfterWhiteOut(void)
|
|
{
|
|
ResetInitialPlayerAvatarState();
|
|
FlagClear(FLAG_SYS_CYCLING_ROAD);
|
|
FlagClear(FLAG_SYS_CRUISE_MODE);
|
|
FlagClear(FLAG_SYS_SAFARI_MODE);
|
|
FlagClear(FLAG_SYS_USE_STRENGTH);
|
|
FlagClear(FLAG_SYS_USE_FLASH);
|
|
}
|
|
|
|
static void sub_805308C(void)
|
|
{
|
|
FlagClear(FLAG_SYS_SAFARI_MODE);
|
|
ChooseAmbientCrySpecies();
|
|
ResetCyclingRoadChallengeData();
|
|
UpdateLocationHistoryForRoamer();
|
|
RoamerMoveToOtherLocationSet();
|
|
}
|
|
|
|
void ResetGameStats(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < NUM_GAME_STATS; i++)
|
|
gSaveBlock1.gameStats[i] = 0;
|
|
}
|
|
|
|
void IncrementGameStat(u8 index)
|
|
{
|
|
if (index < NUM_GAME_STATS)
|
|
{
|
|
if (gSaveBlock1.gameStats[index] < 0xFFFFFF)
|
|
gSaveBlock1.gameStats[index]++;
|
|
else
|
|
gSaveBlock1.gameStats[index] = 0xFFFFFF;
|
|
}
|
|
}
|
|
|
|
u32 GetGameStat(u8 stat)
|
|
{
|
|
if (stat >= NUM_GAME_STATS)
|
|
return 0;
|
|
|
|
return gSaveBlock1.gameStats[stat];
|
|
}
|
|
|
|
void SetGameStat(u8 stat, u32 value)
|
|
{
|
|
if (stat < NUM_GAME_STATS)
|
|
gSaveBlock1.gameStats[stat] = value;
|
|
}
|
|
|
|
void LoadObjEventTemplatesFromHeader(void)
|
|
{
|
|
// Clear object event templates
|
|
CpuFill32(0, gSaveBlock1.objectEventTemplates, sizeof(gSaveBlock1.objectEventTemplates));
|
|
|
|
// Copy map header events to save block
|
|
CpuCopy32(gMapHeader.events->objectEvents,
|
|
gSaveBlock1.objectEventTemplates,
|
|
gMapHeader.events->objectEventCount * sizeof(struct ObjectEventTemplate));
|
|
}
|
|
|
|
static void LoadSaveblockObjEventScripts(void)
|
|
{
|
|
struct ObjectEventTemplate *objectEventTemplates = gSaveBlock1.objectEventTemplates;
|
|
s32 i;
|
|
|
|
for (i = 0; i < 64; i++)
|
|
objectEventTemplates[i].script = gMapHeader.events->objectEvents[i].script;
|
|
}
|
|
|
|
void Overworld_SetObjEventTemplateCoords(u8 localId, s16 x, s16 y)
|
|
{
|
|
s32 i;
|
|
for (i = 0; i < 64; i++)
|
|
{
|
|
struct ObjectEventTemplate *objectEventTemplate = &gSaveBlock1.objectEventTemplates[i];
|
|
if (objectEventTemplate->localId == localId)
|
|
{
|
|
objectEventTemplate->x = x;
|
|
objectEventTemplate->y = y;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Overworld_SetObjEventTemplateMovementType(u8 localId, u8 movementType)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < 64; i++)
|
|
{
|
|
struct ObjectEventTemplate *objectEventTemplate = &gSaveBlock1.objectEventTemplates[i];
|
|
if (objectEventTemplate->localId == localId)
|
|
{
|
|
objectEventTemplate->movementType = movementType;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void mapdata_load_assets_to_gpu_and_full_redraw(void)
|
|
{
|
|
move_tilemap_camera_to_upper_left_corner();
|
|
CopyMapTilesetsToVram(gMapHeader.mapLayout);
|
|
LoadMapTilesetPalettes(gMapHeader.mapLayout);
|
|
DrawWholeMapView();
|
|
cur_mapheader_run_tileset_funcs_after_some_cpuset();
|
|
}
|
|
|
|
static struct MapLayout *GetMapLayout(void)
|
|
{
|
|
u16 mapLayoutId = gSaveBlock1.mapLayoutId;
|
|
if (mapLayoutId)
|
|
return gMapLayouts[mapLayoutId - 1];
|
|
return NULL;
|
|
}
|
|
|
|
static void ApplyCurrentWarp(void)
|
|
{
|
|
gLastUsedWarp = gSaveBlock1.location;
|
|
gSaveBlock1.location = gWarpDestination;
|
|
gFixedDiveWarp = sDummyWarpData;
|
|
gFixedHoleWarp = sDummyWarpData;
|
|
}
|
|
|
|
static void SetWarpData(struct WarpData *warp, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
|
|
{
|
|
warp->mapGroup = mapGroup;
|
|
warp->mapNum = mapNum;
|
|
warp->warpId = warpId;
|
|
warp->x = x;
|
|
warp->y = y;
|
|
}
|
|
|
|
static bool32 IsDummyWarp(struct WarpData *warp)
|
|
{
|
|
if (warp->mapGroup != -1)
|
|
return FALSE;
|
|
if (warp->mapNum != -1)
|
|
return FALSE;
|
|
if (warp->warpId != -1)
|
|
return FALSE;
|
|
if (warp->x != -1)
|
|
return FALSE;
|
|
if (warp->y != -1)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
struct MapHeader *const Overworld_GetMapHeaderByGroupAndId(u16 mapGroup, u16 mapNum)
|
|
{
|
|
return gMapGroups[mapGroup][mapNum];
|
|
}
|
|
|
|
struct MapHeader *const GetDestinationWarpMapHeader(void)
|
|
{
|
|
return Overworld_GetMapHeaderByGroupAndId(gWarpDestination.mapGroup, gWarpDestination.mapNum);
|
|
}
|
|
|
|
static void LoadCurrentMapData(void)
|
|
{
|
|
gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
|
|
gSaveBlock1.mapLayoutId = gMapHeader.mapLayoutId;
|
|
gMapHeader.mapLayout = GetMapLayout();
|
|
}
|
|
|
|
static void LoadSaveblockMapHeader(void)
|
|
{
|
|
gMapHeader = *Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
|
|
gMapHeader.mapLayout = GetMapLayout();
|
|
}
|
|
|
|
static void SetPlayerCoordsFromWarp(void)
|
|
{
|
|
if (gSaveBlock1.location.warpId >= 0 && gSaveBlock1.location.warpId < gMapHeader.events->warpCount)
|
|
{
|
|
gSaveBlock1.pos.x = gMapHeader.events->warps[gSaveBlock1.location.warpId].x;
|
|
gSaveBlock1.pos.y = gMapHeader.events->warps[gSaveBlock1.location.warpId].y;
|
|
}
|
|
else if (gSaveBlock1.location.x >= 0 && gSaveBlock1.location.y >= 0)
|
|
{
|
|
gSaveBlock1.pos.x = gSaveBlock1.location.x;
|
|
gSaveBlock1.pos.y = gSaveBlock1.location.y;
|
|
}
|
|
else
|
|
{
|
|
gSaveBlock1.pos.x = gMapHeader.mapLayout->width / 2;
|
|
gSaveBlock1.pos.y = gMapHeader.mapLayout->height / 2;
|
|
}
|
|
}
|
|
|
|
void WarpIntoMap(void)
|
|
{
|
|
ApplyCurrentWarp();
|
|
LoadCurrentMapData();
|
|
SetPlayerCoordsFromWarp();
|
|
}
|
|
|
|
void Overworld_SetWarpDestination(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
|
|
{
|
|
SetWarpData(&gWarpDestination, mapGroup, mapNum, warpId, x, y);
|
|
}
|
|
|
|
void warp1_set_2(s8 mapGroup, s8 mapNum, s8 warpId)
|
|
{
|
|
Overworld_SetWarpDestination(mapGroup, mapNum, warpId, -1, -1);
|
|
}
|
|
|
|
void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId)
|
|
{
|
|
SetWarpData(&gSaveBlock1.dynamicWarp, mapGroup, mapNum, warpId, gSaveBlock1.pos.x, gSaveBlock1.pos.y);
|
|
}
|
|
|
|
void saved_warp2_set_2(int unused, s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
|
|
{
|
|
SetWarpData(&gSaveBlock1.dynamicWarp, mapGroup, mapNum, warpId, x, y);
|
|
}
|
|
|
|
void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused)
|
|
{
|
|
gWarpDestination = gSaveBlock1.dynamicWarp;
|
|
}
|
|
|
|
void sub_8053538(u8 a1)
|
|
{
|
|
const struct HealLocation *warp = GetHealLocation(a1);
|
|
|
|
if (warp)
|
|
Overworld_SetWarpDestination(warp->mapGroup, warp->mapNum, -1, warp->x, warp->y);
|
|
}
|
|
|
|
void Overworld_SetWarpDestToLastHealLoc(void)
|
|
{
|
|
gWarpDestination = gSaveBlock1.lastHealLocation;
|
|
}
|
|
|
|
void Overworld_SetHealLocationWarp(u8 healLocationId)
|
|
{
|
|
const struct HealLocation *healLocation = GetHealLocation(healLocationId);
|
|
|
|
if (healLocation != NULL)
|
|
SetWarpData(&gSaveBlock1.lastHealLocation, healLocation->mapGroup, healLocation->mapNum, -1, healLocation->x, healLocation->y);
|
|
}
|
|
|
|
void sub_80535C4(s16 a1, s16 a2)
|
|
{
|
|
u8 currMapType = Overworld_GetMapTypeOfSaveblockLocation();
|
|
u8 destMapType = GetMapTypeByGroupAndId(gWarpDestination.mapGroup, gWarpDestination.mapNum);
|
|
if (is_map_type_1_2_3_5_or_6(currMapType) && is_map_type_1_2_3_5_or_6(destMapType) != TRUE)
|
|
sub_805363C(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum, -1, a1 - 7, a2 - 6);
|
|
}
|
|
|
|
void sub_805363C(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
|
|
{
|
|
SetWarpData(&gSaveBlock1.warp4, mapGroup, mapNum, warpId, x, y);
|
|
}
|
|
|
|
void sub_8053678(void)
|
|
{
|
|
gWarpDestination = gSaveBlock1.warp4;
|
|
}
|
|
|
|
void SetFixedDiveWarp(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
|
|
{
|
|
SetWarpData(&gFixedDiveWarp, mapGroup, mapNum, warpId, x, y);
|
|
}
|
|
|
|
static void SetFixedDiveWarpAsDestination(void)
|
|
{
|
|
gWarpDestination = gFixedDiveWarp;
|
|
}
|
|
|
|
void SetFixedHoleWarp(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
|
|
{
|
|
SetWarpData(&gFixedHoleWarp, mapGroup, mapNum, warpId, x, y);
|
|
}
|
|
|
|
void SetFixedHoleWarpAsDestination(s16 x, s16 y)
|
|
{
|
|
if (IsDummyWarp(&gFixedHoleWarp) == TRUE)
|
|
gWarpDestination = gLastUsedWarp;
|
|
else
|
|
Overworld_SetWarpDestination(gFixedHoleWarp.mapGroup, gFixedHoleWarp.mapNum, -1, x, y);
|
|
}
|
|
|
|
void sub_8053778(void)
|
|
{
|
|
gWarpDestination = gSaveBlock1.warp1;
|
|
}
|
|
|
|
void unref_sub_8053790(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y)
|
|
{
|
|
SetWarpData(&gSaveBlock1.warp1, mapGroup, mapNum, warpId, x, y);
|
|
}
|
|
|
|
void sub_80537CC(u8 a1)
|
|
{
|
|
const struct HealLocation *warp = GetHealLocation(a1);
|
|
if (warp)
|
|
SetWarpData(&gSaveBlock1.warp1, warp->mapGroup, warp->mapNum, -1, warp->x, warp->y);
|
|
}
|
|
|
|
void gpu_sync_bg_hide()
|
|
{
|
|
gSaveBlock1.warp1 = gSaveBlock1.dynamicWarp;
|
|
}
|
|
|
|
const struct MapConnection *GetMapConnection(u8 dir)
|
|
{
|
|
s32 i;
|
|
s32 count = gMapHeader.connections->count;
|
|
const struct MapConnection *connection = gMapHeader.connections->connections;
|
|
|
|
if (connection == NULL)
|
|
return NULL;
|
|
|
|
for(i = 0; i < count; i++, connection++)
|
|
if (connection->direction == dir)
|
|
return connection;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static bool8 SetDiveWarp(u8 direction, u16 x, u16 y)
|
|
{
|
|
const struct MapConnection *connection = GetMapConnection(direction);
|
|
|
|
if (connection != NULL)
|
|
{
|
|
Overworld_SetWarpDestination(connection->mapGroup, connection->mapNum, -1, x, y);
|
|
}
|
|
else
|
|
{
|
|
RunOnDiveWarpMapScript();
|
|
if (IsDummyWarp(&gFixedDiveWarp))
|
|
return FALSE;
|
|
|
|
SetFixedDiveWarpAsDestination();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool8 SetDiveWarpEmerge(u16 x, u16 y)
|
|
{
|
|
return SetDiveWarp(CONNECTION_EMERGE, x, y);
|
|
}
|
|
|
|
bool8 SetDiveWarpDive(u16 x, u16 y)
|
|
{
|
|
return SetDiveWarp(CONNECTION_DIVE, x, y);
|
|
}
|
|
|
|
void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum)
|
|
{
|
|
s32 paletteIndex;
|
|
|
|
Overworld_SetWarpDestination(mapGroup, mapNum, -1, -1, -1);
|
|
sub_8053F0C();
|
|
ApplyCurrentWarp();
|
|
LoadCurrentMapData();
|
|
LoadObjEventTemplatesFromHeader();
|
|
ClearTempFieldEventData();
|
|
ResetCyclingRoadChallengeData();
|
|
RestartWildEncounterImmunitySteps();
|
|
TryUpdateRandomTrainerRematches(mapGroup, mapNum);
|
|
DoTimeBasedEvents();
|
|
SetSav1WeatherFromCurrMapHeader();
|
|
ChooseAmbientCrySpecies();
|
|
SetDefaultFlashLevel();
|
|
Overworld_ClearSavedMusic();
|
|
RunOnTransitionMapScript();
|
|
InitMap();
|
|
CopySecondaryTilesetToVram(gMapHeader.mapLayout);
|
|
LoadSecondaryTilesetPalette(gMapHeader.mapLayout);
|
|
|
|
for (paletteIndex = 6; paletteIndex < 12; paletteIndex++)
|
|
ApplyWeatherGammaShiftToPal(paletteIndex);
|
|
|
|
sub_8072ED0();
|
|
UpdateLocationHistoryForRoamer();
|
|
RoamerMove();
|
|
DoCurrentWeather();
|
|
ResetFieldTasksArgs();
|
|
RunOnResumeMapScript();
|
|
ShowMapNamePopup();
|
|
}
|
|
|
|
void sub_8053994(u32 a1)
|
|
{
|
|
bool8 v2;
|
|
bool8 v3;
|
|
|
|
LoadCurrentMapData();
|
|
LoadObjEventTemplatesFromHeader();
|
|
v2 = is_map_type_1_2_3_5_or_6(gMapHeader.mapType);
|
|
v3 = Overworld_MapTypeIsIndoors(gMapHeader.mapType);
|
|
ClearTempFieldEventData();
|
|
ResetCyclingRoadChallengeData();
|
|
RestartWildEncounterImmunitySteps();
|
|
TryUpdateRandomTrainerRematches(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum);
|
|
if (a1 != 1)
|
|
DoTimeBasedEvents();
|
|
SetSav1WeatherFromCurrMapHeader();
|
|
ChooseAmbientCrySpecies();
|
|
if (v2)
|
|
FlagClear(FLAG_SYS_USE_FLASH);
|
|
SetDefaultFlashLevel();
|
|
Overworld_ClearSavedMusic();
|
|
RunOnTransitionMapScript();
|
|
UpdateLocationHistoryForRoamer();
|
|
RoamerMoveToOtherLocationSet();
|
|
InitMap();
|
|
if (a1 != 1 && v3)
|
|
{
|
|
UpdateTVScreensOnMap(gBackupMapLayout.width, gBackupMapLayout.height);
|
|
InitSecretBaseAppearance(TRUE);
|
|
}
|
|
}
|
|
|
|
void ResetInitialPlayerAvatarState(void)
|
|
{
|
|
gInitialPlayerAvatarState.direction = DIR_SOUTH;
|
|
gInitialPlayerAvatarState.transitionFlags = PLAYER_AVATAR_FLAG_ON_FOOT;
|
|
}
|
|
|
|
void StoreInitialPlayerAvatarState(void)
|
|
{
|
|
gInitialPlayerAvatarState.direction = GetPlayerFacingDirection();
|
|
|
|
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE))
|
|
gInitialPlayerAvatarState.transitionFlags = PLAYER_AVATAR_FLAG_MACH_BIKE;
|
|
else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_ACRO_BIKE))
|
|
gInitialPlayerAvatarState.transitionFlags = PLAYER_AVATAR_FLAG_ACRO_BIKE;
|
|
else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
|
|
gInitialPlayerAvatarState.transitionFlags = PLAYER_AVATAR_FLAG_SURFING;
|
|
else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_UNDERWATER))
|
|
gInitialPlayerAvatarState.transitionFlags = PLAYER_AVATAR_FLAG_UNDERWATER;
|
|
else
|
|
gInitialPlayerAvatarState.transitionFlags = PLAYER_AVATAR_FLAG_ON_FOOT;
|
|
}
|
|
|
|
static struct InitialPlayerAvatarState *GetInitialPlayerAvatarState(void)
|
|
{
|
|
struct InitialPlayerAvatarState playerStruct;
|
|
u8 mapType = Overworld_GetMapTypeOfSaveblockLocation();
|
|
u16 metatileBehavior = GetCenterScreenMetatileBehavior();
|
|
u8 transitionFlags = GetAdjustedInitialTransitionFlags(&gInitialPlayerAvatarState, metatileBehavior, mapType);
|
|
playerStruct.transitionFlags = transitionFlags;
|
|
playerStruct.direction = GetAdjustedInitialDirection(&gInitialPlayerAvatarState, transitionFlags, metatileBehavior, mapType);
|
|
gInitialPlayerAvatarState = playerStruct;
|
|
return &gInitialPlayerAvatarState;
|
|
}
|
|
|
|
static u8 GetAdjustedInitialTransitionFlags(struct InitialPlayerAvatarState *playerStruct, u16 metatileBehavior, u8 mapType)
|
|
{
|
|
if (mapType != MAP_TYPE_INDOOR && FlagGet(FLAG_SYS_CRUISE_MODE))
|
|
return PLAYER_AVATAR_FLAG_ON_FOOT;
|
|
if (mapType == MAP_TYPE_UNDERWATER)
|
|
return PLAYER_AVATAR_FLAG_UNDERWATER;
|
|
if (MetatileBehavior_IsSurfableWaterOrUnderwater(metatileBehavior) == TRUE)
|
|
return PLAYER_AVATAR_FLAG_SURFING;
|
|
if (Overworld_IsBikingAllowed() != TRUE)
|
|
return PLAYER_AVATAR_FLAG_ON_FOOT;
|
|
if (playerStruct->transitionFlags == PLAYER_AVATAR_FLAG_MACH_BIKE)
|
|
return PLAYER_AVATAR_FLAG_MACH_BIKE;
|
|
if (playerStruct->transitionFlags != PLAYER_AVATAR_FLAG_ACRO_BIKE)
|
|
return PLAYER_AVATAR_FLAG_ON_FOOT;
|
|
return PLAYER_AVATAR_FLAG_ACRO_BIKE;
|
|
}
|
|
|
|
static u8 GetAdjustedInitialDirection(struct InitialPlayerAvatarState *playerStruct, u8 transitionFlags, u16 metatileBehavior, u8 mapType)
|
|
{
|
|
if (FlagGet(FLAG_SYS_CRUISE_MODE) && mapType == MAP_TYPE_6)
|
|
return DIR_EAST;
|
|
if (MetatileBehavior_IsDeepSouthWarp(metatileBehavior) == TRUE)
|
|
return DIR_NORTH;
|
|
if (MetatileBehavior_IsNonAnimDoor(metatileBehavior) == TRUE || MetatileBehavior_IsDoor(metatileBehavior) == TRUE)
|
|
return DIR_SOUTH;
|
|
if (MetatileBehavior_IsSouthArrowWarp(metatileBehavior) == TRUE)
|
|
return DIR_NORTH;
|
|
if (MetatileBehavior_IsNorthArrowWarp(metatileBehavior) == TRUE)
|
|
return DIR_SOUTH;
|
|
if (MetatileBehavior_IsWestArrowWarp(metatileBehavior) == TRUE)
|
|
return DIR_EAST;
|
|
if (MetatileBehavior_IsEastArrowWarp(metatileBehavior) == TRUE)
|
|
return DIR_WEST;
|
|
if ((playerStruct->transitionFlags == PLAYER_AVATAR_FLAG_UNDERWATER && transitionFlags == PLAYER_AVATAR_FLAG_SURFING)
|
|
|| (playerStruct->transitionFlags == PLAYER_AVATAR_FLAG_SURFING && transitionFlags == PLAYER_AVATAR_FLAG_UNDERWATER))
|
|
return playerStruct->direction;
|
|
if (MetatileBehavior_IsLadder(metatileBehavior) == TRUE)
|
|
return playerStruct->direction;
|
|
return DIR_SOUTH;
|
|
}
|
|
|
|
u16 GetCenterScreenMetatileBehavior(void)
|
|
{
|
|
return MapGridGetMetatileBehaviorAt(gSaveBlock1.pos.x + 7, gSaveBlock1.pos.y + 7);
|
|
}
|
|
|
|
bool32 Overworld_IsBikingAllowed(void)
|
|
{
|
|
// is player in cycling road entrance?
|
|
if (gSaveBlock1.location.mapGroup == MAP_GROUP(MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE)
|
|
&& (gSaveBlock1.location.mapNum == MAP_NUM(MAP_ROUTE110_SEASIDE_CYCLING_ROAD_SOUTH_ENTRANCE)
|
|
|| gSaveBlock1.location.mapNum == MAP_NUM(MAP_ROUTE110_SEASIDE_CYCLING_ROAD_NORTH_ENTRANCE)))
|
|
return TRUE;
|
|
|
|
// is player indoor, in a secret base, or underwater?
|
|
if (gMapHeader.mapType == MAP_TYPE_INDOOR)
|
|
return FALSE;
|
|
if (gMapHeader.mapType == MAP_TYPE_SECRET_BASE)
|
|
return FALSE;
|
|
if (gMapHeader.mapType == MAP_TYPE_UNDERWATER)
|
|
return FALSE;
|
|
|
|
// Thou shalt not bike on the sacred resting grounds of Kyogre/Groudon.
|
|
if (gSaveBlock1.location.mapGroup == MAP_GROUP(MAP_SEAFLOOR_CAVERN_ROOM9)
|
|
&& gSaveBlock1.location.mapNum == MAP_NUM(MAP_SEAFLOOR_CAVERN_ROOM9))
|
|
return FALSE;
|
|
if (gSaveBlock1.location.mapGroup == MAP_GROUP(MAP_CAVE_OF_ORIGIN_B4F)
|
|
&& gSaveBlock1.location.mapNum == MAP_NUM(MAP_CAVE_OF_ORIGIN_B4F))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void SetDefaultFlashLevel(void)
|
|
{
|
|
if (!gMapHeader.cave)
|
|
gSaveBlock1.flashLevel = 0;
|
|
else if (FlagGet(FLAG_SYS_USE_FLASH))
|
|
gSaveBlock1.flashLevel = 1;
|
|
else
|
|
gSaveBlock1.flashLevel = gMaxFlashLevel;
|
|
}
|
|
|
|
void Overworld_SetFlashLevel(s32 flashLevel)
|
|
{
|
|
if (flashLevel < 0 || flashLevel > gMaxFlashLevel)
|
|
flashLevel = 0;
|
|
gSaveBlock1.flashLevel = flashLevel;
|
|
}
|
|
|
|
u8 Overworld_GetFlashLevel(void)
|
|
{
|
|
return gSaveBlock1.flashLevel;
|
|
}
|
|
|
|
void sub_8053D14(u16 mapLayoutId)
|
|
{
|
|
gSaveBlock1.mapLayoutId = mapLayoutId;
|
|
gMapHeader.mapLayout = GetMapLayout();
|
|
}
|
|
|
|
static bool16 ShouldLegendaryMusicPlayAtLocation(struct WarpData *warp)
|
|
{
|
|
if (!FlagGet(FLAG_SYS_WEATHER_CTRL))
|
|
return FALSE;
|
|
if (warp->mapGroup == 0)
|
|
{
|
|
switch (warp->mapNum)
|
|
{
|
|
case MAP_NUM(MAP_LILYCOVE_CITY):
|
|
case MAP_NUM(MAP_MOSSDEEP_CITY):
|
|
case MAP_NUM(MAP_SOOTOPOLIS_CITY):
|
|
case MAP_NUM(MAP_EVER_GRANDE_CITY):
|
|
return TRUE;
|
|
case MAP_NUM(MAP_ROUTE124):
|
|
case MAP_NUM(MAP_ROUTE125):
|
|
case MAP_NUM(MAP_ROUTE126):
|
|
case MAP_NUM(MAP_ROUTE127):
|
|
case MAP_NUM(MAP_ROUTE128):
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
static bool16 IsInfiltratedWeatherInstitute(struct WarpData *warp)
|
|
{
|
|
if (VarGet(VAR_WEATHER_INSTITUTE_STATE))
|
|
return FALSE;
|
|
if (warp->mapGroup != MAP_GROUP(MAP_ROUTE119_WEATHER_INSTITUTE_1F))
|
|
return FALSE;
|
|
if (warp->mapNum == MAP_NUM(MAP_ROUTE119_WEATHER_INSTITUTE_1F)
|
|
|| warp->mapNum == MAP_NUM(MAP_ROUTE119_WEATHER_INSTITUTE_2F))
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
static u16 GetLocationMusic(struct WarpData *warp)
|
|
{
|
|
if (ShouldLegendaryMusicPlayAtLocation(warp) == TRUE)
|
|
return LEGENDARY_MUSIC;
|
|
else if (IsInfiltratedWeatherInstitute(warp) == TRUE)
|
|
return MUS_MT_CHIMNEY;
|
|
else
|
|
return Overworld_GetMapHeaderByGroupAndId(warp->mapGroup, warp->mapNum)->music;
|
|
}
|
|
|
|
u16 GetCurrLocationDefaultMusic(void)
|
|
{
|
|
u16 music;
|
|
|
|
// Play the desert music only when the sandstorm is active on Route 111.
|
|
if (gSaveBlock1.location.mapGroup == MAP_GROUP(MAP_ROUTE111)
|
|
&& gSaveBlock1.location.mapNum == MAP_NUM(MAP_ROUTE111)
|
|
&& GetSav1Weather() == 8)
|
|
return MUS_ROUTE111;
|
|
|
|
music = GetLocationMusic(&gSaveBlock1.location);
|
|
if (music != 0x7FFF)
|
|
{
|
|
return music;
|
|
}
|
|
else
|
|
{
|
|
if (gSaveBlock1.pos.x < 24)
|
|
return MUS_ROUTE110;
|
|
else
|
|
return MUS_ROUTE119;
|
|
}
|
|
}
|
|
|
|
u16 GetWarpDestinationMusic(void)
|
|
{
|
|
u16 music = GetLocationMusic(&gWarpDestination);
|
|
if (music != 0x7FFF)
|
|
{
|
|
return music;
|
|
}
|
|
else
|
|
{
|
|
if (gSaveBlock1.location.mapGroup == MAP_GROUP(MAP_MAUVILLE_CITY)
|
|
&& gSaveBlock1.location.mapNum == MAP_NUM(MAP_MAUVILLE_CITY))
|
|
return MUS_ROUTE110;
|
|
else
|
|
return MUS_ROUTE119;
|
|
}
|
|
}
|
|
|
|
void Overworld_ResetMapMusic(void)
|
|
{
|
|
ResetMapMusic();
|
|
}
|
|
|
|
void Overworld_PlaySpecialMapMusic(void)
|
|
{
|
|
u16 music = GetCurrLocationDefaultMusic();
|
|
|
|
if (music != LEGENDARY_MUSIC)
|
|
{
|
|
if (gSaveBlock1.savedMusic)
|
|
music = gSaveBlock1.savedMusic;
|
|
else if (Overworld_GetMapTypeOfSaveblockLocation() == MAP_TYPE_UNDERWATER)
|
|
music = MUS_UNDERWATER;
|
|
else if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
|
|
music = MUS_SURF;
|
|
}
|
|
|
|
if (music != GetCurrentMapMusic())
|
|
PlayNewMapMusic(music);
|
|
}
|
|
|
|
void Overworld_SetSavedMusic(u16 songNum)
|
|
{
|
|
gSaveBlock1.savedMusic = songNum;
|
|
}
|
|
|
|
void Overworld_ClearSavedMusic(void)
|
|
{
|
|
gSaveBlock1.savedMusic = 0;
|
|
}
|
|
|
|
void sub_8053F0C(void)
|
|
{
|
|
if (FlagGet(FLAG_DONT_TRANSITION_MUSIC) != TRUE)
|
|
{
|
|
u16 newMusic = GetWarpDestinationMusic();
|
|
u16 currentMusic = GetCurrentMapMusic();
|
|
if (newMusic != LEGENDARY_MUSIC)
|
|
{
|
|
if (currentMusic == MUS_UNDERWATER || currentMusic == MUS_SURF)
|
|
return;
|
|
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_SURFING))
|
|
newMusic = MUS_SURF;
|
|
}
|
|
if (newMusic != currentMusic)
|
|
{
|
|
if (TestPlayerAvatarFlags(PLAYER_AVATAR_FLAG_MACH_BIKE | PLAYER_AVATAR_FLAG_ACRO_BIKE))
|
|
FadeOutAndFadeInNewMapMusic(newMusic, 4, 4);
|
|
else
|
|
FadeOutAndPlayNewMapMusic(newMusic, 8);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Overworld_ChangeMusicToDefault(void)
|
|
{
|
|
u16 currentMusic = GetCurrentMapMusic();
|
|
if (currentMusic != GetCurrLocationDefaultMusic())
|
|
FadeOutAndPlayNewMapMusic(GetCurrLocationDefaultMusic(), 8);
|
|
}
|
|
|
|
void Overworld_ChangeMusicTo(u16 newMusic)
|
|
{
|
|
u16 currentMusic = GetCurrentMapMusic();
|
|
if (currentMusic != newMusic && currentMusic != LEGENDARY_MUSIC)
|
|
FadeOutAndPlayNewMapMusic(newMusic, 8);
|
|
}
|
|
|
|
u8 GetMapMusicFadeoutSpeed(void)
|
|
{
|
|
const struct MapHeader *mapHeader = GetDestinationWarpMapHeader();
|
|
if (Overworld_MapTypeIsIndoors(mapHeader->mapType) == TRUE)
|
|
return 2;
|
|
else
|
|
return 4;
|
|
}
|
|
|
|
void TryFadeOutOldMapMusic(void)
|
|
{
|
|
u16 music = GetWarpDestinationMusic();
|
|
if (FlagGet(FLAG_DONT_TRANSITION_MUSIC) != TRUE && music != GetCurrentMapMusic())
|
|
{
|
|
u8 speed = GetMapMusicFadeoutSpeed();
|
|
FadeOutMapMusic(speed);
|
|
}
|
|
}
|
|
|
|
bool8 BGMusicStopped(void)
|
|
{
|
|
return IsNotWaitingForBGMStop();
|
|
}
|
|
|
|
void Overworld_FadeOutMapMusic(void)
|
|
{
|
|
FadeOutMapMusic(4);
|
|
}
|
|
|
|
static void PlayAmbientCry(void)
|
|
{
|
|
s16 x, y;
|
|
s8 pan;
|
|
s8 volume;
|
|
|
|
PlayerGetDestCoords(&x, &y);
|
|
if (sIsAmbientCryWaterMon == TRUE
|
|
&& !MetatileBehavior_IsSurfableWaterOrUnderwater(MapGridGetMetatileBehaviorAt(x, y)))
|
|
return;
|
|
pan = (Random() % 88) + 212;
|
|
volume = (Random() % 30) + 50;
|
|
PlayCry2(sAmbientCrySpecies, pan, volume, 1);
|
|
}
|
|
|
|
void UpdateAmbientCry(s16 *state, u16 *delayCounter)
|
|
{
|
|
switch (*state)
|
|
{
|
|
case 0:
|
|
if (sAmbientCrySpecies == SPECIES_NONE)
|
|
*state = 4;
|
|
else
|
|
*state = 1;
|
|
break;
|
|
case 1:
|
|
*delayCounter = (Random() % 2400) + 1200;
|
|
*state = 3;
|
|
break;
|
|
case 2:
|
|
*delayCounter = (Random() % 1200) + 1200;
|
|
*state = 3;
|
|
break;
|
|
case 3:
|
|
(*delayCounter)--;
|
|
if (*delayCounter == 0)
|
|
{
|
|
PlayAmbientCry();
|
|
*state = 2;
|
|
}
|
|
break;
|
|
case 4:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ChooseAmbientCrySpecies(void)
|
|
{
|
|
if ((gSaveBlock1.location.mapGroup == MAP_GROUP(MAP_ROUTE130)
|
|
&& gSaveBlock1.location.mapNum == MAP_NUM(MAP_ROUTE130))
|
|
&& !IsMirageIslandPresent())
|
|
{
|
|
// Only play water pokemon cries on this route
|
|
// when Mirage Island is not present
|
|
sIsAmbientCryWaterMon = TRUE;
|
|
sAmbientCrySpecies = GetLocalWaterMon();
|
|
}
|
|
else
|
|
{
|
|
sAmbientCrySpecies = GetLocalWildMon(&sIsAmbientCryWaterMon);
|
|
}
|
|
}
|
|
|
|
u8 GetMapTypeByGroupAndId(s8 mapGroup, s8 mapNum)
|
|
{
|
|
return Overworld_GetMapHeaderByGroupAndId(mapGroup, mapNum)->mapType;
|
|
}
|
|
|
|
u8 GetMapTypeByWarpData(struct WarpData *warp)
|
|
{
|
|
return GetMapTypeByGroupAndId(warp->mapGroup, warp->mapNum);
|
|
}
|
|
|
|
u8 Overworld_GetMapTypeOfSaveblockLocation(void)
|
|
{
|
|
return GetMapTypeByWarpData(&gSaveBlock1.location);
|
|
}
|
|
|
|
u8 GetLastUsedWarpMapType(void)
|
|
{
|
|
return GetMapTypeByWarpData(&gLastUsedWarp);
|
|
}
|
|
|
|
bool8 is_map_type_1_2_3_5_or_6(u8 mapType)
|
|
{
|
|
if (mapType == MAP_TYPE_ROUTE
|
|
|| mapType == MAP_TYPE_TOWN
|
|
|| mapType == MAP_TYPE_UNDERWATER
|
|
|| mapType == MAP_TYPE_CITY
|
|
|| mapType == MAP_TYPE_6)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 Overworld_MapTypeAllowsTeleportAndFly(u8 mapType)
|
|
{
|
|
if (mapType == MAP_TYPE_ROUTE
|
|
|| mapType == MAP_TYPE_TOWN
|
|
|| mapType == MAP_TYPE_6
|
|
|| mapType == MAP_TYPE_CITY)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 Overworld_MapTypeIsIndoors(u8 mapType)
|
|
{
|
|
if (mapType == MAP_TYPE_INDOOR
|
|
|| mapType == MAP_TYPE_SECRET_BASE)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
u8 unref_sub_8054260(void)
|
|
{
|
|
return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.dynamicWarp.mapGroup, gSaveBlock1.dynamicWarp.mapNum)->regionMapSectionId;
|
|
}
|
|
|
|
u8 sav1_map_get_name(void)
|
|
{
|
|
return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum)->regionMapSectionId;
|
|
}
|
|
|
|
u8 sav1_map_get_battletype(void)
|
|
{
|
|
return Overworld_GetMapHeaderByGroupAndId(gSaveBlock1.location.mapGroup, gSaveBlock1.location.mapNum)->battleType;
|
|
}
|
|
|
|
#if DEBUG
|
|
|
|
void debug_sub_8076B68(void);
|
|
|
|
void debug_sub_80589D8(void);
|
|
|
|
void debug_sub_8058A50(void);
|
|
|
|
void CB2_InitTestMenu(void)
|
|
{
|
|
m4aSoundVSyncOff();
|
|
SetVBlankCallback(NULL);
|
|
DmaFill32(3, 0, (void *) VRAM, VRAM_SIZE);
|
|
DmaFill32(3, 0, (void *) PLTT, PLTT_SIZE);
|
|
ResetPaletteFade();
|
|
ResetSpriteData();
|
|
ResetTasks();
|
|
ScanlineEffect_Stop();
|
|
Text_LoadWindowTemplate(&gMenuTextWindowTemplate);
|
|
InitMenuWindow(&gMenuTextWindowTemplate);
|
|
debug_sub_8076B68();
|
|
BeginNormalPaletteFade(0xFFFFFFFF, 0, 16, 0, RGB(0, 0, 0));
|
|
REG_IE |= 1;
|
|
REG_DISPCNT = DISPCNT_OBJ_ON | DISPCNT_BG0_ON | DISPCNT_OBJ_1D_MAP;
|
|
m4aSoundVSyncOn();
|
|
SetVBlankCallback(debug_sub_8058A50);
|
|
m4aSongNumStart(0x19D);
|
|
SetMainCallback2(debug_sub_80589D8);
|
|
}
|
|
|
|
void debug_sub_80589D8(void)
|
|
{
|
|
if (UpdatePaletteFade())
|
|
return;
|
|
|
|
RunTasks();
|
|
AnimateSprites();
|
|
BuildOamBuffer();
|
|
}
|
|
|
|
void debug_sub_80589F4(void)
|
|
{
|
|
if (UpdatePaletteFade())
|
|
return;
|
|
|
|
SetVBlankCallback(NULL);
|
|
|
|
DmaFill32(3, 0, (void *) VRAM, VRAM_SIZE);
|
|
DmaFill32(3, 0, (void *) PLTT, PLTT_SIZE);
|
|
|
|
SetMainCallback2(gMain.savedCallback);
|
|
}
|
|
|
|
void debug_sub_8058A50(void)
|
|
{
|
|
ProcessSpriteCopyRequests();
|
|
LoadOam();
|
|
TransferPlttBuffer();
|
|
}
|
|
|
|
#endif
|
|
|
|
void ResetSafariZoneFlag_(void)
|
|
{
|
|
ResetSafariZoneFlag();
|
|
}
|
|
|
|
bool32 is_c1_link_related_active(void)
|
|
{
|
|
if (gMain.callback1 == sub_8055354)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
static void DoCB1_Overworld(u16 newKeys, u16 heldKeys)
|
|
{
|
|
struct FieldInput fieldInput;
|
|
|
|
sub_8059204();
|
|
ClearPlayerFieldInput(&fieldInput);
|
|
GetPlayerFieldInput(&fieldInput, newKeys, heldKeys);
|
|
if (!ScriptContext2_IsEnabled())
|
|
{
|
|
if (ProcessPlayerFieldInput(&fieldInput) == 1)
|
|
{
|
|
ScriptContext2_Enable();
|
|
HideMapNamePopup();
|
|
}
|
|
else
|
|
{
|
|
player_step(fieldInput.dpadDirection, newKeys, heldKeys);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void CB1_Overworld(void)
|
|
{
|
|
if (gMain.callback2 == CB2_Overworld)
|
|
DoCB1_Overworld(gMain.newKeys, gMain.heldKeys);
|
|
}
|
|
|
|
static void OverworldBasic(void)
|
|
{
|
|
ScriptContext2_RunScript();
|
|
RunTasks();
|
|
AnimateSprites();
|
|
CameraUpdate();
|
|
UpdateCameraPanning();
|
|
BuildOamBuffer();
|
|
UpdatePaletteFade();
|
|
sub_8072EDC();
|
|
}
|
|
|
|
// This CB2 is used when starting
|
|
void CB2_OverworldBasic(void)
|
|
{
|
|
OverworldBasic();
|
|
}
|
|
|
|
static void CB2_Overworld(void)
|
|
{
|
|
int fading = (gPaletteFade.active != 0);
|
|
if (fading)
|
|
SetVBlankCallback(NULL);
|
|
OverworldBasic();
|
|
if (fading)
|
|
SetFieldVBlankCallback();
|
|
}
|
|
|
|
void SetMainCallback1(MainCallback cb)
|
|
{
|
|
gMain.callback1 = cb;
|
|
}
|
|
|
|
void sub_80543DC(u16 (*a1)(u32))
|
|
{
|
|
gUnknown_03000584 = a1;
|
|
}
|
|
|
|
static void RunFieldCallback(void)
|
|
{
|
|
if (gFieldCallback != NULL)
|
|
gFieldCallback();
|
|
else
|
|
mapldr_default();
|
|
gFieldCallback = NULL;
|
|
}
|
|
|
|
void CB2_NewGame(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
StopMapMusic();
|
|
ResetSafariZoneFlag_();
|
|
NewGameInitData();
|
|
ResetInitialPlayerAvatarState();
|
|
PlayTimeCounter_Start();
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
gFieldCallback = ExecuteTruckSequence;
|
|
do_load_map_stuff_loop(&gMain.state);
|
|
SetFieldVBlankCallback();
|
|
SetMainCallback1(CB1_Overworld);
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
|
|
#if DEBUG
|
|
|
|
void debug_sub_8058C00(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
StopMapMusic();
|
|
ResetSafariZoneFlag_();
|
|
ResetInitialPlayerAvatarState();
|
|
PlayTimeCounter_Start();
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
|
|
if (JOY_HELD(R_BUTTON))
|
|
gFieldCallback = ExecuteTruckSequence;
|
|
else
|
|
gFieldCallback = sub_8080B60;
|
|
|
|
do_load_map_stuff_loop(&gMain.state);
|
|
SetFieldVBlankCallback();
|
|
SetMainCallback1(CB1_Overworld);
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
|
|
#endif
|
|
|
|
void CB2_WhiteOut(void)
|
|
{
|
|
u8 val;
|
|
gMain.state++;
|
|
if (gMain.state >= 120)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
StopMapMusic();
|
|
ResetSafariZoneFlag_();
|
|
DoWhiteOut();
|
|
ResetInitialPlayerAvatarState();
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
gFieldCallback = sub_8080B60;
|
|
val = 0;
|
|
do_load_map_stuff_loop(&val);
|
|
SetFieldVBlankCallback();
|
|
SetMainCallback1(CB1_Overworld);
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
}
|
|
|
|
void CB2_LoadMap(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
SetMainCallback1(NULL);
|
|
SetMainCallback2(sub_810CC80);
|
|
gMain.savedCallback = CB2_LoadMap2;
|
|
}
|
|
|
|
void CB2_LoadMap2(void)
|
|
{
|
|
do_load_map_stuff_loop(&gMain.state);
|
|
SetFieldVBlankCallback();
|
|
SetMainCallback1(CB1_Overworld);
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
|
|
void sub_8054534(void)
|
|
{
|
|
if (!gMain.state)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
SetMainCallback1(NULL);
|
|
}
|
|
if (sub_805493C(&gMain.state, 1))
|
|
{
|
|
SetFieldVBlankCallback();
|
|
SetMainCallback1(CB1_Overworld);
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
}
|
|
|
|
void sub_8054588(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
gFieldCallback = sub_8080AC4;
|
|
SetMainCallback2(c2_80567AC);
|
|
}
|
|
|
|
static void c2_80567AC(void)
|
|
{
|
|
if (sub_805483C(&gMain.state))
|
|
{
|
|
SetFieldVBlankCallback();
|
|
SetMainCallback1(sub_8055354);
|
|
sub_80543DC(sub_8055390);
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
}
|
|
|
|
void CB2_ReturnToField(void)
|
|
{
|
|
if (is_c1_link_related_active() == TRUE)
|
|
{
|
|
SetMainCallback2(CB2_ReturnToFieldLink);
|
|
}
|
|
else
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
SetMainCallback2(CB2_ReturnToFieldLocal);
|
|
}
|
|
}
|
|
|
|
void CB2_ReturnToFieldLocal(void)
|
|
{
|
|
if (sub_8054A4C(&gMain.state))
|
|
{
|
|
SetFieldVBlankCallback();
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
}
|
|
|
|
void CB2_ReturnToFieldLink(void)
|
|
{
|
|
if (!sub_8055870() && sub_8054A9C(&gMain.state))
|
|
SetMainCallback2(CB2_Overworld);
|
|
}
|
|
|
|
void sub_805465C(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
StopMapMusic();
|
|
sub_8054F70();
|
|
SetMainCallback1(sub_8055354);
|
|
sub_80543DC(sub_8055390);
|
|
gFieldCallback = sub_8080A3C;
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
CB2_ReturnToField();
|
|
}
|
|
|
|
void c2_exit_to_overworld_1_sub_8080DEC(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
gFieldCallback = sub_8080DEC;
|
|
CB2_ReturnToField();
|
|
}
|
|
|
|
void sub_80546B8(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
gFieldCallback = sub_80809B0;
|
|
CB2_ReturnToField();
|
|
}
|
|
|
|
void CB2_ReturnToFieldContinueScriptPlayMapMusic(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
gFieldCallback = sub_8080990;
|
|
CB2_ReturnToField();
|
|
}
|
|
|
|
void sub_80546F0(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
gFieldCallback = sub_8080B60;
|
|
CB2_ReturnToField();
|
|
}
|
|
|
|
void sub_805470C(void)
|
|
{
|
|
if (gMapHeader.flags == 1 && sub_80BBB24() == 1)
|
|
ShowMapNamePopup();
|
|
sub_8080B60();
|
|
}
|
|
|
|
void CB2_ContinueSavedGame(void)
|
|
{
|
|
FieldClearVBlankHBlankCallbacks();
|
|
StopMapMusic();
|
|
#if DEBUG
|
|
if (JOY_HELD(R_BUTTON))
|
|
gUnknown_020297ED = TRUE;
|
|
#endif
|
|
ResetSafariZoneFlag_();
|
|
LoadSaveblockMapHeader();
|
|
LoadSaveblockObjEventScripts();
|
|
UnfreezeObjectEvents();
|
|
DoTimeBasedEvents();
|
|
sub_805308C();
|
|
InitMapFromSavedGame();
|
|
PlayTimeCounter_Start();
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
if (GetSecretBase2Field_9() == 1)
|
|
{
|
|
ClearSecretBase2Field_9();
|
|
sub_8053778();
|
|
WarpIntoMap();
|
|
SetMainCallback2(CB2_LoadMap);
|
|
}
|
|
else
|
|
{
|
|
gFieldCallback = sub_805470C;
|
|
SetMainCallback1(CB1_Overworld);
|
|
CB2_ReturnToField();
|
|
}
|
|
}
|
|
|
|
void FieldClearVBlankHBlankCallbacks(void)
|
|
{
|
|
u16 savedIme = REG_IME;
|
|
REG_IME = 0;
|
|
REG_IE &= ~INTR_FLAG_HBLANK;
|
|
REG_IE |= INTR_FLAG_VBLANK;
|
|
REG_IME = savedIme;
|
|
SetVBlankCallback(NULL);
|
|
SetHBlankCallback(NULL);
|
|
}
|
|
|
|
static void SetFieldVBlankCallback(void)
|
|
{
|
|
SetVBlankCallback(VBlankCB_Field);
|
|
}
|
|
|
|
static void VBlankCB_Field(void)
|
|
{
|
|
LoadOam();
|
|
ProcessSpriteCopyRequests();
|
|
ScanlineEffect_InitHBlankDmaTransfer();
|
|
sub_8057A58();
|
|
TransferPlttBuffer();
|
|
sub_8072E74();
|
|
}
|
|
|
|
static void InitCurrentFlashLevelScanlineEffect(void)
|
|
{
|
|
u8 flashLevel = Overworld_GetFlashLevel();
|
|
if (flashLevel)
|
|
{
|
|
WriteFlashScanlineEffectBuffer(flashLevel);
|
|
ScanlineEffect_SetParams(sFlashEffectParams);
|
|
}
|
|
}
|
|
|
|
static bool32 sub_805483C(u8 *state)
|
|
{
|
|
switch (*state)
|
|
{
|
|
case 0:
|
|
FieldClearVBlankHBlankCallbacks();
|
|
ScriptContext1_Init();
|
|
ScriptContext2_Disable();
|
|
sub_8054F70();
|
|
sub_8054BA8();
|
|
(*state)++;
|
|
break;
|
|
case 1:
|
|
sub_8053994(1);
|
|
(*state)++;
|
|
break;
|
|
case 2:
|
|
sub_8054D4C(1);
|
|
(*state)++;
|
|
break;
|
|
case 3:
|
|
sub_8054E98();
|
|
sub_8054D90();
|
|
sub_8054EC8();
|
|
sub_8054E60();
|
|
(*state)++;
|
|
break;
|
|
case 4:
|
|
InitCurrentFlashLevelScanlineEffect();
|
|
InitOverworldGraphicsRegisters();
|
|
Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C);
|
|
InitMenuWindow(&gMenuTextWindowTemplate);
|
|
(*state)++;
|
|
break;
|
|
case 5:
|
|
move_tilemap_camera_to_upper_left_corner();
|
|
(*state)++;
|
|
break;
|
|
case 6:
|
|
CopyPrimaryTilesetToVram(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 7:
|
|
CopySecondaryTilesetToVram(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 8:
|
|
LoadMapTilesetPalettes(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 9:
|
|
DrawWholeMapView();
|
|
(*state)++;
|
|
break;
|
|
case 10:
|
|
cur_mapheader_run_tileset_funcs_after_some_cpuset();
|
|
(*state)++;
|
|
break;
|
|
case 12:
|
|
RunFieldCallback();
|
|
(*state)++;
|
|
break;
|
|
case 11:
|
|
(*state)++;
|
|
break;
|
|
case 13:
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool32 sub_805493C(u8 *state, u32 a2)
|
|
{
|
|
switch (*state)
|
|
{
|
|
case 0:
|
|
FieldClearVBlankHBlankCallbacks();
|
|
sub_8053994(a2);
|
|
(*state)++;
|
|
break;
|
|
case 1:
|
|
sub_8054BA8();
|
|
(*state)++;
|
|
break;
|
|
case 2:
|
|
sub_8054D4C(a2);
|
|
(*state)++;
|
|
break;
|
|
case 3:
|
|
mli4_mapscripts_and_other();
|
|
sub_8054E34();
|
|
(*state)++;
|
|
break;
|
|
case 4:
|
|
InitCurrentFlashLevelScanlineEffect();
|
|
InitOverworldGraphicsRegisters();
|
|
Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C);
|
|
InitMenuWindow(&gMenuTextWindowTemplate);
|
|
(*state)++;
|
|
break;
|
|
case 5:
|
|
move_tilemap_camera_to_upper_left_corner();
|
|
(*state)++;
|
|
break;
|
|
case 6:
|
|
CopyPrimaryTilesetToVram(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 7:
|
|
CopySecondaryTilesetToVram(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 8:
|
|
LoadMapTilesetPalettes(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 9:
|
|
DrawWholeMapView();
|
|
(*state)++;
|
|
break;
|
|
case 10:
|
|
cur_mapheader_run_tileset_funcs_after_some_cpuset();
|
|
(*state)++;
|
|
break;
|
|
case 11:
|
|
if (gMapHeader.flags == 1 && sub_80BBB24() == 1)
|
|
ShowMapNamePopup();
|
|
(*state)++;
|
|
break;
|
|
case 12:
|
|
RunFieldCallback();
|
|
(*state)++;
|
|
break;
|
|
case 13:
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool32 sub_8054A4C(u8 *state)
|
|
{
|
|
switch (*state)
|
|
{
|
|
case 0:
|
|
sub_8054BA8();
|
|
sub_8054D4C(0);
|
|
sub_8054E20();
|
|
sub_8054E34();
|
|
(*state)++;
|
|
break;
|
|
case 1:
|
|
sub_8054C2C();
|
|
(*state)++;
|
|
break;
|
|
case 2:
|
|
RunFieldCallback();
|
|
(*state)++;
|
|
break;
|
|
case 3:
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool32 sub_8054A9C(u8 *state)
|
|
{
|
|
switch (*state)
|
|
{
|
|
case 0:
|
|
FieldClearVBlankHBlankCallbacks();
|
|
sub_8054BA8();
|
|
(*state)++;
|
|
break;
|
|
case 1:
|
|
sub_8054D4C(1);
|
|
(*state)++;
|
|
break;
|
|
case 2:
|
|
sub_8054F48();
|
|
sub_8054E20();
|
|
sub_8054E7C();
|
|
(*state)++;
|
|
break;
|
|
case 3:
|
|
InitCurrentFlashLevelScanlineEffect();
|
|
InitOverworldGraphicsRegisters();
|
|
Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C);
|
|
InitMenuWindow(&gMenuTextWindowTemplate);
|
|
(*state)++;
|
|
break;
|
|
case 4:
|
|
move_tilemap_camera_to_upper_left_corner();
|
|
(*state)++;
|
|
break;
|
|
case 5:
|
|
CopyPrimaryTilesetToVram(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 6:
|
|
CopySecondaryTilesetToVram(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 7:
|
|
LoadMapTilesetPalettes(gMapHeader.mapLayout);
|
|
(*state)++;
|
|
break;
|
|
case 8:
|
|
DrawWholeMapView();
|
|
(*state)++;
|
|
break;
|
|
case 9:
|
|
cur_mapheader_run_tileset_funcs_after_some_cpuset();
|
|
(*state)++;
|
|
break;
|
|
case 12:
|
|
RunFieldCallback();
|
|
(*state)++;
|
|
break;
|
|
case 10:
|
|
case 11:
|
|
(*state)++;
|
|
break;
|
|
case 13:
|
|
SetFieldVBlankCallback();
|
|
(*state)++;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void do_load_map_stuff_loop(u8 *a1)
|
|
{
|
|
while (!sub_805493C(a1, 0))
|
|
;
|
|
}
|
|
|
|
void sub_8054BA8(void)
|
|
{
|
|
REG_DISPCNT = 0;
|
|
|
|
ScanlineEffect_Stop();
|
|
|
|
DmaClear16(3, PLTT + 2, PLTT_SIZE - 2);
|
|
DmaFill16Large(3, 0, (void *)(VRAM + 0x0), 0x18000, 0x1000);
|
|
ResetOamRange(0, 128);
|
|
LoadOam();
|
|
}
|
|
|
|
void sub_8054C2C(void)
|
|
{
|
|
InitCurrentFlashLevelScanlineEffect();
|
|
InitOverworldGraphicsRegisters();
|
|
Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C);
|
|
InitMenuWindow(&gMenuTextWindowTemplate);
|
|
mapdata_load_assets_to_gpu_and_full_redraw();
|
|
}
|
|
|
|
static void InitOverworldGraphicsRegisters(void)
|
|
{
|
|
REG_MOSAIC = 0;
|
|
REG_WININ = 7967;
|
|
REG_WINOUT = 257;
|
|
REG_WIN0H = 255;
|
|
REG_WIN0V = 255;
|
|
REG_WIN1H = -1;
|
|
REG_WIN1V = -1;
|
|
REG_BLDCNT = gUnknown_081E29E0[1] | gUnknown_081E29E0[2] | gUnknown_081E29E0[3] | 0x1040;
|
|
REG_BLDALPHA = 1805;
|
|
*gBGHOffsetRegs[0] = 0;
|
|
*gBGVOffsetRegs[0] = 0;
|
|
*gBGControlRegs[0] = 0;
|
|
*gBGHOffsetRegs[1] = 0;
|
|
*gBGVOffsetRegs[1] = 0;
|
|
*gBGControlRegs[1] = 7489;
|
|
*gBGHOffsetRegs[2] = 0;
|
|
*gBGVOffsetRegs[2] = 0;
|
|
*gBGControlRegs[2] = 7234;
|
|
*gBGHOffsetRegs[3] = 0;
|
|
*gBGVOffsetRegs[3] = 0;
|
|
*gBGControlRegs[3] = 7747;
|
|
REG_DISPCNT = gUnknown_081E29D8[1] | 0x7060 | gUnknown_081E29D8[2] | gUnknown_081E29D8[0] | gUnknown_081E29D8[3];
|
|
}
|
|
|
|
void sub_8054D4C(u32 a1)
|
|
{
|
|
ResetTasks();
|
|
ResetSpriteData();
|
|
ResetPaletteFade();
|
|
ScanlineEffect_Clear();
|
|
ResetCameraUpdateInfo();
|
|
InstallCameraPanAheadCallback();
|
|
InitObjectEventPalettes(0);
|
|
FieldEffectActiveListClear();
|
|
InitFieldMessageBox();
|
|
StartWeather();
|
|
sub_8080750();
|
|
if (!a1)
|
|
SetUpFieldTasks();
|
|
RunOnResumeMapScript();
|
|
}
|
|
|
|
void sub_8054D90(void)
|
|
{
|
|
gTotalCameraPixelOffsetX = 0;
|
|
gTotalCameraPixelOffsetY = 0;
|
|
ResetObjectEvents();
|
|
TrySpawnObjectEvents(0, 0);
|
|
TryRunOnWarpIntoMapScript();
|
|
}
|
|
|
|
void mli4_mapscripts_and_other(void)
|
|
{
|
|
s16 x, y;
|
|
struct InitialPlayerAvatarState *initialPlayerAvatarState;
|
|
gTotalCameraPixelOffsetX = 0;
|
|
gTotalCameraPixelOffsetY = 0;
|
|
ResetObjectEvents();
|
|
GetCameraFocusCoords(&x, &y);
|
|
initialPlayerAvatarState = GetInitialPlayerAvatarState();
|
|
InitPlayerAvatar(x, y, initialPlayerAvatarState->direction, gSaveBlock2.playerGender);
|
|
SetPlayerAvatarTransitionFlags(initialPlayerAvatarState->transitionFlags);
|
|
ResetInitialPlayerAvatarState();
|
|
TrySpawnObjectEvents(0, 0);
|
|
ResetBerryTreeSparkleFlags();
|
|
TryRunOnWarpIntoMapScript();
|
|
}
|
|
|
|
void sub_8054E20(void)
|
|
{
|
|
sub_805B710(0, 0);
|
|
RotatingGate_InitPuzzleAndGraphics();
|
|
}
|
|
|
|
void sub_8054E34(void)
|
|
{
|
|
gObjectEvents[gPlayerAvatar.objectEventId].trackedByCamera = 1;
|
|
InitCameraUpdateCallback(gPlayerAvatar.spriteId);
|
|
}
|
|
|
|
void sub_8054E60(void)
|
|
{
|
|
InitCameraUpdateCallback(sub_8055AE8(gUnknown_03004860));
|
|
}
|
|
|
|
void sub_8054E7C(void)
|
|
{
|
|
InitCameraUpdateCallback(sub_8055AE8(gUnknown_03004860));
|
|
}
|
|
|
|
void sub_8054E98(void)
|
|
{
|
|
u16 x, y;
|
|
GetCameraFocusCoords(&x, &y);
|
|
SetCameraFocusCoords(x + gUnknown_03004860, y);
|
|
}
|
|
|
|
void sub_8054EC8(void)
|
|
{
|
|
u16 i;
|
|
u16 x, y;
|
|
|
|
GetCameraFocusCoords(&x, &y);
|
|
x -= gUnknown_03004860;
|
|
|
|
for (i = 0; i < gFieldLinkPlayerCount; i++)
|
|
{
|
|
SpawnLinkPlayerObjectEvent(i, i + x, y, gLinkPlayers[i].gender);
|
|
CreateLinkPlayerSprite(i);
|
|
}
|
|
|
|
sub_8055340(word_3002910);
|
|
}
|
|
|
|
void sub_8054F48(void)
|
|
{
|
|
u16 i;
|
|
for (i = 0; i < gFieldLinkPlayerCount; i++)
|
|
CreateLinkPlayerSprite(i);
|
|
}
|
|
|
|
void sub_8054F70(void)
|
|
{
|
|
int i;
|
|
for (i = 0; i < 4; i++)
|
|
gUnknown_03000580[i] = 0x80;
|
|
}
|
|
|
|
bool32 sub_8054F88(u16 a1)
|
|
{
|
|
int i;
|
|
int count = gFieldLinkPlayerCount;
|
|
|
|
for (i = 0; i < count; i++)
|
|
if (gUnknown_03000580[i] != a1)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
bool32 sub_8054FC0(u16 a1)
|
|
{
|
|
int i;
|
|
int count = gFieldLinkPlayerCount;
|
|
|
|
for (i = 0; i < count; i++)
|
|
if (gUnknown_03000580[i] == a1)
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void sub_8054FF8(u32 a1, u16 a2, struct UnkStruct_8054FF8 *a3, u16 *a4)
|
|
{
|
|
const u8 *script;
|
|
|
|
if (gUnknown_03000580[a1] == 0x80)
|
|
{
|
|
script = sub_8055648(a3);
|
|
if (script)
|
|
{
|
|
*a4 = sub_8055758(script);
|
|
gUnknown_03000580[a1] = 0x81;
|
|
if (a3->b)
|
|
{
|
|
sub_80543DC(sub_80553E4);
|
|
sub_8055808(script);
|
|
}
|
|
return;
|
|
}
|
|
if (sub_8054FC0(0x83) == 1)
|
|
{
|
|
gUnknown_03000580[a1] = 0x81;
|
|
if (a3->b)
|
|
{
|
|
sub_80543DC(sub_80553E4);
|
|
sub_805585C();
|
|
}
|
|
return;
|
|
}
|
|
switch (a2)
|
|
{
|
|
case 24:
|
|
if (sub_8055630(a3))
|
|
{
|
|
gUnknown_03000580[a1] = 0x81;
|
|
if (a3->b)
|
|
{
|
|
sub_80543DC(sub_80553E4);
|
|
sub_80557F4();
|
|
}
|
|
}
|
|
break;
|
|
case 18:
|
|
if (sub_8055660(a3) == 1)
|
|
{
|
|
gUnknown_03000580[a1] = 0x81;
|
|
if (a3->b)
|
|
{
|
|
sub_80543DC(sub_80553E4);
|
|
sub_8055824();
|
|
}
|
|
}
|
|
break;
|
|
case 25:
|
|
script = sub_805568C(a3);
|
|
if (script)
|
|
{
|
|
gUnknown_03000580[a1] = 0x81;
|
|
if (a3->b)
|
|
{
|
|
sub_80543DC(sub_80553E4);
|
|
sub_8055840(script);
|
|
}
|
|
}
|
|
break;
|
|
case 27:
|
|
if (sub_8055618(a3))
|
|
{
|
|
gUnknown_03000580[a1] = 0x81;
|
|
if (a3->b)
|
|
{
|
|
sub_80543DC(sub_8055408);
|
|
sub_80557E8();
|
|
}
|
|
}
|
|
break;
|
|
case 28:
|
|
if (sub_8055618(a3))
|
|
{
|
|
gUnknown_03000580[a1] = 0x81;
|
|
if (a3->b)
|
|
{
|
|
sub_80543DC(sub_8055438);
|
|
sub_80557E8();
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (a2)
|
|
{
|
|
case 23:
|
|
gUnknown_03000580[a1] = 0x83;
|
|
break;
|
|
case 22:
|
|
gUnknown_03000580[a1] = 0x82;
|
|
break;
|
|
case 26:
|
|
gUnknown_03000580[a1] = 0x80;
|
|
if (a3->b)
|
|
sub_80543DC(sub_8055390);
|
|
break;
|
|
case 29:
|
|
if (gUnknown_03000580[a1] == 0x82)
|
|
gUnknown_03000580[a1] = 0x81;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sub_8055218(u16 *a1, int a2)
|
|
{
|
|
struct UnkStruct_8054FF8 st;
|
|
int i;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
u16 v5 = a1[i];
|
|
u16 v8 = 0;
|
|
sub_80555B0(i, a2, &st);
|
|
sub_8054FF8(i, v5, &st, &v8);
|
|
if (gUnknown_03000580[i] == 0x80)
|
|
v8 = sub_805530C(v5);
|
|
sub_8055BFC(i, v8);
|
|
}
|
|
}
|
|
|
|
void sub_8055280(u16 a1)
|
|
{
|
|
if (a1 >= 17 && a1 < 30)
|
|
word_3004858 = a1;
|
|
else
|
|
word_3004858 = 17;
|
|
}
|
|
|
|
u16 sub_80552B0(u32 a1)
|
|
{
|
|
if (JOY_HELD(DPAD_UP))
|
|
{
|
|
return 19;
|
|
}
|
|
else if (JOY_HELD(DPAD_DOWN))
|
|
{
|
|
return 18;
|
|
}
|
|
else if (JOY_HELD(DPAD_LEFT))
|
|
{
|
|
return 20;
|
|
}
|
|
else if (JOY_HELD(DPAD_RIGHT))
|
|
{
|
|
return 21;
|
|
}
|
|
else if (JOY_NEW(START_BUTTON))
|
|
{
|
|
return 24;
|
|
}
|
|
else if (JOY_NEW(A_BUTTON))
|
|
{
|
|
return 25;
|
|
}
|
|
else
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
u16 sub_805530C(u16 a1)
|
|
{
|
|
switch (a1)
|
|
{
|
|
case 21:
|
|
return 4;
|
|
case 20:
|
|
return 3;
|
|
case 19:
|
|
return 1;
|
|
case 18:
|
|
return 2;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void sub_8055340(u16 *a1)
|
|
{
|
|
int i;
|
|
for (i = 0; i < 4; i++)
|
|
a1[i] = 17;
|
|
}
|
|
|
|
void sub_8055354(void)
|
|
{
|
|
u8 val = gUnknown_03004860;
|
|
sub_8055218(word_3002910, val);
|
|
sub_8055280(gUnknown_03000584(val));
|
|
sub_8055340(word_3002910);
|
|
}
|
|
|
|
u16 sub_8055390(u32 a1)
|
|
{
|
|
if (ScriptContext2_IsEnabled() == 1)
|
|
return 17;
|
|
if (gLink.recvQueue.count > 4)
|
|
return 27;
|
|
if (gLink.sendQueue.count <= 4)
|
|
return sub_80552B0(a1);
|
|
return 28;
|
|
}
|
|
|
|
u16 sub_80553E0(u32 a1)
|
|
{
|
|
return 17;
|
|
}
|
|
|
|
u16 sub_80553E4(u32 a1)
|
|
{
|
|
u16 retVal;
|
|
if (ScriptContext2_IsEnabled() == 1)
|
|
{
|
|
retVal = 17;
|
|
}
|
|
else
|
|
{
|
|
retVal = 26;
|
|
sub_80543DC(sub_80553E0);
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
u16 sub_8055408(u32 a1)
|
|
{
|
|
u16 retVal;
|
|
if (gLink.recvQueue.count > 2)
|
|
{
|
|
retVal = 17;
|
|
}
|
|
else
|
|
{
|
|
retVal = 26;
|
|
ScriptContext2_Disable();
|
|
sub_80543DC(sub_80553E0);
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
u16 sub_8055438(u32 a1)
|
|
{
|
|
u16 retVal;
|
|
if (gLink.sendQueue.count > 2)
|
|
{
|
|
retVal = 17;
|
|
}
|
|
else
|
|
{
|
|
retVal = 26;
|
|
ScriptContext2_Disable();
|
|
sub_80543DC(sub_80553E0);
|
|
}
|
|
return retVal;
|
|
}
|
|
|
|
u16 sub_8055468(u32 a1)
|
|
{
|
|
return 17;
|
|
}
|
|
|
|
u16 sub_805546C(u32 linkPlayerId)
|
|
{
|
|
if (gUnknown_03000580[linkPlayerId] == 0x82 && JOY_NEW(B_BUTTON))
|
|
{
|
|
sub_80543DC(sub_8055468);
|
|
return 29;
|
|
}
|
|
else
|
|
{
|
|
return 17;
|
|
}
|
|
}
|
|
|
|
u16 sub_80554A4(u32 a1)
|
|
{
|
|
sub_80543DC(sub_805546C);
|
|
return 22;
|
|
}
|
|
|
|
u16 sub_80554B8(u32 a1)
|
|
{
|
|
return 17;
|
|
}
|
|
|
|
u16 sub_80554BC(u32 a1)
|
|
{
|
|
if (sub_8054F88(0x83) == TRUE)
|
|
{
|
|
ScriptContext1_SetupScript(gUnknown_081A4508);
|
|
sub_80543DC(sub_80554B8);
|
|
}
|
|
return 17;
|
|
}
|
|
|
|
u16 sub_80554E4(u32 a1)
|
|
{
|
|
sub_80543DC(sub_80554BC);
|
|
return 23;
|
|
}
|
|
|
|
s32 sub_80554F8(void)
|
|
{
|
|
if (sub_8054FC0(0x83) == TRUE)
|
|
return 2;
|
|
if (gUnknown_03000584 == sub_805546C && gUnknown_03000580[gUnknown_03004860] != 0x82)
|
|
return 0;
|
|
if (gUnknown_03000584 == sub_8055468 && gUnknown_03000580[gUnknown_03004860] == 0x81)
|
|
return 2;
|
|
return sub_8054F88(0x82);
|
|
}
|
|
|
|
bool32 unref_sub_8055568(void)
|
|
{
|
|
return sub_8054FC0(0x83);
|
|
}
|
|
|
|
u16 sub_8055574(void)
|
|
{
|
|
sub_80543DC(sub_80554A4);
|
|
return 0;
|
|
}
|
|
|
|
u16 sub_8055588(void)
|
|
{
|
|
sub_80543DC(sub_80553E4);
|
|
return 0;
|
|
}
|
|
|
|
u16 sub_805559C(void)
|
|
{
|
|
sub_80543DC(sub_80554E4);
|
|
return 0;
|
|
}
|
|
|
|
void sub_80555B0(int linkPlayerId, int a2, struct UnkStruct_8054FF8 *a3)
|
|
{
|
|
s16 x, y;
|
|
|
|
a3->a = linkPlayerId;
|
|
a3->b = (linkPlayerId == a2) ? 1 : 0;
|
|
a3->c = gLinkPlayerObjectEvents[linkPlayerId].mode;
|
|
a3->d = sub_8055B30(linkPlayerId);
|
|
sub_8055B08(linkPlayerId, &x, &y);
|
|
a3->sub.x = x;
|
|
a3->sub.y = y;
|
|
a3->sub.height = sub_8055B50(linkPlayerId);
|
|
a3->field_C = MapGridGetMetatileBehaviorAt(x, y);
|
|
}
|
|
|
|
bool32 sub_8055618(struct UnkStruct_8054FF8 *a1)
|
|
{
|
|
u8 v1 = a1->c;
|
|
if (v1 == 2 || v1 == 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
bool32 sub_8055630(struct UnkStruct_8054FF8 *a1)
|
|
{
|
|
u8 v1 = a1->c;
|
|
if (v1 == 2 || v1 == 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
const u8 *sub_8055648(struct UnkStruct_8054FF8 *a1)
|
|
{
|
|
if (a1->c != 2)
|
|
return 0;
|
|
return GetCoordEventScriptAtMapPosition(&a1->sub);
|
|
}
|
|
|
|
bool32 sub_8055660(struct UnkStruct_8054FF8 *a1)
|
|
{
|
|
if (a1->c != 2 && a1->c != 0)
|
|
return FALSE;
|
|
if (!MetatileBehavior_IsSouthArrowWarp(a1->field_C))
|
|
return FALSE;
|
|
if (a1->d != 1)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
const u8 *sub_805568C(struct UnkStruct_8054FF8 *a1)
|
|
{
|
|
struct MapPosition unkStruct;
|
|
u8 linkPlayerId;
|
|
|
|
if (a1->c && a1->c != 2)
|
|
return 0;
|
|
|
|
unkStruct = a1->sub;
|
|
unkStruct.x += gDirectionToVectors[a1->d].x;
|
|
unkStruct.y += gDirectionToVectors[a1->d].y;
|
|
unkStruct.height = 0;
|
|
linkPlayerId = GetLinkPlayerIdAt(unkStruct.x, unkStruct.y);
|
|
|
|
if (linkPlayerId != 4)
|
|
{
|
|
if (!a1->b)
|
|
return TradeRoom_TooBusyToNotice;
|
|
if (gUnknown_03000580[linkPlayerId] != 0x80)
|
|
return TradeRoom_TooBusyToNotice;
|
|
if (!sub_8083BF4(linkPlayerId))
|
|
return TradeRoom_ReadTrainerCard1;
|
|
else
|
|
return TradeRoom_ReadTrainerCard2;
|
|
}
|
|
|
|
return GetInteractedLinkPlayerScript(&unkStruct, a1->field_C, a1->d);
|
|
}
|
|
|
|
static u16 sub_8055758(const u8 *script)
|
|
{
|
|
if (script == DoubleBattleColosseum_EventScript_1A4383)
|
|
return 10;
|
|
if (script == DoubleBattleColosseum_EventScript_1A439E)
|
|
return 9;
|
|
if (script == DoubleBattleColosseum_EventScript_1A43B9)
|
|
return 10;
|
|
if (script == DoubleBattleColosseum_EventScript_1A43D4)
|
|
return 9;
|
|
if (script == RecordCorner_EventScript_1A4418)
|
|
return 10;
|
|
if (script == RecordCorner_EventScript_1A442D)
|
|
return 9;
|
|
if (script == RecordCorner_EventScript_1A4442)
|
|
return 10;
|
|
if (script == RecordCorner_EventScript_1A4457)
|
|
return 9;
|
|
if (script == SingleBattleColosseum_EventScript_1A436F)
|
|
return 10;
|
|
if (script == SingleBattleColosseum_EventScript_1A4379)
|
|
return 9;
|
|
if (script == TradeCenter_EventScript_1A43F0)
|
|
return 10;
|
|
if (script == TradeCenter_EventScript_1A43FA)
|
|
return 9;
|
|
return 0;
|
|
}
|
|
|
|
void sub_80557E8(void)
|
|
{
|
|
ScriptContext2_Enable();
|
|
}
|
|
|
|
void sub_80557F4(void)
|
|
{
|
|
PlaySE(SE_WIN_OPEN);
|
|
sub_8071310();
|
|
ScriptContext2_Enable();
|
|
}
|
|
|
|
static void sub_8055808(const u8 *script)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
ScriptContext1_SetupScript(script);
|
|
ScriptContext2_Enable();
|
|
}
|
|
|
|
void sub_8055824(void)
|
|
{
|
|
PlaySE(SE_WIN_OPEN);
|
|
ScriptContext1_SetupScript(TradeRoom_PromptToCancelLink);
|
|
ScriptContext2_Enable();
|
|
}
|
|
|
|
static void sub_8055840(const u8 *script)
|
|
{
|
|
PlaySE(SE_SELECT);
|
|
ScriptContext1_SetupScript(script);
|
|
ScriptContext2_Enable();
|
|
}
|
|
|
|
void sub_805585C(void)
|
|
{
|
|
ScriptContext1_SetupScript(TradeRoom_TerminateLink);
|
|
ScriptContext2_Enable();
|
|
}
|
|
|
|
bool32 sub_8055870(void)
|
|
{
|
|
if (!is_c1_link_related_active())
|
|
return 0;
|
|
if (gLink.recvQueue.count >= 3)
|
|
gUnknown_03000588 = 1;
|
|
else
|
|
gUnknown_03000588 = 0;
|
|
return gUnknown_03000588;
|
|
}
|
|
|
|
bool32 sub_80558AC(void)
|
|
{
|
|
u8 temp;
|
|
|
|
if (is_c1_link_related_active() != TRUE)
|
|
return FALSE;
|
|
|
|
if (sub_8007B24() != TRUE)
|
|
return FALSE;
|
|
|
|
if (gUnknown_03000584 == sub_8055408)
|
|
return TRUE;
|
|
|
|
if (gUnknown_03000584 != sub_80553E4)
|
|
return FALSE;
|
|
|
|
temp = gUnknown_03000588;
|
|
gUnknown_03000588 = 0;
|
|
|
|
if (temp == TRUE)
|
|
return TRUE;
|
|
|
|
if (gPaletteFade.active && gPaletteFade.softwareFadeFinishing)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool32 sub_8055910(void)
|
|
{
|
|
if (is_c1_link_related_active() != TRUE)
|
|
return FALSE;
|
|
|
|
if (sub_8007B24() != TRUE)
|
|
return FALSE;
|
|
|
|
if (gUnknown_03000584 == sub_8055438)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
bool32 sub_8055940(void)
|
|
{
|
|
if (!sub_8007B24())
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
void ClearLinkPlayerObjectEvent(struct LinkPlayerObjectEvent *linkPlayerObjEvent)
|
|
{
|
|
memset(linkPlayerObjEvent, 0, sizeof(struct LinkPlayerObjectEvent));
|
|
}
|
|
|
|
void ClearLinkPlayerObjectEvents(void)
|
|
{
|
|
memset(gLinkPlayerObjectEvents, 0, sizeof(gLinkPlayerObjectEvents));
|
|
}
|
|
|
|
static void ClearObjectEvent(struct ObjectEvent *objEvent)
|
|
{
|
|
memset(objEvent, 0, sizeof(struct ObjectEvent));
|
|
}
|
|
|
|
static void SpawnLinkPlayerObjectEvent(u8 linkPlayerId, s16 x, s16 y, u8 a4)
|
|
{
|
|
u8 objEventId = GetFirstInactiveObjectEventId();
|
|
struct LinkPlayerObjectEvent *linkPlayerObjEvent = &gLinkPlayerObjectEvents[linkPlayerId];
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
|
|
ClearLinkPlayerObjectEvent(linkPlayerObjEvent);
|
|
ClearObjectEvent(objEvent);
|
|
|
|
linkPlayerObjEvent->active = 1;
|
|
linkPlayerObjEvent->linkPlayerId = linkPlayerId;
|
|
linkPlayerObjEvent->objEventId = objEventId;
|
|
linkPlayerObjEvent->mode = 0;
|
|
|
|
objEvent->active = 1;
|
|
objEvent->singleMovementActive = a4;
|
|
objEvent->range.as_byte = 2;
|
|
objEvent->spriteId = 64;
|
|
|
|
InitLinkPlayerObjectEventPos(objEvent, x, y);
|
|
}
|
|
|
|
static void InitLinkPlayerObjectEventPos(struct ObjectEvent *objEvent, s16 x, s16 y)
|
|
{
|
|
objEvent->currentCoords.x = x;
|
|
objEvent->currentCoords.y = y;
|
|
objEvent->previousCoords.x = x;
|
|
objEvent->previousCoords.y = y;
|
|
sub_80603CC(x, y, &objEvent->initialCoords.x, &objEvent->initialCoords.y);
|
|
objEvent->initialCoords.x += 8;
|
|
ObjectEventUpdateZCoord(objEvent);
|
|
}
|
|
|
|
void unref_sub_8055A6C(u8 linkPlayerId, u8 a2)
|
|
{
|
|
if (gLinkPlayerObjectEvents[linkPlayerId].active)
|
|
{
|
|
u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
objEvent->range.as_byte = a2;
|
|
}
|
|
}
|
|
|
|
void unref_sub_8055A9C(u8 linkPlayerId)
|
|
{
|
|
struct LinkPlayerObjectEvent *linkPlayerObjEvent = &gLinkPlayerObjectEvents[linkPlayerId];
|
|
u8 objEventId = linkPlayerObjEvent->objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
if (objEvent->spriteId != 64 )
|
|
DestroySprite(&gSprites[objEvent->spriteId]);
|
|
linkPlayerObjEvent->active = 0;
|
|
objEvent->active = 0;
|
|
}
|
|
|
|
u8 sub_8055AE8(u8 linkPlayerId)
|
|
{
|
|
u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
return objEvent->spriteId;
|
|
}
|
|
|
|
void sub_8055B08(u8 linkPlayerId, u16 *x, u16 *y)
|
|
{
|
|
u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
*x = objEvent->currentCoords.x;
|
|
*y = objEvent->currentCoords.y;
|
|
}
|
|
|
|
u8 sub_8055B30(u8 linkPlayerId)
|
|
{
|
|
u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
return objEvent->range.as_byte;
|
|
}
|
|
|
|
u8 sub_8055B50(u8 linkPlayerId)
|
|
{
|
|
u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
return objEvent->currentElevation;
|
|
}
|
|
|
|
s32 unref_sub_8055B74(u8 linkPlayerId)
|
|
{
|
|
u8 objEventId = gLinkPlayerObjectEvents[linkPlayerId].objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
return 16 - (s8)objEvent->directionSequenceIndex;
|
|
}
|
|
|
|
static u8 GetLinkPlayerIdAt(s16 x, s16 y)
|
|
{
|
|
u8 i;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
if (gLinkPlayerObjectEvents[i].active
|
|
&& (gLinkPlayerObjectEvents[i].mode == 0 || gLinkPlayerObjectEvents[i].mode == 2))
|
|
{
|
|
struct ObjectEvent *objEvent = &gObjectEvents[gLinkPlayerObjectEvents[i].objEventId];
|
|
if (objEvent->currentCoords.x == x && objEvent->currentCoords.y == y)
|
|
return i;
|
|
}
|
|
}
|
|
return 4;
|
|
}
|
|
|
|
void sub_8055BFC(u8 linkPlayerId, u8 a2)
|
|
{
|
|
struct LinkPlayerObjectEvent *linkPlayerObjEvent = &gLinkPlayerObjectEvents[linkPlayerId];
|
|
u8 objEventId = linkPlayerObjEvent->objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
|
|
if (linkPlayerObjEvent->active)
|
|
{
|
|
if (a2 > 10)
|
|
objEvent->triggerGroundEffectsOnMove = 1;
|
|
else
|
|
gUnknown_082166D8[gUnknown_082166A0[linkPlayerObjEvent->mode](linkPlayerObjEvent, objEvent, a2)](linkPlayerObjEvent, objEvent);
|
|
}
|
|
}
|
|
|
|
static u8 sub_8055C68(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3)
|
|
{
|
|
return gUnknown_082166AC[a3](linkPlayerObjEvent, objEvent, a3);
|
|
}
|
|
|
|
static u8 sub_8055C88(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
static u8 sub_8055C8C(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3)
|
|
{
|
|
return gUnknown_082166AC[a3](linkPlayerObjEvent, objEvent, a3);
|
|
}
|
|
|
|
static u8 sub_8055CAC(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static u8 sub_8055CB0(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3)
|
|
{
|
|
s16 x, y;
|
|
|
|
objEvent->range.as_byte = npc_something3(a3, objEvent->range.as_byte);
|
|
ObjectEventMoveDestCoords(objEvent, objEvent->range.as_byte, &x, &y);
|
|
|
|
if (LinkPlayerDetectCollision(linkPlayerObjEvent->objEventId, objEvent->range.as_byte, x, y))
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
objEvent->directionSequenceIndex = 16;
|
|
ShiftObjectEventCoords(objEvent, x, y);
|
|
ObjectEventUpdateZCoord(objEvent);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
static u8 sub_8055D18(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent, u8 a3)
|
|
{
|
|
objEvent->range.as_byte = npc_something3(a3, objEvent->range.as_byte);
|
|
return 0;
|
|
}
|
|
|
|
static void sub_8055D30(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent)
|
|
{
|
|
linkPlayerObjEvent->mode = 0;
|
|
}
|
|
|
|
static void sub_8055D38(struct LinkPlayerObjectEvent *linkPlayerObjEvent, struct ObjectEvent *objEvent)
|
|
{
|
|
objEvent->directionSequenceIndex--;
|
|
linkPlayerObjEvent->mode = 1;
|
|
MoveCoords(objEvent->range.as_byte, &objEvent->initialCoords.x, &objEvent->initialCoords.y);
|
|
if (!objEvent->directionSequenceIndex)
|
|
{
|
|
ShiftStillObjectEventCoords(objEvent);
|
|
linkPlayerObjEvent->mode = 2;
|
|
}
|
|
}
|
|
|
|
static u8 npc_something3(u8 a1, u8 a2)
|
|
{
|
|
switch (a1 - 1)
|
|
{
|
|
case 0:
|
|
case 6:
|
|
return 2;
|
|
case 1:
|
|
case 7:
|
|
return 1;
|
|
case 2:
|
|
case 8:
|
|
return 3;
|
|
case 3:
|
|
case 9:
|
|
return 4;
|
|
}
|
|
return a2;
|
|
}
|
|
|
|
static u8 LinkPlayerDetectCollision(u8 selfObjEventId, u8 a2, s16 x, s16 y)
|
|
{
|
|
u8 i;
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
if (i != selfObjEventId)
|
|
{
|
|
if ((gObjectEvents[i].currentCoords.x == x && gObjectEvents[i].currentCoords.y == y)
|
|
|| (gObjectEvents[i].previousCoords.x == x && gObjectEvents[i].previousCoords.y == y))
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
return MapGridGetCollisionAt(x, y);
|
|
}
|
|
|
|
static void CreateLinkPlayerSprite(u8 linkPlayerId)
|
|
{
|
|
struct LinkPlayerObjectEvent *linkPlayerObjEvent = &gLinkPlayerObjectEvents[linkPlayerId];
|
|
u8 objEventId = linkPlayerObjEvent->objEventId;
|
|
struct ObjectEvent *objEvent = &gObjectEvents[objEventId];
|
|
struct Sprite *sprite;
|
|
|
|
if (linkPlayerObjEvent->active)
|
|
{
|
|
u8 val = GetRivalAvatarGraphicsIdByStateIdAndGender(PLAYER_AVATAR_STATE_NORMAL, objEvent->singleMovementActive);
|
|
objEvent->spriteId = AddPseudoObjectEvent(val, SpriteCB_LinkPlayer, 0, 0, 0);
|
|
sprite = &gSprites[objEvent->spriteId];
|
|
sprite->coordOffsetEnabled = TRUE;
|
|
sprite->data[0] = linkPlayerId;
|
|
objEvent->triggerGroundEffectsOnMove = 0;
|
|
}
|
|
}
|
|
|
|
static void SpriteCB_LinkPlayer(struct Sprite *sprite)
|
|
{
|
|
struct LinkPlayerObjectEvent *linkPlayerObjEvent = &gLinkPlayerObjectEvents[sprite->data[0]];
|
|
struct ObjectEvent *objEvent = &gObjectEvents[linkPlayerObjEvent->objEventId];
|
|
sprite->x = objEvent->initialCoords.x;
|
|
sprite->y = objEvent->initialCoords.y;
|
|
SetObjectSubpriorityByZCoord(objEvent->previousElevation, sprite, 1);
|
|
sprite->oam.priority = ZCoordToPriority(objEvent->previousElevation);
|
|
if (!linkPlayerObjEvent->mode)
|
|
StartSpriteAnim(sprite, GetFaceDirectionAnimNum(objEvent->range.as_byte));
|
|
else
|
|
StartSpriteAnimIfDifferent(sprite, GetMoveDirectionAnimNum(objEvent->range.as_byte));
|
|
UpdateObjectEventSpriteVisibility(sprite, 0);
|
|
if (objEvent->triggerGroundEffectsOnMove)
|
|
{
|
|
sprite->invisible = ((sprite->data[7] & 4) >> 2);
|
|
sprite->data[7]++;
|
|
}
|
|
}
|