This commit is contained in:
Philip Dubé 2025-04-22 12:12:35 +02:00 committed by GitHub
commit b3f24b458f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 326 additions and 384 deletions

View file

@ -1,7 +1,5 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "spdlog/spdlog.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
@ -12,48 +10,47 @@ extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}
#define CVAR_BLOCKLIFT_NAME CVAR_ENHANCEMENT("FasterHeavyBlockLift")
#define CVAR_BLOCKLIFT_VALUE CVarGetInteger(CVAR_BLOCKLIFT_NAME, 0)
#define CVAR_SKIP_CUTSCENE_NAME CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint")
#define CVAR_SKIP_CUTSCENE_VALUE CVarGetInteger(CVAR_SKIP_CUTSCENE_NAME, IS_RANDO)
/**
* This primarily handles speeding up the heavy block lifts (OGC and in the Fire Trial) but also handles skipping
* the one point cutscene since the two options are so similar in what they do.
*/
void FasterHeavyBlockLift_Register() {
REGISTER_VB_SHOULD(VB_PLAY_ONEPOINT_ACTOR_CS, {
void RegisterFasterHeavyBlockLift() {
COND_VB_SHOULD(VB_PLAY_ONEPOINT_ACTOR_CS, CVAR_BLOCKLIFT_VALUE || CVAR_SKIP_CUTSCENE_VALUE, {
Actor* actor = va_arg(args, Actor*);
if (actor->id == ACTOR_BG_HEAVY_BLOCK &&
(CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) ||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO))) {
if (actor->id == ACTOR_BG_HEAVY_BLOCK) {
*should = false;
}
});
REGISTER_VB_SHOULD(VB_FREEZE_LINK_FOR_BLOCK_THROW, {
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) ||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) {
*should = false;
}
});
COND_VB_SHOULD(VB_FREEZE_LINK_FOR_BLOCK_THROW, CVAR_BLOCKLIFT_VALUE || CVAR_SKIP_CUTSCENE_VALUE,
{ *should = false; });
REGISTER_VB_SHOULD(VB_PLAY_THROW_ANIMATION, {
COND_VB_SHOULD(VB_PLAY_THROW_ANIMATION, CVAR_BLOCKLIFT_VALUE, {
Player* player = GET_PLAYER(gPlayState);
Actor* interactRangeActor = player->interactRangeActor;
s32 interactActorId = interactRangeActor->id;
LinkAnimationHeader* anim = va_arg(args, LinkAnimationHeader*);
// Same actor is used for small and large silver rocks, use actor params to identify large ones
bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && interactRangeActor->params & 1 == 1;
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0) &&
(isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK)) {
bool isLargeSilverRock = interactActorId == ACTOR_EN_ISHI && (interactRangeActor->params & 1) == 1;
if (isLargeSilverRock || interactActorId == ACTOR_BG_HEAVY_BLOCK) {
*should = false;
LinkAnimation_PlayOnceSetSpeed(gPlayState, &player->skelAnime, anim, 5.0f);
}
});
REGISTER_VB_SHOULD(VB_MOVE_THROWN_ACTOR, {
if (CVarGetInteger(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 0)) {
Actor* heldActor = va_arg(args, Actor*);
COND_VB_SHOULD(VB_MOVE_THROWN_ACTOR, CVAR_BLOCKLIFT_VALUE, {
Actor* heldActor = va_arg(args, Actor*);
heldActor->shape.rot.x -= 3510;
}
heldActor->shape.rot.x -= 3510;
});
}
static RegisterShipInitFunc initFunc(RegisterFasterHeavyBlockLift, { CVAR_BLOCKLIFT_NAME, CVAR_SKIP_CUTSCENE_NAME });

View file

@ -1,7 +1,5 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "spdlog/spdlog.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
@ -12,11 +10,8 @@ extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}
void FasterRupeeAccumulator_Register() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnInterfaceUpdate>([]() {
if (!CVarGetInteger(CVAR_ENHANCEMENT("FasterRupeeAccumulator"), 0))
return;
void RegisterFasterRupeeAccumulator() {
COND_HOOK(OnInterfaceUpdate, CVarGetInteger(CVAR_ENHANCEMENT("FasterRupeeAccumulator"), 0), []() {
if (gSaveContext.rupeeAccumulator == 0) {
return;
}
@ -46,3 +41,5 @@ void FasterRupeeAccumulator_Register() {
}
});
}
static RegisterShipInitFunc initFunc(RegisterFasterRupeeAccumulator, { CVAR_ENHANCEMENT("FasterRupeeAccumulator") });

View file

@ -1,6 +1,6 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/randomizer/context.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
@ -10,12 +10,12 @@ extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}
void SkipIntro_Register() {
void RegisterSkipIntro() {
REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, {
// If we're playing rando and if starting age is adult and/or overworld spawns are shuffled we need to skip
// the cutscene regardless of the enhancement being on.
bool adultStart = gSaveContext.linkAge == LINK_AGE_ADULT;
bool shuffleEntrances = OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_ENTRANCES).Is(true);
bool shuffleEntrances = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_ENTRANCES).Is(true);
if ((CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), IS_RANDO) ||
(IS_RANDO && (adultStart || shuffleEntrances))) &&
gSaveContext.cutsceneIndex == 0xFFF1) {
@ -45,3 +45,5 @@ void SkipIntro_Register() {
}
});
}
static RegisterShipInitFunc initFunc(RegisterSkipIntro);

