From 596ea5ebbb3e5a5dfab72fb7bee6d4802d8b13d4 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Mon, 8 Jan 2024 09:25:47 -0600 Subject: Vanilla Behavior Overhaul Co-authored-by: jordanpg --- soh/src/code/z_demo.c | 171 +++++++++++++++++++++++++++--------------- soh/src/code/z_en_item00.c | 120 +++++++++++------------------ soh/src/code/z_message_PAL.c | 19 ++++- soh/src/code/z_onepointdemo.c | 18 +++-- soh/src/code/z_parameter.c | 8 +- soh/src/code/z_play.c | 126 ------------------------------- soh/src/code/z_player_lib.c | 4 +- 7 files changed, 191 insertions(+), 275 deletions(-) (limited to 'soh/src/code') diff --git a/soh/src/code/z_demo.c b/soh/src/code/z_demo.c index 9c0dd9b05..94b04580f 100644 --- a/soh/src/code/z_demo.c +++ b/soh/src/code/z_demo.c @@ -32,6 +32,7 @@ #include "scenes/misc/hakaana_ouke/hakaana_ouke_scene.h" #include "soh/Enhancements/randomizer/randomizer_entrance.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" u16 D_8011E1C0 = 0; u16 D_8011E1C4 = 0; @@ -485,6 +486,7 @@ void func_80065134(PlayState* play, CutsceneContext* csCtx, CsCmdDayTime* cmd) { gSaveContext.dayTime = temp1 + temp2; gSaveContext.skyboxTime = temp1 + temp2; + LUSLOG_INFO("SET TIME %d", gSaveContext.dayTime); } } @@ -493,11 +495,16 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB Player* player = GET_PLAYER(play); s32 temp = 0; - // Automatically skip certain cutscenes when in rando - // cmd->base == 8: Traveling back/forward in time cutscene - // cmd->base == 24: Dropping a fish for Jabu Jabu - // cmd->base == 33: Zelda escaping with impa cutscene - bool randoCsSkip = (IS_RANDO && (cmd->base == 8 || cmd->base == 24 || cmd->base == 33)); + bool shouldSkipCommand = false; + + if (cmd->base == 8 && !GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, true, NULL)) { + shouldSkipCommand = true; + } + + if (cmd->base == 24 && !GameInteractor_Should(GI_VB_PLAY_DROP_FISH_FOR_JABU_CS, true, NULL)) { + shouldSkipCommand = true; + } + bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) && (gSaveContext.fileNum != 0xFEDC) && CVarGetInteger("gDebugEnabled", 0)); @@ -558,7 +565,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB } } - if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (randoCsSkip || debugCsSkip))) { + if (playCutscene || (temp != 0) || ((csCtx->frames > 20) && (shouldSkipCommand || debugCsSkip))) { csCtx->state = CS_STATE_UNSKIPPABLE_EXEC; Audio_SetCutsceneFlag(0); @@ -624,7 +631,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB gSaveContext.fw.set = 0; gSaveContext.respawn[RESPAWN_MODE_TOP].data = 0; } - if (!Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL)) { + if (GameInteractor_Should(GI_VB_PLAY_PULL_MASTER_SWORD_CS, !Flags_GetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL), NULL)) { Flags_SetEventChkInf(EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL); play->nextEntranceIndex = ENTR_CUTSCENE_MAP_0; play->transitionTrigger = TRANS_TRIGGER_START; @@ -716,7 +723,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_WHITE; break; case 22: - Item_Give(play, ITEM_SONG_REQUIEM); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) { + Item_Give(play, ITEM_SONG_REQUIEM); + } play->nextEntranceIndex = ENTR_DESERT_COLOSSUS_0; play->transitionTrigger = TRANS_TRIGGER_START; gSaveContext.cutsceneIndex = 0xFFF0; @@ -768,7 +777,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->nextEntranceIndex = ENTR_CHAMBER_OF_THE_SAGES_0; play->transitionTrigger = TRANS_TRIGGER_START; play->transitionType = TRANS_TYPE_FADE_WHITE; - Item_Give(play, ITEM_MEDALLION_FIRE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FIRE_MEDALLION, true, NULL)) { + Item_Give(play, ITEM_MEDALLION_FIRE); + } gSaveContext.chamberCutsceneNum = 1; break; case 31: @@ -848,7 +859,9 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; break; case 47: - Item_Give(play, ITEM_SONG_NOCTURNE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) { + Item_Give(play, ITEM_SONG_NOCTURNE); + } Flags_SetEventChkInf(EVENTCHKINF_LEARNED_NOCTURNE_OF_SHADOW); play->nextEntranceIndex = ENTR_KAKARIKO_VILLAGE_0; play->transitionTrigger = TRANS_TRIGGER_START; @@ -1292,7 +1305,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB break; } - if (randoCsSkip) { + if (shouldSkipCommand && IS_RANDO) { Entrance_OverrideCutsceneEntrance(cmd->base); } } @@ -1561,7 +1574,49 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText } else if ((cmd->type == 4) && CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) { Message_StartTextbox(play, cmd->textId1, NULL); } else { + GetItemEntry getItemEntry = GET_ITEM_NONE; + if (IS_RANDO) { + switch (cmd->base) { + case 0x80: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_QUEEN_GOHMA, RG_KOKIRI_EMERALD); + break; + case 0x81: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_KING_DODONGO, RG_GORON_RUBY); + break; + case 0x82: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BARINADE, RG_ZORA_SAPPHIRE); + break; + case 0x3E: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_PHANTOM_GANON, RG_FOREST_MEDALLION); + break; + case 0x3C: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_VOLVAGIA, RG_FIRE_MEDALLION); + break; + case 0x3D: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_MORPHA, RG_WATER_MEDALLION); + break; + case 0x3F: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TWINROVA, RG_SPIRIT_MEDALLION); + break; + case 0x41: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_BONGO_BONGO, RG_SHADOW_MEDALLION); + break; + case 0x40: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_GIFT_FROM_SAGES, RG_LIGHT_MEDALLION); + break; + case 0x72: + getItemEntry = Randomizer_GetItemFromKnownCheck(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_LIGHT_ARROWS); + break; + } + if (getItemEntry.getItemId != GI_NONE) { + // cmd->base = getItemEntry.textId; + // GET_PLAYER(play)->getItemEntry = getItemEntry; + } + } Message_StartTextbox(play, cmd->base, NULL); + if (IS_RANDO && getItemEntry.getItemId != GI_NONE) { + // GET_PLAYER(play)->getItemEntry = (GetItemEntry)GET_ITEM_NONE; + } } return; } @@ -1584,12 +1639,14 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText if ((dialogState == TEXT_STATE_CHOICE) && Message_ShouldAdvance(play)) { if (play->msgCtx.choiceIndex == 0) { if (cmd->textId1 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox D: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId1); } else { csCtx->frames++; } } else { if (cmd->textId2 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox E: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId2); } else { csCtx->frames++; @@ -1599,6 +1656,7 @@ void Cutscene_Command_Textbox(PlayState* play, CutsceneContext* csCtx, CsCmdText if (dialogState == TEXT_STATE_9) { if (cmd->textId1 != 0xFFFF) { + // LUSLOG_INFO("Cutscene_Command_Textbox F: base:0x%x textId1:0x%x textId2:0x%x", cmd->base, cmd->textId1, cmd->textId2); Message_ContinueTextbox(play, cmd->textId1); } else { csCtx->frames++; @@ -2113,34 +2171,23 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) { u8 requiredAge; s16 i; - if (IS_RANDO && - // don't skip epona escape cutscenes - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_11 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_12 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_13 && - gSaveContext.entranceIndex != ENTR_HYRULE_FIELD_15 && - // don't skip nabooru iron knuckle cs - gSaveContext.entranceIndex != ENTR_SPIRIT_TEMPLE_BOSS_0) { - gSaveContext.showTitleCard = false; - return; - } - for (i = 0; i < ARRAY_COUNT(sEntranceCutsceneTable); i++) { entranceCutscene = &sEntranceCutsceneTable[i]; - requiredAge = entranceCutscene->ageRestriction; if (requiredAge == 2) { requiredAge = gSaveContext.linkAge; } if ((gSaveContext.entranceIndex == entranceCutscene->entrance) && - (!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == 0x18)) && + (!Flags_GetEventChkInf(entranceCutscene->flag) || (entranceCutscene->flag == EVENTCHKINF_EPONA_OBTAINED)) && (gSaveContext.cutsceneIndex < 0xFFF0) && ((u8)gSaveContext.linkAge == requiredAge) && (gSaveContext.respawnFlag <= 0)) { Flags_SetEventChkInf(entranceCutscene->flag); - Cutscene_SetSegment(play, entranceCutscene->segAddr); - gSaveContext.cutsceneTrigger = 2; - gSaveContext.showTitleCard = false; + if (GameInteractor_Should(GI_VB_PLAY_ENTRANCE_CS, true, &entranceCutscene->flag)) { + Cutscene_SetSegment(play, entranceCutscene->segAddr); + gSaveContext.cutsceneTrigger = 2; + gSaveContext.showTitleCard = false; + } break; } } @@ -2148,48 +2195,48 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) { void Cutscene_HandleConditionalTriggers(PlayState* play) { osSyncPrintf("\ngame_info.mode=[%d] restart_flag", ((void)0, gSaveContext.respawnFlag)); + LUSLOG_INFO("Cutscene_HandleConditionalTriggers - entranceIndex: %#x cutsceneIndex: %#x", gSaveContext.entranceIndex, gSaveContext.cutsceneIndex); + + if (!GameInteractor_Should(GI_VB_PLAY_TRANSITION_CS, true, NULL)) { + return; + } if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - const bool bShouldTowerRandoSkip = - (IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)); if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); - gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0; - gSaveContext.cutsceneIndex = 0xFFF0; - } - } else if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && LINK_IS_ADULT && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) && - (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) && - !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); - gSaveContext.cutsceneIndex = 0xFFF0; - } + Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); + gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_0; + gSaveContext.cutsceneIndex = 0xFFF0; + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW, ( + (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0) && + LINK_IS_ADULT && + Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) && + Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) && + !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL) + ), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); + gSaveContext.cutsceneIndex = 0xFFF0; } else if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); + if (GameInteractor_Should(GI_VB_GIVE_ITEM_FAIRY_OCARINA, true, NULL)) { Item_Give(play, ITEM_OCARINA_FAIRY); - gSaveContext.entranceIndex = ENTR_LOST_WOODS_0; - gSaveContext.cutsceneIndex = 0xFFF0; - } - } else if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && - LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && - (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)) { - if (!IS_RANDO) { - Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); - gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0; - gSaveContext.cutsceneIndex = 0xFFF8; } - } else if ((!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) && - gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS) || - (bShouldTowerRandoSkip && - gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR)) { + gSaveContext.entranceIndex = ENTR_LOST_WOODS_0; + gSaveContext.cutsceneIndex = 0xFFF0; + } else if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS, ( + CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && + CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && + LINK_IS_ADULT && + !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) + ), NULL)) { + Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); + gSaveContext.entranceIndex = ENTR_TEMPLE_OF_TIME_0; + gSaveContext.cutsceneIndex = 0xFFF8; + } else if (!Flags_GetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO) && + (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_GANON_BOSS)) { Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); gSaveContext.entranceIndex = ENTR_GANON_BOSS_0; - // In rando, skip the cutscene for the tower falling down after the escape. - if (IS_RANDO) { - return; - } gSaveContext.cutsceneIndex = 0xFFF0; } } diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 77f42aebd..da7454961 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -3,6 +3,7 @@ #include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/effects/ovl_Effect_Ss_Dead_Sound/z_eff_ss_dead_sound.h" #include "textures/icon_item_static/icon_item_static.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" #define FLAGS 0 @@ -349,6 +350,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { s32 getItemId = GI_NONE; this->randoGiEntry = (GetItemEntry)GET_ITEM_NONE; this->randoCheck = (RandomizerCheck)RC_UNKNOWN_CHECK; + this->itemEntry = (GetItemEntry)GET_ITEM_NONE; s16 spawnParam8000 = this->actor.params & 0x8000; s32 pad1; @@ -358,7 +360,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.params &= 0xFF; - if (Flags_GetCollectible(play, this->collectibleFlag)) { + if (GameInteractor_Should(GI_VB_ITEM00_DESPAWN, Flags_GetCollectible(play, this->collectibleFlag), this)) { Actor_Kill(&this->actor); return; } @@ -381,12 +383,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->unk_158 = 0; Actor_SetScale(&this->actor, 0.03f); this->scale = 0.03f; - // Offset keys in randomizer slightly higher for their GID replacement - if (!IS_RANDO) { - yOffset = 350.0f; - } else { - yOffset = 430.0f; - } + yOffset = 350.0f; break; case ITEM00_HEART_PIECE: this->unk_158 = 0; @@ -479,6 +476,14 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { Actor_SetScale(&this->actor, 0.03f); this->scale = 0.03f; break; + case ITEM00_SOH_GIVE_ITEM_ENTRY: + case ITEM00_SOH_GIVE_ITEM_ENTRY_GI: + case ITEM00_SOH_DUMMY: + this->unk_158 = 0; + Actor_SetScale(&this->actor, 0.03f); + this->scale = 0.03f; + yOffset = 430.0f; + break; } this->unk_156 = 0; @@ -507,6 +512,10 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { this->actor.velocity.y = 0.0f; this->actor.gravity = 0.0f; + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) { + return; + } + switch (this->actor.params) { case ITEM00_RUPEE_GREEN: Item_Give(play, ITEM_RUPEE_GREEN); @@ -576,16 +585,8 @@ void EnItem00_Init(Actor* thisx, PlayState* play) { break; } - if (!Actor_HasParent(&this->actor, play)) { - if (getItemId != GI_NONE) { - if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) { - func_8002F554(&this->actor, play, getItemId); - } else { - if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } - } + if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { + func_8002F554(&this->actor, play, getItemId); } EnItem00_SetupAction(this, func_8001E5C8); @@ -603,8 +604,7 @@ void func_8001DFC8(EnItem00* this, PlayState* play) { (this->actor.params == ITEM00_HEART_PIECE)) { this->actor.shape.rot.y += 960; } else { - if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) && - (this->actor.params != ITEM00_BOMBCHU)) { + if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) { if (this->unk_15A == -1) { if (Math_SmoothStepToS(&this->actor.shape.rot.x, this->actor.world.rot.x - 0x4000, 2, 3000, 1500) == 0) { @@ -697,8 +697,7 @@ void func_8001E304(EnItem00* this, PlayState* play) { if (this->actor.params <= ITEM00_RUPEE_RED) { this->actor.shape.rot.y += 960; - } else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params != ITEM00_BOMBS_SPECIAL) && - (this->actor.params != ITEM00_BOMBCHU)) { + } else if ((this->actor.params >= ITEM00_SHIELD_DEKU) && (this->actor.params < ITEM00_BOMBS_SPECIAL)) { this->actor.world.rot.x -= 700; this->actor.shape.rot.y += 400; this->actor.shape.rot.x = this->actor.world.rot.x - 0x4000; @@ -733,13 +732,7 @@ void func_8001E5C8(EnItem00* this, PlayState* play) { Player* player = GET_PLAYER(play); if (this->getItemId != GI_NONE) { if (!Actor_HasParent(&this->actor, play)) { - if (!IS_RANDO) { - func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); - } else { - if (GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } + func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); this->unk_15A++; } else { this->getItemId = GI_NONE; @@ -781,13 +774,15 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { s32 pad; // Rotate some drops when 3D drops are on, otherwise reset rotation back to 0 for billboard effect - if ((this->actor.params == ITEM00_HEART && this->unk_15A >= 0) || + if ( + (this->actor.params == ITEM00_HEART && this->unk_15A >= 0) || (this->actor.params >= ITEM00_ARROWS_SMALL && this->actor.params <= ITEM00_SMALL_KEY) || - this->actor.params == ITEM00_BOMBS_A || this->actor.params == ITEM00_ARROWS_SINGLE || - this->actor.params == ITEM00_BOMBS_SPECIAL || this->actor.params == ITEM00_BOMBCHU) { - if (CVarGetInteger("gNewDrops", 0) || - // Keys in randomizer need to always rotate for their GID replacement - (IS_RANDO && this->actor.params == ITEM00_SMALL_KEY)) { + this->actor.params == ITEM00_BOMBS_A || + this->actor.params == ITEM00_ARROWS_SINGLE || + this->actor.params == ITEM00_BOMBS_SPECIAL || + (this->actor.params >= ITEM00_BOMBCHU && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI) + ) { + if (CVarGetInteger("gNewDrops", 0) || (this->actor.params >= ITEM00_SOH_DUMMY && this->actor.params <= ITEM00_SOH_GIVE_ITEM_ENTRY_GI)) { this->actor.shape.rot.y += 960; } else { this->actor.shape.rot.y = 0; @@ -871,6 +866,10 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { return; } + if (!GameInteractor_Should(GI_VB_GIVE_ITEM_FROM_ITEM_00, true, this)) { + return; + } + switch (this->actor.params) { case ITEM00_RUPEE_GREEN: Item_Give(play, ITEM_RUPEE_GREEN); @@ -955,14 +954,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) { params = &this->actor.params; if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { - if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) { - func_8002F554(&this->actor, play, getItemId); - } else { - getItemId = this->randoGiEntry.getItemId; - if (GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry) && this->randoInf != RAND_INF_MAX) { - Flags_SetRandomizerInf(this->randoInf); - } - } + func_8002F554(&this->actor, play, getItemId); } switch (*params) { @@ -1052,7 +1044,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { } break; case ITEM00_HEART_PIECE: - if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) { + if (CVarGetInteger("gNewDrops", 0)) { mtxScale = 21.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); GetItem_Draw(play, GID_HEART_PIECE); @@ -1162,7 +1154,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { break; } case ITEM00_SMALL_KEY: - if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) { + if (CVarGetInteger("gNewDrops", 0)) { mtxScale = 8.0f; Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); GetItem_Draw(play, GID_KEY_SMALL); @@ -1368,17 +1360,7 @@ static const Vtx customDropVtx[] = { * Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...). */ void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) { - if (IS_RANDO && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) { - if (this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } - - f32 mtxScale = 10.67f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry); - GetItemEntry_Draw(play, this->randoGiEntry); - } else if (this->actor.params == ITEM00_BOMBCHU) { + if (this->actor.params == ITEM00_BOMBCHU) { OPEN_DISPS(play->state.gfxCtx); Matrix_ReplaceRotation(&play->billboardMtxF); @@ -1458,29 +1440,17 @@ void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play) { * Draw Function used for the Piece of Heart type of En_Item00. */ void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) { - if (IS_RANDO) { - if (this->randoCheck != RC_UNKNOWN_CHECK) { - this->randoGiEntry = Randomizer_GetItemFromKnownCheck(this->randoCheck, GI_NONE); - this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; - } - - f32 mtxScale = 16.0f; - Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); - EnItem00_CustomItemsParticles(&this->actor, play, this->randoGiEntry); - GetItemEntry_Draw(play, this->randoGiEntry); - } else { - s32 pad; + s32 pad; - OPEN_DISPS(play->state.gfxCtx); + OPEN_DISPS(play->state.gfxCtx); - Gfx_SetupDL_25Xlu(play->state.gfxCtx); - func_8002ED80(&this->actor, play, 0); - gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), - G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL); + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + func_8002ED80(&this->actor, play, 0); + gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), + G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_XLU_DISP++, gHeartPieceInteriorDL); - CLOSE_DISPS(play->state.gfxCtx); - } + CLOSE_DISPS(play->state.gfxCtx); } /** diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 4c661aad7..1d00f73bb 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -2603,8 +2603,23 @@ void Message_DrawMain(PlayState* play, Gfx** p) { msgCtx->lastPlayedSong = msgCtx->ocarinaStaff->state; msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_SUCCESS; - if (!IS_RANDO) { - Item_Give(play, ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]); + u8 songItemId = ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]; + + if ( + (songItemId == ITEM_SONG_MINUET && GameInteractor_Should(GI_VB_GIVE_ITEM_MINUET_OF_FOREST, true, NULL)) || + (songItemId == ITEM_SONG_BOLERO && GameInteractor_Should(GI_VB_GIVE_ITEM_BOLERO_OF_FIRE, true, NULL)) || + (songItemId == ITEM_SONG_SERENADE && GameInteractor_Should(GI_VB_GIVE_ITEM_SERENADE_OF_WATER, true, NULL)) || + (songItemId == ITEM_SONG_REQUIEM && GameInteractor_Should(GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT, true, NULL)) || + (songItemId == ITEM_SONG_NOCTURNE && GameInteractor_Should(GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW, true, NULL)) || + (songItemId == ITEM_SONG_PRELUDE && GameInteractor_Should(GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT, true, NULL)) || + (songItemId == ITEM_SONG_LULLABY && GameInteractor_Should(GI_VB_GIVE_ITEM_ZELDAS_LULLABY, true, NULL)) || + (songItemId == ITEM_SONG_EPONA && GameInteractor_Should(GI_VB_GIVE_ITEM_EPONAS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_SARIA && GameInteractor_Should(GI_VB_GIVE_ITEM_SARIAS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_SUN && GameInteractor_Should(GI_VB_GIVE_ITEM_SUNS_SONG, true, NULL)) || + (songItemId == ITEM_SONG_TIME && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_TIME, true, NULL)) || + (songItemId == ITEM_SONG_STORMS && GameInteractor_Should(GI_VB_GIVE_ITEM_SONG_OF_STORMS, true, NULL)) + ) { + Item_Give(play, songItemId); } osSyncPrintf(VT_FGCOL(YELLOW)); diff --git a/soh/src/code/z_onepointdemo.c b/soh/src/code/z_onepointdemo.c index 9489eefcd..ad5df65bd 100644 --- a/soh/src/code/z_onepointdemo.c +++ b/soh/src/code/z_onepointdemo.c @@ -1,6 +1,7 @@ #include "global.h" #include "vt.h" #include "overlays/actors/ovl_En_Sw/z_en_sw.h" +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" static s16 sDisableAttention = false; static s16 sUnused = -1; @@ -810,12 +811,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor break; case 4100: csInfo->keyFrames = D_801225D4; - // RANDO: Waterfall opening cutscene skips to the end of the cutscene data earlier by doing this - if (!(IS_RANDO)) { - csInfo->keyFrameCnt = 5; - } else { - csInfo->keyFrameCnt = 2; - } + csInfo->keyFrameCnt = ARRAY_COUNT(D_801225D4); player->actor.shape.rot.y = player->actor.world.rot.y = player->currentYaw = 0x3FFC; func_800C0808(play, camIdx, player, CAM_SET_CS_C); @@ -1176,6 +1172,16 @@ s16 OnePointCutscene_Init(PlayState* play, s16 csId, s16 timer, Actor* actor, s1 s16 csCamIdx; Camera* csCam; + if (actor != NULL && actor->id != ACTOR_PLAYER) { + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_ACTOR_CS, true, actor)) { + return; + } + } else { + if (!GameInteractor_Should(GI_VB_PLAY_ONEPOINT_CS, true, &csId)) { + return; + } + } + if (parentCamIdx == SUBCAM_ACTIVE) { parentCamIdx = play->activeCamera; } diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 828e98368..bc253ef3a 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2128,7 +2128,9 @@ u8 Item_Give(PlayState* play, u8 item) { AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS); } } - item = ITEM_STICK; + // [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook + INV_CONTENT(ITEM_STICK) = ITEM_STICK; + return Return_Item(item, MOD_NONE, returnItem); } else if (item == ITEM_NUT) { if (gSaveContext.inventory.items[slot] == ITEM_NONE) { Inventory_ChangeUpgrade(UPG_NUTS, 1); @@ -2152,7 +2154,9 @@ u8 Item_Give(PlayState* play, u8 item) { AMMO(ITEM_NUT) = CUR_CAPACITY(UPG_NUTS); } } - item = ITEM_NUT; + // [SOH] This results in the same behavior as the original code, but also allows us to get an accurate ReceivedItemEntry hook + INV_CONTENT(ITEM_NUT) = ITEM_NUT; + return Return_Item(item, MOD_NONE, returnItem); } else if (item == ITEM_BOMB) { // "Bomb Bomb Bomb Bomb Bomb Bomb Bomb" osSyncPrintf(" 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 爆弾 \n"); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index f9b3e7cf4..3ce5eeefc 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -226,60 +226,6 @@ void Play_Destroy(GameState* thisx) { gPlayState = NULL; } -void GivePlayerRandoRewardSongOfTime(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_16 && player != NULL && !Player_InBlockingCsMode(play, player) && - !Flags_GetTreasure(play, 0x1F) && gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT && !gSaveContext.pendingIceTrapCount) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0x1F; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } -} - -void GivePlayerRandoRewardNocturne(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if ((gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 || - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_1 || - gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_2) && LINK_IS_ADULT && CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST) && - CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE) && CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER) && player != NULL && - !Player_InBlockingCsMode(play, player) && !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_NOCTURNE_OF_SHADOW); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0xAA; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } -} - -void GivePlayerRandoRewardRequiem(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { - if ((gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT) && player != NULL && - !Player_InBlockingCsMode(play, player)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_SONG_OF_TIME); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = 0xAC; - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - } - } -} - -void GivePlayerRandoRewardMasterSword(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - if (gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_2 && LINK_IS_ADULT && player != NULL && - !Player_InBlockingCsMode(play, player) && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && - !Flags_GetRandomizerInf(RAND_INF_TOT_MASTER_SWORD)) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_MASTER_SWORD); - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagID = RAND_INF_TOT_MASTER_SWORD; - player->pendingFlag.flagType = FLAG_RANDOMIZER_INF; - } -} - u8 CheckStoneCount() { u8 stoneCount = 0; @@ -402,69 +348,6 @@ u8 CheckLACSRewardCount() { return lacsRewardCount; } -void GivePlayerRandoRewardZeldaLightArrowsGift(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - - u8 meetsRequirements = 0; - - switch (Randomizer_GetSettingValue(RSK_GANONS_BOSS_KEY)) { - case RO_GANON_BOSS_KEY_LACS_STONES: - if ((CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_STONE_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_MEDALLIONS: - if ((CheckMedallionCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_MEDALLION_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_REWARDS: - if ((CheckMedallionCount() + CheckStoneCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_REWARD_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_DUNGEONS: - if ((CheckDungeonCount() + CheckLACSRewardCount()) >= Randomizer_GetSettingValue(RSK_LACS_DUNGEON_COUNT)) { - meetsRequirements = true; - } - break; - case RO_GANON_BOSS_KEY_LACS_TOKENS: - if (gSaveContext.inventory.gsTokens >= Randomizer_GetSettingValue(RSK_LACS_TOKEN_COUNT)) { - meetsRequirements = true; - } - break; - default: - if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) { - meetsRequirements = true; - } - break; - } - - if (meetsRequirements && LINK_IS_ADULT && - (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) && - !Flags_GetTreasure(play, 0x1E) && player != NULL && !Player_InBlockingCsMode(play, player) && - play->transitionTrigger == TRANS_TRIGGER_OFF) { - GetItemEntry getItem = Randomizer_GetItemFromKnownCheck(check, GI_ARROW_LIGHT); - if (GiveItemEntryWithoutActor(play, getItem)) { - player->pendingFlag.flagID = 0x1E; - player->pendingFlag.flagType = FLAG_SCENE_TREASURE; - } - } -} - -void GivePlayerRandoRewardSariaGift(PlayState* play, RandomizerCheck check) { - Player* player = GET_PLAYER(play); - if (gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) { - GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheck(check, RG_ZELDAS_LULLABY); - - if (!Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE) && player != NULL && !Player_InBlockingCsMode(play, player)) { - GiveItemEntryWithoutActor(play, getItemEntry); - player->pendingFlag.flagType = FLAG_EVENT_CHECK_INF; - player->pendingFlag.flagID = 0xC1; - } - } -} - void Play_Init(GameState* thisx) { PlayState* play = (PlayState*)thisx; GraphicsContext* gfxCtx = play->state.gfxCtx; @@ -1448,15 +1331,6 @@ skip: Environment_Update(play, &play->envCtx, &play->lightCtx, &play->pauseCtx, &play->msgCtx, &play->gameOverCtx, play->state.gfxCtx); - - if (IS_RANDO) { - GivePlayerRandoRewardSariaGift(play, RC_LW_GIFT_FROM_SARIA); - GivePlayerRandoRewardSongOfTime(play, RC_SONG_FROM_OCARINA_OF_TIME); - GivePlayerRandoRewardZeldaLightArrowsGift(play, RC_TOT_LIGHT_ARROWS_CUTSCENE); - GivePlayerRandoRewardNocturne(play, RC_SHEIK_IN_KAKARIKO); - GivePlayerRandoRewardRequiem(play, RC_SHEIK_AT_COLOSSUS); - GivePlayerRandoRewardMasterSword(play, RC_TOT_MASTER_SWORD); - } } void Play_DrawOverlayElements(PlayState* play) { diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c index dfffa7729..1f136674b 100644 --- a/soh/src/code/z_player_lib.c +++ b/soh/src/code/z_player_lib.c @@ -564,8 +564,8 @@ uint8_t Player_IsCustomLinkModel() { } s32 Player_InBlockingCsMode(PlayState* play, Player* this) { - return (this->stateFlags1 & 0x20000080) || (this->csAction != 0) || (play->transitionTrigger == TRANS_TRIGGER_START) || - (this->stateFlags1 & 1) || (this->stateFlags3 & 0x80) || + return (this->stateFlags1 & (PLAYER_STATE1_DEAD | PLAYER_STATE1_IN_CUTSCENE)) || (this->csAction != 0) || (play->transitionTrigger == TRANS_TRIGGER_START) || + (this->stateFlags1 & PLAYER_STATE1_LOADING) || (this->stateFlags3 & PLAYER_STATE3_HOOKSHOT_TRAVELLING) || ((gSaveContext.magicState != MAGIC_STATE_IDLE) && (Player_ActionToMagicSpell(this, this->itemAction) >= 0)); } -- cgit v1.2.3