Polishing, climb everything door opening + sloped ledge climb up (#6936)

Allow player to try opening doors while climbing. Player can't open anything if a door doesn't offer it, so it's ok to try. Handle doors don't change player y position (player walks in the air), so manually lower it.
    Increase y height limit for doors to offer open from 15.0f/20.0f to 50.0f (normal door height). (For shutter doors height could be individualized depending on shutter door type in the future.)
    Make climbing up animation play even for sloped ledges. The animation/action breaks because game thinks player is not on ground. So, at the end of Player_ProcessSceneCollision, if player is in climbing up action, manually set BGCHECKFLAG_GROUND.
This commit is contained in:
djevangelia
2026-07-19 19:04:32 +02:00
committed by GitHub
parent 8cb0c74592
commit e579e7b9a4
7 changed files with 82 additions and 3 deletions
+2
View File
@@ -1102,6 +1102,8 @@ void Path_CopyLastPoint(Path* path, Vec3f* dest);
void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx);
s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input);
u8 PlayerGrounded(Player* player);
s32 Player_ActionHandler_1(Player* player, PlayState* play);
void Player_Action_8084BDFC(Player* player, PlayState* play);
void Player_SetBootData(PlayState* play, Player* player);
void Player_StartAnimMovement(PlayState* play, Player* player, s32 flags);
s32 Player_InBlockingCsMode(PlayState* play, Player* player);
@@ -2,10 +2,61 @@
#include "soh/ShipInit.hpp"
#include "soh/cvar_prefixes.h"
extern "C" {
#include "functions.h"
#include "macros.h"
#include "src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h"
extern PlayState* gPlayState;
}
static void RegisterClimbEverything() {
COND_VB_SHOULD(VB_SURFACE_IS_CLIMBABLE, CVarGetInteger(CVAR_CHEAT("ClimbEverything"), 0), { *should = true; });
COND_VB_SHOULD(VB_SURFACE_ANGLE_IS_CLIMBABLE, CVarGetInteger(CVAR_CHEAT("ClimbEverything"), 0),
{ *should = true; });
COND_VB_SHOULD(VB_CLIMB, CVarGetInteger(CVAR_CHEAT("ClimbEverything"), false), {
Player* player = GET_PLAYER(gPlayState);
// Allow try opening door while climbing
if (Player_ActionHandler_1(player, gPlayState)) {
*should = false;
if (player->doorType == PLAYER_DOORTYPE_HANDLE) {
player->actor.world.pos.y = player->doorActor->world.pos.y;
}
}
});
COND_VB_SHOULD(VB_AFTER_PROCESS_SCENE_COLLISION, CVarGetInteger(CVAR_CHEAT("ClimbEverything"), false), {
Player* player = GET_PLAYER(gPlayState);
// Keep climb up animation on sloping ledges
if (player->actionFunc == Player_Action_8084BDFC) {
player->actor.bgCheckFlags |= BGCHECKFLAG_GROUND;
}
});
COND_VB_SHOULD(VB_EN_DOOR_OFFER_OPEN, CVarGetInteger(CVAR_CHEAT("ClimbEverything"), false), {
Vec3f playerPosRelToDoor = *va_arg(args, Vec3f*);
Player* player = GET_PLAYER(gPlayState);
// Set higher y distance limit to offer open door
if (fabsf(playerPosRelToDoor.y) < 50.0f && fabsf(playerPosRelToDoor.x) < 20.0f &&
fabsf(playerPosRelToDoor.z) < 50.0f) {
*should = true;
}
});
COND_VB_SHOULD(VB_BE_NEAR_DOOR_SHUTTER, CVarGetInteger(CVAR_CHEAT("ClimbEverything"), false), {
DoorShutter* doorShutter = va_arg(args, DoorShutter*);
Vec3f relPlayerPos = *va_arg(args, Vec3f*);
f32* maxDistSides = va_arg(args, f32*);
// Set higher y distance limit to offer open door
// Todo: Individualize this y depending on shutter door type.
if (fabsf(relPlayerPos.x) < *maxDistSides && fabsf(relPlayerPos.y) < 50.0f) {
*should = false;
}
});
}
static RegisterShipInitFunc initFunc(RegisterClimbEverything, { CVAR_CHEAT("ClimbEverything") });
@@ -19,6 +19,8 @@ void RegisterWideShutterDoorRange() {
COND_VB_SHOULD(VB_BE_NEAR_DOOR_SHUTTER, CVAR_WIDE_SHUTTER_DOOR_RANGE_VALUE, {
DoorShutter* doorShutter = va_arg(args, DoorShutter*);
Vec3f relPlayerPos = *va_arg(args, Vec3f*);
f32* maxDistSides = va_arg(args, f32*);
if (doorShutter->gfxType == SHUTTER_BACK_LOCKED || doorShutter->gfxType == SHUTTER_PG_BARS ||
doorShutter->gfxType == SHUTTER_BOSS || doorShutter->gfxType == SHUTTER_GOHMA_BLOCK) {
*should = (SHUTTER_DOOR_RANGE_X < fabsf(relPlayerPos.x) || SHUTTER_DOOR_RANGE_Y < fabsf(relPlayerPos.y));
@@ -367,6 +367,14 @@ typedef enum {
// - None
VB_CLIMB,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_AFTER_PROCESS_SCENE_COLLISION,
// #### `result`
// ```c
// CHECK_BTN_ALL(input->press.button, BTN_START)
@@ -2945,8 +2953,18 @@ typedef enum {
// ```
// #### `args`
// - `*DoorShutter`
// - `*Vec3f` (relPlayerPos)
// - `*f32` (maxDistSides)
VB_BE_NEAR_DOOR_SHUTTER,
// #### `result`
// ```c
// arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y)
// ```
// #### `args`
// - `*Vec3f` (playerPosRelToDoor)
VB_EN_DOOR_OFFER_OPEN,
// #### `result`
// ```c
// CVarGetInteger(CVAR_ENHANCEMENT("3DSceneRender"), 0)
@@ -335,7 +335,9 @@ f32 DoorShutter_GetPlayerDistance(PlayState* play, DoorShutter* this, f32 arg2,
sp28.y = player->actor.world.pos.y + arg2;
sp28.z = player->actor.world.pos.z;
Actor_WorldToActorCoords(&this->dyna.actor, &sp1C, &sp28);
if (GameInteractor_Should(VB_BE_NEAR_DOOR_SHUTTER, arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y), this, &sp1C)) {
if (GameInteractor_Should(VB_BE_NEAR_DOOR_SHUTTER, (arg3 < fabsf(sp1C.x) || arg4 < fabsf(sp1C.y)), this, &sp1C,
&arg3)) {
return FLT_MAX;
} else {
return sp1C.z;
@@ -212,8 +212,10 @@ void EnDoor_Idle(EnDoor* this, PlayState* play) {
GameInteractor_ExecuteOnDungeonKeyUsedHooks(gSaveContext.mapIndex);
}
} else if (!Player_InCsMode(play)) {
if (fabsf(playerPosRelToDoor.y) < 20.0f && fabsf(playerPosRelToDoor.x) < 20.0f &&
fabsf(playerPosRelToDoor.z) < 50.0f) {
if (GameInteractor_Should(VB_EN_DOOR_OFFER_OPEN,
(fabsf(playerPosRelToDoor.y) < 20.0f && fabsf(playerPosRelToDoor.x) < 20.0f &&
fabsf(playerPosRelToDoor.z) < 50.0f),
&playerPosRelToDoor)) {
phi_v0 = player->actor.shape.rot.y - this->actor.shape.rot.y;
if (playerPosRelToDoor.z > 0.0f) {
phi_v0 = 0x8000 - phi_v0;
@@ -11437,6 +11437,8 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) {
this->prevFloorType = sFloorType;
this->floorTypeTimer = 0;
}
GameInteractor_Should(VB_AFTER_PROCESS_SCENE_COLLISION, true);
}
void Player_UpdateCamAndSeqModes(PlayState* play, Player* this) {