View file

@ -1,6 +1,7 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/randomizer/context.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "macros.h"
@ -14,120 +15,6 @@ extern "C" {
static bool sEnteredBlueWarp = false;
/**
* This will override the transitions into the blue warp cutscenes, set any appropriate flags, and
* set the entrance index to where you would normally end up after the blue warp cutscene. This
* should also account for the difference between your first and following visits to the blue warp.
*/
void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
// Do nothing when in a boss rush
if (IS_BOSS_RUSH) {
return;
}
bool overrideBlueWarpDestinations =
IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
// Force blue warp skip on when ER needs to place Link somewhere else.
// This is preferred over having story cutscenes play in the overworld and then reloading Link somewhere else after.
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) || overrideBlueWarpDestinations) {
bool isBlueWarpCutscene = false;
// Deku Tree Blue warp
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP;
isBlueWarpCutscene = true;
// Dodongo's Cavern Blue warp
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT &&
gSaveContext.cutsceneIndex == 0xFFF1) {
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP;
isBlueWarpCutscene = true;
// Jabu Jabu's Blue warp
} else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP &&
gSaveContext.cutsceneIndex == 0xFFF0) {
gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP;
isBlueWarpCutscene = true;
// Forest Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) {
// Normally set in the blue warp cutscene
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT);
if (IS_RANDO) {
gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP;
} else {
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12;
}
isBlueWarpCutscene = true;
// Fire Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE &&
gSaveContext.cutsceneIndex == 0xFFF3) {
// Normally set in the blue warp cutscene
Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED);
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
// Water Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) {
// Normally set in the blue warp cutscene
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800;
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
// Spirit Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) {
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
// Shadow Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) {
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
}
if (isBlueWarpCutscene) {
if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP) {
// Normally set in the blue warp cutscene
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000;
}
*should = false;
gSaveContext.cutsceneIndex = 0;
}
// This is outside the above condition because we want to handle both first and following visits to the blue
// warp
if (sEnteredBlueWarp && overrideBlueWarpDestinations) {
Entrance_OverrideBlueWarp();
}
}
sEnteredBlueWarp = false;
}
/**
* Using this hook to simply observe that Link has entered a bluewarp
* This way we know to allow entrance rando overrides to be processed on the next tranisition hook
*/
void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
sEnteredBlueWarp = true;
}
/**
* While we could rely on the Item_Give that's normally called, it's not very clear to the player that they
* received the item when skipping the blue warp cutscene, so we'll prevent that and queue it up to be given
* to the player instead.
*/
void SkipBlueWarp_ShouldGiveItem(GIVanillaBehavior _, bool* should, va_list originalArgs) {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
*should = false;
}
}
// Todo: Move item queueing here
/**
@ -150,35 +37,143 @@ void EnKo_MoveWhenReady(EnKo* enKo, PlayState* play) {
void SkipBlueWarp_OnActorUpdate(void* actorPtr) {
EnKo* enKo = static_cast<EnKo*>(actorPtr);
if ((enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3 && enKo->actionFunc == func_80A995CC &&
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
if ((enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3 && enKo->actionFunc == func_80A995CC) {
enKo->actionFunc = EnKo_MoveWhenReady;
}
}
/**
* This will ensure that the Deku Tree Sprout considers the Forest Temple finished when you skip the blue warp cutscene.
* Typically this checks for if you have the medallion, and when skipping the cutscene at this point you don't have it
* yet.
*/
void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _, bool* should, va_list originalArgs) {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP &&
gSaveContext.cutsceneIndex == 0xFFF1) {
*should = Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
}
}
void RegisterSkipBlueWarp() {
COND_ID_HOOK(OnActorUpdate, ACTOR_EN_KO,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO),
SkipBlueWarp_OnActorUpdate);
/**
* This will ensure that the Deku Tree Sprout considers the Forest Temple finished when you skip the blue warp
* cutscene. Typically this checks for if you have the medallion, and when skipping the cutscene at this point you
* don't have it yet.
*/
COND_VB_SHOULD(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), {
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP &&
gSaveContext.cutsceneIndex == 0xFFF1) {
*should = Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
}
});
/**
* While we could rely on the Item_Give that's normally called, it's not very clear to the player that they
* received the item when skipping the blue warp cutscene, so we'll prevent that and queue it up to be given
* to the player instead.
*/
COND_VB_SHOULD(VB_GIVE_ITEM_FROM_BLUE_WARP,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), { *should = false; });
}
void SkipBlueWarp_Register() {
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(ACTOR_EN_KO,
SkipBlueWarp_OnActorUpdate);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(
VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(
VB_PLAY_BLUE_WARP_CS, SkipBlueWarp_ShouldPlayBlueWarpCS);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(
VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_GIVE_ITEM_FROM_BLUE_WARP,
SkipBlueWarp_ShouldGiveItem);
void RegisterShouldPlayBlueWarp() {
/**
* This will override the transitions into the blue warp cutscenes, set any appropriate flags, and
* set the entrance index to where you would normally end up after the blue warp cutscene. This
* should also account for the difference between your first and following visits to the blue warp.
*/
REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, {
// Do nothing when in a boss rush
if (IS_BOSS_RUSH) {
return;
}
bool overrideBlueWarpDestinations =
IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
// Force blue warp skip on when ER needs to place Link somewhere else.
// This is preferred over having story cutscenes play in the overworld and then reloading Link somewhere else
// after.
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) ||
overrideBlueWarpDestinations) {
bool isBlueWarpCutscene = false;
// Deku Tree Blue warp
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP;
isBlueWarpCutscene = true;
// Dodongo's Cavern Blue warp
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT &&
gSaveContext.cutsceneIndex == 0xFFF1) {
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP;
isBlueWarpCutscene = true;
// Jabu Jabu's Blue warp
} else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP &&
gSaveContext.cutsceneIndex == 0xFFF0) {
gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP;
isBlueWarpCutscene = true;
// Forest Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) {
// Normally set in the blue warp cutscene
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT);
if (IS_RANDO) {
gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP;
} else {
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12;
}
isBlueWarpCutscene = true;
// Fire Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE &&
gSaveContext.cutsceneIndex == 0xFFF3) {
// Normally set in the blue warp cutscene
Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED);
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
// Water Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) {
// Normally set in the blue warp cutscene
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800;
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
// Spirit Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) {
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
// Shadow Temple Blue warp
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 &&
gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) {
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
isBlueWarpCutscene = true;
}
if (isBlueWarpCutscene) {
if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP) {
// Normally set in the blue warp cutscene
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000;
}
*should = false;
gSaveContext.cutsceneIndex = 0;
}
// This is outside the above condition because we want to handle both first and following visits to the blue
// warp
if (sEnteredBlueWarp && overrideBlueWarpDestinations) {
Entrance_OverrideBlueWarp();
}
}
sEnteredBlueWarp = false;
});
/**
* Using this hook to simply observe that Link has entered a bluewarp
* This way we know to allow entrance rando overrides to be processed on the next tranisition hook
*/
REGISTER_VB_SHOULD(VB_PLAY_BLUE_WARP_CS, { sEnteredBlueWarp = true; });
}
static RegisterShipInitFunc initFunc(RegisterSkipBlueWarp,
{ CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), "IS_RANDO" });
static RegisterShipInitFunc initFunc2(RegisterShouldPlayBlueWarp);

View file

@ -1,6 +1,5 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h"
@ -9,15 +8,17 @@ extern "C" {
/**
* This will skip the Deku Tree intro, and simply open the mouth as you approach it.
*/
void SkipDekuTreeIntro_Register() {
REGISTER_VB_SHOULD(VB_PLAY_DEKU_TREE_INTRO_CS, {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
BgTreemouth* treeMouth = va_arg(args, BgTreemouth*);
Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH);
Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
BgTreemouth_SetupAction(treeMouth, func_808BC6F8);
*should = false;
}
});
void RegisterSkipDekuTreeIntro() {
COND_VB_SHOULD(VB_PLAY_DEKU_TREE_INTRO_CS,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), {
BgTreemouth* treeMouth = va_arg(args, BgTreemouth*);
Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH);
Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
BgTreemouth_SetupAction(treeMouth, func_808BC6F8);
*should = false;
});
}
static RegisterShipInitFunc initFunc(RegisterSkipDekuTreeIntro,
{ CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), "IS_RANDO" });

View file

@ -1,6 +1,6 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
@ -9,21 +9,19 @@ extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}
void SkipLostWoodsBridge_Register() {
void RegisterSkipLostWoodsBridge() {
/**
* This skips the cutscene where you speak to Saria on the bridge in Lost Woods, where she gives you the Fairy
* Ocarina.
*/
REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) &&
!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) {
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE);
if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) {
Item_Give(gPlayState, ITEM_OCARINA_FAIRY);
}
*should = false;
COND_VB_SHOULD(VB_PLAY_TRANSITION_CS, CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), {
if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_BRIDGE_EAST_EXIT) &&
!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) {
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE);
if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true)) {
Item_Give(gPlayState, ITEM_OCARINA_FAIRY);
}
*should = false;
}
});
@ -32,11 +30,11 @@ void SkipLostWoodsBridge_Register() {
* player that they received the item when skipping the cutscene, so we'll prevent it, and queue it up to be given
* instead.
*/
REGISTER_VB_SHOULD(VB_GIVE_ITEM_FAIRY_OCARINA, {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
*should = false;
}
});
COND_VB_SHOULD(VB_GIVE_ITEM_FAIRY_OCARINA,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), { *should = false; });
// Todo: Move item queueing here
}
static RegisterShipInitFunc initFunc(RegisterSkipLostWoodsBridge,
{ CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), "IS_RANDO" });

View file

@ -1,6 +1,5 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h"
@ -33,16 +32,17 @@ void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) {
}
void SkipToGivingZeldasLetter_OnActorInit(void* actorPtr) {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
EnZl4* enZl4 = static_cast<EnZl4*>(actorPtr);
if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0)
return;
EnZl4* enZl4 = static_cast<EnZl4*>(actorPtr);
if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0)
return;
enZl4->actionFunc = EnZl4_SkipToGivingZeldasLetter;
}
enZl4->actionFunc = EnZl4_SkipToGivingZeldasLetter;
}
void SkipToGivingZeldasLetter_Register() {
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(ACTOR_EN_ZL4,
SkipToGivingZeldasLetter_OnActorInit);
void RegisterSkipToGivingZeldasLetter() {
COND_ID_HOOK(OnActorInit, ACTOR_EN_ZL4, CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO),
SkipToGivingZeldasLetter_OnActorInit);
}
static RegisterShipInitFunc initFunc(RegisterSkipToGivingZeldasLetter,
{ CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), "IS_RANDO" });

View file

@ -1,6 +1,5 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
@ -8,18 +7,6 @@ extern "C" {
extern SaveContext gSaveContext;
}
void SkipZeldaFleeingCastle_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN && gSaveContext.cutsceneIndex == 0xFFF1) {
// Normally set in the cutscene
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4AAA;
gSaveContext.cutsceneIndex = 0;
*should = false;
}
}
}
/**
* When this cutscene is skipped, walking up to the bridge to castle town triggers a quick fade in/out
* which can be confusing to beginners, because they need to then fetch the Ocarina of Time from the water.
@ -46,7 +33,7 @@ void SkipZeldaFleeingCastle_OnActorUpdate(void* actorPtr) {
void SkipZeldaFleeingCastle_OnActorInit(void* actorPtr) {
Actor* actor = static_cast<Actor*>(actorPtr);
if (actor->params == 3 && CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
if (actor->params == 3) {
framesSinceSpawn = 0;
itemOcarinaUpdateHook = GameInteractor::Instance->RegisterGameHookForPtr<GameInteractor::OnActorUpdate>(
(uintptr_t)actorPtr, SkipZeldaFleeingCastle_OnActorUpdate);
@ -59,9 +46,20 @@ void SkipZeldaFleeingCastle_OnActorInit(void* actorPtr) {
}
}
void SkipZeldaFleeingCastle_Register() {
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(ACTOR_ITEM_OCARINA,
SkipZeldaFleeingCastle_OnActorInit);
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(
VB_PLAY_TRANSITION_CS, SkipZeldaFleeingCastle_ShouldPlayTransitionCS);
void RegisterSkipZeldaFleeingCastle() {
COND_ID_HOOK(OnActorInit, ACTOR_ITEM_OCARINA,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO),
SkipZeldaFleeingCastle_OnActorInit);
COND_VB_SHOULD(VB_PLAY_TRANSITION_CS, CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO), {
if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN && gSaveContext.cutsceneIndex == 0xFFF1) {
// Normally set in the cutscene
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4AAA;
gSaveContext.cutsceneIndex = 0;
*should = false;
}
});
}
static RegisterShipInitFunc initFunc(RegisterSkipZeldaFleeingCastle,
{ CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), "IS_RANDO" });

View file

@ -1,28 +1,28 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "src/overlays/actors/ovl_Bg_Bdan_Objects/z_bg_bdan_objects.h"
}
void BdanInit(void* actorRef) {
Player* player = GET_PLAYER(gPlayState);
BgBdanObjects* bgBdanObjects = static_cast<BgBdanObjects*>(actorRef);
if (bgBdanObjects->dyna.actor.params == 1) {
if (player->actor.world.pos.y < -500.0f) {
bgBdanObjects->timer = 220;
}
}
}
/**
* Adjusts the behavior of the elevator to start near the bottom if you are entering the room from the bottom
*/
void MoveJabuJabuElevator_Register() {
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(
ACTOR_BG_BDAN_OBJECTS, [](void* actorRef) {
Player* player = GET_PLAYER(gPlayState);
BgBdanObjects* bgBdanObjects = static_cast<BgBdanObjects*>(actorRef);
if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
return;
}
if (bgBdanObjects->dyna.actor.params == 1) {
if (player->actor.world.pos.y < -500.0f) {
bgBdanObjects->timer = 220;
}
}
});
void RegisterMoveJabuJabuElevator() {
COND_ID_HOOK(OnActorInit, ACTOR_BG_BDAN_OBJECTS,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), BdanInit);
}
static RegisterShipInitFunc initFunc(RegisterMoveJabuJabuElevator,
{ CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), "IS_RANDO" });

