mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 13:23:45 -07:00
Add enhancement to toggle grave hole geometry
This commit is contained in:
parent
7b4df9bdb2
commit
e1b72e4ea9
2 changed files with 77 additions and 0 deletions
73
soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp
Normal file
73
soh/soh/Enhancements/Restorations/GraveHoleJumps.cpp
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#include "public/bridge/consolevariablebridge.h"
|
||||||
|
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||||
|
#include "soh/ShipInit.hpp"
|
||||||
|
#include "functions.h"
|
||||||
|
#include "soh/Enhancements/enhancementTypes.h"
|
||||||
|
#include "soh/resource/type/Scene.h"
|
||||||
|
#include "soh/resource/type/scenecommand/SceneCommand.h"
|
||||||
|
#include "soh/resource/type/scenecommand/SetCollisionHeader.h"
|
||||||
|
|
||||||
|
#define CVAR_GRAVE_HOLE_NAME CVAR_ENHANCEMENT("GraveHoles")
|
||||||
|
#define GRAVE_HOLES_DEFAULT 0
|
||||||
|
#define CVAR_GRAVE_HOLE_VALUE CVarGetInteger(CVAR_GRAVE_HOLE_NAME, GRAVE_HOLES_DEFAULT)
|
||||||
|
#define GRAVEYARD_SCENE_FILEPATH "scenes/shared/spot02_scene/spot02_scene"
|
||||||
|
#define CUSTOM_SURFACE_TYPE 32
|
||||||
|
|
||||||
|
const static std::vector<std::pair<std::pair<u16, u16>, std::pair<u16, u16>>> graveyardGeometryPatches = {
|
||||||
|
// { { startPolygon, endPolygon }, { originalSurfaceType, patchedSurfaceType } }
|
||||||
|
{ { 487, 509 }, { 20, CUSTOM_SURFACE_TYPE } }, // Floor around graves
|
||||||
|
{ { 651, 658 }, { 20, CUSTOM_SURFACE_TYPE } }, // Floor around Royal Family Tomb
|
||||||
|
{ { 613, 620 }, { 0, 15 } }, // Grave ledges (Hylian Shield)
|
||||||
|
{ { 623, 630 }, { 0, 15 } }, // Grave ledges (Redead)
|
||||||
|
{ { 633, 640 }, { 0, 15 } }, // Grave ledges (Dampe)
|
||||||
|
{ { 643, 650 }, { 0, 15 } }, // Grave ledges (Royal Family)
|
||||||
|
};
|
||||||
|
|
||||||
|
CollisionHeader* getGraveyardCollisionHeader() {
|
||||||
|
/*
|
||||||
|
* Load the graveyard collision header manually. Since its position varies between versions, we cannot directly use
|
||||||
|
* dspot02_sceneCollisionHeader_003C54. We have to scroll through the scene cmds to get the header the same way the
|
||||||
|
* game does.
|
||||||
|
*/
|
||||||
|
SOH::Scene* scene =
|
||||||
|
(SOH::Scene*)Ship::Context::GetInstance()->GetResourceManager()->LoadResource(GRAVEYARD_SCENE_FILEPATH).get();
|
||||||
|
SOH::ISceneCommand* sceneCmd = nullptr;
|
||||||
|
for (int i = 0; i < scene->commands.size(); i++) {
|
||||||
|
auto cmd = scene->commands[i];
|
||||||
|
if (cmd->cmdId == SOH::SceneCommandID::SetCollisionHeader) {
|
||||||
|
sceneCmd = cmd.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CollisionHeader* graveyardColHeader = (CollisionHeader*)((SOH::SetCollisionHeader*)sceneCmd)->GetRawPointer();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the surface type list and give ourselves some extra space to create another surface type for Link to fall
|
||||||
|
* into graves. NTSC 1.0's graveyard has 31 surface types, while later versions have 32. The contents of the lists
|
||||||
|
* are shifted somewhat between versions, so to be safe we just create an extra slot that is not in any version.
|
||||||
|
*/
|
||||||
|
size_t surfaceTypeListSize = sizeof(SurfaceType) * 33;
|
||||||
|
SurfaceType* newSurfaceTypes = (SurfaceType*)malloc(surfaceTypeListSize);
|
||||||
|
memcpy(newSurfaceTypes, graveyardColHeader->surfaceTypeList, surfaceTypeListSize);
|
||||||
|
newSurfaceTypes[CUSTOM_SURFACE_TYPE].data[0] = 0x24000004;
|
||||||
|
newSurfaceTypes[CUSTOM_SURFACE_TYPE].data[1] = 0xFC8;
|
||||||
|
graveyardColHeader->surfaceTypeList = newSurfaceTypes;
|
||||||
|
|
||||||
|
return graveyardColHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyGraveyardGeometryPatches() {
|
||||||
|
static CollisionHeader* graveyardColHeader = getGraveyardCollisionHeader();
|
||||||
|
for (auto& mappingPatch : graveyardGeometryPatches) {
|
||||||
|
for (int i = mappingPatch.first.first; i <= mappingPatch.first.second; i++) {
|
||||||
|
CollisionPoly* poly = &graveyardColHeader->polyList[i];
|
||||||
|
poly->type = CVAR_GRAVE_HOLE_VALUE ? mappingPatch.second.first : mappingPatch.second.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterGraveHoleJumps() {
|
||||||
|
ApplyGraveyardGeometryPatches();
|
||||||
|
}
|
||||||
|
|
||||||
|
static RegisterShipInitFunc initFunc_GraveHoleJumps(RegisterGraveHoleJumps, { CVAR_GRAVE_HOLE_NAME });
|
|
@ -1161,6 +1161,10 @@ void SohMenu::AddMenuEnhancements() {
|
||||||
.CVar(CVAR_ENHANCEMENT("NGCKaleidoSwitcher"))
|
.CVar(CVAR_ENHANCEMENT("NGCKaleidoSwitcher"))
|
||||||
.Options(CheckboxOptions().Tooltip(
|
.Options(CheckboxOptions().Tooltip(
|
||||||
"Makes L and R switch pages like on the GameCube. Z opens the Debug Menu instead."));
|
"Makes L and R switch pages like on the GameCube. Z opens the Debug Menu instead."));
|
||||||
|
AddWidget(path, "Grave Hole Jumps", WIDGET_CVAR_CHECKBOX)
|
||||||
|
.CVar(CVAR_ENHANCEMENT("GraveHoles"))
|
||||||
|
.Options(CheckboxOptions().Tooltip(
|
||||||
|
"Restores NTSC 1.0 behavior where Link jumps over grave holes and grabs the ledges."));
|
||||||
|
|
||||||
// Difficulty Options
|
// Difficulty Options
|
||||||
path.sidebarName = "Difficulty";
|
path.sidebarName = "Difficulty";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue