Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, va_list or
DEFINE_HOOK(OnSaveFile, (int32_t fileNum));
DEFINE_HOOK(OnLoadFile, (int32_t fileNum));
DEFINE_HOOK(OnDeleteFile, (int32_t fileNum));
DEFINE_HOOK(OnLinkAnimEnd, (SkelAnime * skelAnime));
DEFINE_HOOK(OnQPADamage, (uint32_t * dmgFlags));
DEFINE_HOOK(OnESS, ());
DEFINE_HOOK(OnWaitForPutaway, ());
DEFINE_HOOK(OnAnimationSetLoadFrame, (LinkAnimationHeader * animation, int32_t* frame));

DEFINE_HOOK(OnDialogMessage, ());
DEFINE_HOOK(OnPresentTitleCard, ());
Expand Down Expand Up @@ -74,3 +79,4 @@ DEFINE_HOOK(OnSetGameLanguage, ());
DEFINE_HOOK(OnFileDropped, (std::string filePath));
DEFINE_HOOK(OnAssetAltChange, ());
DEFINE_HOOK(OnKaleidoUpdate, ());
DEFINE_HOOK(OnKaleidoMoveCursorFromSpecialPos, (PauseContext * pauseCtx, uint16_t* cursorItem));
24 changes: 24 additions & 0 deletions soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,26 @@ void GameInteractor_ExecuteOnCuccoOrChickenHatch() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnCuccoOrChickenHatch>();
}

void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnLinkAnimEnd>(skelAnime);
}

void GameInteractor_ExecuteOnQPADamage(uint32_t* dmgFlags) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnQPADamage>(dmgFlags);
}

void GameInteractor_ExecuteOnESS() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnESS>();
}

void GameInteractor_ExecuteOnWaitForPutaway() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnWaitForPutaway>();
}

void GameInteractor_ExecuteOnAnimationSetLoadFrame(LinkAnimationHeader* animation, int32_t* frame) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnAnimationSetLoadFrame>(animation, frame);
}

void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnShopSlotChange>(cursorIndex, price);
}
Expand Down Expand Up @@ -323,3 +343,7 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) {
void GameInteractor_ExecuteOnKaleidoUpdate() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnKaleidoUpdate>();
}

void GameInteractor_ExecuteOnKaleidoMoveCursorFromSpecialPos(PauseContext* pauseCtx, uint16_t* cursorItem) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnKaleidoMoveCursorFromSpecialPos>(pauseCtx, cursorItem);
}
6 changes: 6 additions & 0 deletions soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ void GameInteractor_ExecuteOnPlayerUpdate();
void GameInteractor_ExecuteOnSetDoAction(uint16_t action);
void GameInteractor_ExecuteOnOcarinaSongAction();
void GameInteractor_ExecuteOnCuccoOrChickenHatch();
void GameInteractor_ExecuteOnLinkAnimEnd(SkelAnime* skelAnime);
void GameInteractor_ExecuteOnQPADamage(uint32_t* dmgFlags);
void GameInteractor_ExecuteOnESS();
void GameInteractor_ExecuteOnWaitForPutaway();
void GameInteractor_ExecuteOnAnimationSetLoadFrame(LinkAnimationHeader* animation, int32_t* frame);
void GameInteractor_ExecuteOnActorInit(void* actor);
void GameInteractor_ExecuteOnActorSpawn(void* actor);
void GameInteractor_ExecuteOnActorUpdate(void* actor);
Expand Down Expand Up @@ -84,6 +89,7 @@ void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void));

// Mark: - Pause Menu
void GameInteractor_ExecuteOnKaleidoUpdate();
void GameInteractor_ExecuteOnKaleidoMoveCursorFromSpecialPos(PauseContext* pauseCtx, uint16_t* cursorItem);