View file

@ -1,6 +1,5 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "z64save.h"
@ -15,14 +14,17 @@ extern SaveContext gSaveContext;
* This simply skips the Mido interaction in Kokiri Forest, once you equip the Kokiri
* Sword and Deku Shield he will move out of the way without you needing to talk to him.
*/
void MoveMidoInKokiriForest_Register() {
REGISTER_VB_SHOULD(VB_MOVE_MIDO_IN_KOKIRI_FOREST, {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO) &&
!Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) &&
(CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) &&
(CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) && gSaveContext.cutsceneIndex == 0) {
Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
*should = true;
}
});
void RegisterMoveMidoInKokiriForest() {
COND_VB_SHOULD(
VB_MOVE_MIDO_IN_KOKIRI_FOREST, CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), {
if (!Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) &&
(CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) &&
(CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) && gSaveContext.cutsceneIndex == 0) {
Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
*should = true;
}
});
}
static RegisterShipInitFunc initFunc(RegisterMoveMidoInKokiriForest,
{ CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), "IS_RANDO" });

View file

@ -1,6 +1,5 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/OTRGlobals.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "overlays/actors/ovl_En_Ru1/z_en_ru1.h"
@ -9,93 +8,87 @@ extern "C" {
Actor* func_80AEB124(PlayState* play);
}
void SkipChildRutoInteractions_Register() {
// Skips the Child Ruto introduction cutscene, where she drops down into the hole in Jabu-Jabu's Belly
REGISTER_VB_SHOULD(VB_PLAY_CHILD_RUTO_INTRO, {
EnRu1* enRu1 = va_arg(args, EnRu1*);
void Ru1Init(void* actorRef) {
EnRu1* enRu1 = static_cast<EnRu1*>(actorRef);
if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
return;
}
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO);
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME);
Flags_SetInfTable(INFTABLE_143);
if (enRu1->action == 22) {
enRu1->action = 27;
enRu1->drawConfig = 1;
enRu1->actor.world.pos.x = 127.0f;
enRu1->actor.world.pos.y = -340.0f;
enRu1->actor.world.pos.z = -3041.0f;
enRu1->actor.shape.rot.y = enRu1->actor.world.rot.y = -5098;
enRu1->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY;
Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildSittingAnim, 1.0f, 0.0f,
Animation_GetLastFrame((void*)&gRutoChildSittingAnim), ANIMMODE_LOOP, 0.0f);
}
}
if (*should) {
Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildTurnAroundAnim, 1.0f, 0,
Animation_GetLastFrame((void*)&gRutoChildTurnAroundAnim), ANIMMODE_ONCE, -8.0f);
enRu1->action = 10;
}
void RegisterSkipChildRutoInteractions() {
// Skips the Child Ruto introduction cutscene, where she drops down into the hole in Jabu-Jabu's Belly
COND_VB_SHOULD(
VB_PLAY_CHILD_RUTO_INTRO, CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), {
EnRu1* enRu1 = va_arg(args, EnRu1*);
*should = false;
});
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_MEET_RUTO);
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME);
Flags_SetInfTable(INFTABLE_143);
enRu1->drawConfig = 1;
enRu1->actor.world.pos.x = 127.0f;
enRu1->actor.world.pos.y = -340.0f;
enRu1->actor.world.pos.z = -3041.0f;
enRu1->actor.shape.rot.y = enRu1->actor.world.rot.y = -5098;
if (*should) {
Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildTurnAroundAnim, 1.0f, 0,
Animation_GetLastFrame((void*)&gRutoChildTurnAroundAnim), ANIMMODE_ONCE, -8.0f);
enRu1->action = 10;
}
*should = false;
});
// Skips a short dialogue sequence where Ruto tells you to throw her to the Sapphire
REGISTER_VB_SHOULD(VB_RUTO_WANT_TO_BE_TOSSED_TO_SAPPHIRE, {
if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
return;
}
if (*should) {
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE);
*should = false;
}
});
COND_VB_SHOULD(VB_RUTO_WANT_TO_BE_TOSSED_TO_SAPPHIRE,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), {
if (*should) {
Flags_SetInfTable(INFTABLE_RUTO_IN_JJ_WANTS_TO_BE_TOSSED_TO_SAPPHIRE);
*should = false;
}
});
// Prevents Ruto from running to the Sapphire when she wants to be tossed to it, instead she just stands up and
// waits for link to get closer
REGISTER_VB_SHOULD(VB_RUTO_RUN_TO_SAPPHIRE, {
EnRu1* enRu1 = va_arg(args, EnRu1*);
DynaPolyActor* dynaPolyActor = va_arg(args, DynaPolyActor*);
COND_VB_SHOULD(VB_RUTO_RUN_TO_SAPPHIRE,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), {
EnRu1* enRu1 = va_arg(args, EnRu1*);
DynaPolyActor* dynaPolyActor = va_arg(args, DynaPolyActor*);
if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
return;
}
if (*should) {
enRu1->unk_28C = (BgBdanObjects*)dynaPolyActor;
Flags_SetInfTable(INFTABLE_145);
Flags_SetSwitch(gPlayState, 0x02);
Flags_SetSwitch(gPlayState, 0x1F);
enRu1->action = 42;
Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildWait2Anim, 1.0f, 0,
Animation_GetLastFrame((void*)&gRutoChildWait2Anim), ANIMMODE_LOOP, -8.0f);
// If we aren't skipping one point cutscenes and BgBdan objects has set the camera setting
// to CAM_SET_NORMAL1 (2), don't reset the camera setting to 1. This prevents the One Point
// Cutscene of Ruto getting lifted up from getting queued up twice.
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO) ||
enRu1->unk_28C->cameraSetting != 2) {
enRu1->unk_28C->cameraSetting = 1;
}
Actor* sapphire = func_80AEB124(gPlayState);
if (sapphire != NULL) {
Actor_Kill(sapphire);
}
enRu1->actor.room = gPlayState->roomCtx.curRoom.num;
*should = false;
}
});
if (*should) {
enRu1->unk_28C = (BgBdanObjects*)dynaPolyActor;
Flags_SetInfTable(INFTABLE_145);
Flags_SetSwitch(gPlayState, 0x02);
Flags_SetSwitch(gPlayState, 0x1F);
enRu1->action = 42;
Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildWait2Anim, 1.0f, 0,
Animation_GetLastFrame((void*)&gRutoChildWait2Anim), ANIMMODE_LOOP, -8.0f);
// If we aren't skipping one point cutscenes and BgBdan objects has set the camera setting
// to CAM_SET_NORMAL1 (2), don't reset the camera setting to 1. This prevents the One Point
// Cutscene of Ruto getting lifted up from getting queued up twice.
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO) ||
enRu1->unk_28C->cameraSetting != 2) {
enRu1->unk_28C->cameraSetting = 1;
}
Actor* sapphire = func_80AEB124(gPlayState);
if (sapphire != NULL) {
Actor_Kill(sapphire);
}
enRu1->actor.room = gPlayState->roomCtx.curRoom.num;
*should = false;
}
});
// This overrides the behavior that causes Ruto to get upset at you before sitting back down again when
// INFTABLE_RUTO_IN_JJ_TALK_FIRST_TIME is set
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(ACTOR_EN_RU1, [](void* actorRef) {
EnRu1* enRu1 = static_cast<EnRu1*>(actorRef);
if (!CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
return;
}
if (enRu1->action == 22) {
enRu1->action = 27;
enRu1->drawConfig = 1;
enRu1->actor.flags |= ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY;
Animation_Change(&enRu1->skelAnime, (AnimationHeader*)&gRutoChildSittingAnim, 1.0f, 0.0f,
Animation_GetLastFrame((void*)&gRutoChildSittingAnim), ANIMMODE_LOOP, 0.0f);
}
});
COND_ID_HOOK(OnActorInit, ACTOR_EN_RU1,
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO), Ru1Init);
}
static RegisterShipInitFunc initFunc(RegisterSkipChildRutoInteractions,
{ CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), "IS_RANDO" });

