Migrate rainbow bridge

This commit is contained in:
Garrett Cox 2024-04-18 21:13:40 -05:00
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, GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER,
// Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP // 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_PRELUDE_OF_LIGHT,
GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE,
/* Vanilla Condition: /* Vanilla Condition:
``` ```
LINK_IS_ADULT && LINK_IS_ADULT &&
@ -255,6 +256,7 @@ typedef enum {
GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE, GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE,
// Opt: *EnOkarinaTag // Opt: *EnOkarinaTag
GI_VB_PLAY_DOOR_OF_TIME_CS, GI_VB_PLAY_DOOR_OF_TIME_CS,
GI_VB_PLAY_RAINBOW_BRIDGE_CS,
/*** Give Items ***/ /*** Give Items ***/

View file

@ -116,6 +116,59 @@ bool CompletedAllTrials() {
Flags_GetEventChkInf(EVENTCHKINF_COMPLETED_FOREST_TRIAL); 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 // Todo Move this to randomizer context, clear it out on save load etc
static std::queue<RandomizerCheck> randomizerQueuedChecks; static std::queue<RandomizerCheck> randomizerQueuedChecks;
static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK; static RandomizerCheck randomizerQueuedCheck = RC_UNKNOWN_CHECK;
@ -996,6 +1049,10 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void
*should = false; *should = false;
break; break;
} }
case GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE: {
*should = MeetsRainbowBridgeRequirements();
break;
}
case GI_VB_TRADE_TIMER_ODD_MUSHROOM: case GI_VB_TRADE_TIMER_ODD_MUSHROOM:
case GI_VB_TRADE_TIMER_EYEDROPS: case GI_VB_TRADE_TIMER_EYEDROPS:
case GI_VB_TRADE_TIMER_FROG: case GI_VB_TRADE_TIMER_FROG:

View file

@ -666,6 +666,13 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void*
break; 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 "z_bg_gjyo_bridge.h"
#include "objects/object_gjyo_objects/object_gjyo_objects.h" #include "objects/object_gjyo_objects/object_gjyo_objects.h"
#include "scenes/dungeons/ganon_tou/ganon_tou_scene.h" #include "scenes/dungeons/ganon_tou/ganon_tou_scene.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS 0 #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); 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)) {
if (Flags_GetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT) || (IS_RANDO && bridge == RO_BRIDGE_ALWAYS_OPEN)) {
this->actionFunc = func_808787A4; this->actionFunc = func_808787A4;
} else { } else {
this->dyna.actor.draw = NULL; this->dyna.actor.draw = NULL;
@ -70,8 +70,10 @@ void func_808787A4(BgGjyoBridge* this, PlayState* play) {
} }
void LaunchBridgeCutscene(BgGjyoBridge* this, PlayState* play) { void LaunchBridgeCutscene(BgGjyoBridge* this, PlayState* play) {
play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs); if (GameInteractor_Should(GI_VB_PLAY_RAINBOW_BRIDGE_CS, true, NULL)) {
gSaveContext.cutsceneTrigger = 1; play->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs);
gSaveContext.cutsceneTrigger = 1;
}
this->actionFunc = BgGjyoBridge_SpawnBridge; this->actionFunc = BgGjyoBridge_SpawnBridge;
} }
@ -84,70 +86,24 @@ u8 CheckPlayerPosition(Player* player, PlayState* play) {
void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, PlayState* play) { void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, PlayState* play) {
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if (!IS_RANDO) { u8 vanillaBridgeCondition =
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) &&
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) && CheckPlayerPosition(player, play)) { CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
LaunchBridgeCutscene(this, play); (INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) &&
} CheckPlayerPosition(player, 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);
switch (bridge) { if (GameInteractor_Should(GI_VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE, vanillaBridgeCondition, NULL)) {
case RO_BRIDGE_VANILLA: LaunchBridgeCutscene(this, play);
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;
}
} }
} }
void BgGjyoBridge_SpawnBridge(BgGjyoBridge* this, PlayState* play) { void BgGjyoBridge_SpawnBridge(BgGjyoBridge* this, PlayState* play) {
if (IS_RANDO || (play->csCtx.state != CS_STATE_IDLE) && (play->csCtx.npcActions[2] != NULL) && u8 vanillaBridgeCondition =
(play->csCtx.npcActions[2]->action == 2)) { (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; this->dyna.actor.draw = BgGjyoBridge_Draw;
func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId); func_8003EC50(play, &play->colCtx.dyna, this->dyna.bgId);
Flags_SetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT); Flags_SetEventChkInf(EVENTCHKINF_RAINBOW_BRIDGE_BUILT);