mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-08-13 17:03:47 -04:00
d45968270a
* prefix randomizer methods with Randomizer_ * make filename a local var * remove unused file, update malon to use new names * move randomizertypes to randomizer directory * rename to Randomizer_GetSettingValue Co-authored-by: briaguya <briaguya@alice>
261 lines
8.2 KiB
C
261 lines
8.2 KiB
C
/*
|
|
* File: z_bg_gjyo_bridge.c
|
|
* Overlay: ovl_Bg_Gjyo_Bridge
|
|
* Description: Rainbow Bridge outside Ganon's Castle
|
|
*/
|
|
|
|
#include "z_bg_gjyo_bridge.h"
|
|
#include "objects/object_gjyo_objects/object_gjyo_objects.h"
|
|
#include "scenes/dungeons/ganon_tou/ganon_tou_scene.h"
|
|
|
|
#define FLAGS 0
|
|
|
|
void BgGjyoBridge_Init(Actor* thisx, GlobalContext* globalCtx);
|
|
void BgGjyoBridge_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|
void BgGjyoBridge_Update(Actor* thisx, GlobalContext* globalCtx);
|
|
void BgGjyoBridge_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void func_808787A4(BgGjyoBridge* this, GlobalContext* globalCtx);
|
|
void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, GlobalContext* globalCtx);
|
|
void BgGjyoBridge_SpawnBridge(BgGjyoBridge* this, GlobalContext* globalCtx);
|
|
|
|
const ActorInit Bg_Gjyo_Bridge_InitVars = {
|
|
ACTOR_BG_GJYO_BRIDGE,
|
|
ACTORCAT_PROP,
|
|
FLAGS,
|
|
OBJECT_GJYO_OBJECTS,
|
|
sizeof(BgGjyoBridge),
|
|
(ActorFunc)BgGjyoBridge_Init,
|
|
(ActorFunc)BgGjyoBridge_Destroy,
|
|
(ActorFunc)BgGjyoBridge_Update,
|
|
(ActorFunc)BgGjyoBridge_Draw,
|
|
NULL,
|
|
};
|
|
|
|
static InitChainEntry sInitChain[] = {
|
|
ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE),
|
|
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
|
|
};
|
|
|
|
void BgGjyoBridge_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgGjyoBridge* this = (BgGjyoBridge*)thisx;
|
|
s32 pad;
|
|
CollisionHeader* colHeader;
|
|
|
|
colHeader = NULL;
|
|
|
|
Actor_ProcessInitChain(thisx, sInitChain);
|
|
DynaPolyActor_Init(&this->dyna, DPM_UNK);
|
|
CollisionHeader_GetVirtual(&gRainbowBridgeCol, &colHeader);
|
|
|
|
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, thisx, colHeader);
|
|
|
|
int bridge = Randomizer_GetSettingValue(RSK_RAINBOW_BRIDGE);
|
|
if (gSaveContext.eventChkInf[4] & 0x2000 || (gSaveContext.n64ddFlag && bridge == 0)) {
|
|
this->actionFunc = func_808787A4;
|
|
} else {
|
|
this->dyna.actor.draw = NULL;
|
|
func_8003EBF8(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
|
this->actionFunc = BgGjyoBridge_TriggerCutscene;
|
|
}
|
|
}
|
|
|
|
void BgGjyoBridge_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgGjyoBridge* this = (BgGjyoBridge*)thisx;
|
|
|
|
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
|
}
|
|
|
|
void func_808787A4(BgGjyoBridge* this, GlobalContext* globalCtx) {
|
|
}
|
|
|
|
void LaunchBridgeCutscene(BgGjyoBridge* this, GlobalContext* globalCtx) {
|
|
globalCtx->csCtx.segment = SEGMENTED_TO_VIRTUAL(gRainbowBridgeCs);
|
|
gSaveContext.cutsceneTrigger = 1;
|
|
this->actionFunc = BgGjyoBridge_SpawnBridge;
|
|
}
|
|
|
|
u8 CheckPlayerPosition(Player* player, GlobalContext* globalCtx) {
|
|
return (player->actor.world.pos.x > -70.0f) && (player->actor.world.pos.x < 300.0f) &&
|
|
(player->actor.world.pos.y > 1340.0f) && (player->actor.world.pos.z > 1340.0f) &&
|
|
(player->actor.world.pos.z < 1662.0f) && !Gameplay_InCsMode(globalCtx);
|
|
}
|
|
|
|
u8 CheckStoneCount() {
|
|
u8 stoneCount = 0;
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)) {
|
|
stoneCount++;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_GORON_RUBY)) {
|
|
stoneCount++;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)) {
|
|
stoneCount++;
|
|
}
|
|
|
|
return stoneCount;
|
|
}
|
|
|
|
u8 CheckMedallionCount() {
|
|
u8 medallionCount = 0;
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)) {
|
|
medallionCount++;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)) {
|
|
medallionCount++;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) {
|
|
medallionCount++;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW)) {
|
|
medallionCount++;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT)) {
|
|
medallionCount++;
|
|
}
|
|
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_LIGHT)) {
|
|
medallionCount++;
|
|
}
|
|
|
|
return medallionCount;
|
|
}
|
|
|
|
u8 CheckDungeonCount() {
|
|
u8 dungeonCount = 0;
|
|
|
|
if (gSaveContext.dungeonsDone[0] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
if (gSaveContext.dungeonsDone[1] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
if (gSaveContext.dungeonsDone[2] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
if (gSaveContext.dungeonsDone[3] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
if (gSaveContext.dungeonsDone[4] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
if (gSaveContext.dungeonsDone[5] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
if (gSaveContext.dungeonsDone[6] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
if (gSaveContext.dungeonsDone[7] == 1) {
|
|
dungeonCount++;
|
|
}
|
|
|
|
return dungeonCount;
|
|
}
|
|
|
|
void BgGjyoBridge_TriggerCutscene(BgGjyoBridge* this, GlobalContext* globalCtx) {
|
|
Player* player = GET_PLAYER(globalCtx);
|
|
|
|
if (!gSaveContext.n64ddFlag) {
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
|
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT) && CheckPlayerPosition(player, globalCtx)) {
|
|
LaunchBridgeCutscene(this, globalCtx);
|
|
}
|
|
} 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);
|
|
|
|
if (CheckPlayerPosition(player, globalCtx)) {
|
|
switch (bridge) {
|
|
case 1:
|
|
if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
|
|
(INV_CONTENT(ITEM_ARROW_LIGHT) == ITEM_ARROW_LIGHT)) {
|
|
LaunchBridgeCutscene(this, globalCtx);
|
|
}
|
|
break;
|
|
case 2:
|
|
if (CheckStoneCount() >= bridgeStoneCount) {
|
|
LaunchBridgeCutscene(this, globalCtx);
|
|
}
|
|
break;
|
|
case 3:
|
|
if (CheckMedallionCount() >= bridgeMedallionCount) {
|
|
LaunchBridgeCutscene(this, globalCtx);
|
|
}
|
|
break;
|
|
case 4:
|
|
if ((CheckMedallionCount() + CheckStoneCount()) >= bridgeRewardCount) {
|
|
LaunchBridgeCutscene(this, globalCtx);
|
|
}
|
|
break;
|
|
case 5:
|
|
if (CheckDungeonCount() >= bridgeDungeonCount) {
|
|
LaunchBridgeCutscene(this, globalCtx);
|
|
}
|
|
break;
|
|
case 6:
|
|
if (gSaveContext.inventory.gsTokens >= bridgeTokenCount) {
|
|
LaunchBridgeCutscene(this, globalCtx);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void BgGjyoBridge_SpawnBridge(BgGjyoBridge* this, GlobalContext* globalCtx) {
|
|
if ((globalCtx->csCtx.state != CS_STATE_IDLE) && (globalCtx->csCtx.npcActions[2] != NULL) &&
|
|
(globalCtx->csCtx.npcActions[2]->action == 2)) {
|
|
this->dyna.actor.draw = BgGjyoBridge_Draw;
|
|
func_8003EC50(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
|
gSaveContext.eventChkInf[4] |= 0x2000;
|
|
}
|
|
}
|
|
|
|
void BgGjyoBridge_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgGjyoBridge* this = (BgGjyoBridge*)thisx;
|
|
|
|
this->actionFunc(this, globalCtx);
|
|
}
|
|
|
|
void BgGjyoBridge_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgGjyoBridge* this = (BgGjyoBridge*)thisx;
|
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
|
|
|
func_80093D84(globalCtx->state.gfxCtx);
|
|
|
|
gSPSegment(POLY_XLU_DISP++, 8,
|
|
Gfx_TexScroll(globalCtx->state.gfxCtx, globalCtx->gameplayFrames & 127,
|
|
globalCtx->gameplayFrames * -3 & 127, 32, 32));
|
|
|
|
gSPSegment(POLY_XLU_DISP++, 9,
|
|
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -globalCtx->gameplayFrames & 127, 32, 32, 1, 0,
|
|
globalCtx->gameplayFrames & 127, 32, 32));
|
|
|
|
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
|
|
gSPDisplayList(POLY_XLU_DISP++, gRainbowBridgeDL);
|
|
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
|
}
|