#ifdef __cplusplus
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2253,6 +2253,22 @@ typedef enum {
// #### `args`
// - `*DoorShutter`
VB_BE_NEAR_DOOR_SHUTTER,

// #### `result`
// ```c
// false
// ```
// #### `args`
// - None
VB_SKIP_FORCE_PLAY_OCARINA,

// #### `result`
// ```c
// true
// ```
// #### `args`
// - None
VB_HOVER_WITH_ISG,
} GIVanillaBehavior;

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -2132,6 +2132,80 @@ void StaticData::HintTable_Init_Item() {
CustomMessage("a four legged friend", /*german*/"ein vierbeiniger Freund", /*french*/"un puissant animal")});
// /*spanish*/una amiga cuadrúpeda

hintTextTable[RHT_ABILITY_ISG] = HintText(CustomMessage("ISG", /*german*/"ISG", /*french*/"ISG"),
// /*spanish*/ISG
{
CustomMessage("a flashy weapon", /*german*/"ISG", /*french*/"ISG")
// /*spanish*/ISG
}, {
CustomMessage("a permanent hitbox", /*german*/"ISG", /*french*/"ISG")});
// /*spanish*/ISG

hintTextTable[RHT_ABILITY_OI] = HintText(CustomMessage("OI", /*german*/"OI", /*french*/"OI"),
// /*spanish*/OI
{
CustomMessage("a musical bottle", /*german*/"OI", /*french*/"OI")
// /*spanish*/OI
}, {
CustomMessage("a potato of any color", /*german*/"OI", /*french*/"OI")});
// /*spanish*/OI
hintTextTable[RHT_ABILITY_QPA] = HintText(CustomMessage("QPA", /*german*/"QPA", /*french*/"QPA"),
// /*spanish*/QPA
{
CustomMessage("some funky damage", /*german*/"QPA", /*french*/"QPA")
// /*spanish*/QPA
}, {
CustomMessage("some fast hands", /*german*/"QPA", /*french*/"QPA")});
// /*spanish*/QPA
hintTextTable[RHT_ABILITY_HESS] = HintText(CustomMessage("Extended Superslide", /*german*/"Extended Superslide", /*french*/"Extended Superslide"),
// /*spanish*/Extended Superslide
{
CustomMessage("some explosive speed", /*german*/"Extended Superslide", /*french*/"Extended Superslide")
// /*spanish*/Extended Superslide
}, {
CustomMessage("some slick feet", /*german*/"Extended Superslide", /*french*/"Extended Superslide")});
// /*spanish*/Extended Superslide
hintTextTable[RHT_ABILITY_SUPERSLIDE] = HintText(CustomMessage("Superslide", /*german*/"Superslide", /*french*/"Superslide"),
// /*spanish*/Superslide
{
CustomMessage("some straight line speed", /*german*/"Superslide", /*french*/"Superslide")
// /*spanish*/Superslide
}, {
CustomMessage("some shield power", /*german*/"Superslide", /*french*/"Superslide")});
// /*spanish*/Superslide
hintTextTable[RHT_ABILITY_HOVER] = HintText(CustomMessage("Hovering", /*german*/"Hovering", /*french*/"Hovering"),
// /*spanish*/Hovering
{
CustomMessage("a weightless trick", /*german*/"Hovering", /*french*/"Hovering")
// /*spanish*/Hovering
}, {
CustomMessage("gravityn't", /*german*/"Hovering", /*french*/"Hovering")});
// /*spanish*/Hovering
hintTextTable[RHT_ABILITY_EQUIP_SWAP] = HintText(CustomMessage("Equip Swap", /*german*/"Equip Swap", /*french*/"Equip Swap"),
// /*spanish*/Equip Swap
{
CustomMessage("an unbufferable ability", /*german*/"Equip Swap", /*french*/"Equip Swap")
// /*spanish*/Equip Swap
}, {
CustomMessage("a timeless talent", /*german*/"Equip Swap", /*french*/"Equip Swap")});
// /*spanish*/Equip Swap
hintTextTable[RHT_ABILITY_GROUND_JUMP] = HintText(CustomMessage("Ground Jump", /*german*/"Ground Jump", /*french*/"Ground Jump"),
// /*spanish*/Ground Jump
{
CustomMessage("a little leap", /*german*/"Ground Jump", /*french*/"Ground Jump")
// /*spanish*/Ground Jump
}, {
CustomMessage("a beginner's trick", /*german*/"Ground Jump", /*french*/"Ground Jump")});
// /*spanish*/Ground Jump
hintTextTable[RHT_ABILITY_WEIRDSHOT] = HintText(CustomMessage("Weirdshot", /*german*/"Weirdshot", /*french*/"Weirdshot"),
// /*spanish*/Weirdshot
{
CustomMessage("a weird shot", /*german*/"Weirdshot", /*french*/"Weirdshot")
// /*spanish*/Weirdshot
}, {
CustomMessage("a mangled animation", /*german*/"Weirdshot", /*french*/"Weirdshot")});
// /*spanish*/Weirdshot

