Document platform lift

This documents the `unk_0207160C.c` file, which is in charge of setting
up and managing the platform lift dynamic map feature for maps that
contains platform lifts (Iron Island and the Pokémon League).

This does not manage platform lifts used by gyms.

Signed-off-by: Kuruyia <github@kuruyia.net>
This commit is contained in:
Kuruyia 2025-03-29 10:20:11 +01:00
parent 0497e60823
commit 7329ad4784
10 changed files with 521 additions and 475 deletions

View File

@ -1,7 +1,7 @@
#ifndef POKEPLATINUM_CONSTANTS_FIELD_MAP_PROP_H
#define POKEPLATINUM_CONSTANTS_FIELD_MAP_PROP_H
enum MapPropModelId {
enum MapPropModelID {
// Model name: treeeff
MAP_PROP_MODEL_HONEY_TREE = 26,
// Model name: c2_s03a
@ -51,7 +51,7 @@ enum MapPropModelId {
// Model name: table_l03
MAP_PROP_MODEL_DESK_DRAWER_LAPTOP_FACING_LEFT = 248,
// Model name: lift_base01
MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM = 258,
MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT = 258,
// Model name: gym_door01
MAP_PROP_MODEL_HEARTHOME_GYM_INSIDE_DOOR = 260,
// Model name: gym_door00
@ -87,7 +87,7 @@ enum MapPropModelId {
// Model name: ev_o01
MAP_PROP_MODEL_ELEVATOR_LIGHTS = 498,
// Model name: leage_lift
MAP_PROP_MODEL_POKEMON_LEAGUE_LIFT_PLATFORM = 502,
MAP_PROP_MODEL_POKEMON_LEAGUE_PLATFORM_LIFT = 502,
// Model name: leage_o03
MAP_PROP_MODEL_POKEMON_LEAGUE_HALL_OF_FAME_MACHINE = 507,
// Model name: pc_mb

11
include/platform_lift.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef POKEPLATINUM_PLATFORM_LIFT_H
#define POKEPLATINUM_PLATFORM_LIFT_H
#include "field/field_system_decl.h"
void PlatformLift_DynamicMapFeaturesInit(FieldSystem *fieldSystem);
void PersistedMapFeatures_InitForPlatformLift(FieldSystem *fieldSystem);
u8 PlatformLift_WasNotUsedWhenEnteredMap(FieldSystem *fieldSystem);
void PlatformLift_Trigger(FieldSystem *fieldSystem);
#endif // POKEPLATINUM_PLATFORM_LIFT_H

View File

@ -1,11 +0,0 @@
#ifndef POKEPLATINUM_UNK_0207160C_H
#define POKEPLATINUM_UNK_0207160C_H
#include "field/field_system_decl.h"
void PlatformLift_DynamicMapFeaturesInit(FieldSystem *fieldSystem);
void PersistedMapFeatures_InitForPlatformLift(FieldSystem *fieldSystem);
u8 sub_02071818(FieldSystem *fieldSystem);
void sub_0207183C(FieldSystem *fieldSystem);
#endif // POKEPLATINUM_UNK_0207160C_H

View File

@ -279,7 +279,7 @@ Static main
Object main.nef.p/src_unk_0207070C.c.o
Object main.nef.p/src_unk_020711C8.c.o
Object main.nef.p/src_unk_020711EC.c.o
Object main.nef.p/src_unk_0207160C.c.o
Object main.nef.p/src_platform_lift.c.o
Object main.nef.p/src_persisted_map_features_init.c.o
Object main.nef.p/src_map_header_util.c.o
Object main.nef.p/src_unk_02071D40.c.o

View File

@ -14,8 +14,8 @@
#include "field_system.h"
#include "persisted_map_features.h"
#include "platform_lift.h"
#include "savedata_misc.h"
#include "unk_0207160C.h"
const static DynamicMapFeaturesInitFunc sInitFuncs[DYNAMIC_MAP_FEATURES_COUNT] = {
NULL,

View File

@ -266,7 +266,7 @@ pokeplatinum_c = files(
'unk_0207070C.c',
'unk_020711C8.c',
'unk_020711EC.c',
'unk_0207160C.c',
'platform_lift.c',
'persisted_map_features_init.c',
'map_header_util.c',
'unk_02071D40.c',

View File

@ -780,7 +780,7 @@ static BOOL ov8_0224A018(FieldTask *taskMan)
(v2->unk_00)++;
break;
case 1: {
v0 = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM);
v0 = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT);
{
VecFx32 v3;
@ -826,7 +826,7 @@ static BOOL ov8_0224A0E8(FieldTask *taskMan)
(v2->unk_00)++;
break;
case 1: {
v0 = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM);
v0 = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT);
{
VecFx32 v3;

499
src/platform_lift.c Normal file
View File

@ -0,0 +1,499 @@
#include "platform_lift.h"
#include <nitro.h>
#include <string.h>
#include "constants/field/dynamic_map_features.h"
#include "constants/field/map.h"
#include "constants/field/map_prop.h"
#include "constants/heap.h"
#include "generated/map_headers.h"
#include "field/field_system.h"
#include "field/field_system_sub2_t.h"
#include "overlay005/dynamic_terrain_height.h"
#include "overlay005/map_prop.h"
#include "field_system.h"
#include "field_task.h"
#include "heap.h"
#include "persisted_map_features.h"
#include "player_avatar.h"
#include "savedata_misc.h"
#include "terrain_collision_manager.h"
#include "unk_02005474.h"
#define PLATFORM_LIFT_SIZE_X 3
#define PLATFORM_LIFT_SIZE_Y 2
#define PLATFORM_LIFT_DYNAMIC_HEIGHT_PLATE_ID 0
#define PLATFORM_LIFT_IRON_ISLAND_B2F_LEFT_ROOM_POS_X (FX32_ONE * (16 * 19 + 8))
#define PLATFORM_LIFT_IRON_ISLAND_B2F_LEFT_ROOM_POS_Z (FX32_ONE * (16 * (MAP_TILES_COUNT_Y + 12) + 8))
#define IRON_ISLAND_B1F_RIGHT_ROOM_BOTTOM_FLOOR_WARP_Z 26
#define IRON_ISLAND_B2F_LEFT_ROOM_BOTTOM_FLOOR_WARP_Z (MAP_TILES_COUNT_Y * 1 + 16)
#define IRON_ISLAND_B3F_BOTTOM_FLOOR_WARP_Z 15
#define POKEMON_LEAGUE_ELEVATOR_TO_ELITE_FOUR_ROOM_BOTTOM_FLOOR_WARP_Z 15
#define POKEMON_LEAGUE_ELEVATOR_TO_CHAMPION_ROOM_BOTTOM_FLOOR_WARP_Z 23
#define POKEMON_LEAGUE_CHAMPION_ROOM_BOTTOM_FLOOR_WARP_Z 18
enum PlatformLiftFloorID {
PLATFORM_LIFT_BOTTOM_FLOOR = 0,
PLATFORM_LIFT_TOP_FLOOR,
PLATFORM_LIFT_FLOOR_COUNT,
};
enum PlatformLiftID {
PLATFORM_LIFT_IRON_ISLAND_B1F_RIGHT_ROOM = 0,
PLATFORM_LIFT_IRON_ISLAND_B2F_LEFT_ROOM,
PLATFORM_LIFT_IRON_ISLAND_B3F,
PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_AARON_ROOM,
PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_BERTHA_ROOM,
PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_FLINT_ROOM,
PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_LUCIAN_ROOM,
PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_CHAMPION_ROOM,
PLATFORM_LIFT_POKEMON_LEAGUE_CHAMPION_ROOM,
PLATFORM_LIFT_COUNT,
};
enum PlatformLiftKind {
PLATFORM_LIFT_KIND_IRON_ISLAND = 0,
PLATFORM_LIFT_KIND_POKEMON_LEAGUE,
};
enum PlatformLiftFieldTaskState {
PLATFORM_LIFT_STATE_START_MOVING = 0,
PLATFORM_LIFT_STATE_MOVE,
PLATFORM_LIFT_STATE_FINISH_MOVING,
PLATFORM_LIFT_STATE_END,
};
typedef struct PlatformLiftConfiguration {
fx32 floorHeights[PLATFORM_LIFT_FLOOR_COUNT];
int startTileX;
int startTileZ;
BOOL preventGoingDown;
BOOL isIronIslandB2FLeftRoom;
} PlatformLiftConfiguration;
typedef struct PlatformLiftPersistedData {
u16 floorID;
u16 id;
BOOL notUsedWhenEnteredMap;
int kind;
} PlatformLiftPersistedData;
typedef struct PlatformLiftFieldTaskEnv {
int state;
fx32 targetHeight;
BOOL isIronIslandB2FLeftRoom;
int kind;
} PlatformLiftFieldTaskEnv;
static BOOL FieldTask_PlatformLiftGoUp(FieldTask *taskMan);
static BOOL FieldTask_PlatformLiftGoDown(FieldTask *taskMan);
static void PlatformLift_PlaySoundEffect(const int platformLiftKind);
static void PlatformLift_StopSoundEffect(const int platformLiftKind);
static const PlatformLiftConfiguration sPerMapPlatformLiftConfiguration[PLATFORM_LIFT_COUNT] = {
[PLATFORM_LIFT_IRON_ISLAND_B1F_RIGHT_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 1), (MAP_OBJECT_TILE_SIZE * 9) },
.startTileX = 10,
.startTileZ = 23,
.preventGoingDown = FALSE,
.isIronIslandB2FLeftRoom = FALSE,
},
[PLATFORM_LIFT_IRON_ISLAND_B2F_LEFT_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 1), (MAP_OBJECT_TILE_SIZE * 9) },
.startTileX = 18,
.startTileZ = 44,
.preventGoingDown = FALSE,
.isIronIslandB2FLeftRoom = TRUE,
},
[PLATFORM_LIFT_IRON_ISLAND_B3F] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 1), (MAP_OBJECT_TILE_SIZE * 9) },
.startTileX = 8,
.startTileZ = 11,
.preventGoingDown = FALSE,
.isIronIslandB2FLeftRoom = FALSE,
},
[PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_AARON_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 0), (MAP_OBJECT_TILE_SIZE * 10) },
.startTileX = 3,
.startTileZ = 11,
.preventGoingDown = TRUE,
.isIronIslandB2FLeftRoom = FALSE,
},
[PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_BERTHA_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 0), (MAP_OBJECT_TILE_SIZE * 5) },
.startTileX = 3,
.startTileZ = 11,
.preventGoingDown = TRUE,
.isIronIslandB2FLeftRoom = FALSE,
},
[PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_FLINT_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 0), (MAP_OBJECT_TILE_SIZE * 5) },
.startTileX = 3,
.startTileZ = 11,
.preventGoingDown = TRUE,
.isIronIslandB2FLeftRoom = FALSE,
},
[PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_LUCIAN_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 0), (MAP_OBJECT_TILE_SIZE * 5) },
.startTileX = 3,
.startTileZ = 11,
.preventGoingDown = TRUE,
.isIronIslandB2FLeftRoom = FALSE,
},
[PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_CHAMPION_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 0), (MAP_OBJECT_TILE_SIZE * 5) },
.startTileX = 3,
.startTileZ = 19,
.preventGoingDown = TRUE,
.isIronIslandB2FLeftRoom = FALSE,
},
[PLATFORM_LIFT_POKEMON_LEAGUE_CHAMPION_ROOM] = {
.floorHeights = { (MAP_OBJECT_TILE_SIZE * 0), (MAP_OBJECT_TILE_SIZE * 15) },
.startTileX = 7,
.startTileZ = 8,
.preventGoingDown = TRUE,
.isIronIslandB2FLeftRoom = FALSE,
}
};
void PlatformLift_DynamicMapFeaturesInit(FieldSystem *fieldSystem)
{
PersistedMapFeatures *persistedMapFeatures = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
PlatformLiftPersistedData *data = PersistedMapFeatures_GetBuffer(persistedMapFeatures, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
const PlatformLiftConfiguration *platformLiftConfiguration = &sPerMapPlatformLiftConfiguration[data->id];
fx32 currentHeight = platformLiftConfiguration->floorHeights[data->floorID];
MapProp *platformLiftMapProp;
if (platformLiftConfiguration->isIronIslandB2FLeftRoom) {
VecFx32 platformLiftInitialPosition = {
PLATFORM_LIFT_IRON_ISLAND_B2F_LEFT_ROOM_POS_X,
0,
PLATFORM_LIFT_IRON_ISLAND_B2F_LEFT_ROOM_POS_Z
};
platformLiftInitialPosition.y = currentHeight;
MapPropManager_LoadOne(fieldSystem->mapPropManager, fieldSystem->areaDataManager, MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT, &platformLiftInitialPosition, NULL, fieldSystem->mapPropAnimMan);
platformLiftMapProp = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT);
} else {
const int platformLiftModels[2] = {
MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT,
MAP_PROP_MODEL_POKEMON_LEAGUE_PLATFORM_LIFT
};
BOOL platformLiftFound = FieldSystem_FindLoadedMapPropByModelIDs(fieldSystem, platformLiftModels, NELEMS(platformLiftModels), &platformLiftMapProp, NULL);
GF_ASSERT(platformLiftFound);
}
VecFx32 platformLiftPosition;
platformLiftPosition = MapProp_GetPosition(platformLiftMapProp);
platformLiftPosition.y = currentHeight;
MapProp_SetPosition(platformLiftMapProp, &platformLiftPosition);
DynamicTerrainHeightManager_SetPlate(PLATFORM_LIFT_DYNAMIC_HEIGHT_PLATE_ID, platformLiftConfiguration->startTileX, platformLiftConfiguration->startTileZ, PLATFORM_LIFT_SIZE_X, PLATFORM_LIFT_SIZE_Y, currentHeight, fieldSystem->dynamicTerrainHeightMan);
}
void PersistedMapFeatures_InitForPlatformLift(FieldSystem *fieldSystem)
{
PersistedMapFeatures *persistedMapFeatures = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
PersistedMapFeatures_InitWithID(persistedMapFeatures, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
PlatformLiftPersistedData *data = PersistedMapFeatures_GetBuffer(persistedMapFeatures, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
data->notUsedWhenEnteredMap = TRUE;
data->kind = PLATFORM_LIFT_KIND_IRON_ISLAND;
switch (fieldSystem->location->mapId) {
case MAP_HEADER_IRON_ISLAND_B1F_RIGHT_ROOM:
if (fieldSystem->location->z == IRON_ISLAND_B1F_RIGHT_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
}
data->id = PLATFORM_LIFT_IRON_ISLAND_B1F_RIGHT_ROOM;
break;
case MAP_HEADER_IRON_ISLAND_B2F_LEFT_ROOM:
if (fieldSystem->location->z == IRON_ISLAND_B2F_LEFT_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
}
data->id = PLATFORM_LIFT_IRON_ISLAND_B2F_LEFT_ROOM;
break;
case MAP_HEADER_IRON_ISLAND_B3F:
if (fieldSystem->location->z == IRON_ISLAND_B3F_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
}
data->id = PLATFORM_LIFT_IRON_ISLAND_B3F;
break;
case MAP_HEADER_POKEMON_LEAGUE_ELEVATOR_TO_AARON_ROOM:
if (fieldSystem->location->z == POKEMON_LEAGUE_ELEVATOR_TO_ELITE_FOUR_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
data->notUsedWhenEnteredMap = FALSE;
}
data->id = PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_AARON_ROOM;
data->kind = PLATFORM_LIFT_KIND_POKEMON_LEAGUE;
break;
case MAP_HEADER_POKEMON_LEAGUE_ELEVATOR_TO_BERTHA_ROOM:
if (fieldSystem->location->z == POKEMON_LEAGUE_ELEVATOR_TO_ELITE_FOUR_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
data->notUsedWhenEnteredMap = FALSE;
}
data->id = PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_BERTHA_ROOM;
data->kind = PLATFORM_LIFT_KIND_POKEMON_LEAGUE;
break;
case MAP_HEADER_POKEMON_LEAGUE_ELEVATOR_TO_FLINT_ROOM:
if (fieldSystem->location->z == POKEMON_LEAGUE_ELEVATOR_TO_ELITE_FOUR_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
data->notUsedWhenEnteredMap = FALSE;
}
data->id = PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_FLINT_ROOM;
data->kind = PLATFORM_LIFT_KIND_POKEMON_LEAGUE;
break;
case MAP_HEADER_POKEMON_LEAGUE_ELEVATOR_TO_LUCIAN_ROOM:
if (fieldSystem->location->z == POKEMON_LEAGUE_ELEVATOR_TO_ELITE_FOUR_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
data->notUsedWhenEnteredMap = FALSE;
}
data->id = PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_LUCIAN_ROOM;
data->kind = PLATFORM_LIFT_KIND_POKEMON_LEAGUE;
break;
case MAP_HEADER_POKEMON_LEAGUE_ELEVATOR_TO_CHAMPION_ROOM:
if (fieldSystem->location->z == POKEMON_LEAGUE_ELEVATOR_TO_CHAMPION_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
data->notUsedWhenEnteredMap = FALSE;
}
data->id = PLATFORM_LIFT_POKEMON_LEAGUE_ELEVATOR_TO_CHAMPION_ROOM;
data->kind = PLATFORM_LIFT_KIND_POKEMON_LEAGUE;
break;
case MAP_HEADER_POKEMON_LEAGUE_CHAMPION_ROOM:
if (fieldSystem->location->z == POKEMON_LEAGUE_CHAMPION_ROOM_BOTTOM_FLOOR_WARP_Z) {
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
} else {
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
data->notUsedWhenEnteredMap = FALSE;
}
data->id = PLATFORM_LIFT_POKEMON_LEAGUE_CHAMPION_ROOM;
data->kind = PLATFORM_LIFT_KIND_POKEMON_LEAGUE;
break;
default:
GF_ASSERT(FALSE);
}
}
u8 PlatformLift_WasNotUsedWhenEnteredMap(FieldSystem *fieldSystem)
{
PersistedMapFeatures *persistedMapFeatures = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
PlatformLiftPersistedData *data = PersistedMapFeatures_GetBuffer(persistedMapFeatures, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
return data->notUsedWhenEnteredMap != FALSE;
}
void PlatformLift_Trigger(FieldSystem *fieldSystem)
{
PersistedMapFeatures *persistedMapFeatures = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
PlatformLiftPersistedData *data = PersistedMapFeatures_GetBuffer(persistedMapFeatures, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
if (sPerMapPlatformLiftConfiguration[data->id].preventGoingDown && data->floorID == PLATFORM_LIFT_TOP_FLOOR) {
return;
}
PlatformLiftFieldTaskEnv *taskEnv = Heap_AllocFromHeapAtEnd(HEAP_ID_FIELDMAP, sizeof(PlatformLiftFieldTaskEnv));
taskEnv->state = PLATFORM_LIFT_STATE_START_MOVING;
taskEnv->isIronIslandB2FLeftRoom = sPerMapPlatformLiftConfiguration[data->id].isIronIslandB2FLeftRoom;
taskEnv->kind = data->kind;
if (data->floorID == PLATFORM_LIFT_BOTTOM_FLOOR) {
taskEnv->targetHeight = sPerMapPlatformLiftConfiguration[data->id].floorHeights[PLATFORM_LIFT_TOP_FLOOR];
FieldTask_InitCall(fieldSystem->task, FieldTask_PlatformLiftGoUp, taskEnv);
data->floorID = PLATFORM_LIFT_TOP_FLOOR;
} else {
taskEnv->targetHeight = sPerMapPlatformLiftConfiguration[data->id].floorHeights[PLATFORM_LIFT_BOTTOM_FLOOR];
FieldTask_InitCall(fieldSystem->task, FieldTask_PlatformLiftGoDown, taskEnv);
data->floorID = PLATFORM_LIFT_BOTTOM_FLOOR;
}
}
static BOOL FieldTask_PlatformLiftGoUp(FieldTask *taskMan)
{
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(taskMan);
PlatformLiftFieldTaskEnv *taskEnv = FieldTask_GetEnv(taskMan);
switch (taskEnv->state) {
case PLATFORM_LIFT_STATE_START_MOVING:
sub_0205ED2C(fieldSystem->playerAvatar, 0);
PlatformLift_PlaySoundEffect(taskEnv->kind);
taskEnv->state++;
break;
case PLATFORM_LIFT_STATE_MOVE: {
MapProp *platformLiftMapProp;
if (taskEnv->isIronIslandB2FLeftRoom) {
platformLiftMapProp = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT);
} else {
const int platformLiftModels[2] = {
MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT,
MAP_PROP_MODEL_POKEMON_LEAGUE_PLATFORM_LIFT
};
BOOL platformLiftFound = FieldSystem_FindLoadedMapPropByModelIDs(fieldSystem, platformLiftModels, NELEMS(platformLiftModels), &platformLiftMapProp, NULL);
GF_ASSERT(platformLiftFound);
}
fx32 heightIncrement;
VecFx32 platformLiftPosition;
platformLiftPosition = MapProp_GetPosition(platformLiftMapProp);
if (taskEnv->kind == PLATFORM_LIFT_KIND_IRON_ISLAND) {
heightIncrement = FX32_ONE;
} else {
heightIncrement = FX32_ONE * 2;
}
platformLiftPosition.y += heightIncrement;
if (platformLiftPosition.y >= taskEnv->targetHeight) {
platformLiftPosition.y = taskEnv->targetHeight;
PlatformLift_StopSoundEffect(taskEnv->kind);
taskEnv->state++;
}
sub_0205ED0C(fieldSystem->playerAvatar, platformLiftPosition.y);
MapProp_SetPosition(platformLiftMapProp, &platformLiftPosition);
break;
}
case PLATFORM_LIFT_STATE_FINISH_MOVING:
DynamicTerrainHeightManager_SetHeight(PLATFORM_LIFT_DYNAMIC_HEIGHT_PLATE_ID, taskEnv->targetHeight, fieldSystem->dynamicTerrainHeightMan);
sub_0205ED48(fieldSystem->playerAvatar, 1);
Sound_PlayEffect(SEQ_SE_DP_KI_GASYAN);
taskEnv->state++;
break;
case PLATFORM_LIFT_STATE_END:
Heap_FreeToHeap(taskEnv);
return TRUE;
}
return FALSE;
}
static BOOL FieldTask_PlatformLiftGoDown(FieldTask *taskMan)
{
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(taskMan);
PlatformLiftFieldTaskEnv *taskEnv = FieldTask_GetEnv(taskMan);
switch (taskEnv->state) {
case PLATFORM_LIFT_STATE_START_MOVING:
sub_0205ED2C(fieldSystem->playerAvatar, 0);
PlatformLift_PlaySoundEffect(taskEnv->kind);
taskEnv->state++;
break;
case PLATFORM_LIFT_STATE_MOVE: {
MapProp *platformLiftMapProp;
if (taskEnv->isIronIslandB2FLeftRoom) {
platformLiftMapProp = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT);
} else {
const int platformLiftModels[2] = {
MAP_PROP_MODEL_IRON_ISLAND_PLATFORM_LIFT,
MAP_PROP_MODEL_POKEMON_LEAGUE_PLATFORM_LIFT
};
BOOL platformLiftFound = FieldSystem_FindLoadedMapPropByModelIDs(fieldSystem, platformLiftModels, NELEMS(platformLiftModels), &platformLiftMapProp, NULL);
GF_ASSERT(platformLiftFound);
}
VecFx32 platformLiftPosition;
platformLiftPosition = MapProp_GetPosition(platformLiftMapProp);
platformLiftPosition.y -= FX32_ONE;
if (platformLiftPosition.y <= taskEnv->targetHeight) {
platformLiftPosition.y = taskEnv->targetHeight;
PlatformLift_StopSoundEffect(taskEnv->kind);
taskEnv->state++;
}
sub_0205ED0C(fieldSystem->playerAvatar, platformLiftPosition.y);
MapProp_SetPosition(platformLiftMapProp, &platformLiftPosition);
break;
}
case PLATFORM_LIFT_STATE_FINISH_MOVING:
DynamicTerrainHeightManager_SetHeight(PLATFORM_LIFT_DYNAMIC_HEIGHT_PLATE_ID, taskEnv->targetHeight, fieldSystem->dynamicTerrainHeightMan);
sub_0205ED48(fieldSystem->playerAvatar, 1);
Sound_PlayEffect(SEQ_SE_DP_KI_GASYAN);
taskEnv->state++;
break;
case PLATFORM_LIFT_STATE_END:
Heap_FreeToHeap(taskEnv);
return TRUE;
}
return FALSE;
}
static void PlatformLift_PlaySoundEffect(const int platformLiftKind)
{
if (platformLiftKind == PLATFORM_LIFT_KIND_IRON_ISLAND) {
Sound_PlayEffect(SEQ_SE_DP_ELEBETA);
} else {
Sound_PlayEffect(SEQ_SE_DP_ELEBETA4);
}
}
static void PlatformLift_StopSoundEffect(const int platformLiftKind)
{
if (platformLiftKind == PLATFORM_LIFT_KIND_IRON_ISLAND) {
Sound_StopEffect(SEQ_SE_DP_ELEBETA, 0);
} else {
Sound_StopEffect(SEQ_SE_DP_ELEBETA4, 0);
}
}

View File

@ -123,6 +123,7 @@
#include "party.h"
#include "pc_boxes.h"
#include "persisted_map_features_init.h"
#include "platform_lift.h"
#include "player_avatar.h"
#include "poffin.h"
#include "pokedex.h"
@ -209,7 +210,6 @@
#include "unk_0206CCB0.h"
#include "unk_0206F314.h"
#include "unk_02070428.h"
#include "unk_0207160C.h"
#include "unk_02071D40.h"
#include "unk_020722AC.h"
#include "unk_0207DA28.h"
@ -6754,7 +6754,7 @@ static BOOL InitPersistedMapFeaturesForPlatformLift(ScriptContext *ctx)
static BOOL ScrCmd_25C(ScriptContext *ctx)
{
sub_0207183C(ctx->fieldSystem);
PlatformLift_Trigger(ctx->fieldSystem);
return 1;
}
@ -6762,7 +6762,7 @@ static BOOL ScrCmd_25D(ScriptContext *ctx)
{
u16 *v0 = ScriptContext_GetVarPointer(ctx);
if (sub_02071818(ctx->fieldSystem)) {
if (PlatformLift_WasNotUsedWhenEnteredMap(ctx->fieldSystem)) {
(*v0) = 1;
} else {
(*v0) = 0;

View File

@ -1,453 +0,0 @@
#include "unk_0207160C.h"
#include <nitro.h>
#include <string.h>
#include "constants/field/dynamic_map_features.h"
#include "constants/field/map_prop.h"
#include "field/field_system.h"
#include "field/field_system_sub2_t.h"
#include "overlay005/dynamic_terrain_height.h"
#include "overlay005/map_prop.h"
#include "field_system.h"
#include "field_task.h"
#include "heap.h"
#include "persisted_map_features.h"
#include "player_avatar.h"
#include "savedata_misc.h"
#include "terrain_collision_manager.h"
#include "unk_02005474.h"
typedef struct {
fx32 unk_00[2];
int unk_08;
int unk_0C;
BOOL unk_10;
BOOL unk_14;
} UnkStruct_020F03F4;
typedef struct {
u16 unk_00;
u16 unk_02;
BOOL unk_04;
int unk_08;
} UnkStruct_020716D4;
typedef struct {
int unk_00;
fx32 unk_04;
BOOL unk_08;
int unk_0C;
} UnkStruct_020718D8;
static BOOL sub_020718D8(FieldTask *taskMan);
static BOOL sub_020719D8(FieldTask *taskMan);
static void sub_02071ACC(const int param0);
static void sub_02071AEC(const int param0);
static const UnkStruct_020F03F4 Unk_020F03F4[9] = {
{
{ (FX32_ONE * 16 * 1), (FX32_ONE * 16 * 9) },
0xA,
0x17,
0x0,
0x0,
},
{
{ (FX32_ONE * 16 * 1), (FX32_ONE * 16 * 9) },
0x12,
0x2C,
0x0,
0x1,
},
{
{ (FX32_ONE * 16 * 1), (FX32_ONE * 16 * 9) },
0x8,
0xB,
0x0,
0x0,
},
{
{ 0x0, (FX32_ONE * 16 * 10) },
0x3,
0xB,
0x1,
0x0,
},
{
{ 0x0, (FX32_ONE * 16 * 5) },
0x3,
0xB,
0x1,
0x0,
},
{
{ 0x0, (FX32_ONE * 16 * 5) },
0x3,
0xB,
0x1,
0x0,
},
{
{ 0x0, (FX32_ONE * 16 * 5) },
0x3,
0xB,
0x1,
0x0,
},
{
{ 0x0, (FX32_ONE * 16 * 5) },
0x3,
0x13,
0x1,
0x0,
},
{
{ 0x0, (FX32_ONE * 16 * 15) },
0x7,
0x8,
0x1,
0x0,
}
};
void PlatformLift_DynamicMapFeaturesInit(FieldSystem *fieldSystem)
{
BOOL v0;
MapProp *v1;
PersistedMapFeatures *v2;
UnkStruct_020716D4 *v3;
const UnkStruct_020F03F4 *v4;
fx32 v5;
v2 = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
v3 = (UnkStruct_020716D4 *)PersistedMapFeatures_GetBuffer(v2, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
v4 = &Unk_020F03F4[v3->unk_02];
v5 = v4->unk_00[v3->unk_00];
if (v4->unk_14) {
VecFx32 v6 = {
(FX32_ONE * (16 * 19 + 8)),
0,
(FX32_ONE * (16 * (32 + 12) + 8))
};
v6.y = v5;
MapPropManager_LoadOne(fieldSystem->mapPropManager, fieldSystem->areaDataManager, MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM, &v6, NULL, fieldSystem->mapPropAnimMan);
v1 = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM);
} else {
const int v7[2] = {
MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM,
MAP_PROP_MODEL_POKEMON_LEAGUE_LIFT_PLATFORM
};
v0 = FieldSystem_FindLoadedMapPropByModelIDs(fieldSystem, v7, 2, &v1, NULL);
GF_ASSERT(v0);
}
{
VecFx32 v8;
v8 = MapProp_GetPosition(v1);
v8.y = v5;
MapProp_SetPosition(v1, &v8);
}
DynamicTerrainHeightManager_SetPlate(0, v4->unk_08, v4->unk_0C, 3, 2, v5, fieldSystem->dynamicTerrainHeightMan);
}
void PersistedMapFeatures_InitForPlatformLift(FieldSystem *fieldSystem)
{
PersistedMapFeatures *persistedMapFeatures = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
PersistedMapFeatures_InitWithID(persistedMapFeatures, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
UnkStruct_020716D4 *data = PersistedMapFeatures_GetBuffer(persistedMapFeatures, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
data->unk_04 = 1;
data->unk_08 = 0;
switch (fieldSystem->location->mapId) {
case 291:
if (fieldSystem->location->z == 26) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
}
data->unk_02 = 0;
break;
case 293:
if (fieldSystem->location->z == (32 * 1 + 16)) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
}
data->unk_02 = 1;
break;
case 294:
if (fieldSystem->location->z == 15) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
}
data->unk_02 = 2;
break;
case 176:
if (fieldSystem->location->z == 15) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
data->unk_04 = 0;
}
data->unk_02 = 3;
data->unk_08 = 1;
break;
case 178:
if (fieldSystem->location->z == 15) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
data->unk_04 = 0;
}
data->unk_02 = 4;
data->unk_08 = 1;
break;
case 180:
if (fieldSystem->location->z == 15) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
data->unk_04 = 0;
}
data->unk_02 = 5;
data->unk_08 = 1;
break;
case 182:
if (fieldSystem->location->z == 15) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
data->unk_04 = 0;
}
data->unk_02 = 6;
data->unk_08 = 1;
break;
case 184:
if (fieldSystem->location->z == 23) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
data->unk_04 = 0;
}
data->unk_02 = 7;
data->unk_08 = 1;
break;
case 185:
if (fieldSystem->location->z == 18) {
data->unk_00 = 0;
} else {
data->unk_00 = 1;
data->unk_04 = 0;
}
data->unk_02 = 8;
data->unk_08 = 1;
break;
default:
GF_ASSERT(0);
}
}
u8 sub_02071818(FieldSystem *fieldSystem)
{
PersistedMapFeatures *v0;
UnkStruct_020716D4 *v1;
v0 = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
v1 = (UnkStruct_020716D4 *)PersistedMapFeatures_GetBuffer(v0, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
if (v1->unk_04) {
return 1;
} else {
return 0;
}
}
void sub_0207183C(FieldSystem *fieldSystem)
{
PersistedMapFeatures *v0;
UnkStruct_020716D4 *v1;
UnkStruct_020718D8 *v2;
v0 = MiscSaveBlock_GetPersistedMapFeatures(FieldSystem_GetSaveData(fieldSystem));
v1 = (UnkStruct_020716D4 *)PersistedMapFeatures_GetBuffer(v0, DYNAMIC_MAP_FEATURES_PLATFORM_LIFT_ROOM);
if ((Unk_020F03F4[v1->unk_02].unk_10) && (v1->unk_00 == 1)) {
return;
}
v2 = Heap_AllocFromHeapAtEnd(11, sizeof(UnkStruct_020718D8));
v2->unk_00 = 0;
{
v2->unk_08 = Unk_020F03F4[v1->unk_02].unk_14;
v2->unk_0C = v1->unk_08;
if (v1->unk_00 == 0) {
v2->unk_04 = Unk_020F03F4[v1->unk_02].unk_00[1];
FieldTask_InitCall(fieldSystem->task, sub_020718D8, v2);
v1->unk_00 = 1;
} else {
v2->unk_04 = Unk_020F03F4[v1->unk_02].unk_00[0];
FieldTask_InitCall(fieldSystem->task, sub_020719D8, v2);
v1->unk_00 = 0;
}
}
}
static BOOL sub_020718D8(FieldTask *taskMan)
{
MapProp *v0;
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(taskMan);
UnkStruct_020718D8 *v2 = FieldTask_GetEnv(taskMan);
switch (v2->unk_00) {
case 0:
sub_0205ED2C(fieldSystem->playerAvatar, 0);
sub_02071ACC(v2->unk_0C);
(v2->unk_00)++;
break;
case 1: {
if (v2->unk_08) {
v0 = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM);
} else {
const int v3[2] = {
MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM,
MAP_PROP_MODEL_POKEMON_LEAGUE_LIFT_PLATFORM
};
BOOL v4 = FieldSystem_FindLoadedMapPropByModelIDs(fieldSystem, v3, 2, &v0, NULL);
GF_ASSERT(v4);
}
{
fx32 v5;
VecFx32 v6;
v6 = MapProp_GetPosition(v0);
if (v2->unk_0C == 0) {
v5 = (FX32_ONE);
} else {
v5 = (FX32_ONE * 2);
}
v6.y += v5;
if (v6.y >= v2->unk_04) {
v6.y = v2->unk_04;
sub_02071AEC(v2->unk_0C);
(v2->unk_00)++;
}
sub_0205ED0C(fieldSystem->playerAvatar, v6.y);
MapProp_SetPosition(v0, &v6);
}
} break;
case 2:
DynamicTerrainHeightManager_SetHeight(0, v2->unk_04, fieldSystem->dynamicTerrainHeightMan);
sub_0205ED48(fieldSystem->playerAvatar, 1);
Sound_PlayEffect(SEQ_SE_DP_KI_GASYAN);
(v2->unk_00)++;
break;
case 3:
Heap_FreeToHeap(v2);
return 1;
}
return 0;
}
static BOOL sub_020719D8(FieldTask *taskMan)
{
MapProp *v0;
FieldSystem *fieldSystem = FieldTask_GetFieldSystem(taskMan);
UnkStruct_020718D8 *v2 = FieldTask_GetEnv(taskMan);
switch (v2->unk_00) {
case 0:
sub_0205ED2C(fieldSystem->playerAvatar, 0);
sub_02071ACC(v2->unk_0C);
(v2->unk_00)++;
break;
case 1: {
if (v2->unk_08) {
v0 = MapPropManager_FindLoadedPropByModelID(fieldSystem->mapPropManager, MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM);
} else {
const int v3[2] = {
MAP_PROP_MODEL_IRON_ISLAND_LIFT_PLATFORM,
MAP_PROP_MODEL_POKEMON_LEAGUE_LIFT_PLATFORM
};
BOOL v4 = FieldSystem_FindLoadedMapPropByModelIDs(fieldSystem, v3, 2, &v0, NULL);
GF_ASSERT(v4);
}
{
VecFx32 v5;
v5 = MapProp_GetPosition(v0);
v5.y -= (FX32_ONE);
if (v5.y <= v2->unk_04) {
v5.y = v2->unk_04;
sub_02071AEC(v2->unk_0C);
(v2->unk_00)++;
}
sub_0205ED0C(fieldSystem->playerAvatar, v5.y);
MapProp_SetPosition(v0, &v5);
}
} break;
case 2:
DynamicTerrainHeightManager_SetHeight(0, v2->unk_04, fieldSystem->dynamicTerrainHeightMan);
sub_0205ED48(fieldSystem->playerAvatar, 1);
Sound_PlayEffect(SEQ_SE_DP_KI_GASYAN);
(v2->unk_00)++;
break;
case 3:
Heap_FreeToHeap(v2);
return 1;
}
return 0;
}
static void sub_02071ACC(const int param0)
{
if (param0 == 0) {
Sound_PlayEffect(SEQ_SE_DP_ELEBETA);
} else {
Sound_PlayEffect(SEQ_SE_DP_ELEBETA4);
}
}
static void sub_02071AEC(const int param0)
{
if (param0 == 0) {
Sound_StopEffect(1553, 0);
} else {
Sound_StopEffect(1556, 0);
}
}