View file

@ -1,18 +0,0 @@
#include "TimeSavers.h"
void TimeSavers_Register() {
// SkipCutscene
// Story
SkipBlueWarp_Register();
SkipDekuTreeIntro_Register();
SkipLostWoodsBridge_Register();
SkipToGivingZeldasLetter_Register();
SkipZeldaFleeingCastle_Register();
SkipIntro_Register();
// SkipMiscInteractions
MoveJabuJabuElevator_Register();
MoveMidoInKokiriForest_Register();
SkipChildRutoInteractions_Register();
FasterHeavyBlockLift_Register();
FasterRupeeAccumulator_Register();
}

View file

@ -1,21 +0,0 @@
#ifndef TIME_SAVERS_H
#define TIME_SAVERS_H
void TimeSavers_Register();
// SkipCutscene
// Story
void SkipBlueWarp_Register();
void SkipDekuTreeIntro_Register();
void SkipLostWoodsBridge_Register();
void SkipToGivingZeldasLetter_Register();
void SkipZeldaFleeingCastle_Register();
void SkipIntro_Register();
// SkipMiscInteractions
void MoveJabuJabuElevator_Register();
void MoveMidoInKokiriForest_Register();
void SkipChildRutoInteractions_Register();
void FasterHeavyBlockLift_Register();
void FasterRupeeAccumulator_Register();
#endif // TIME_SAVERS_H

View file

@ -14,7 +14,6 @@
#include <soh/Enhancements/item-tables/ItemTableManager.h>
#include "soh/Enhancements/nametag.h"
#include "soh/Enhancements/timesaver_hook_handlers.h"
#include "soh/Enhancements/TimeSavers/TimeSavers.h"
#include "soh/Enhancements/randomizer/hook_handlers.h"
#include "src/overlays/actors/ovl_En_Bb/z_en_bb.h"
@ -1071,7 +1070,6 @@ void InitMods() {
BossRush_RegisterHooks();
RandomizerRegisterHooks();
TimeSaverRegisterHooks();
TimeSavers_Register();
RegisterTTS();
RegisterOcarinaTimeTravel();
RegisterDaytimeGoldSkultullas();