//What is this used for?
hintTextTable[RHT_HINT_MYSTERIOUS] = HintText(CustomMessage("something mysterious", /*german*/"etwas Mysteriöses", /*french*/"un sacré mystère"));
// /*spanish*/algo misterioso
Expand Down
28 changes: 28 additions & 0 deletions soh/soh/Enhancements/randomizer/3drando/item_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,34 @@ void GenerateItemPool() {
AddItemToMainPool(RG_PROGRESSIVE_SCALE);
}

if (ctx->GetOption(RSK_SHUFFLE_ISG)) {
AddItemToMainPool(RG_ABILITY_ISG);
}
if (ctx->GetOption(RSK_SHUFFLE_OI)) {
AddItemToMainPool(RG_ABILITY_OI);
}
if (ctx->GetOption(RSK_SHUFFLE_QPA)) {
AddItemToMainPool(RG_ABILITY_QPA);
}
if (ctx->GetOption(RSK_SHUFFLE_HESS)) {
AddItemToMainPool(RG_ABILITY_HESS);
}
if (ctx->GetOption(RSK_SHUFFLE_SUPERSLIDE)) {
AddItemToMainPool(RG_ABILITY_SUPERSLIDE);
}
if (ctx->GetOption(RSK_SHUFFLE_HOVER)) {
AddItemToMainPool(RG_ABILITY_HOVER);
}
if (ctx->GetOption(RSK_SHUFFLE_EQUIP_SWAP)) {
AddItemToMainPool(RG_ABILITY_EQUIP_SWAP);
}
if (ctx->GetOption(RSK_SHUFFLE_GROUND_JUMP)) {
AddItemToMainPool(RG_ABILITY_GROUND_JUMP);
}
if (ctx->GetOption(RSK_SHUFFLE_WEIRDSHOT)) {
AddItemToMainPool(RG_ABILITY_WEIRDSHOT);
}

if (ctx->GetOption(RSK_SHUFFLE_BEEHIVES)) {
// 32 total beehive locations
AddItemToPool(PendingJunkPool, RG_RED_RUPEE, 23);
Expand Down
128 changes: 128 additions & 0 deletions soh/soh/Enhancements/randomizer/hook_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ extern void EnGe1_Wait_Archery(EnGe1* enGe1, PlayState* play);
extern void EnGe1_SetAnimationIdle(EnGe1* enGe1);
extern void EnGe1_SetAnimationIdle(EnGe1* enGe1);
extern void EnGe2_SetupCapturePlayer(EnGe2* enGe2, PlayState* play);
extern void func_80832318(Player* player);
extern void Player_SetupActionPreserveItemAction(PlayState* play, Player* player, PlayerActionFunc actionFunc,
s32 flags);
extern void Player_Action_Idle(Player* player, PlayState* play);
extern s32 Player_DecelerateToZero(Player* player);
extern s32 func_80834BD4(Player* player, PlayState* play);
}

