Migrate rainbow bridge

This commit is contained in:
Garrett Cox 2024-04-18 21:13:40 -05:00
parent edf6d9334a
commit 1683617210
4 changed files with 85 additions and 63 deletions

View File

@ -113,6 +113,7 @@ typedef enum {
GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER,
// Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP
GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT,
GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE,
/* Vanilla Condition:
```
LINK_IS_ADULT &&
@ -255,6 +256,7 @@ typedef enum {
GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE,
// Opt: *EnOkarinaTag
GI_VB_PLAY_DOOR_OF_TIME_CS,
GI_VB_PLAY_RAINBOW_BRIDGE_CS,
/*** Give Items ***/

View File

@ -116,6 +116,59 @@ bool CompletedAllTrials() {
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL);
}
bool MeetsRainbowBridgeRequirements() {
switch (RAND_GET_OPTION(RSK_RAINBOW_BRIDGE)) {
case RO_BRIDGE_VANILLA: {
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT)) {
return true;
}
break;
}
case RO_BRIDGE_STONES: {
if ((CheckStoneCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_STONE_COUNT)) {
return true;
}
break;
}
case RO_BRIDGE_MEDALLIONS: {
if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT)) {
return true;
}
break;
}
case RO_BRIDGE_DUNGEON_REWARDS: {
if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_REWARD_COUNT)) {
return true;
}
break;
}
case RO_BRIDGE_DUNGEONS: {
if ((CheckDungeonCount() + CheckBridgeRewardCount()) >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT)) {
return true;
}
break;
}
case RO_BRIDGE_TOKENS: {
if (gSaveContext.inventory.gsTokens >= RAND_GET_OPTION(RSK_RAINBOW_BRIDGE_TOKEN_COUNT)) {
return true;
}
break;
}
case RO_BRIDGE_GREG: {
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
return true;
}
break;
}
case RO_BRIDGE_ALWAYS_OPEN: {
return true;
}
}
return false;
}
// Todo Move this to randomizer context, clear it out on save load etc
static std::queue<RandomizerCheck> randomizerQueuedChecks;
static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK;
@ -996,6 +1049,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
*should = false;
break;
}
case GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE: {
*should = MeetsRainbowBridgeRequirements();
break;
}
case GI_VB_TRADE_TIMER_ODD_MUSHROOM:
case GI_VB_TRADE_TIMER_EYEDROPS:
case GI_VB_TRADE_TIMER_FROG:

View File

@ -666,6 +666,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void*
break;
}
case GI_VB_PLAY_RAINBOW_BRIDGE_CS: {
if (CVarGetInteger("gTimeSavers.SkipCutscene.Story", IS_RANDO)) {
*should = false;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
}
}
}

View File

@ -7,6 +7,7 @@
#include "z_bg_gjyo_bridge.h"
#include "objects/object_gjyo_objects/object_gjyo_objects.h"
#include "scenes/dungeons/ganon_tou/ganon_tou_scene.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS 0
@ -50,8 +51,7 @@ void BgGjyoBridge_Init(Actor* thisx, PlayState* play) {
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, thisx, colHeader);
int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE);
if (Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT) || (IS_RANDO && bridge == RO_BRIDGE_ALWAYS_OPEN)) {
if (Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT)) {
this->actionFunc = func_808787A4;
} else {
this->dyna.actor.draw = NULL;
@ -70,8 +70,10 @@ void func_808787A4(BgGjyoBridge* this, PlayState* play) {
}
void LaunchBridgeCutscene(BgGjyoBridge* this, PlayState* play) {
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs);
gSaveContext.cutsceneTrigger = 1;
if (GameInteractor_Should(GI_VB_PLAY_RAINBOW_BRIDGE_CS, true, NULL)) {
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs);
gSaveContext.cutsceneTrigger = 1;
}
this->actionFunc = BgGjyoBridge_SpawnBridge;
}
@ -84,70 +86,24 @@ u8 CheckPlayerPosition(Player* player, PlayState* play) {
void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (!IS_RANDO) {
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) && CheckPlayerPosition(player, play)) {
LaunchBridgeCutscene(this, play);
}
} else {
int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE);
int bridgeStoneCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_STONE_COUNT);
int bridgeMedallionCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT);
int bridgeRewardCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_REWARD_COUNT);
int bridgeDungeonCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT);
int bridgeTokenCount = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE_TOKEN_COUNT);
u8 vanillaBridgeCondition =
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) &&
CheckPlayerPosition(player, play);
switch (bridge) {
case RO_BRIDGE_VANILLA:
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT)) {
this->actionFunc = BgGjyoBridge_SpawnBridge;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
case RO_BRIDGE_STONES:
if ((CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeStoneCount) {
this->actionFunc = BgGjyoBridge_SpawnBridge;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
case RO_BRIDGE_MEDALLIONS:
if ((CheckMedallionCount() + CheckBridgeRewardCount()) >= bridgeMedallionCount) {
this->actionFunc = BgGjyoBridge_SpawnBridge;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
case RO_BRIDGE_DUNGEON_REWARDS:
if ((CheckMedallionCount() + CheckStoneCount() + CheckBridgeRewardCount()) >= bridgeRewardCount) {
this->actionFunc = BgGjyoBridge_SpawnBridge;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
case RO_BRIDGE_DUNGEONS:
if ((CheckDungeonCount() + CheckBridgeRewardCount()) >= bridgeDungeonCount) {
this->actionFunc = BgGjyoBridge_SpawnBridge;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
case RO_BRIDGE_TOKENS:
if (gSaveContext.inventory.gsTokens >= bridgeTokenCount) {
this->actionFunc = BgGjyoBridge_SpawnBridge;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
case RO_BRIDGE_GREG:
if (Flags_GetRandomizerInf(RAND_INF_GREG_FOUND)) {
this->actionFunc = BgGjyoBridge_SpawnBridge;
func_800F595C(NA_BGM_BRIDGE_TO_GANONS);
}
break;
}
if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE, vanillaBridgeCondition, NULL)) {
LaunchBridgeCutscene(this, play);
}
}
void BgGjyoBridge_SpawnBridge(BgGjyoBridge* this, PlayState* play) {
if (IS_RANDO || (play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.npcActions[2] != NULL) &&
(play->csCtx.npcActions[2]->action == 2)) {
u8 vanillaBridgeCondition =
(play->csCtx.state != CS_STATE_IDLE) &&
(play->csCtx.npcActions[2] != NULL) &&
(play->csCtx.npcActions[2]->action == 2);
if (!GameInteractor_Should(GI_VB_PLAY_RAINBOW_BRIDGE_CS, true, NULL) || vanillaBridgeCondition) {
this->dyna.actor.draw = BgGjyoBridge_Draw;
func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId);
Flags_SetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT);