Hookifying Various Cheats and FixVineFall (#6827)

This commit is contained in:
Chris
2026-06-30 00:10:56 -04:00
committed by GitHub
parent 1fd3a467cd
commit c5835669fe
11 changed files with 199 additions and 58 deletions
+4 -3
View File
@@ -3,6 +3,7 @@
#include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include <assert.h>
#define SS_NULL 0xFFFF
@@ -1892,7 +1893,7 @@ s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResul
s32 bgId2;
f32 nx, ny, nz; // unit normal of polygon
if (CVarGetInteger(CVAR_CHEAT("NoClip"), 0) && actor != NULL && actor->id == ACTOR_PLAYER) {
if (!GameInteractor_Should(VB_PERFORM_WALL_COLLISION_CHECK, true, actor)) {
return false;
}
@@ -4011,7 +4012,7 @@ u32 func_80041D94(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) {
* SurfaceType Get Wall Flags
*/
s32 func_80041DB8(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) {
if (CVarGetInteger(CVAR_CHEAT("ClimbEverything"), 0) != 0) {
if (GameInteractor_Should(VB_SURFACE_IS_CLIMBABLE, false)) {
return (1 << 3) | D_80119D90[func_80041D94(colCtx, poly, bgId)];
} else {
return D_80119D90[func_80041D94(colCtx, poly, bgId)];
@@ -4108,7 +4109,7 @@ u32 SurfaceType_GetEcho(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId)
* SurfaceType Is Hookshot Surface
*/
u32 SurfaceType_IsHookshotSurface(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) {
return CVarGetInteger(CVAR_CHEAT("HookshotEverything"), 0) || SurfaceType_GetData(colCtx, poly, bgId, 1) >> 17 & 1;
return GameInteractor_Should(VB_SURFACE_IS_HOOKSHOT, SurfaceType_GetData(colCtx, poly, bgId, 1) >> 17 & 1);
}
/**
+1 -1
View File
@@ -5776,7 +5776,7 @@ void Interface_Draw(PlayState* play) {
if ((play->pauseCtx.state == 0) && (play->pauseCtx.debugState == 0)) {
if (gSaveContext.minigameState != 1) {
// Carrots rendering if the action corresponds to riding a horse
if (interfaceCtx->unk_1EE == 8 && !CVarGetInteger(CVAR_CHEAT("InfiniteEponaBoost"), 0)) {
if (interfaceCtx->unk_1EE == 8 && GameInteractor_Should(VB_DRAW_EPONA_BOOST_CARROTS, true)) {
// Load Carrot Icon
gDPLoadTextureBlock(OVERLAY_DISP++, gCarrotIconTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 16, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK,
@@ -9,6 +9,7 @@
#include "objects/object_horse/object_horse.h"
#include "objects/object_hni/object_hni.h"
#include "scenes/overworld/spot09/spot09_scene.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include <assert.h>
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -3332,7 +3333,7 @@ void EnHorse_CheckBoost(EnHorse* thisx, PlayState* play2) {
this->stateFlags |= ENHORSE_BOOST;
this->stateFlags |= ENHORSE_FIRST_BOOST_REGEN;
this->stateFlags |= ENHORSE_FLAG_8;
if (!CVarGetInteger(CVAR_CHEAT("InfiniteEponaBoost"), 0)) {
if (GameInteractor_Should(VB_CONSUME_EPONA_BOOST, true, this)) {
this->numBoosts--;
}
this->boostTimer = 0;
@@ -4681,7 +4681,7 @@ int func_8083816C(s32 arg0) {
}
void func_8083819C(Player* this, PlayState* play) {
if (this->currentShield == PLAYER_SHIELD_DEKU && (CVarGetInteger(CVAR_CHEAT("FireproofDekuShield"), 0) == 0)) {
if (GameInteractor_Should(VB_BURN_SHIELD, this->currentShield == PLAYER_SHIELD_DEKU, this)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_SHIELD, this->actor.world.pos.x, this->actor.world.pos.y,
this->actor.world.pos.z, 0, 0, 0, 1);
Inventory_DeleteEquipment(play, EQUIP_TYPE_SHIELD);
@@ -5705,7 +5705,7 @@ s32 func_8083A6AC(Player* this, PlayState* play) {
if (BgCheck_EntityLineTest1(&play->colCtx, &this->actor.world.pos, &sp74, &sp68, &sp84, true, false, false,
true, &sp80) &&
((ABS(sp84->normal.y) < 600) || (CVarGetInteger(CVAR_CHEAT("ClimbEverything"), 0) != 0))) {
GameInteractor_Should(VB_SURFACE_ANGLE_IS_CLIMBABLE, ABS(sp84->normal.y) < 600)) {
f32 nx = COLPOLY_GET_NORMAL(sp84->normal.x);
f32 ny = COLPOLY_GET_NORMAL(sp84->normal.y);
f32 nz = COLPOLY_GET_NORMAL(sp84->normal.z);
@@ -11305,56 +11305,7 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) {
sTouchedWallFlags = func_80041DB8(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId);
// conflicts arise from these two being enabled at once, and with ClimbEverything on, FixVineFall is redundant
// anyway
if (CVarGetInteger(CVAR_ENHANCEMENT("FixVineFall"), 0) && !CVarGetInteger(CVAR_CHEAT("ClimbEverything"), 0)) {
/* This fixes the "started climbing a wall and then immediately fell off" bug.
* The main idea is if a climbing wall is detected, double-check that it will
* still be valid once climbing begins by doing a second raycast with a small
* margin to make sure it still hits a climbable poly. Then update the flags
* in sTouchedWallFlags again and proceed as normal.
*/
if (sTouchedWallFlags & 8) {
Vec3f checkPosA;
Vec3f checkPosB;
f32 yawCos;
f32 yawSin;
s32 hitWall;
/* Angle the raycast slightly out towards the side based on the angle of
* attack the player takes coming at the climb wall. This is necessary because
* the player's XZ position actually wobbles very slightly while climbing
* due to small rounding errors in the sin/cos lookup tables. This wobble
* can cause wall checks while climbing to be slightly left or right of
* the wall check to start the climb. By adding this buffer it accounts for
* any possible wobble. The end result is the player has to be further than
* some epsilon distance from the edge of the climbing poly to actually
* start the climb. I divide it by 2 to make that epsilon slightly smaller,
* mainly for visuals. Using the full yawDiff leaves a noticeable gap on
* the edges that can't be climbed. But with the half distance it looks like
* the player is climbing right on the edge, and still works.
*/
yawCos = Math_CosS(this->actor.wallYaw - (yawDiff / 2) + 0x8000);
yawSin = Math_SinS(this->actor.wallYaw - (yawDiff / 2) + 0x8000);
checkPosA.x = this->actor.world.pos.x + (-20.0f * yawSin);
checkPosA.z = this->actor.world.pos.z + (-20.0f * yawCos);
checkPosB.x = this->actor.world.pos.x + (50.0f * yawSin);
checkPosB.z = this->actor.world.pos.z + (50.0f * yawCos);
checkPosB.y = checkPosA.y = this->actor.world.pos.y + 26.0f;
hitWall = BgCheck_EntityLineTest1(&play->colCtx, &checkPosA, &checkPosB, &sInteractWallCheckResult,
&wallPoly, true, false, false, true, &wallBgId);
if (hitWall) {
this->actor.wallPoly = wallPoly;
this->actor.wallBgId = wallBgId;
this->actor.wallYaw = Math_Atan2S(wallPoly->normal.z, wallPoly->normal.x);
yawDiff = this->actor.shape.rot.y - (s16)(this->actor.wallYaw + 0x8000);
sTouchedWallFlags = func_80041DB8(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId);
}
}
}
GameInteractor_Should(VB_REVALIDATE_CLIMBED_WALL, true, play, this, &sTouchedWallFlags, &yawDiff);
sShapeYawToTouchedWall = ABS(yawDiff);
@@ -11380,7 +11331,7 @@ void Player_ProcessSceneCollision(PlayState* play, Player* this) {
if ((this->actor.bgCheckFlags & 0x200) && (sShapeYawToTouchedWall < 0x3000)) {
CollisionPoly* wallPoly = this->actor.wallPoly;
if (ABS(wallPoly->normal.y) < 600 || (CVarGetInteger(CVAR_CHEAT("ClimbEverything"), 0) != 0)) {
if (GameInteractor_Should(VB_SURFACE_ANGLE_IS_CLIMBABLE, ABS(wallPoly->normal.y) < 600)) {
f32 wallPolyNormalX = COLPOLY_GET_NORMAL(wallPoly->normal.x);
f32 wallPolyNormalY = COLPOLY_GET_NORMAL(wallPoly->normal.y);
f32 wallPolyNormalZ = COLPOLY_GET_NORMAL(wallPoly->normal.z);