bool LocMatchesQuest(Rando::Location loc) {
Expand Down Expand Up @@ -2282,6 +2288,15 @@ void RandomizerOnPlayerUpdateHandler() {
GameInteractor::State::TriforceHuntPieceGiven = 0;
}
}

if (!Flags_GetRandomizerInf(RAND_INF_CAN_GROUND_JUMP)) {
if (GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_CARRYING_ACTOR &&
GET_PLAYER(gPlayState)->stateFlags1 & PLAYER_STATE1_SHIELDING) {
if (GET_PLAYER(gPlayState)->upperActionFunc == func_80834BD4 && GET_PLAYER(gPlayState)->heldActor == NULL) {
GET_PLAYER(gPlayState)->stateFlags1 &= ~PLAYER_STATE1_CARRYING_ACTOR;
}
}
}
}

void RandomizerOnSceneSpawnActorsHandler() {
Expand Down Expand Up @@ -2343,6 +2358,83 @@ void RandomizerOnCuccoOrChickenHatch() {
}
}

void RandomizerOnLinkAnimEnd(SkelAnime* skelAnime) {
if (!Flags_GetRandomizerInf(RAND_INF_CAN_ISG)) {
Player* player = GET_PLAYER(gPlayState);

// Make sure we are only checking for the end of link's animation
// TODO: Use gPlayerAnim_link_normal_defense_kiru?
if (skelAnime == &player->skelAnime && player->meleeWeaponAnimation == PLAYER_MWA_STAB_1H) {
func_80832318(player);
}
}
}

void RandomizerShouldSkipForcePlayOcarina(bool* should) {

if (!Flags_GetRandomizerInf(RAND_INF_CAN_OI)) {
Player* player = GET_PLAYER(gPlayState);

if (player->itemAction != PLAYER_IA_OCARINA_FAIRY && player->itemAction != PLAYER_IA_OCARINA_OF_TIME) {
player->unk_6AD = 0;
Sfx_PlaySfxCentered(NA_SE_SY_ERROR);
Player_SetupActionPreserveItemAction(gPlayState, player, Player_Action_Idle, 0);
player->stateFlags1 &= ~PLAYER_STATE1_IN_CUTSCENE;
*should = true;
}
}
}

void RandomizerOnQPADamage(uint32_t* dmgFlags) {
if (!Flags_GetRandomizerInf(RAND_INF_CAN_QPA)) {
*dmgFlags = 0;
}
}

void RandomizerOnESS() {
if (!Flags_GetRandomizerInf(RAND_INF_CAN_HESS)) {
Player_DecelerateToZero(GET_PLAYER(gPlayState));
}
}

void RandomizerOnWaitForPutaway() {
if (!Flags_GetRandomizerInf(RAND_INF_CAN_SUPERSLIDE)) {
Player_DecelerateToZero(GET_PLAYER(gPlayState));
}
}

void RandomizerShouldHover(bool* should) {
if (!Flags_GetRandomizerInf(RAND_INF_CAN_HOVER)) {
*should = false;
}
}

void RandomizerOnKaleidoMoveCursorFromSpecialPos(PauseContext* pauseCtx, uint16_t* cursorItem) {
if (!Flags_GetRandomizerInf(RAND_INF_CAN_EQUIP_SWAP)) {
*cursorItem = PAUSE_ITEM_NONE;
// PAUSE_ITEM_NONE feels more accurate to intended behaviour, but alternative here also works
// *cursorItem = gSaveContext.inventory.items[pauseCtx->cursorPoint[PAUSE_ITEM]];
}
}

void RandomizerOnAnimationSetLoadFrame(LinkAnimationHeader* animation, int32_t* frame) {
if (!Flags_GetRandomizerInf(RAND_INF_CAN_WEIRDSHOT)) {
std::optional<const char*> animationName;

if (ResourceMgr_OTRSigCheck(reinterpret_cast<char*>(animation)) != 0) {
animationName = reinterpret_cast<const char*>(animation);
animation = reinterpret_cast<LinkAnimationHeader*>(ResourceMgr_LoadAnimByName(*animationName));
}

const auto playerAnimHeader =
static_cast<LinkAnimationHeader*>(SEGMENTED_TO_VIRTUAL(static_cast<void*>(animation)));

if (*frame < 0 || *frame >= playerAnimHeader->common.frameCount) {
*frame = 0;
}
}
}

void RandomizerRegisterHooks() {
static uint32_t onFlagSetHook = 0;
static uint32_t onSceneFlagSetHook = 0;
Expand All @@ -2362,6 +2454,12 @@ void RandomizerRegisterHooks() {
static uint32_t onExitGameHook = 0;
static uint32_t onKaleidoUpdateHook = 0;
static uint32_t onCuccoOrChickenHatchHook = 0;
static uint32_t onLinkAnimEndHook = 0;
static uint32_t onQPADamageHook = 0;
static uint32_t onESSHook = 0;
static uint32_t onWaitForPutawayHook = 0;
static uint32_t onKaleidoMoveCursorFromSpecialPosHook = 0;
static uint32_t onAnimationSetLoadFrameHook = 0;

static uint32_t fishsanityOnActorInitHook = 0;
static uint32_t fishsanityOnActorUpdateHook = 0;
Expand Down Expand Up @@ -2394,6 +2492,14 @@ void RandomizerRegisterHooks() {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnExitGame>(onExitGameHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnKaleidoscopeUpdate>(onKaleidoUpdateHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnCuccoOrChickenHatch>(onCuccoOrChickenHatchHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnLinkAnimEnd>(onLinkAnimEndHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnQPADamage>(onQPADamageHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnESS>(onESSHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnWaitForPutaway>(onWaitForPutawayHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnKaleidoMoveCursorFromSpecialPos>(
onKaleidoMoveCursorFromSpecialPosHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnAnimationSetLoadFrame>(
onAnimationSetLoadFrameHook);

GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(fishsanityOnActorInitHook);
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(fishsanityOnActorUpdateHook);
Expand All @@ -2420,6 +2526,7 @@ void RandomizerRegisterHooks() {
onExitGameHook = 0;
onKaleidoUpdateHook = 0;
onCuccoOrChickenHatchHook = 0;
onLinkAnimEndHook = 0;

fishsanityOnActorInitHook = 0;
fishsanityOnActorUpdateHook = 0;
Expand Down Expand Up @@ -2475,6 +2582,27 @@ void RandomizerRegisterHooks() {
RandomizerOnKaleidoscopeUpdateHandler);
onCuccoOrChickenHatchHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnCuccoOrChickenHatch>(
RandomizerOnCuccoOrChickenHatch);
onLinkAnimEndHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLinkAnimEnd>(
[](SkelAnime* skelAnime) { RandomizerOnLinkAnimEnd(skelAnime); });
onQPADamageHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnQPADamage>(
[](uint32_t* dmgFlags) { RandomizerOnQPADamage(dmgFlags); });
onESSHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnESS>(RandomizerOnESS);
onWaitForPutawayHook =
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnWaitForPutaway>(RandomizerOnWaitForPutaway);
onKaleidoMoveCursorFromSpecialPosHook =
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnKaleidoMoveCursorFromSpecialPos>(
[](PauseContext* pauseCtx, uint16_t* cursorItem) {
RandomizerOnKaleidoMoveCursorFromSpecialPos(pauseCtx, cursorItem);
});
onAnimationSetLoadFrameHook =
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnAnimationSetLoadFrame>(
[](LinkAnimationHeader* animation, int32_t* frame) {
RandomizerOnAnimationSetLoadFrame(animation, frame);
});

COND_VB_SHOULD(VB_SKIP_FORCE_PLAY_OCARINA, true, { RandomizerShouldSkipForcePlayOcarina(should); });

COND_VB_SHOULD(VB_HOVER_WITH_ISG, true, { RandomizerShouldHover(should); });

if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) {
OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave();
Expand Down
Loading
Loading