mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-04 15:22:26 -05:00
Merge branch 'develop' of garrettjoecox.github.com:HarbourMasters/Shipwright into let-it-snow
This commit is contained in:
commit
2ee5e5c428
12
soh/include/attributes.h
Normal file
12
soh/include/attributes.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef ATTRIBUTES_H
|
||||
#define ATTRIBUTES_H
|
||||
|
||||
#if !defined(__GNUC__) && !defined(__attribute__)
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#define UNUSED __attribute__((unused))
|
||||
#define FALLTHROUGH __attribute__((fallthrough))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
|
||||
#endif
|
@ -980,9 +980,9 @@ f32 Math_SmoothStepToDegF(f32* pValue, f32 target, f32 fraction, f32 step, f32 m
|
||||
s16 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep);
|
||||
void Math_ApproachS(s16* pValue, s16 target, s16 scale, s16 step);
|
||||
void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src);
|
||||
void func_80078884(u16 sfxId);
|
||||
void func_800788CC(u16 sfxId);
|
||||
void func_80078914(Vec3f* arg0, u16 sfxId);
|
||||
void Sfx_PlaySfxCentered(u16 sfxId);
|
||||
void Sfx_PlaySfxCentered2(u16 sfxId);
|
||||
void Sfx_PlaySfxAtPos(Vec3f* arg0, u16 sfxId);
|
||||
s16 getHealthMeterXOffset();
|
||||
s16 getHealthMeterYOffset();
|
||||
void HealthMeter_Init(PlayState* play);
|
||||
@ -1419,18 +1419,6 @@ void ViMode_Init(ViMode* viMode);
|
||||
void ViMode_Destroy(ViMode* viMode);
|
||||
void ViMode_ConfigureFeatures(ViMode* viMode, s32 viFeatures);
|
||||
void ViMode_Update(ViMode* viMode, Input* input);
|
||||
void func_800ACE70(struct_801664F0* this);
|
||||
void func_800ACE90(struct_801664F0* this);
|
||||
void func_800ACE98(struct_801664F0* this, Gfx** gfxp);
|
||||
void VisMono_Init(VisMono* this);
|
||||
void VisMono_Destroy(VisMono* this);
|
||||
void VisMono_UpdateTexture(VisMono* this, u16* tex);
|
||||
Gfx* VisMono_DrawTexture(VisMono* this, Gfx* gfx);
|
||||
void VisMono_Draw(VisMono* this, Gfx** gfxp);
|
||||
void VisMono_DrawOld(VisMono* this);
|
||||
void func_800AD920(struct_80166500* this);
|
||||
void func_800AD950(struct_80166500* this);
|
||||
void func_800AD958(struct_80166500* this, Gfx** gfxp);
|
||||
void Skybox_Init(GameState* state, SkyboxContext* skyboxCtx, s16 skyboxId);
|
||||
Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z);
|
||||
void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z);
|
||||
@ -1536,9 +1524,9 @@ void KaleidoScopeCall_Init(PlayState* play);
|
||||
void KaleidoScopeCall_Destroy(PlayState* play);
|
||||
void KaleidoScopeCall_Update(PlayState* play);
|
||||
void KaleidoScopeCall_Draw(PlayState* play);
|
||||
void func_800BC490(PlayState* play, s16 point);
|
||||
s32 func_800BC56C(PlayState* play, s16 arg1);
|
||||
void func_800BC590(PlayState* play);
|
||||
void Play_SetViewpoint(PlayState* play, s16 viewpoint);
|
||||
s32 Play_CheckViewpoint(PlayState* play, s16 viewpoint);
|
||||
void Play_SetShopBrowsingViewpoint(PlayState* play);
|
||||
void Gameplay_SetupTransition(PlayState* play, s32 arg1);
|
||||
Gfx* Play_SetFog(PlayState* play, Gfx* gfx);
|
||||
void Play_Destroy(GameState* thisx);
|
||||
@ -1552,7 +1540,7 @@ u8 CheckLACSRewardCount();
|
||||
s32 Play_InCsMode(PlayState* play);
|
||||
f32 func_800BFCB8(PlayState* play, MtxF* mf, Vec3f* vec);
|
||||
void* Play_LoadFile(PlayState* play, RomFile* file);
|
||||
void Play_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn);
|
||||
void Play_SpawnScene(PlayState* play, s32 sceneId, s32 spawn);
|
||||
void func_800C016C(PlayState* play, Vec3f* src, Vec3f* dest);
|
||||
s16 Play_CreateSubCamera(PlayState* play);
|
||||
s16 Play_GetActiveCamId(PlayState* play);
|
||||
@ -2279,7 +2267,7 @@ void __osMallocInit(Arena* arena, void* start, size_t size);
|
||||
void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size);
|
||||
void ArenaImpl_RemoveAllBlocks(Arena* arena);
|
||||
void __osMallocCleanup(Arena* arena);
|
||||
u8 __osMallocIsInitalized(Arena* arena);
|
||||
s32 __osMallocIsInitialized(Arena* arena);
|
||||
void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node);
|
||||
void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, s32 line);
|
||||
void* __osMallocDebug(Arena* arena, size_t size, const char* file, s32 line);
|
||||
@ -2296,7 +2284,7 @@ void* __osReallocDebug(Arena* arena, void* ptr, size_t newSize, const char* file
|
||||
void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc);
|
||||
void __osDisplayArena(Arena* arena);
|
||||
void ArenaImpl_FaultClient(Arena* arena);
|
||||
u32 __osCheckArena(Arena* arena);
|
||||
s32 __osCheckArena(Arena* arena);
|
||||
u8 func_800FF334(Arena* arena);
|
||||
s32 PrintUtils_VPrintf(PrintCallback* pfn, const char* fmt, va_list args);
|
||||
s32 PrintUtils_Printf(PrintCallback* pfn, const char* fmt, ...);
|
||||
@ -2420,7 +2408,7 @@ OSThread* __osGetCurrFaultedThread(void);
|
||||
u32* osViGetCurrentFramebuffer(void);
|
||||
s32 __osSpSetPc(void* pc);
|
||||
f32 absf(f32);
|
||||
void* func_801068B0(void* dst, void* src, size_t size);
|
||||
void* oot_memmove(void* dest, const void* src, size_t len);
|
||||
void Message_UpdateOcarinaGame(PlayState* play);
|
||||
u8 Message_ShouldAdvance(PlayState* play);
|
||||
u8 Message_ShouldAdvanceSilent(PlayState* play);
|
||||
|
9
soh/include/gfx.h
Normal file
9
soh/include/gfx.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef GFX_H
|
||||
#define GFX_H
|
||||
|
||||
// Texture memory size, 4 KiB
|
||||
#define TMEM_SIZE 0x1000
|
||||
|
||||
// Upstream TODO: Rest of this file
|
||||
|
||||
#endif
|
@ -299,6 +299,10 @@ extern GraphicsContext* __gfxCtx;
|
||||
#define BGCHECK_POS_ERROR_CHECK(vec3f) BgCheck_PosErrorCheck(vec3f, __FILE__, __LINE__)
|
||||
|
||||
#define SEG_ADDR(seg, addr) (addr | (seg << 24) | 1)
|
||||
|
||||
// Upstream TODO: Bring back decomp file/line macro use in src (but ignore the args for our needs)
|
||||
#define SYSTEM_ARENA_MALLOC(size, file, line) SystemArena_MallocDebug(size, __FILE__, __LINE__)
|
||||
#define SYSTEM_ARENA_FREE(ptr, file, line) SystemArena_FreeDebug(ptr, __FILE__, __LINE__)
|
||||
// #endregion
|
||||
|
||||
#define DPAD_ITEM(button) ((gSaveContext.buttonStatus[(button) + 5] != BTN_DISABLED) \
|
||||
|
@ -120,7 +120,7 @@ extern "C"
|
||||
extern KaleidoMgrOverlay gKaleidoMgrOverlayTable[KALEIDO_OVL_MAX];
|
||||
extern KaleidoMgrOverlay* gKaleidoMgrCurOvl;
|
||||
extern u8 gBossMarkState;
|
||||
extern void* D_8012D1F0;
|
||||
extern void* gDebugCutsceneScript;
|
||||
extern s32 gScreenWidth;
|
||||
extern s32 gScreenHeight;
|
||||
extern Mtx gMtxClear;
|
||||
@ -158,9 +158,9 @@ extern "C"
|
||||
extern char D_80133398[];
|
||||
extern SoundBankEntry* gSoundBanks[7];
|
||||
extern u8 gSfxChannelLayout;
|
||||
extern Vec3f D_801333D4;
|
||||
extern f32 D_801333E0;
|
||||
extern s8 D_801333E8;
|
||||
extern Vec3f gSfxDefaultPos;
|
||||
extern f32 gSfxDefaultFreqAndVolScale;
|
||||
extern s8 gSfxDefaultReverb;
|
||||
extern u8 D_801333F0;
|
||||
extern u8 gAudioSfxSwapOff;
|
||||
extern u8 D_80133408;
|
||||
@ -203,7 +203,7 @@ extern "C"
|
||||
extern f32 gBossMarkScale;
|
||||
extern PauseMapMarksData* gLoadedPauseMarkDataTable;
|
||||
extern s32 gTrnsnUnkState;
|
||||
extern Color_RGBA8_u32 D_801614B0;
|
||||
extern Color_RGBA8_u32 gVisMonoColor;
|
||||
extern PreNmiBuff* gAppNmiBufferPtr;
|
||||
extern SchedContext gSchedContext;
|
||||
extern PadMgr gPadMgr;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <libultraship/libultra.h>
|
||||
#include "unk.h" // this used to get pulled in via ultra64.h
|
||||
#include "attributes.h"
|
||||
#include "z64save.h"
|
||||
#include "z64light.h"
|
||||
#include "z64bgcheck.h"
|
||||
@ -24,12 +25,14 @@
|
||||
#include "z64skin.h"
|
||||
#include "z64transition.h"
|
||||
#include "z64interface.h"
|
||||
#include "z64vis.h"
|
||||
#include "alignment.h"
|
||||
#include "sequence.h"
|
||||
#include "sfx.h"
|
||||
#include <libultraship/color.h>
|
||||
#include "ichain.h"
|
||||
#include "regs.h"
|
||||
#include "gfx.h"
|
||||
|
||||
#if defined(__LP64__)
|
||||
#define _SOH64
|
||||
@ -2035,13 +2038,13 @@ typedef struct ArenaNode {
|
||||
/* 0x04 */ size_t size;
|
||||
/* 0x08 */ struct ArenaNode* next;
|
||||
/* 0x0C */ struct ArenaNode* prev;
|
||||
///* 0x10 */ const char* filename;
|
||||
///* 0x14 */ s32 line;
|
||||
///* 0x18 */ OSId threadId;
|
||||
///* 0x1C */ Arena* arena;
|
||||
///* 0x20 */ OSTime time;
|
||||
///* 0x28 */ u8 unk_28[0x30-0x28]; // probably padding
|
||||
} ArenaNode; // size = 0x10
|
||||
// /* 0x10 */ const char* filename;
|
||||
// /* 0x14 */ s32 line;
|
||||
// /* 0x18 */ OSId threadId;
|
||||
// /* 0x1C */ Arena* arena;
|
||||
// /* 0x20 */ OSTime time;
|
||||
// /* 0x28 */ u8 unk_28[0x30-0x28]; // probably padding
|
||||
} ArenaNode; // size = 0x30
|
||||
|
||||
typedef struct OverlayRelocationSection {
|
||||
/* 0x00 */ u32 textSize;
|
||||
@ -2224,31 +2227,6 @@ typedef struct {
|
||||
/* 0x0084 */ u32 unk_84;
|
||||
} ViMode;
|
||||
|
||||
// Vis...
|
||||
typedef struct {
|
||||
/* 0x00 */ u32 type;
|
||||
/* 0x04 */ u32 setScissor;
|
||||
/* 0x08 */ Color_RGBA8_u32 color;
|
||||
/* 0x0C */ Color_RGBA8_u32 envColor;
|
||||
} struct_801664F0; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ u32 unk_00;
|
||||
/* 0x04 */ u32 setScissor;
|
||||
/* 0x08 */ Color_RGBA8_u32 primColor;
|
||||
/* 0x0C */ Color_RGBA8_u32 envColor;
|
||||
/* 0x10 */ u16* tlut;
|
||||
/* 0x14 */ Gfx* monoDl;
|
||||
} VisMono; // size = 0x18
|
||||
|
||||
// Vis...
|
||||
typedef struct {
|
||||
/* 0x00 */ u32 useRgba;
|
||||
/* 0x04 */ u32 setScissor;
|
||||
/* 0x08 */ Color_RGBA8_u32 primColor;
|
||||
/* 0x08 */ Color_RGBA8_u32 envColor;
|
||||
} struct_80166500; // size = 0x10
|
||||
|
||||
typedef struct {
|
||||
/* 0x000 */ u8 rumbleEnable[4];
|
||||
/* 0x004 */ u8 unk_04[0x40];
|
||||
|
@ -361,7 +361,7 @@ typedef enum {
|
||||
/* 4 */ SCENE_LAYER_CUTSCENE_FIRST
|
||||
} SceneLayer;
|
||||
|
||||
#define IS_CUTSCENE_LAYER (gSaveContext.sceneLayer >= SCENE_LAYER_CUTSCENE_FIRST)
|
||||
#define IS_CUTSCENE_LAYER (gSaveContext.sceneSetupIndex >= SCENE_LAYER_CUTSCENE_FIRST)
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ LINK_AGE_ADULT,
|
||||
|
101
soh/include/z64vis.h
Normal file
101
soh/include/z64vis.h
Normal file
@ -0,0 +1,101 @@
|
||||
#ifndef Z64_VIS_H
|
||||
#define Z64_VIS_H
|
||||
|
||||
// #include "ultra64.h"
|
||||
// #include "color.h"
|
||||
#include <libultraship/libultra.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define this thisx
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef enum FramebufferFilterType {
|
||||
/* 0 */ FB_FILTER_NONE,
|
||||
/* 1 */ FB_FILTER_CVG_RGB,
|
||||
/* 2 */ FB_FILTER_CVG_RGB_UNIFORM,
|
||||
/* 3 */ FB_FILTER_CVG_ONLY,
|
||||
/* 4 */ FB_FILTER_CVG_RGB_FOG, // Not recommended, easily overflows blender
|
||||
/* 5 */ FB_FILTER_ZBUF_IA,
|
||||
/* 6 */ FB_FILTER_ZBUF_RGBA,
|
||||
/* 7 */ FB_FILTER_MONO
|
||||
} FramebufferFilterType;
|
||||
|
||||
typedef enum VisScissorType {
|
||||
/* 0 */ VIS_NO_SETSCISSOR,
|
||||
/* 1 */ VIS_SETSCISSOR
|
||||
} VisScissorType;
|
||||
|
||||
typedef struct Vis {
|
||||
/* 0x00 */ u32 type;
|
||||
/* 0x04 */ u32 scissorType;
|
||||
/* 0x08 */ Color_RGBA8_u32 primColor;
|
||||
/* 0x0C */ Color_RGBA8_u32 envColor;
|
||||
} Vis; // size = 0x10
|
||||
|
||||
|
||||
|
||||
/* Cvg: Coverage */
|
||||
|
||||
#define FB_FILTER_TO_CVG_TYPE(filter) (filter)
|
||||
|
||||
typedef enum VisCvgType {
|
||||
/* 0 */ VIS_CVG_TYPE_NONE = FB_FILTER_TO_CVG_TYPE(FB_FILTER_NONE),
|
||||
/* 1 */ VIS_CVG_TYPE_CVG_RGB = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB),
|
||||
/* 2 */ VIS_CVG_TYPE_CVG_RGB_UNIFORM = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB_UNIFORM),
|
||||
/* 3 */ VIS_CVG_TYPE_CVG_ONLY = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_ONLY),
|
||||
/* 4 */ VIS_CVG_TYPE_CVG_RGB_FOG = FB_FILTER_TO_CVG_TYPE(FB_FILTER_CVG_RGB_FOG)
|
||||
} VisCvgType;
|
||||
|
||||
typedef struct VisCvg {
|
||||
/* 0x00 */ Vis vis;
|
||||
} VisCvg; // size = 0x10
|
||||
|
||||
void VisCvg_Init(VisCvg* this);
|
||||
void VisCvg_Destroy(VisCvg* this);
|
||||
void VisCvg_Draw(VisCvg* this, Gfx** gfxP);
|
||||
|
||||
|
||||
|
||||
/* Mono: Desaturation */
|
||||
|
||||
// Only one type
|
||||
|
||||
typedef struct VisMono {
|
||||
/* 0x00 */ Vis vis;
|
||||
/* 0x10 */ u16* tlut;
|
||||
/* 0x14 */ Gfx* dList;
|
||||
} VisMono; // size = 0x18
|
||||
|
||||
void VisMono_Init(VisMono* this);
|
||||
void VisMono_Destroy(VisMono* this);
|
||||
void VisMono_Draw(VisMono* this, Gfx** gfxP);
|
||||
|
||||
|
||||
|
||||
/* ZBuf: Z-Buffer */
|
||||
|
||||
#define FB_FILTER_TO_ZBUF_TYPE(filter) ((filter) - FB_FILTER_ZBUF_IA)
|
||||
|
||||
typedef enum VisZBufType {
|
||||
/* 0 */ VIS_ZBUF_TYPE_IA = FB_FILTER_TO_ZBUF_TYPE(FB_FILTER_ZBUF_IA),
|
||||
/* 1 */ VIS_ZBUF_TYPE_RGBA = FB_FILTER_TO_ZBUF_TYPE(FB_FILTER_ZBUF_RGBA)
|
||||
} VisZBufType;
|
||||
|
||||
typedef struct VisZBuf {
|
||||
/* 0x00 */ Vis vis;
|
||||
} VisZBuf; // size = 0x10
|
||||
|
||||
void VisZBuf_Init(VisZBuf* this);
|
||||
void VisZBuf_Destroy(VisZBuf* this);
|
||||
void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#undef this
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -3,35 +3,43 @@
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
#include "variables.h"
|
||||
#include "macros.h"
|
||||
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
#include "variables.h"
|
||||
}
|
||||
|
||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex()
|
||||
|
||||
static bool sEnteredBlueWarp = false;
|
||||
|
||||
/**
|
||||
* This will override the transitions into the blue warp cutscenes, set any appropriate flags, and
|
||||
* set the entrance index to where you would normally end up after the blue warp cutscene. This
|
||||
* should also account for the difference between your first and following visits to the blue warp.
|
||||
*/
|
||||
void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
uint8_t isBlueWarpCutscene = 0;
|
||||
bool overrideBlueWarpDestinations =
|
||||
IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF ||
|
||||
RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF);
|
||||
|
||||
// Force blue warp skip on when ER needs to place Link somewhere else.
|
||||
// This is preferred over having story cutscenes play in the overworld and then reloading Link somewhere else after.
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO) || overrideBlueWarpDestinations) {
|
||||
bool isBlueWarpCutscene = false;
|
||||
// Deku Tree Blue warp
|
||||
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP;
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
// Dodongo's Cavern Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_BOTTOM_EXIT && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP;
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
// Jabu Jabu's Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP && gSaveContext.cutsceneIndex == 0xFFF0) {
|
||||
gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP;
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
// Forest Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) {
|
||||
// Normally set in the blue warp cutscene
|
||||
@ -43,14 +51,14 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
|
||||
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12;
|
||||
}
|
||||
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
// Fire Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_FRONT_GATE && gSaveContext.cutsceneIndex == 0xFFF3) {
|
||||
// Normally set in the blue warp cutscene
|
||||
Flags_SetEventChkInf(EVENTCHKINF_DEATH_MOUNTAIN_ERUPTED);
|
||||
|
||||
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
// Water Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) {
|
||||
// Normally set in the blue warp cutscene
|
||||
@ -58,15 +66,15 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
|
||||
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
|
||||
|
||||
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
// Spirit Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) {
|
||||
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
// Shadow Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) {
|
||||
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
|
||||
isBlueWarpCutscene = 1;
|
||||
isBlueWarpCutscene = true;
|
||||
}
|
||||
|
||||
if (isBlueWarpCutscene) {
|
||||
@ -80,10 +88,20 @@ void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, va_l
|
||||
}
|
||||
|
||||
// This is outside the above condition because we want to handle both first and following visits to the blue warp
|
||||
if (IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
|
||||
if (sEnteredBlueWarp && overrideBlueWarpDestinations) {
|
||||
Entrance_OverrideBlueWarp();
|
||||
}
|
||||
}
|
||||
|
||||
sEnteredBlueWarp = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Using this hook to simply observe that Link has entered a bluewarp
|
||||
* This way we know to allow entrance rando overrides to be processed on the next tranisition hook
|
||||
*/
|
||||
void SkipBlueWarp_ShouldPlayBlueWarpCS(GIVanillaBehavior _, bool* should, va_list originalArgs) {
|
||||
sEnteredBlueWarp = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,6 +161,7 @@ void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _,
|
||||
void SkipBlueWarp_Register() {
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_BLUE_WARP_CS, SkipBlueWarp_ShouldPlayBlueWarpCS);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_GIVE_ITEM_FROM_BLUE_WARP, SkipBlueWarp_ShouldGiveItem);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ void SkipDekuTreeIntro_Register() {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
BgTreemouth* treeMouth = va_arg(args, BgTreemouth*);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
BgTreemouth_SetupAction(treeMouth, func_808BC6F8);
|
||||
*should = false;
|
||||
}
|
||||
|
@ -21,7 +21,8 @@ void MoveMidoInKokiriForest_Register() {
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) &&
|
||||
(CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) &&
|
||||
(CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI)
|
||||
(CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI) &&
|
||||
gSaveContext.cutsceneIndex == 0
|
||||
) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
|
||||
*should = true;
|
||||
|
@ -1174,7 +1174,7 @@ void ActorViewerWindow::DrawElement() {
|
||||
Actor_Spawn(&gPlayState->actorCtx, gPlayState, newActor.id, newActor.pos.x, newActor.pos.y,
|
||||
newActor.pos.z, newActor.rot.x, newActor.rot.y, newActor.rot.z, newActor.params, 0);
|
||||
} else {
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,7 +1187,7 @@ void ActorViewerWindow::DrawElement() {
|
||||
newActor.pos.y, newActor.pos.z, newActor.rot.x, newActor.rot.y,
|
||||
newActor.rot.z, newActor.params);
|
||||
} else {
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <libultraship/bridge.h>
|
||||
#include <libultraship/libultraship.h>
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
|
||||
extern "C" {
|
||||
#include <z64.h>
|
||||
@ -276,11 +277,6 @@ void CreateSphereData() {
|
||||
sphereGfx.push_back(gsSPEndDisplayList());
|
||||
}
|
||||
|
||||
void ColViewerWindow::InitElement() {
|
||||
CreateCylinderData();
|
||||
CreateSphereData();
|
||||
}
|
||||
|
||||
// Initializes the display list for a ColRenderSetting
|
||||
void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
|
||||
uint32_t rm;
|
||||
@ -689,3 +685,10 @@ extern "C" void DrawColViewer() {
|
||||
|
||||
CLOSE_DISPS(gPlayState->state.gfxCtx);
|
||||
}
|
||||
|
||||
void ColViewerWindow::InitElement() {
|
||||
CreateCylinderData();
|
||||
CreateSphereData();
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayDrawEnd>(DrawColViewer);
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ typedef enum {
|
||||
VB_MIDO_SPAWN,
|
||||
// Opt: *EnMd
|
||||
// Vanilla condition: EnMd->interactInfo.talkState == NPC_TALK_STATE_ACTION
|
||||
// Note: When overriding this, ensure you're not in the intro cutscene as Mido's path has not been loaded
|
||||
VB_MOVE_MIDO_IN_KOKIRI_FOREST,
|
||||
// Opt: *EnMd
|
||||
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
|
||||
@ -341,6 +342,7 @@ typedef enum {
|
||||
VB_SHOULD_GIVE_VANILLA_FISHING_PRIZE,
|
||||
VB_GIVE_RANDO_FISHING_PRIZE,
|
||||
VB_PLAY_THROW_ANIMATION,
|
||||
VB_INFLICT_VOID_DAMAGE,
|
||||
VB_GANONDORF_DECIDE_TO_FIGHT,
|
||||
|
||||
/*** Give Items ***/
|
||||
|
@ -341,7 +341,7 @@ void GameInteractor::RawAction::UpdateActor(void* refActor) {
|
||||
}
|
||||
|
||||
void GameInteractor::RawAction::TeleportPlayer(int32_t nextEntrance) {
|
||||
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
gPlayState->nextEntranceIndex = nextEntrance;
|
||||
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||
gPlayState->transitionType = TRANS_TYPE_FADE_BLACK;
|
||||
|
@ -215,12 +215,12 @@ namespace Rando {
|
||||
} else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_LEFT) {
|
||||
if ((pauseCtx->stickRelX > 30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DRIGHT))) {
|
||||
pauseCtx->cursorSpecialPos = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else if (pauseCtx->cursorSpecialPos == PAUSE_CURSOR_PAGE_RIGHT) {
|
||||
if ((pauseCtx->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) {
|
||||
pauseCtx->cursorSpecialPos = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -230,7 +230,7 @@ namespace Rando {
|
||||
if (shouldScroll) {
|
||||
entry->SetYOffset(yOffset);
|
||||
yOffset += 18;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
Matrix_Push();
|
||||
entry->Draw(play, &mEntryDl);
|
||||
|
@ -66,15 +66,6 @@ static const ALIGN_ASSET(2) char tokinoma_room_0DL_007A70[] = dtokinoma_room_0DL
|
||||
#define dtokinoma_room_0DL_007FD0 "__OTR__scenes/shared/tokinoma_scene/tokinoma_room_0DL_007FD0"
|
||||
static const ALIGN_ASSET(2) char tokinoma_room_0DL_007FD0[] = dtokinoma_room_0DL_007FD0;
|
||||
|
||||
// TODO: When there's more uses of something like this, create a new GI::RawAction?
|
||||
void ReloadSceneTogglingLinkAge() {
|
||||
gPlayState->nextEntranceIndex = gSaveContext.entranceIndex;
|
||||
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||
gPlayState->transitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST); // Fade Out
|
||||
gSaveContext.nextTransitionType = TRANS_TYPE_CIRCLE(TCA_WAVE, TCC_WHITE, TCS_FAST);
|
||||
gPlayState->linkAgeOnLoad ^= 1; // toggle linkAgeOnLoad
|
||||
}
|
||||
|
||||
void RegisterInfiniteMoney() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
|
||||
if (!GameInteractor::IsSaveLoaded(true)) return;
|
||||
@ -221,42 +212,43 @@ void RegisterFreezeTime() {
|
||||
}
|
||||
|
||||
/// Switches Link's age and respawns him at the last entrance he entered.
|
||||
void RegisterSwitchAge() {
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
|
||||
static bool warped = false;
|
||||
void SwitchAge() {
|
||||
if (gPlayState == NULL) return;
|
||||
|
||||
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||
CVarClear(CVAR_GENERAL("SwitchAge"));
|
||||
warped = false;
|
||||
return;
|
||||
Player* player = GET_PLAYER(gPlayState);
|
||||
|
||||
// Hyrule Castle: Very likely to fall through floor, so we force a specific entrance
|
||||
if (gPlayState->sceneNum == SCENE_HYRULE_CASTLE || gPlayState->sceneNum == SCENE_OUTSIDE_GANONS_CASTLE) {
|
||||
gPlayState->nextEntranceIndex = ENTR_CASTLE_GROUNDS_SOUTH_EXIT;
|
||||
} else {
|
||||
gSaveContext.respawnFlag = 1;
|
||||
gPlayState->nextEntranceIndex = gSaveContext.entranceIndex;
|
||||
|
||||
// Preserve the player's position and orientation
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].entranceIndex = gPlayState->nextEntranceIndex;
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex = gPlayState->roomCtx.curRoom.num;
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = player->actor.world.pos;
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = player->actor.shape.rot.y;
|
||||
|
||||
if (gPlayState->roomCtx.curRoom.behaviorType2 < 4) {
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0DFF;
|
||||
} else {
|
||||
// Scenes with static backgrounds use a special camera we need to preserve
|
||||
Camera* camera = GET_ACTIVE_CAM(gPlayState);
|
||||
s16 camId = camera->camDataIdx;
|
||||
gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = 0x0D00 | camId;
|
||||
}
|
||||
}
|
||||
|
||||
static Vec3f playerPos;
|
||||
static int16_t playerYaw;
|
||||
static RoomContext* roomCtx;
|
||||
static s32 roomNum;
|
||||
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
|
||||
gPlayState->transitionType = TRANS_TYPE_INSTANT;
|
||||
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST;
|
||||
gPlayState->linkAgeOnLoad ^= 1;
|
||||
|
||||
if (CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) && !warped) {
|
||||
playerPos = GET_PLAYER(gPlayState)->actor.world.pos;
|
||||
playerYaw = GET_PLAYER(gPlayState)->actor.shape.rot.y;
|
||||
roomCtx = &gPlayState->roomCtx;
|
||||
roomNum = roomCtx->curRoom.num;
|
||||
ReloadSceneTogglingLinkAge();
|
||||
warped = true;
|
||||
}
|
||||
|
||||
if (warped && gPlayState->transitionTrigger != TRANS_TRIGGER_START &&
|
||||
gSaveContext.nextTransitionType == TRANS_NEXT_TYPE_DEFAULT) {
|
||||
GET_PLAYER(gPlayState)->actor.shape.rot.y = playerYaw;
|
||||
GET_PLAYER(gPlayState)->actor.world.pos = playerPos;
|
||||
if (roomNum != roomCtx->curRoom.num) {
|
||||
func_8009728C(gPlayState, roomCtx, roomNum); //load original room
|
||||
//func_800973FC(gPlayState, &gPlayState->roomCtx); // commit to room load?
|
||||
func_80097534(gPlayState, roomCtx); // load map for new room (unloading the previous room)
|
||||
}
|
||||
warped = false;
|
||||
CVarClear(CVAR_GENERAL("SwitchAge"));
|
||||
}
|
||||
static HOOK_ID hookId = 0;
|
||||
hookId = REGISTER_VB_SHOULD(VB_INFLICT_VOID_DAMAGE, {
|
||||
*should = false;
|
||||
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnVanillaBehavior>(hookId);
|
||||
});
|
||||
}
|
||||
|
||||
@ -264,8 +256,7 @@ void RegisterSwitchAge() {
|
||||
void RegisterOcarinaTimeTravel() {
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnOcarinaSongAction>([]() {
|
||||
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||
CVarClear(CVAR_ENHANCEMENT("TimeTravel"));
|
||||
if (!GameInteractor::IsSaveLoaded(true) || !CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -275,22 +266,14 @@ void RegisterOcarinaTimeTravel() {
|
||||
Actor* nearbyOcarinaSpot = Actor_FindNearby(gPlayState, player, ACTOR_EN_OKARINA_TAG, ACTORCAT_PROP, 120.0f);
|
||||
Actor* nearbyDoorOfTime = Actor_FindNearby(gPlayState, player, ACTOR_DOOR_TOKI, ACTORCAT_BG, 500.0f);
|
||||
Actor* nearbyFrogs = Actor_FindNearby(gPlayState, player, ACTOR_EN_FR, ACTORCAT_NPC, 300.0f);
|
||||
uint8_t hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
|
||||
uint8_t hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
|
||||
// If TimeTravel + Player have the Ocarina of Time + Have Master Sword + is in proper range
|
||||
bool justPlayedSoT = gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME;
|
||||
bool notNearAnySource = !nearbyTimeBlockEmpty && !nearbyTimeBlock && !nearbyOcarinaSpot && !nearbyDoorOfTime && !nearbyFrogs;
|
||||
bool hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
|
||||
bool doesntNeedOcarinaOfTime = CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2;
|
||||
bool hasMasterSword = CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER);
|
||||
// TODO: Once Swordless Adult is fixed: Remove the Master Sword check
|
||||
if (((CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 1 && hasOcarinaOfTime) || CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2) && hasMasterSword &&
|
||||
gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock &&
|
||||
!nearbyOcarinaSpot && !nearbyFrogs) {
|
||||
|
||||
if (IS_RANDO) {
|
||||
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1);
|
||||
} else if (!IS_RANDO && !nearbyDoorOfTime) {
|
||||
// This check is made for when Link is learning the Song Of Time in a vanilla save file that load a
|
||||
// Temple of Time scene where the only object present is the Door of Time
|
||||
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1);
|
||||
}
|
||||
ReloadSceneTogglingLinkAge();
|
||||
if (justPlayedSoT && notNearAnySource && (hasOcarinaOfTime || doesntNeedOcarinaOfTime) && hasMasterSword) {
|
||||
SwitchAge();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1087,7 +1070,7 @@ void RegisterAltTrapTypes() {
|
||||
eventTimer = 3;
|
||||
break;
|
||||
case ADD_SPEED_TRAP:
|
||||
Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
GameInteractor::State::RunSpeedModifier = -2;
|
||||
statusTimer = 200;
|
||||
Overlay_DisplayText(10, "Speed Decreased!");
|
||||
@ -1096,7 +1079,7 @@ void RegisterAltTrapTypes() {
|
||||
eventTimer = 3;
|
||||
break;
|
||||
case ADD_VOID_TRAP:
|
||||
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
eventTimer = 3;
|
||||
break;
|
||||
case ADD_AMMO_TRAP:
|
||||
@ -1136,7 +1119,7 @@ void RegisterAltTrapTypes() {
|
||||
AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5;
|
||||
AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5;
|
||||
AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5;
|
||||
Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
break;
|
||||
case ADD_TELEPORT_TRAP: {
|
||||
int entrance;
|
||||
@ -1431,7 +1414,6 @@ void InitMods() {
|
||||
RegisterEzQPA();
|
||||
RegisterUnrestrictedItems();
|
||||
RegisterFreezeTime();
|
||||
RegisterSwitchAge();
|
||||
RegisterOcarinaTimeTravel();
|
||||
RegisterAutoSave();
|
||||
RegisterDaytimeGoldSkultullas();
|
||||
|
@ -17,6 +17,7 @@ void UpdateHyperEnemiesState();
|
||||
void UpdateHyperBossesState();
|
||||
void InitMods();
|
||||
void UpdatePatchHand();
|
||||
void SwitchAge();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te
|
||||
processedText.erase(std::remove_if(processedText.begin(), processedText.end(), [](const char& c) {
|
||||
// 172 is max supported texture for the in-game font system,
|
||||
// and filter anything less than a space but not the newline or nul characters
|
||||
return c > (s8)172 || (c < ' ' && c != '\n' && c != '\0');
|
||||
return (unsigned char)c > 172 || (c < ' ' && c != '\n' && c != '\0');
|
||||
}), processedText.end());
|
||||
|
||||
int16_t numChar = processedText.length();
|
||||
|
@ -353,8 +353,6 @@ const std::vector<const char*> cheatCvars = {
|
||||
CVAR_DEVELOPER_TOOLS("SaveFileID"),
|
||||
CVAR_CHEAT("EnableBetaQuest"),
|
||||
CVAR_DEVELOPER_TOOLS("BetterDebugWarpScreen"),
|
||||
CVAR_GENERAL("SwitchAge"),
|
||||
CVAR_GENERAL("SwitchTimeline"),
|
||||
CVAR_CHEAT("NoRedeadFreeze"),
|
||||
CVAR_CHEAT("NoKeeseGuayTarget"),
|
||||
CVAR_CHEAT("BombTimerMultiplier"),
|
||||
|
@ -211,6 +211,14 @@ bool Here(const RandomizerRegion region, ConditionFn condition) {
|
||||
return areaTable[region].Here(condition);
|
||||
}
|
||||
|
||||
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||
return areaTable[region].MQSpiritShared(condition, false, anyAge);
|
||||
}
|
||||
|
||||
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge) {
|
||||
return areaTable[region].MQSpiritShared(condition, true, anyAge);
|
||||
}
|
||||
|
||||
bool CanPlantBean(const RandomizerRegion region) {
|
||||
return areaTable[region].CanPlantBeanCheck();
|
||||
}
|
||||
@ -256,7 +264,7 @@ void RegionTable_Init() {
|
||||
LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_ROOT_EXITS, {[]{return true;}})
|
||||
Entrance(RR_ROOT_EXITS, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_ROOT_EXITS] = Region("Root Exits", "", {RA_LINKS_POCKET}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
|
@ -18,54 +18,54 @@ extern std::shared_ptr<Rando::Logic> logic;
|
||||
class EventAccess {
|
||||
public:
|
||||
|
||||
explicit EventAccess(bool* event_, std::vector<ConditionFn> conditions_met_)
|
||||
: event(event_) {
|
||||
conditions_met.resize(2);
|
||||
for (size_t i = 0; i < conditions_met_.size(); i++) {
|
||||
conditions_met[i] = conditions_met_[i];
|
||||
}
|
||||
explicit EventAccess(bool* event_, std::vector<ConditionFn> conditions_met_)
|
||||
: event(event_) {
|
||||
conditions_met.resize(2);
|
||||
for (size_t i = 0; i < conditions_met_.size(); i++) {
|
||||
conditions_met[i] = conditions_met_[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool ConditionsMet() const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
|
||||
return true;
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
|
||||
return conditions_met[0]();
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) {
|
||||
if (conditions_met[0]()) {
|
||||
return true;
|
||||
} else if (conditions_met[1] != NULL) {
|
||||
return conditions_met[1]();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
bool ConditionsMet() const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
|
||||
return true;
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
|
||||
return conditions_met[0]();
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) {
|
||||
if (conditions_met[0]()) {
|
||||
return true;
|
||||
} else if (conditions_met[1] != NULL) {
|
||||
return conditions_met[1]();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckConditionAtAgeTime(bool& age, bool& time) {
|
||||
bool CheckConditionAtAgeTime(bool& age, bool& time) {
|
||||
|
||||
logic->IsChild = false;
|
||||
logic->IsAdult = false;
|
||||
logic->AtDay = false;
|
||||
logic->AtNight = false;
|
||||
logic->IsChild = false;
|
||||
logic->IsAdult = false;
|
||||
logic->AtDay = false;
|
||||
logic->AtNight = false;
|
||||
|
||||
time = true;
|
||||
age = true;
|
||||
time = true;
|
||||
age = true;
|
||||
|
||||
return ConditionsMet();
|
||||
}
|
||||
return ConditionsMet();
|
||||
}
|
||||
|
||||
void EventOccurred() {
|
||||
*event = true;
|
||||
}
|
||||
void EventOccurred() {
|
||||
*event = true;
|
||||
}
|
||||
|
||||
bool GetEvent() const {
|
||||
return *event;
|
||||
}
|
||||
bool GetEvent() const {
|
||||
return *event;
|
||||
}
|
||||
|
||||
private:
|
||||
bool* event;
|
||||
std::vector<ConditionFn> conditions_met;
|
||||
bool* event;
|
||||
std::vector<ConditionFn> conditions_met;
|
||||
};
|
||||
|
||||
std::string CleanCheckConditionString(std::string condition);
|
||||
@ -76,49 +76,49 @@ std::string CleanCheckConditionString(std::string condition);
|
||||
class LocationAccess {
|
||||
public:
|
||||
|
||||
explicit LocationAccess(RandomizerCheck location_, std::vector<ConditionFn> conditions_met_)
|
||||
: location(location_), condition_str("") {
|
||||
conditions_met.resize(2);
|
||||
for (size_t i = 0; i < conditions_met_.size(); i++) {
|
||||
conditions_met[i] = conditions_met_[i];
|
||||
}
|
||||
explicit LocationAccess(RandomizerCheck location_, std::vector<ConditionFn> conditions_met_)
|
||||
: location(location_), condition_str("") {
|
||||
conditions_met.resize(2);
|
||||
for (size_t i = 0; i < conditions_met_.size(); i++) {
|
||||
conditions_met[i] = conditions_met_[i];
|
||||
}
|
||||
}
|
||||
|
||||
explicit LocationAccess(RandomizerCheck location_, std::vector<ConditionFn> conditions_met_, std::string condition_str_)
|
||||
: location(location_), condition_str(condition_str_) {
|
||||
conditions_met.resize(2);
|
||||
for (size_t i = 0; i < conditions_met_.size(); i++) {
|
||||
conditions_met[i] = conditions_met_[i];
|
||||
}
|
||||
explicit LocationAccess(RandomizerCheck location_, std::vector<ConditionFn> conditions_met_, std::string condition_str_)
|
||||
: location(location_), condition_str(condition_str_) {
|
||||
conditions_met.resize(2);
|
||||
for (size_t i = 0; i < conditions_met_.size(); i++) {
|
||||
conditions_met[i] = conditions_met_[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool GetConditionsMet() const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
|
||||
return true;
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
|
||||
return conditions_met[0]();
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) {
|
||||
if (conditions_met[0]()) {
|
||||
return true;
|
||||
} else if (conditions_met[1] != NULL) {
|
||||
return conditions_met[1]();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
bool GetConditionsMet() const {
|
||||
auto ctx = Rando::Context::GetInstance();
|
||||
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
|
||||
return true;
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
|
||||
return conditions_met[0]();
|
||||
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) {
|
||||
if (conditions_met[0]()) {
|
||||
return true;
|
||||
} else if (conditions_met[1] != NULL) {
|
||||
return conditions_met[1]();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckConditionAtAgeTime(bool& age, bool& time) const;
|
||||
bool CheckConditionAtAgeTime(bool& age, bool& time) const;
|
||||
|
||||
bool ConditionsMet() const;
|
||||
bool ConditionsMet() const;
|
||||
|
||||
RandomizerCheck GetLocation() const {
|
||||
return location;
|
||||
}
|
||||
RandomizerCheck GetLocation() const {
|
||||
return location;
|
||||
}
|
||||
|
||||
std::string GetConditionStr() const {
|
||||
return condition_str;
|
||||
}
|
||||
std::string GetConditionStr() const {
|
||||
return condition_str;
|
||||
}
|
||||
|
||||
protected:
|
||||
RandomizerCheck location;
|
||||
@ -138,127 +138,199 @@ namespace Rando {
|
||||
|
||||
class Region {
|
||||
public:
|
||||
Region();
|
||||
Region(std::string regionName_, std::string scene_, std::set<RandomizerArea> areas,
|
||||
Region();
|
||||
Region(std::string regionName_, std::string scene_, std::set<RandomizerArea> areas,
|
||||
bool timePass_,
|
||||
std::vector<EventAccess> events_,
|
||||
std::vector<LocationAccess> locations_,
|
||||
std::list<Rando::Entrance> exits_);
|
||||
~Region();
|
||||
~Region();
|
||||
|
||||
std::string regionName;
|
||||
std::string scene;
|
||||
std::set<RandomizerArea> areas;
|
||||
bool timePass;
|
||||
std::vector<EventAccess> events;
|
||||
std::vector<LocationAccess> locations;
|
||||
std::list<Rando::Entrance> exits;
|
||||
std::list<Rando::Entrance*> entrances;
|
||||
//^ The above exits are now stored in a list instead of a vector because
|
||||
//the entrance randomization algorithm plays around with pointers to these
|
||||
//entrances a lot. By putting the entrances in a list, we don't have to
|
||||
//worry about a vector potentially reallocating itself and invalidating all our
|
||||
//entrance pointers.
|
||||
std::string regionName;
|
||||
std::string scene;
|
||||
std::set<RandomizerArea> areas;
|
||||
bool timePass;
|
||||
std::vector<EventAccess> events;
|
||||
std::vector<LocationAccess> locations;
|
||||
std::list<Rando::Entrance> exits;
|
||||
std::list<Rando::Entrance*> entrances;
|
||||
//^ The above exits are now stored in a list instead of a vector because
|
||||
//the entrance randomization algorithm plays around with pointers to these
|
||||
//entrances a lot. By putting the entrances in a list, we don't have to
|
||||
//worry about a vector potentially reallocating itself and invalidating all our
|
||||
//entrance pointers.
|
||||
|
||||
bool childDay = false;
|
||||
bool childNight = false;
|
||||
bool adultDay = false;
|
||||
bool adultNight = false;
|
||||
bool addedToPool = false;;
|
||||
bool childDay = false;
|
||||
bool childNight = false;
|
||||
bool adultDay = false;
|
||||
bool adultNight = false;
|
||||
bool addedToPool = false;;
|
||||
|
||||
void ApplyTimePass();
|
||||
void ApplyTimePass();
|
||||
|
||||
bool UpdateEvents();
|
||||
bool UpdateEvents();
|
||||
|
||||
void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition);
|
||||
void AddExit(RandomizerRegion parentKey, RandomizerRegion newExitKey, ConditionFn condition);
|
||||
|
||||
void RemoveExit(Rando::Entrance* exitToRemove);
|
||||
void RemoveExit(Rando::Entrance* exitToRemove);
|
||||
|
||||
void SetAsPrimary(RandomizerRegion exitToBePrimary);
|
||||
void SetAsPrimary(RandomizerRegion exitToBePrimary);
|
||||
|
||||
Rando::Entrance* GetExit(RandomizerRegion exit);
|
||||
Rando::Entrance* GetExit(RandomizerRegion exit);
|
||||
|
||||
bool Child() const {
|
||||
return childDay || childNight;
|
||||
bool Child() const {
|
||||
return childDay || childNight;
|
||||
}
|
||||
|
||||
bool Adult() const {
|
||||
return adultDay || adultNight;
|
||||
}
|
||||
|
||||
bool BothAgesCheck() const {
|
||||
return Child() && Adult();
|
||||
}
|
||||
|
||||
bool HasAccess() const {
|
||||
return Child() || Adult();
|
||||
}
|
||||
|
||||
bool AllAccess() const {
|
||||
return childDay && childNight && adultDay && adultNight;
|
||||
}
|
||||
|
||||
//Check to see if an exit can be access as both ages at both times of day
|
||||
bool CheckAllAccess(RandomizerRegion exitKey);
|
||||
|
||||
std::set<RandomizerArea> GetAllAreas() const{
|
||||
return areas;
|
||||
}
|
||||
|
||||
RandomizerArea GetFirstArea() const{
|
||||
if (areas.empty()){
|
||||
assert(false);
|
||||
return RA_NONE;
|
||||
} else {
|
||||
return *areas.begin();
|
||||
}
|
||||
}
|
||||
|
||||
bool Adult() const {
|
||||
return adultDay || adultNight;
|
||||
}
|
||||
void ReplaceAreas(std::set<RandomizerArea> newAreas) {
|
||||
areas = newAreas;
|
||||
}
|
||||
|
||||
bool BothAgesCheck() const {
|
||||
return Child() && Adult();
|
||||
}
|
||||
//Here checks conditional access based on whether or not both ages have
|
||||
//access to this area. For example: if there are rocks that block a path
|
||||
//which both child and adult can access, adult having hammer can give
|
||||
//both child and adult access to the path.
|
||||
bool Here(ConditionFn condition) {
|
||||
|
||||
bool HasAccess() const {
|
||||
return Child() || Adult();
|
||||
}
|
||||
//store current age variables
|
||||
bool pastAdult = logic->IsAdult;
|
||||
bool pastChild = logic->IsChild;
|
||||
|
||||
bool AllAccess() const {
|
||||
return childDay && childNight && adultDay && adultNight;
|
||||
}
|
||||
//set age access as this areas ages
|
||||
logic->IsChild = Child();
|
||||
logic->IsAdult = Adult();
|
||||
|
||||
//Check to see if an exit can be access as both ages at both times of day
|
||||
bool CheckAllAccess(RandomizerRegion exitKey);
|
||||
//heck condition as well as having at least child or adult access
|
||||
bool hereVal = condition() && (logic->IsAdult || logic->IsChild);
|
||||
|
||||
std::set<RandomizerArea> GetAllAreas() const{
|
||||
return areas;
|
||||
}
|
||||
//set back age variables
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
RandomizerArea GetFirstArea() const{
|
||||
if (areas.empty()){
|
||||
assert(false);
|
||||
return RA_NONE;
|
||||
} else {
|
||||
return *areas.begin();
|
||||
}
|
||||
}
|
||||
return hereVal;
|
||||
}
|
||||
|
||||
void ReplaceAreas(std::set<RandomizerArea> newAreas) {
|
||||
areas = newAreas;
|
||||
}
|
||||
bool CanPlantBeanCheck() const;
|
||||
bool AllAccountedFor() const;
|
||||
|
||||
//Here checks conditional access based on whether or not both ages have
|
||||
//access to this area. For example: if there are rocks that block a path
|
||||
//which both child and adult can access, adult having hammer can give
|
||||
//both child and adult access to the path.
|
||||
bool Here(ConditionFn condition) {
|
||||
void ResetVariables();
|
||||
|
||||
void printAgeTimeAccess() const {
|
||||
auto message = "Child Day: " + std::to_string(childDay) + "\t"
|
||||
"Child Night: " + std::to_string(childNight) + "\t"
|
||||
"Adult Day: " + std::to_string(adultDay) + "\t"
|
||||
"Adult Night: " + std::to_string(adultNight);
|
||||
}
|
||||
|
||||
/*This logic covers checks that exist in the shared areas of MQ spirit from a glitchless standpoint.
|
||||
This room has Quantum logic that I am currently handling with this function, however this is NOT suitable for glitch logic as it relies on specific ages
|
||||
In this chunk there are 3 possibilities for passing a check, but first I have to talk about parallel universes.
|
||||
|
||||
In MQ Spirit key logic, we mostly care about 2 possibilities for how the player can spend keys, creating 2 Parralel universes
|
||||
In the first universe, the player did not enter spirit as adult until after climbing as child, thus child spends keys linearly, only needing 2 to reach statue room.
|
||||
In the second universe, the player went in as adult, possibly out of logic, and started wasting the keys to lock child out.
|
||||
These Universes converge when the player has 7 keys (meaning adult can no longer lock child out) and adult is known to be able to reach Statue room. This creates "Certain Access", which is tracked seperatly for each age.
|
||||
Child Certain Access is simple, if we have 7 keys and child access, it's Certain Access.
|
||||
Adult Certain Access is also simple, adult is not key locked, so if they make it to a location, it's Certain Access.
|
||||
Things get complicated when we handle the overlap of the 2 universes,
|
||||
though an important detail is that if we have Certain Access as either age, we don't need to checked the overlap because overlap logic is strictly stricter than either Certain Access.
|
||||
|
||||
In order to track the first universe, the logic allows technical child access with the minimum number of keys, and then checks in this function for if we have 7 keys to determine if that is Certain or not.
|
||||
This is for technical reasons, as areas with no access at all will simply not be checked.
|
||||
Normally we would need to do similar shenanigans to track the second universe, however adult must have go through statue room to waste keys,
|
||||
so can go back there and get new keys for Child to use if they do, and the navigation logic for shared MQ spirit from Statue Room is very simple for Adult.
|
||||
Additionally, we don't need to know if adult can actually reach spirit temple or climb to statue room, because if the player can't do that, then universe 2 can't happen anyway,
|
||||
and if the player does so out of logic, they can do it again, as the only consumable used sets a permanent flag.
|
||||
|
||||
The Adult Navigation logic is as such:
|
||||
- Broken Wall room is 6 key locked, because if the player tries to spend 6 keys in a way that would block adults access, they would have to give child access instead.
|
||||
- The child side hammer switch for the time travelling chest is 7 key locked for adult
|
||||
- Reaching gauntlets hand is 7 key locked
|
||||
- Going back into big block room is complex, but the only check there is child only so not a concern
|
||||
- Everything else is possible with basic adult movement, or is impossible for child to reach glitchlessly
|
||||
Anything 7 key locked does not need to be checked as shared, as all child access is Certain and because of this workaround we don't need to fake Adult access, meaning that is also Certain.
|
||||
All of this combined means that when checking if adult can reach a location in universe 2, we only have to ask if it is a 6 key locked location or not.
|
||||
|
||||
Knowing all of this this, we can confirm things are logical in 3 different ways:
|
||||
- If we have Adult Access, we know it is Certain Access, so they can get checks alone.
|
||||
- If we have 7 keys, child has Certain Access as we know they cannot be locked out, so can get checks alone, otherwise we check the logical overlap
|
||||
- If Child and Adult can get the check (ignoring actual adult access to the location), and the location is either not 6 key locked or we have 6 keys, we can get the check with the overlap*/
|
||||
bool MQSpiritShared(ConditionFn condition, bool IsBrokenWall, bool anyAge = false) {
|
||||
//if we have Certain Access as child, we can check anyAge and if true, resolve a condition with Here as if adult is here it's also Certain Access
|
||||
if (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)){
|
||||
if (anyAge){
|
||||
return Here(condition);
|
||||
}
|
||||
return condition();
|
||||
//else, if we are here as adult, we have Certain Access from that and don't need special handling for checking adult
|
||||
} else if (Adult() && logic->IsAdult){
|
||||
return condition();
|
||||
//if we do not have Certain Access, we need to check the overlap by seeing if we are both here as child and meet the adult universe's access condition
|
||||
//We only need to do it as child, as only child access matters for this check, as adult access is assumed based on keys
|
||||
} else if (Child() && logic->IsChild && (!IsBrokenWall || logic->SmallKeys(RR_SPIRIT_TEMPLE, 6))) {
|
||||
bool result = false;
|
||||
//store current age variables
|
||||
bool pastAdult = logic->IsAdult;
|
||||
bool pastChild = logic->IsChild;
|
||||
|
||||
//set age access as this areas ages
|
||||
logic->IsChild = Child();
|
||||
logic->IsAdult = Adult();
|
||||
|
||||
//heck condition as well as having at least child or adult access
|
||||
bool hereVal = condition() && (logic->IsAdult || logic->IsChild);
|
||||
|
||||
//First check if the check is possible as child
|
||||
logic->IsChild = true;
|
||||
logic->IsAdult = false;
|
||||
result = condition();
|
||||
//If so, check again as adult. both have to be true for result to be true
|
||||
if (result) {
|
||||
logic->IsChild = false;
|
||||
logic->IsAdult = true;
|
||||
result = condition();
|
||||
}
|
||||
|
||||
//set back age variables
|
||||
logic->IsChild = pastChild;
|
||||
logic->IsAdult = pastAdult;
|
||||
|
||||
return hereVal;
|
||||
}
|
||||
|
||||
bool CanPlantBeanCheck() const;
|
||||
bool AllAccountedFor() const;
|
||||
|
||||
void ResetVariables();
|
||||
|
||||
void printAgeTimeAccess() const {
|
||||
auto message = "Child Day: " + std::to_string(childDay) + "\t"
|
||||
"Child Night: " + std::to_string(childNight) + "\t"
|
||||
"Adult Day: " + std::to_string(adultDay) + "\t"
|
||||
"Adult Night: " + std::to_string(adultNight);
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
extern std::array<Region, RR_MAX> areaTable;
|
||||
extern std::vector<EventAccess> grottoEvents;
|
||||
|
||||
bool Here(const RandomizerRegion region, ConditionFn condition); //RANDOTODO make a less stupid way to check own at either age than self referncing with this
|
||||
bool MQSpiritSharedStatueRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||
bool MQSpiritSharedBrokenWallRoom(const RandomizerRegion region, ConditionFn condition, bool anyAge = false);
|
||||
bool CanPlantBean(const RandomizerRegion region);
|
||||
bool BothAges(const RandomizerRegion region);
|
||||
bool ChildCanAccess(const RandomizerRegion region);
|
||||
|
@ -32,7 +32,7 @@ void RegionTable_Init_GanonsCastle() {
|
||||
Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}),
|
||||
Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}),
|
||||
Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}),
|
||||
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_1, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||
(logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
|
||||
(logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
|
||||
(logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
|
||||
@ -111,13 +111,6 @@ void RegionTable_Init_GanonsCastle() {
|
||||
}, {});
|
||||
}
|
||||
|
||||
areaTable[RR_GANONS_CASTLE_TOWER] = Region("Ganon's Castle Tower", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)),
|
||||
LOCATION(RC_GANONDORF_HINT, logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY) && (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD))),
|
||||
LOCATION(RC_GANON, logic->HasBossSoul(RG_GANON_SOUL) && logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY) && logic->CanUse(RG_LIGHT_ARROWS) && logic->CanUse(RG_MASTER_SWORD)),
|
||||
}, {});
|
||||
|
||||
/*---------------------------
|
||||
| MASTER QUEST DUNGEON |
|
||||
---------------------------*/
|
||||
@ -142,7 +135,7 @@ void RegionTable_Init_GanonsCastle() {
|
||||
Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL_CHAIRS_ROOM, {[]{return true;}}),
|
||||
Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_DINOLFOS_ROOM, {[]{return Here(RR_GANONS_CASTLE_MQ_MAIN, []{return logic->CanUse(RG_GOLDEN_GAUNTLETS);});}}),
|
||||
//RANDOTODO could we just set these events automatically based on the setting?
|
||||
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_1, {[]{return (logic->ForestTrialClear || ctx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
|
||||
(logic->FireTrialClear || ctx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
|
||||
(logic->WaterTrialClear || ctx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
|
||||
(logic->ShadowTrialClear || ctx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
|
||||
@ -376,4 +369,53 @@ void RegionTable_Init_GanonsCastle() {
|
||||
EventAccess(&logic->LightTrialClear, {[]{return logic->CanUse(RG_LIGHT_ARROWS);}}),
|
||||
}, {}, {});
|
||||
}
|
||||
|
||||
/*--------------------------
|
||||
| TOWER AND ESCAPE |
|
||||
---------------------------*/
|
||||
areaTable[RR_GANONS_TOWER_FLOOR_1] = Region("Ganon's Tower Floor 1", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_GANONS_CASTLE_LOBBY, {[]{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}}),
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_2, {[]{return Here(RR_GANONS_TOWER_FLOOR_1, []{return logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_GANONS_TOWER_FLOOR_2] = Region("Ganon's Tower Floor 2", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_GANONS_TOWER_BOSS_KEY_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_1, {[]{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}),
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_3, {[]{return Here(RR_GANONS_TOWER_FLOOR_2, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_GANONS_TOWER_FLOOR_3] = Region("Ganon's Tower Floor 3", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_GANONS_TOWER_FLOOR_2, {[]{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);});}}),
|
||||
Entrance(RR_GANONS_TOWER_GANONDORF_LAIR, {[]{return Here(RR_GANONS_TOWER_FLOOR_3, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE, ED_CLOSE, true, 2);}) && logic->HasItem(RG_GANONS_CASTLE_BOSS_KEY);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_GANONS_TOWER_GANONDORF_LAIR] = Region("Ganondorf's Lair", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_GANONDORF_HINT, logic->HasBossSoul(RG_GANON_SOUL)),
|
||||
//18 pots
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_GANONS_CASTLE_ESCAPE, {[]{return logic->CanKillEnemy(RE_GANONDORF);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_GANONS_CASTLE_ESCAPE] = Region("Ganon's Castle Escape", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//10 pots
|
||||
}, {
|
||||
//Exits
|
||||
//temporary
|
||||
Entrance(RR_GANONS_CASTLE_GANON_ARENA, {[]{return true;}}),
|
||||
//real logic once we figure out how to deal with castle escape skip
|
||||
//Entrance(RR_GANONS_CASTLE_GANON_ARENA, {[]{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_GANONS_CASTLE_GANON_ARENA] = Region("Ganon's Arena", "Ganons Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_GANON, logic->CanKillEnemy(RE_GANON)),
|
||||
}, {});
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ void RegionTable_Init_GerudoTrainingGrounds() {
|
||||
|
||||
areaTable[RR_GERUDO_TRAINING_GROUNDS_MQ_STATUE_ROOM] = Region("Gerudo Training Grounds MQ Statue ROom", "Gerudo Training Grounds", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)),
|
||||
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_EYE_STATUE_CHEST, logic->CanUse(RG_FAIRY_BOW)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STATUE_ROOM_LEDGE, {[]{return logic->CanUse(RG_LONGSHOT);}}),
|
||||
@ -220,7 +220,7 @@ void RegionTable_Init_GerudoTrainingGrounds() {
|
||||
//Locations
|
||||
//implies logic->CanKillEnemy(RE_TORCH_SLUG)
|
||||
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_SECOND_IRON_KNUCKLE_CHEST, logic->CanKillEnemy(RE_IRON_KNUCKLE)),
|
||||
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanHitSwitch(ED_BOOMERANG)),
|
||||
LOCATION(RC_GERUDO_TRAINING_GROUND_MQ_FLAME_CIRCLE_CHEST, logic->CanHitSwitch(ED_BOMB_THROW)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_GERUDO_TRAINING_GROUNDS_MQ_STATUE_ROOM, {[]{return Here(RR_GERUDO_TRAINING_GROUNDS_MQ_TORCH_SLUG_ROOM, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}),
|
||||
|
@ -11,7 +11,7 @@ void RegionTable_Init_ShadowTemple() {
|
||||
areaTable[RR_SHADOW_TEMPLE_ENTRYWAY] = Region("Shadow Temple Entryway", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsVanilla() && (ctx->GetTrickOption(RT_LENS_SHADOW) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT));}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BEGINNING, {[]{return ctx->GetDungeon(SHADOW_TEMPLE)->IsMQ();}}),
|
||||
Entrance(RR_GRAVEYARD_WARP_PAD_REGION, {[]{return true;}}),
|
||||
});
|
||||
|
||||
@ -94,88 +94,238 @@ void RegionTable_Init_ShadowTemple() {
|
||||
//RANDOTODO doublecheck CanAttack when rewriting, as I assumed it only checked adult due to the entrance
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_BEGINNING] = Region("Shadow Temple MQ Beginning", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT)));}}),
|
||||
//Trick: logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_HOVER_BOOTS) || (LogicShadowMQGap && logic->CanUse(RG_LONGSHOT)))
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, {[]{return logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM] = Region("Shadow Temple MQ Spinner Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}) &&
|
||||
(logic->CanUse(RG_HOVER_BOOTS) || Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->CanUse(RG_FIRE_ARROWS);}) || (ctx->GetTrickOption(RT_SHADOW_MQ_GAP) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer()));}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, {[]{return Here(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, []{return logic->HasExplosives();}) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),
|
||||
});
|
||||
|
||||
//Assumes we're in the "main" area and needed lens to enter. logic will need changes if a void warp puts us somewhere weird
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA] = Region("Shadow Temple MQ Dead Hand Region", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanJumpslashExceptHammer()),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanJumpslashExceptHammer() && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)),
|
||||
}, {});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanJumpslashExceptHammer()),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, logic->CanAttack() || logic->CanUse(RG_NUTS)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_REDEAD)),
|
||||
//There's a shared flag tied to some glass here. eye target here and killing an enemy group later in the dungeon toggles. I'm building the logic as "intended", assuming the switch needs flipping
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_HOVER_BOOTS_CHEST, logic->CanKillEnemy(RE_DEAD_HAND) && (logic->IsChild || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanHitEyeTargets()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//also includes the B2 gibdo room
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS] = Region("Shadow Temple MQ First Beamos", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))),
|
||||
//Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO))
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetOption(RSK_DAMAGE_MULTIPLIER).IsNot(RO_DAMAGE_MULTIPLIER_OHKO))),
|
||||
//Trick: logic->CanUse(RG_SONG_OF_TIME) || (LogicShadowMQInvisibleBlades && DamageMultiplier.IsNot(DAMAGEMULTIPLIER_OHKO))
|
||||
//Doing this sets the shared flag for the glass in RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA, but doesn't seem to affect the chest
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_EARLY_GIBDOS_CHEST, logic->CanKillEnemy(RE_GIBDO) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return logic->HasFireSource() || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}),
|
||||
//Trick: logic->HasFireSource() || LogicShadowMQHugePit
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM] = Region("Shadow Temple MQ B2 Spinning Blade Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_MAP_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return Here(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, []{return logic->CanKillEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)));});}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH] = Region("Shadow Temple MQ Shortcut Path", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_NEAR_SHIP_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, {[]{return logic->ShadowShortcutBlock;}}),
|
||||
//WARNING if there's any way past here to ship without already reaching the other side the key logic in this dungeon becomes Quantum
|
||||
});
|
||||
|
||||
//Room exists for if it's ever possible to go backwards or void warp into the middle of shadow
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR] = Region("Shadow Temple MQ B2 to B3 Corridor", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, {[]{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return true;}}),
|
||||
//bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT] = Region("Shadow Temple MQ Upper Huge Pit", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return (logic->HasFireSource() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))) || ctx->GetTrickOption(RT_SHADOW_MQ_HUGE_PIT);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM, {[]{return ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM] = Region("Shadow Temple MQ Invisible Blades Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//RT_SHADOW_MQ_INVISIBLE_BLADES does not work with NL as like-likes will not swallow you, likewise like-likes will not spit you with a fairy revive
|
||||
//you take half a heart base from a spit out, double check EffectiveHealth when damage logic gets reworked
|
||||
//Child is too small to get hit by the blades doesn't need the trick or lens for dodging them
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_VISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) &&
|
||||
(ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_INVISIBLE_CHEST, (logic->CanUse(RG_SONG_OF_TIME) || (ctx->GetTrickOption(RT_SHADOW_MQ_INVISIBLE_BLADES) && logic->EffectiveHealth() > 1)) &&
|
||||
((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) || logic->IsChild || logic->CanUse(RG_NAYRUS_LOVE))) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT] = Region("Shadow Temple MQ Lower Huge Pit", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->IsAdult && logic->CanUse(RG_LONGSHOT)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS)) || logic->HasItem(RG_GORONS_BRACELET)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanJumpslashExceptHammer() && logic->CanUse(RG_HOVER_BOOTS) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, (logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) && logic->CanUse(RG_HOVER_BOOTS) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3) && logic->CanUse(RG_HOOKSHOT) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) &&
|
||||
ctx->GetTrickOption(RT_LENS_SHADOW_MQ_INVISIBLE_BLADES) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && logic->CanUse(RG_HOVER_BOOTS))),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_BEAMOS_SILVER_RUPEES_CHEST, logic->CanUse(RG_LONGSHOT)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return logic->CanUse(RG_HOVER_BOOTS) && ((ctx->GetTrickOption(RT_LENS_SHADOW_MQ) && ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM)) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanUse(RG_HOOKSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FALLING_SPIKES_ROOM, {[]{return Here(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, []{return logic->CanJumpslash() || logic->HasExplosives();});}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ_PLATFORM) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->SmallKeys(RR_SHADOW_TEMPLE, 3);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Region("Shadow Temple MQ Wind Tunnel", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_FALLING_SPIKES_ROOM] = Region("Shadow Temple MQ Falling Spikes Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_LOWER_CHEST, true),
|
||||
//Assuming the known setup for RT_SHADOW_UMBRELLA and RT_SHADOW_UMBRELLA_GS, probably possible without sword + shield.
|
||||
//Handling the trick here instead of upper as using the block to climb is not a valid method for getting this skull without other tricks to use the block before it is intended
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_FALLING_SPIKES_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG) ||
|
||||
(ctx->GetTrickOption(RT_SHADOW_UMBRELLA_GS) && ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT, {[]{return Here(RR_SHADOW_TEMPLE_MQ_FALLING_SPIKES_ROOM, []{return ctx->GetTrickOption(RT_VISIBLE_COLLISION) || logic->CanHitSwitch();});}}),
|
||||
//Assuming the known setup for RT_SHADOW_UMBRELLA, probably possible without sword + shield
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_FALLING_SPIKES_ROOM, {[]{return logic->IsAdult && (logic->HasItem(RG_GORONS_BRACELET) || (ctx->GetTrickOption(RT_SHADOW_UMBRELLA) && logic->CanUse(RG_HOVER_BOOTS) && logic->CanStandingShield() && logic->CanUse(RG_MASTER_SWORD)));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_UPPER_FALLING_SPIKES_ROOM] = Region("Shadow Temple MQ Upper Falling Spikes Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_UPPER_CHEST, true),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FALLING_SPIKES_SWITCH_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FALLING_SPIKES_ROOM, {[]{return true;}}),
|
||||
});
|
||||
|
||||
//while the spikes here are annoying, they don't really stop you doing anything, so I'll assume either lens trick, lens to see them, or taking damage from them. Not hovers though as a new player won't see the threat without lens to react properly
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM] = Region("Shadow Temple MQ Floor Spikes Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events //lens or trick is always required for hookshot targets. We handle it here to not complicate the RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_UPPER_DOOR logic
|
||||
EventAccess(&logic->MQShadowFloorSpikeRupees, {[]{return (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||
//Upper door side high rupee needs (hookshot and redead kill(as either age) for chest and adult) or longshot. hovers can cross from the left side with a backflip but that would be a trick
|
||||
//East midair rupee needs (hookshot and(hover boots or jumpslash from the upper door platform)) or longshot.
|
||||
//Combined these are longshot or (IsAdult && hookshot && (CanJumpslash || (Hover Boots && Here(CanKillRedeads))))
|
||||
(logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->CanJumpslash() || (logic->CanUse(RG_HOVER_BOOTS) && Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);}))))) &&
|
||||
//1 rupee is in spikes, needs hovers or damage
|
||||
(logic->TakeDamage() || logic->CanUse(RG_HOVER_BOOTS));}}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_INVISIBLE_SPIKES_CHEST, logic->CanKillEnemy(RE_REDEAD) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->TakeDamage() || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, {[]{return logic->MQShadowFloorSpikeRupees;}}),
|
||||
//We need to assume we can get here with or without the glass platforms
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (logic->IsAdult && logic->CanUse(RG_HOOKSHOT) && (logic->MQShadowFloorSpikeRupees || Here(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, []{return logic->CanKillEnemy(RE_REDEAD);})))) &&
|
||||
(logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM] = Region("Shadow Temple MQ Stalfos Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_STALFOS_ROOM_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, {[]{return Here(RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL] = Region("Shadow Temple MQ Wind Tunnel", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 4) && logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT));}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, {[]{return logic->CanPassEnemy(RE_BIG_SKULLTULA) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM] = Region("Shadow Temple MQ Wind Hint Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->CanPassEnemy(RE_REDEAD)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM] = Region("Shadow Temple MQ B4 Gibdo Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->NutPot, {[]{return true;}}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_WIND_HINT_CHEST, true),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslashExceptHammer()),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, true),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_WIND_HINT_ROOM, true),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, true),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives() && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_WIND, logic->HasExplosives()),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return logic->CanUse(RG_ZELDAS_LULLABY) && logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}),
|
||||
//child can make it using the wind strat
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL, {[]{return (ctx->GetTrickOption(RT_SHADOW_MQ_WINDY_WALKWAY)) || logic->CanUse(RG_HOVER_BOOTS);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_DOCK, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_DOCK] = Region("Shadow Temple MQ Dock", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ShadowShortcutBlock, {[]{return logic->HasItem(RG_GORONS_BRACELET);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH, {[]{return logic->ShadowShortcutBlock;}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 5);}}),
|
||||
//funnily enough, the wheel jump seems to be in logic as there's no strength requirement in N64
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return (logic->IsAdult || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT] = Region("Shadow Temple MQ Beyond Boat", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, true),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))),
|
||||
}, {
|
||||
//It's a trick on N64 to kill this and drop down to collect this with normal weapons, as doing so without the statue dropped doing voids you to before the boat
|
||||
//hilariously, you can also hit this with a pot before you bring down the statue, but there's no great way to reset it without crossing. the statues collision is very inconvenient afterwards
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_AFTER_SHIP, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME) && logic->IsAdult && logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return (logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5))) && logic->CanUse(RG_HOVER_BOOTS) && logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, {[]{return Here(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, []{return logic->CanUse(RG_FAIRY_BOW) || (ctx->GetTrickOption(RT_SHADOW_STATUE) && logic->CanUse(RG_BOMBCHU_5));});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM] = Region("Shadow Temple MQ Across Chasm", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanDetonateUprightBombFlower();}) && logic->IsAdult;}}),
|
||||
//assumes RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT by previous access. If backwards shadow ever exists remember that child cannot jump onto the statue from this side and make an event for the switch
|
||||
//Lens isn't needed to reach it but is needed to navigate the next room
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return Here(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, []{return logic->CanHitEyeTargets() && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_LONGSHOT);});}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BOSS_DOOR, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_BOSS_DOOR] = Region("Shadow Temple MQ Boss Door", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//you can drop onto this and the respawn is reasonable
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_GS_NEAR_BOSS, (logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_BOOMERANG) || logic->CanUse(RG_MEGATON_HAMMER)) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM, {[]{return logic->CanUse(RG_HOVER_BOOTS) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SHADOW_TEMPLE_BOSS_KEY);}}),
|
||||
});
|
||||
|
||||
//Assumes lens is checked on entry
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE] = Region("Shadow Temple MQ Invisible Maze", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE) && logic->SmallKeys(RR_SHADOW_TEMPLE, 6)),
|
||||
//below previously returned true
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true),
|
||||
}, {});
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_BOMB_FLOWER_CHEST, (logic->CanUse(RG_LENS_OF_TRUTH) || ctx->GetTrickOption(RT_LENS_SHADOW_MQ_DEADHAND)) && logic->CanKillEnemy(RE_DEAD_HAND) && logic->CanDetonateUprightBombFlower()),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_FREESTANDING_KEY, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT, {[]{return true;}}),
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM] = Region("Shadow Temple MQ Spike Walls Room", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)),
|
||||
LOCATION(RC_SHADOW_TEMPLE_MQ_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE, {[]{return logic->SmallKeys(RR_SHADOW_TEMPLE, 6) && (ctx->GetTrickOption(RT_LENS_SHADOW_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),});
|
||||
}
|
||||
|
||||
/*---------------------------
|
||||
|
@ -10,8 +10,8 @@ void RegionTable_Init_SpiritTemple() {
|
||||
---------------------------*/
|
||||
areaTable[RR_SPIRIT_TEMPLE_ENTRYWAY] = Region("Spirit Temple Entryway", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla();}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ();}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsVanilla();}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ();}}),
|
||||
Entrance(RR_DESERT_COLOSSUS_OUTSIDE_TEMPLE, {[]{return true;}}),
|
||||
});
|
||||
|
||||
@ -137,102 +137,340 @@ void RegionTable_Init_SpiritTemple() {
|
||||
if (ctx->GetDungeon(SPIRIT_TEMPLE)->IsMQ()) {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LOBBY] = Region("Spirit Temple MQ Lobby", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && ((logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanUse(RG_BOMBCHU_5) || (logic->IsAdult && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT))) || (logic->IsChild && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG)))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_LEFT_CHEST, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_LEFT_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->BlastOrSmash();}) && logic->CanHitEyeTargets()),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_BACK_RIGHT_CHEST, logic->CanHitSwitch(ED_BOOMERANG)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->Spirit1FSilverRupees),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_CHILD, {[]{return logic->IsChild;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_ADULT, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_SILVER_GAUNTLETS);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return logic->IsChild;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH, {[]{return logic->CanUse(RG_LONGSHOT) && logic->CanUse(RG_BOMBCHU_5);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_CHILD] = Region("Spirit Temple MQ Child", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_WEST] = Region("Spirit Temple MQ 1F West", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FairyPot, {[]{return logic->FairyPot || (logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT));}}),
|
||||
//not technically a rusted switch, but a boulder through a wall, but is part of the same trick on N64
|
||||
EventAccess(&logic->MQSpiritCrawlBoulder, {[]{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER);})),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->CanUse(RG_KOKIRI_SWORD) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->CanUse(RG_DINS_FIRE)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, logic->CanUse(RG_KOKIRI_SWORD) || logic->CanUse(RG_BOMB_BAG)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (Here(RR_SPIRIT_TEMPLE_MQ_ADULT, []{return logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)));})))),
|
||||
//Trick: logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_FAIRY_SLINGSHOT) && (logic->CanUse(RG_DINS_FIRE) || (SPIRIT_TEMPLE_MQ_ADULT.Adult() && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQFrozenEye && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME)))))
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_HAMMER_SWITCH_CHEST, logic->MQSpiritTimeTravelChest),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_1F_WEST, []{return logic->CanKillEnemy(RE_TORCH_SLUG);});}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, {[]{return logic->IsChild && logic->MQSpiritCrawlBoulder;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_ADULT] = Region("Spirit Temple MQ Adult", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH] = Region("Spirit Temple MQ 1F Gibdo Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets();}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, {[]{return logic->CanUse(RG_BOMBCHU_5) && logic->CanHitEyeTargets() && logic->CanKillEnemy(RE_GIBDO);}}),
|
||||
});
|
||||
|
||||
// Room to store the 2 pots in to handle glitch logic going backwards around the loop later
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH] = Region("Spirit Temple MQ Gibdo Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM] = Region("Spirit Temple Turntable Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//For non-fairy pot items, you can also get them with rang without killing the stalfos
|
||||
EventAccess(&logic->FairyPot, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH] = Region("Spirit Temple MQ Map Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQSpiritMapRoomEnemies, {[]{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE);}}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_HOVER_BOOTS))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_ROOM_ENEMY_CHEST, logic->MQSpiritMapRoomEnemies),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)));}}),
|
||||
//Trick: logic->CanUse(RG_MIRROR_SHIELD) && logic->IsAdult && (logic->CanUse(RG_FIRE_ARROWS) || (LogicSpiritMQLowerAdult && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_FAIRY_BOW)))
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BOSS_AREA, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6) && logic->CanUse(RG_ZELDAS_LULLABY) && logic->CanUse(RG_MEGATON_HAMMER);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH));}}),
|
||||
//Stalfos room blocks you in with fire until you kill the stalfos, which won't spawn from behind the fire
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SHARED] = Region("Spirit Temple MQ Shared", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH] = Region("Spirit Temple MQ Map Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//You can lure the keese over by aggroing them with dins if you use it as close to the torch keese as possible, but it's a trick as it's not intuitive and basically never comes up
|
||||
EventAccess(&logic->MQSpiritMapRoomEnemies, {[]{return logic->CanKillEnemy(RE_ANUBIS) && logic->CanKillEnemy(RE_KEESE, ED_BOOMERANG);}}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 6)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, (logic->IsChild && logic->CanUse(RG_FAIRY_SLINGSHOT) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7)) || (logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_FAIRY_SLINGSHOT))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult),
|
||||
//Trick: logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT))) || logic->IsAdult),
|
||||
//Trick: (LogicSpiritMQSunBlockGS && logic->CanUse(RG_BOOMERANG) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT)) || logic->IsAdult
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)));}}),
|
||||
//Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH)))
|
||||
Entrance(RR_DESERT_COLOSSUS, {[]{return (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanJumpslashExceptHammer() && (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult);}}),
|
||||
//Trick: (logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && (logic->CanUse(RG_SONG_OF_TIME) || LogicSpiritMQSunBlockSoT || logic->IsAdult)) || (logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) && logic->CanUse(RG_SONG_OF_TIME) && (LogicLensSpiritMQ || logic->CanUse(RG_LENS_OF_TRUTH)) && logic->IsAdult)
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT] = Region("Spirit Temple MQ Lower Adult", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG)
|
||||
&& logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_ENTRANCE_FRONT_RIGHT_CHEST, logic->CanUse(RG_MEGATON_HAMMER)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) && logic->CanUse(RG_SUNS_SONG)
|
||||
&& logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY)),
|
||||
}, {});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BOSS_AREA] = Region("Spirit Temple MQ Boss Region", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MAP_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return logic->CanUse(RG_MIRROR_SHIELD) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
//The bridge is a temp flag, so not a way to cross south to north in logic
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] =
|
||||
Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {},
|
||||
{
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SHARED, { [] { return true; } }),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, { [] { return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY); } }),
|
||||
});
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH] = Region("Spirit Temple MQ West 1F Rusted Switch", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQSpiritTimeTravelChest, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}),
|
||||
EventAccess(&logic->MQSpiritCrawlBoulder, {[]{return logic->CanUse(RG_BOMBCHU_5) || (ctx->GetTrickOption(RT_RUSTED_SWITCHES) && logic->CanUse(RG_MEGATON_HAMMER));}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_WEST, {[]{return logic->IsChild && logic->MQSpiritCrawlBoulder;}}),
|
||||
//This tracks possible child access, if adult has not entered STATUE_ROOM. Certain Child Access is checked for separately as 7 Keys
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 1);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//THIS REGION NEEDS MQSpiritSharedBrokenWallRoom WHEN ADDING THE POT
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE] = Region("Spirit Temple MQ Under Like Like", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
//This covers adult access only, as child arrives here from the other side of this door
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, {[]{return logic->CanHitSwitch();}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM] = Region("Spirit Temple MQ Broken Wall Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true),
|
||||
}, {});
|
||||
//Implies CanKillEnemy(RE_LIKE_LIKE)
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_NORTH_CHEST, MQSpiritSharedBrokenWallRoom(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, []{return logic->CanKillEnemy(RE_BEAMOS);})),
|
||||
//Sunlights only temp spawn this chest, which is unintuitive/a bug.
|
||||
//chest is only reachable as adult glitchlessly, so we can skip the shared in favour of IsAdult as adult access is always Certain
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHILD_CLIMB_SOUTH_CHEST, logic->IsAdult && logic->HasExplosives() && (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)) && logic->CanUse(RG_HOOKSHOT)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE, {[]{return logic->CanHitSwitch();}}),
|
||||
//This exit only governs child possible access, adult access starts on the other side so never checks this
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 2);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM] = Region("Spirit Temple MQ Statue Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_COMPASS_CHEST, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->CanHitEyeTargets();})),
|
||||
}, {
|
||||
//Exits
|
||||
//we check possible adult access directly in MQSpiritSharedBrokenWallRoom, so this exit only covers Certain Access
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||
//We can use Here instead of Shared here because adult will never need to rely on child access to reach this room, and adult access is Certain
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, []{return logic->HasFireSource() || (ctx->GetTrickOption(RT_SPIRIT_MQ_FROZEN_EYE) && logic->CanUse(RG_FAIRY_BOW) && logic->CanUse(RG_SONG_OF_TIME));});}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {[]{return logic->IsAdult || ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_SOT) || logic->CanUse(RG_SONG_OF_TIME);}}),
|
||||
//explicit adult check here is a precaution against possible child logic leaking, child with a hookshot can do this
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return logic->IsAdult && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM] = Region("Spirit Temple MQ Sun Block Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//We don't need Shared here because If we are checking as child, universe 2 adult access needs nothing so it always passes, and if we are checking as adult, it is Certain Access
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM_CHEST, true),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SUN_BLOCK_ROOM, MQSpiritSharedStatueRoom(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, []{return logic->CanUse(RG_HOOKSHOT) || (ctx->GetTrickOption(RT_SPIRIT_MQ_SUN_BLOCK_GS) && logic->CanUse(RG_BOOMERANG));})),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}),
|
||||
//This door causes the Universes to merge as it requires 7 keys for both ages
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->CanKillEnemy(RE_IRON_KNUCKLE);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND] = Region("Spirit Temple MQ Silver Gauntlets Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_SILVER_GAUNTLETS_CHEST, true),
|
||||
}, {});
|
||||
}, {
|
||||
//Exits
|
||||
//If it is ever relevent for 1 age to spawn the mirror shield chest for the other can longshot across, it needs an eventAccess
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE, {[]{return true;}}),
|
||||
Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH] = Region("Spirit Temple MQ Block Room South", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return true;}}),
|
||||
//The block here is unusual in that it is a permanent flag, but reset anyway as child. This is because there's a check that would be blocked off by pushing them otherwise
|
||||
//It may be worth considering making this always temp in future so adult doesn't have the same issue
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH, {[]{return logic->IsChild ? logic->CanUse(RG_SILVER_GAUNTLETS) : Here(RR_SPIRIT_TEMPLE_MQ_LOBBY, []{return logic->CanUse(RG_SILVER_GAUNTLETS);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH] = Region("Spirit Temple MQ Block Room North", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//Does not need to be shared as it's hard child locked, because adult pushing the block is a permanent flag that blocks the eye target and cannot be undone
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SILVER_BLOCK_HALLWAY_CHEST, logic->IsChild && logic->SmallKeys(RR_SPIRIT_TEMPLE, 7) && logic->CanHitEyeTargets()),
|
||||
}, {
|
||||
//Exits
|
||||
//if going to RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH from here is ever relevant, there needs to be an event to handle the block
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST] = Region("Spirit Temple MQ Statue Room East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_LULLABY_CHEST, logic->CanUse(RG_HOOKSHOT) & logic->CanUse(RG_ZELDAS_LULLABY) && (logic->CanJumpslash() || logic->CanUse(RG_HOVER_BOOTS))),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_STATUE_ROOM_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return true;}}),
|
||||
//!QUANTUM LOGIC!
|
||||
//We only need 4 keys, access to Shield hand and longshot to reach Gauntlets hand, as if we waste the 5th key we have given ourselves Gauntlets hand access through child climb
|
||||
//This exit handles that possibility as cleanly as possible without quantum logic, but will not survive glitch logic
|
||||
//logic->CanKillEnemy(RE_FLOORMASTER) is implied
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 4) &&
|
||||
logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) &&
|
||||
logic->CanJumpslash() &&
|
||||
(ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||
logic->CanKillEnemy(RE_IRON_KNUCKLE) &&
|
||||
logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, {[]{return logic->CanUse(RG_FIRE_ARROWS) || (ctx->GetTrickOption(RT_SPIRIT_MQ_LOWER_ADULT) && logic->CanUse(RG_DINS_FIRE));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F] = Region("Spirit Temple MQ Three Suns Room 2F", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//implies logic->CanKillEnemy(RE_WALLMASTER). If we have lights, we can kill stalfos and wallmasters with bow
|
||||
EventAccess(&logic->MQSpirit3SunsEnemies, {[]{return (logic->CanUse(RG_MIRROR_SHIELD) && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2)) ||
|
||||
(ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS));}}),
|
||||
}, {}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, {[]{return logic->MQSpirit3SunsEnemies;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F] = Region("Spirit Temple MQ Three Suns Room 1F", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F, {[]{return logic->MQSpirit3SunsEnemies;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_1F_EAST] = Region("Spirit Temple MQ 1F East", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//Assumes RR_SPIRIT_TEMPLE_MQ_LOBBY access
|
||||
EventAccess(&logic->Spirit1FSilverRupees, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return logic->CanUse(RG_MEGATON_HAMMER);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM] = Region("Spirit Temple MQ Leever Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_LEEVER_ROOM_CHEST, logic->CanKillEnemy(RE_PURPLE_LEEVER) && logic->CanUse(RG_HOOKSHOT)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_LEEVER_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
}, {
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM] = Region("Spirit Temple MQ Symphony Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_1F_EAST, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||
//Implies CanPassEnemy(RE_MOBLIN_CHIEF)
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM, {[]{return logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_EPONAS_SONG) &&
|
||||
logic->CanUse(RG_SUNS_SONG) && logic->CanUse(RG_SONG_OF_STORMS) && logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM] = Region("Spirit Temple MQ After Symphony Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM_CHEST, logic->CanPassEnemy(RE_BIG_SKULLTULA)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_SYMPHONY_ROOM, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM] = Region("Spirit Temple MQ Four Beamos Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BEAMOS_ROOM_CHEST, logic->CanKillEnemy(RE_BEAMOS)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST, {[]{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME) && logic->SmallKeys(RR_SPIRIT_TEMPLE, 5) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return logic->CanAvoidEnemy(RE_BEAMOS, true, 4) && logic->CanUse(RG_SONG_OF_TIME);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 6);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM] = Region("Spirit Temple MQ SoT Sun Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_CHEST_SWITCH_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, {[]{return logic->CanJumpslash();}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, []{return (logic->IsAdult || logic->CanUse(RG_SONG_OF_TIME)) && logic->CanUse(RG_MIRROR_SHIELD);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND] = Region("Spirit Temple MQ East Stairs to Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, {[]{return (ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)) &&
|
||||
Here(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return logic->CanKillEnemy(RE_FLOORMASTER);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE] = Region("Spirit Temple MQ East Iron Knuckle", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND, []{return logic->CanKillEnemy(RE_IRON_KNUCKLE);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND] = Region("Spirit Temple MQ Mirror Shield Hand", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MIRROR_SHIELD_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND, {[]{return logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE, {[]{return true;}}),
|
||||
Entrance(RR_DESERT_COLOSSUS, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM] = Region("Spirit Temple MQ 3F Gibdo Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_BOSS_KEY_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_WALL] = Region("Spirit Temple MQ Big Wall", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM, {[]{return true;}}),
|
||||
//technically we only need to avoid them, but the sheer height and the moving walls makes getting to the top after only stunning them very difficult/impossible
|
||||
//The silver rupees are irrelevant without silver shuffle
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return logic->CanKillEnemy(RE_KEESE);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL] = Region("Spirit Temple MQ 4F Central", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_WALL, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM, {[]{return logic->SmallKeys(RR_SPIRIT_TEMPLE, 7);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM] = Region("Spirit Temple MQ Nine Chairs Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
//These skulls rely on the iron knuckle existing without a trick to shoot through the chairs
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_WEST, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_GS_NINE_THRONES_ROOM_NORTH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM] = Region("Spirit Temple MQ Big Mirror Room", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL, {[]{return true;}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM, []{return logic->CanUse(RG_MEGATON_HAMMER);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE] = Region("Spirit Temple MQ Big Mirror Cave", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_SPIRIT_TEMPLE_MQ_MIRROR_PUZZLE_INVISIBLE_CHEST, ctx->GetTrickOption(RT_LENS_SPIRIT_MQ) || logic->CanUse(RG_LENS_OF_TRUTH)),
|
||||
}, {
|
||||
//Exits
|
||||
//If it's ever relevant to longshot into head from lobby, this needs to be an event access
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);}) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM, {[]{return Here(RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE, []{return logic->CanUse(RG_MIRROR_SHIELD);});}}),
|
||||
});
|
||||
|
||||
areaTable[RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD] = Region("Spirit Temple MQ Inside Statue Head", "Spirit Temple", {RA_SPIRIT_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
// Exits
|
||||
Entrance(RR_SPIRIT_TEMPLE_MQ_LOBBY, {[]{return true;} }),
|
||||
Entrance(RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_SPIRIT_TEMPLE_BOSS_KEY);}}),
|
||||
});
|
||||
}
|
||||
|
||||
/*---------------------------
|
||||
|
@ -10,9 +10,9 @@ void RegionTable_Init_WaterTemple() {
|
||||
---------------------------*/
|
||||
areaTable[RR_WATER_TEMPLE_ENTRYWAY] = Region("Water Temple Entryway", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsVanilla();}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsMQ();}}),
|
||||
Entrance(RR_LAKE_HYLIA, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsVanilla();}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->HasItem(RG_BRONZE_SCALE) && ctx->GetDungeon(WATER_TEMPLE)->IsMQ();}}),
|
||||
Entrance(RR_LAKE_HYLIA, {[]{return true;}}),
|
||||
});
|
||||
|
||||
/*--------------------------
|
||||
@ -23,29 +23,29 @@ void RegionTable_Init_WaterTemple() {
|
||||
areaTable[RR_WATER_TEMPLE_LOBBY] = Region("Water Temple Lobby", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return logic->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && (logic->CanUse(RG_IRON_BOOTS) || (logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_WATER_LONGSHOT_TORCH))));}}),
|
||||
Entrance(RR_WATER_TEMPLE_NORTH_LOWER, {[]{return logic->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}),
|
||||
Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, {[]{return logic->WaterTempleLow && logic->HasExplosives() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}),
|
||||
Entrance(RR_WATER_TEMPLE_WEST_LOWER, {[]{return logic->WaterTempleLow && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}),
|
||||
Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return logic->WaterTempleLow && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}),
|
||||
Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}),
|
||||
Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, {[]{return logic->WaterTempleMiddle;}}),
|
||||
Entrance(RR_WATER_TEMPLE_EAST_LOWER, {[]{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && (logic->CanUse(RG_IRON_BOOTS) || (logic->CanUse(RG_LONGSHOT) && ctx->GetTrickOption(RT_WATER_LONGSHOT_TORCH))));}}),
|
||||
Entrance(RR_WATER_TEMPLE_NORTH_LOWER, {[]{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}),
|
||||
Entrance(RR_WATER_TEMPLE_SOUTH_LOWER, {[]{return logic->CanWaterTempleLowFromHigh && logic->HasExplosives() && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}),
|
||||
Entrance(RR_WATER_TEMPLE_WEST_LOWER, {[]{return logic->CanWaterTempleLowFromHigh && logic->HasItem(RG_GORONS_BRACELET) && (logic->IsChild || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS)) && (ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC));}}),
|
||||
Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_LOWER, {[]{return logic->CanWaterTempleLowFromHigh && logic->SmallKeys(RR_WATER_TEMPLE, 5);}}),
|
||||
Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}),
|
||||
Entrance(RR_WATER_TEMPLE_EAST_MIDDLE, {[]{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_WEST_MIDDLE, {[]{return logic->CanWaterTempleMiddle;}}),
|
||||
Entrance(RR_WATER_TEMPLE_HIGH_WATER, {[]{return logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_DAMAGE_BOOST) && logic->CanUse(RG_BOMB_BAG) && logic->TakeDamage()));}}),
|
||||
Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, {[]{return (logic->WaterTempleLow || logic->WaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->WaterTempleMiddle)));}}),
|
||||
Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->WaterTempleHigh && logic->SmallKeys(RR_WATER_TEMPLE, 4);}}),
|
||||
Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return logic->WaterTempleHigh && logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_BLOCK_CORRIDOR, {[]{return (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle) && (logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW)) && (logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS) || (ctx->GetTrickOption(RT_WATER_CENTRAL_BOW) && (logic->IsAdult || logic->CanWaterTempleMiddle)));}}),
|
||||
Entrance(RR_WATER_TEMPLE_FALLING_PLATFORM_ROOM, {[]{return logic->CanWaterTempleHigh && logic->SmallKeys(RR_WATER_TEMPLE, 4);}}),
|
||||
Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return logic->CanWaterTempleHigh && logic->CanUse(RG_LONGSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_EAST_LOWER] = Region("Water Temple East Lower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->WaterTempleLow, {[]{return logic->WaterTempleLow || logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
EventAccess(&logic->CanWaterTempleLowFromHigh, {[]{return logic->CanWaterTempleLowFromHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->WaterTempleLow || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MAP_ROOM, {[]{return logic->WaterTempleHigh;}}),
|
||||
Entrance(RR_WATER_TEMPLE_CRACKED_WALL, {[]{return logic->WaterTempleMiddle || (logic->WaterTempleHigh && logic->WaterTempleLow && ((logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_WATER_CRACKED_WALL_HOVERS)) || ctx->GetTrickOption(RT_WATER_CRACKED_WALL)));}}),
|
||||
Entrance(RR_WATER_TEMPLE_TORCH_ROOM, {[]{return logic->WaterTempleLow && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}),
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanWaterTempleLowFromHigh || ((ctx->GetTrickOption(RT_FEWER_TUNIC_REQUIREMENTS) || logic->CanUse(RG_ZORA_TUNIC)) && logic->CanUse(RG_IRON_BOOTS));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MAP_ROOM, {[]{return logic->CanWaterTempleHigh;}}),
|
||||
Entrance(RR_WATER_TEMPLE_CRACKED_WALL, {[]{return logic->CanWaterTempleMiddle || (logic->CanWaterTempleHigh && logic->CanWaterTempleLowFromHigh && ((logic->CanUse(RG_HOVER_BOOTS) && ctx->GetTrickOption(RT_WATER_CRACKED_WALL_HOVERS)) || ctx->GetTrickOption(RT_WATER_CRACKED_WALL)));}}),
|
||||
Entrance(RR_WATER_TEMPLE_TORCH_ROOM, {[]{return logic->CanWaterTempleLowFromHigh && (logic->HasFireSourceWithTorch() || logic->CanUse(RG_FAIRY_BOW));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MAP_ROOM] = Region("Water Temple Map Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
@ -145,15 +145,15 @@ void RegionTable_Init_WaterTemple() {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 5);}}),
|
||||
Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, {[]{return logic->WaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}}),
|
||||
Entrance(RR_WATER_TEMPLE_CENTRAL_PILLAR_BASEMENT, {[]{return logic->CanWaterTempleMiddle && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_CENTRAL_PILLAR_UPPER] = Region("Water Temple Central Pillar Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->WaterTempleMiddle, {[]{return logic->WaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
EventAccess(&logic->CanWaterTempleMiddle, {[]{return logic->CanWaterTempleMiddle || logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->WaterTempleHigh && logic->HookshotOrBoomerang())),
|
||||
LOCATION(RC_WATER_TEMPLE_GS_CENTRAL_PILLAR, logic->CanUse(RG_LONGSHOT) || (((ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->SmallKeys(RR_WATER_TEMPLE, 5))) || (ctx->GetTrickOption(RT_WATER_IRONS_CENTRAL_GS) && logic->CanUse(RG_IRON_BOOTS) && ((logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_FAIRY_BOW)) || (logic->CanUse(RG_DINS_FIRE))))) && logic->CanWaterTempleHigh && logic->HookshotOrBoomerang())),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}),
|
||||
@ -184,7 +184,7 @@ void RegionTable_Init_WaterTemple() {
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_HIGH_WATER] = Region("Water Temple High Water", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->WaterTempleHigh, {[]{return logic->WaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
EventAccess(&logic->CanWaterTempleHigh, {[]{return logic->CanWaterTempleHigh || logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return true;}}),
|
||||
@ -192,7 +192,7 @@ void RegionTable_Init_WaterTemple() {
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_BLOCK_CORRIDOR] = Region("Water Temple Block Corridor", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->WaterTempleLow || logic->WaterTempleMiddle)),
|
||||
LOCATION(RC_WATER_TEMPLE_CENTRAL_BOW_TARGET_CHEST, logic->HasItem(RG_GORONS_BRACELET) && (logic->CanWaterTempleLowFromHigh || logic->CanWaterTempleMiddle)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_LOBBY, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
|
||||
@ -251,53 +251,407 @@ void RegionTable_Init_WaterTemple() {
|
||||
| MASTER QUEST DUNGEON |
|
||||
---------------------------*/
|
||||
if (ctx->GetDungeon(WATER_TEMPLE)->IsMQ()) {
|
||||
areaTable[RR_WATER_TEMPLE_MQ_LOBBY] = Region("Water Temple MQ Lobby", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
areaTable[RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE] = Region("Water Temple MQ 3F South Ledge", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DIVE, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_IRON_BOOTS);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DARK_LINK_REGION, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslashExceptHammer();}}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY) && logic->IsAdult && logic->CanJumpslashExceptHammer() && logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_ENTRYWAY, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}),
|
||||
//If we are not on WL_HIGH, we reach RR_WATER_TEMPLE_MQ_3F_MAIN with hookshot via 2F, otherwise we can reach the platform
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_2F_CENTRAL, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DIVE] = Region("Water Temple MQ Dive", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->HasFireSource() && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS)) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_SONG_OF_TIME)))),
|
||||
//Trick: logic->IsAdult && logic->CanUse(RG_ZORA_TUNIC) && logic->CanUse(RG_HOOKSHOT) && ((LogicWaterMQCentralPillar && logic->CanUse(RG_FIRE_ARROWS)) || (logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_SONG_OF_TIME)))
|
||||
//This region covers simply existing in the area around the central pillar without being on a specific platform, either swimming or walking on the lakebed
|
||||
//Entry should only include being in the correct area, taking any possible fall damage, and floating up to the surface of WL_HIGH if coming from below
|
||||
//This area then leads to others based on level and worst-case water timers for follow-up exits from the water's surface
|
||||
//remember that any solution that works for any level doesn't need to be given a level, even if that solution is overkill for a lower level
|
||||
areaTable[RR_WATER_TEMPLE_MQ_MAIN] = Region("Water Temple MQ Main", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE, {[]{return logic->HasItem(RG_BRONZE_SCALE) && logic->MQWaterLevel(WL_HIGH);}}),
|
||||
//Jumping across is possible but a trick due to the janky ledge
|
||||
Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER, {[]{return (logic->WaterTimer() >= 24 && logic->CanUse(RG_IRON_BOOTS)) ||
|
||||
(logic->MQWaterLevel(WL_MID) && logic->HasItem(RG_GOLDEN_SCALE) && logic->WaterTimer() >= 16) ||
|
||||
logic->MQWaterLevel(WL_LOW);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->HasItem(RG_BRONZE_SCALE);}}),
|
||||
//First water timer uses the hook to go from the top of center to storage room/central pillar as coming from the bottom
|
||||
//Second water timer is simply diving down and entering the door as fast as possible from the surface
|
||||
Entrance(RR_WATER_TEMPLE_MQ_2F_CENTRAL, {[]{return ((logic->MQWaterLevel(WL_LOW) || (logic->CanUse(RG_IRON_BOOTS) && (logic->MQWaterLevel(WL_MID) || logic->WaterTimer() >= 16))) && logic->CanUse(RG_LONGSHOT)) ||
|
||||
((logic->MQWaterLevel(WL_MID) || (logic->MQWaterLevel(WL_HIGH_OR_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8)) && logic->HasItem(RG_BRONZE_SCALE));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_1F, {[]{return logic->MQWaterLevel(WL_LOW);}}),
|
||||
//A special entry as we can't set it to high after entering at a lower height
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_2F_SOUTH, {[]{return (logic->MQWaterLevel(WL_MID) || (logic->MQWaterLevel(WL_HIGH_OR_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->HasItem(RG_BRONZE_SCALE);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, {[]{return logic->MQWaterB1Switch && (logic->MQWaterLevel(WL_LOW) || ((logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24) && logic->HasItem(RG_BRONZE_SCALE)));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM, {[]{return logic->MQWaterB1Switch &&
|
||||
((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_SILVER_SCALE)) ||
|
||||
(logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}}),
|
||||
//Adult needs to jump in instead of dive for swim access, but you just hold forward. RT_WATER_BK_REGION Isn't relevant unless the Dark Link loop can be done without longshot with other tricks
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, {[]{return logic->MQWaterB1Switch &&
|
||||
((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT))) &&
|
||||
(logic->CanUse(RG_LONGSHOT) || (ctx->GetTrickOption(RT_WATER_BK_REGION) && logic->CanUse(RG_HOVER_BOOTS)));}}),
|
||||
});
|
||||
|
||||
//This region specifically covers the topmost platform around central pillar
|
||||
areaTable[RR_WATER_TEMPLE_MQ_3F_CENTRAL] = Region("Water Temple MQ 3F Central", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE, {[]{return logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_2F_CENTRAL, {[]{return (logic->MQWaterLevel(WL_LOW_OR_MID) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16)) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_LONGSHOT);}}),
|
||||
//Jumping across is possible but a trick due to the janky ledge
|
||||
Entrance(RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, {[]{return logic->CanUse(RG_HOOKSHOT) || (logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS));}}),
|
||||
//room access is (logic->IsAdult || (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_HOOKSHOT)))
|
||||
Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_LONGSHOT);}}),
|
||||
//this swimless jump with irons may be a trick as you have to put irons on quite late.
|
||||
Entrance(RR_WATER_TEMPLE_MQ_2F_SOUTH, {[]{return (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16) || logic->MQWaterLevel(WL_LOW_OR_MID);}}),
|
||||
});
|
||||
|
||||
//This region specifically covers walking on the lower platform around central pillar. This is underwater when WL_HIGH
|
||||
//RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH should be accessed directly to use the central pillar door while at WL_HIGH
|
||||
areaTable[RR_WATER_TEMPLE_MQ_2F_CENTRAL] = Region("Water Temple MQ 2F Central", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STORAGE_ROOM, {[]{return logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) && (logic->IsAdult || logic->CanUse(RG_HOVER_BOOTS)) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_2F_SOUTH, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) && logic->CanUse(RG_HOVER_BOOTS);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_HIGH_EMBLEM] = Region("Water Temple MQ High Emblem", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->ReachedWaterHighEmblem, {[]{return true;}}),
|
||||
EventAccess(&logic->CanWaterTempleHigh, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE] = Region("Water Temple MQ 3F North Ledge", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
//what we need if WL_LOW, we can't guarantee repeated access otherwise.
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->TakeDamage();}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_DOOR, {[]{return logic->CanUse(RG_LONGSHOT) || logic->CanUse(RG_ICE_ARROWS) || logic->CanUse(RG_NAYRUS_LOVE);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BOSS_DOOR] = Region("Water Temple MQ Main", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE, {[]{return logic->CanUse(RG_ICE_ARROWS) || logic->TakeDamage();}}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ENTRYWAY, {[]{return logic->HasItem(RG_WATER_TEMPLE_BOSS_KEY);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER] = Region("Water Temple MQ East Tower", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//if we can't reach these, we can't move the water at all, so no need to specify level or account for WL_LOW access here
|
||||
//review is some way to play ocarina underwater exists
|
||||
EventAccess(&logic->CouldWaterTempleLow, {[]{return true;}}),
|
||||
EventAccess(&logic->CanWaterTempleLowFromHigh, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
//Reserved for glitches/tricks that could do this
|
||||
//EventAccess(&logic->CanWaterTempleLowFromMid, {[]{return false;}}),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_MAP_CHEST, logic->MQWaterLevel(WL_HIGH) && logic->HasFireSource() && logic->CanUse(RG_HOOKSHOT)),
|
||||
//easy to get at WL_HIGH with the hook-the-underwater-chest glitch
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_HOOKSHOT)),
|
||||
}, {
|
||||
Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM, {[]{return logic->MQWaterLevel(WL_LOW) && (logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE) || logic->CanUse(RG_STICKS));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS] = Region("Water Temple MQ Lowered Water Levels", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Raising the targets by clearing this room achieves nothing logically because it requires WL_LOW to do and hookshot to use, which implies access to WL_MID and WL_HIGH already
|
||||
areaTable[RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM] = Region("Water Temple MQ East Tower 1F Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, ((logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)) || logic->CanUse(RG_DINS_FIRE) || Here(RR_WATER_TEMPLE_MQ_LOBBY, []{return logic->IsChild && logic->CanUse(RG_STICKS) && logic->HasExplosives();})) &&
|
||||
(logic->CanJumpslashExceptHammer() || logic->CanUseProjectile())),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_LONGSHOT_CHEST, logic->IsAdult && logic->CanUse(RG_HOOKSHOT)),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, logic->CanUse(RG_DINS_FIRE)),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, logic->IsAdult && logic->CanUse(RG_LONGSHOT)),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_COMPASS_CHEST, logic->CanKillEnemy(RE_LIZALFOS) && logic->CanKillEnemy(RE_SPIKE)),
|
||||
}, {
|
||||
Entrance(RR_WATER_TEMPLE_MQ_EAST_TOWER, {[]{return true;}}),
|
||||
});
|
||||
|
||||
//This area assumes we entered through the lower door, so water is low and cannot be changed without leaving.
|
||||
areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_1F] = Region("Water Temple MQ Central Pillar 1F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//This is harder than the other possibilities as you have to move between shots on top of the extra range, but there's basically no universe this should matter.
|
||||
EventAccess(&logic->MQWaterB1Switch, {[]{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->HasItem(RG_BRONZE_SCALE);}}),
|
||||
//I don't know if this FW trick can ever matter but maybe it's needed to get child to CENTRAL_2F or something
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F, {[]{return logic->CanUse(RG_HOOKSHOT) ||
|
||||
(logic->MQWaterLevel(WL_MID) && ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) && logic->HasItem(RG_BRONZE_SCALE));}}),
|
||||
//if the gate is open, you sink straight in, so you can't climb up this way in logic without swimming
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, {[]{return logic->MQWaterOpenedPillarB1 && logic->MQWaterLevel(WL_HIGH_OR_MID) &&
|
||||
ctx->GetTrickOption(RT_WATER_FW_CENTRAL_GS) && logic->CanUse(RG_FARORES_WIND) &&
|
||||
logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}}),
|
||||
});
|
||||
|
||||
//If we enter here in WL_HIGH, go to RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH instead, Assumes WL_MID_OR_LOW
|
||||
areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F] = Region("Water Temple MQ Central Pillar 2F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->CouldWaterTempleMiddle, {[]{return true;}}),
|
||||
EventAccess(&logic->CanWaterTempleMiddle, {[]{return logic->CanUse(RG_ZELDAS_LULLABY);}}),
|
||||
//It's possible to do this even on low water, but more awkward. I'm not sure if it's even possible for it to be relevant though.
|
||||
EventAccess(&logic->MQWaterOpenedPillarB1, {[]{return ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS);}}),
|
||||
//this could theoretically matter once OI and equip swap is in logic, as one age may be able to get here dry and not wet, and the other may not be able to OI, but as you can OI with hookshot it probably never happens
|
||||
//EventAccess(&logic->MQWaterPillarSoTBlock, {[]{return logic->CanUse(RG_HOOKSHOT) && logic->CanUse(RG_SONG_OF_TIME);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH, {[]{return logic->MQWaterLevel(WL_HIGH) && logic->CanUse(RG_FARORES_WIND) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, {[]{return logic->MQWaterOpenedPillarB1 && logic->MQWaterLevel(WL_MID) && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH] = Region("Water Temple MQ Central Pillar High", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQWaterOpenedPillarB1, {[]{return ((logic->CanUse(RG_SONG_OF_TIME) && logic->CanUse(RG_DINS_FIRE)) || (ctx->GetTrickOption(RT_WATER_MQ_CENTRAL_PILLAR) && logic->CanUse(RG_FIRE_ARROWS))) &&
|
||||
(logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_LONGSHOT) && logic->CanJumpslash()));}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1, {[]{return logic->MQWaterB1Switch && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_ZORA_TUNIC);}}),
|
||||
});
|
||||
|
||||
//Assuming tunic and irons was checked on entry
|
||||
areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1] = Region("Water Temple MQ Central Pillar B1", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
//Can't know water level, so we'll just assume any possibility and skip to MAIN
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterOpenedPillarB1 && logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_BRONZE_SCALE);}}),
|
||||
//Child needs to release irons for height to push down the larger "peg", however they can push the lower one down by climbing and then hit the switch through the larger peg, but it's a trick
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL, {[]{return ((logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (logic->CanUse(RG_HOOKSHOT) && logic->HasItem(RG_BRONZE_SCALE)));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL] = Region("Water Temple MQ Central Pillar B1 Final", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_CENTRAL_PILLAR_CHEST, logic->CanUse(RG_HOOKSHOT)),
|
||||
}, {});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DARK_LINK_REGION] = Region("Water Temple MQ Dark Link Region", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Region exists to add crate/pot/box locations
|
||||
areaTable[RR_WATER_TEMPLE_MQ_STORAGE_ROOM] = Region("Water Temple MQ Storage Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F] = Region("Water Temple MQ Behind Blue Switch 2F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F, {[]{return logic->CanUse(RG_LONGSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F] = Region("Water Temple MQ Behind Blue Switch 2F", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_BEFORE_UPPER_WATER_SWITCH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_HIGH_EMBLEM, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_2F_SOUTH] = Region("Water Temple MQ Lowered Water Levels", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_2F_SOUTH_CAGE, {[]{return logic->MQWaterLevel(WL_LOW_OR_MID) && logic->CanUse(RG_DINS_FIRE);}}),
|
||||
//this technically exists, but only complicates things, uncomment if some edge case/glitch can use RR_WATER_TEMPLE_MQ_2F_SOUTH to reach RR_WATER_TEMPLE_MQ_3F_CENTRAL, or if a void warp goes here
|
||||
/*Entrance(RR_WATER_TEMPLE_MQ_3F_EAST_LEDGE, {[]{return (logic->CanUse(RG_HOOKSHOT) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS))) ||
|
||||
(logic->MQWaterLevel(WL_LOW_OR_MID) && logic->CanUse(RG_HOOKSHOT)) ||
|
||||
logic->MQWaterLevel(WL_HIGH) && (logic->HasItem(RG_BRONZE_SCALE));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_3F_EAST_LEDGE] = Region("Water Temple MQ 3F East Ledge", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS);}}),*/
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_2F_SOUTH_CAGE] = Region("Water Temple MQ Lowered Water Levels", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_LIZALFOS_HALLWAY, logic->CanKillEnemy(RE_GOLD_SKULLTULA)),
|
||||
}, {});
|
||||
|
||||
//This room exists to hold the wonderitems that drop from the emblems here. Specifically this assumes you are standing on the final ledge
|
||||
areaTable[RR_WATER_TEMPLE_MQ_WATERFALL] = Region("Water Temple Waterfall", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_3F_CENTRAL, {[]{return logic->SmallKeys(RR_WATER_TEMPLE, 1) && logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, {[]{return (logic->MQWaterStalfosPit && logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) || logic->CanUse(RG_HOVER_BOOTS);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_LONGSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT] = Region("Water Temple MQ Stalfos Pit", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQWaterStalfosPit, {[]{return ((logic->IsAdult && logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 3, false, true)) ||
|
||||
(logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT) && logic->CanKillEnemy(RE_STALFOS, ED_BOMB_THROW, true, 3, false, true)));}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, {[]{return (logic->IsAdult && logic->CanUse(RG_HOOKSHOT)) ||
|
||||
(logic->CanUse(RG_HOOKSHOT) && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && (logic->CanUse(RG_HOVER_BOOTS) || logic->MQWaterStalfosPit));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->MQWaterStalfosPit && (logic->IsAdult || logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
});
|
||||
|
||||
//also includes the suns fairy in the middle
|
||||
areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS] = Region("Water Temple MQ Stalfos Pit Pots", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FairyPot, {[]{return true;}}),
|
||||
EventAccess(&logic->NutPot, {[]{return true;}}),
|
||||
}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && (ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE) || logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS))),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_RIVER, true),
|
||||
}, {
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS, {[]{return logic->IsAdult && logic->WaterTimer() >= 24 && logic->CanUse(RG_DINS_FIRE) && logic->CanUse(RG_IRON_BOOTS);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_WATERFALL, {[]{return logic->MQWaterStalfosPit && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_LONGSHOT));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->MQWaterStalfosPit && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS] = Region("Water Temple MQ Basement Gated Areas", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//specifically the area past the spikes
|
||||
areaTable[RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER] = Region("Water Temple MQ Stalfos Pit Upper", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT, {[]{return logic->IsAdult || logic->TakeDamage();}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS, {[]{return logic->IsAdult || logic->TakeDamage();}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_AFTER_DARK_LINK, {[]{return logic->CanKillEnemy(RE_DARK_LINK);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_AFTER_DARK_LINK] = Region("Water Temple MQ After Dark Link", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FairyPot, {[]{return true;}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER, {[]{return logic->CanKillEnemy(RE_DARK_LINK);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_RIVER_SKULL, {[]{return logic->CanUse(RG_HOOKSHOT) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8) || logic->CanUse(RG_LONGSHOT));}}),
|
||||
});
|
||||
|
||||
//if we can use hookshot, we are standing on the targets, otherwise assume we're in the water
|
||||
areaTable[RR_WATER_TEMPLE_MQ_RIVER_SKULL] = Region("Water Temple MQ River Skull", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, logic->CanUse(RG_FIRE_ARROWS) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW))),
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, ctx->GetTrickOption(RT_WATER_MQ_LOCKED_GS) || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)) && logic->CanJumpslashExceptHammer())),
|
||||
//Trick: LogicWaterMQLockedGS || (logic->SmallKeys(RR_WATER_TEMPLE, 2) && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanUse(RG_SCARECROW) || LogicWaterNorthBasementLedgeJump))
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_RIVER, logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT))),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_RIVER_POTS, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_RIVER_POTS] = Region("Water Temple MQ River Pots", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->FairyPot, {[]{return true;}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_RIVER_SKULL, {[]{return logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && logic->CanUse(RG_HOOKSHOT));}}),
|
||||
//You don't need to swim for this if you put irons on in midair and hold forward while aiming for the tunnel with a tight angle, but if you miss you have to void unless you have a hook. It's only relevant with glitches anyway
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->IsAdult && logic->HasItem(RG_BRONZE_SCALE) && ctx->GetTrickOption(RT_WATER_DRAGON_JUMP_DIVE));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT) || (logic->CanUse(RG_HOVER_BOOTS) && logic->CanJumpslash());}}),
|
||||
});
|
||||
|
||||
//This region assumes Iron boots to access
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL] = Region("Water Temple MQ Dragon Room Tunnel", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_RIVER_POTS, {[]{return logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE] = Region("Water Temple MQ Dragon Room Alcove", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
EventAccess(&logic->MQWaterDragonTorches, {[]{return true;}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return logic->HasItem(RG_SILVER_SCALE);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR] = Region("Water Temple MQ Dragon Room Door", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_RIVER_POTS, {[]{return logic->CanUse(RG_LONGSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16 && logic->CanUse(RG_HOOKSHOT);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE, {[]{return logic->HasItem(RG_SILVER_SCALE);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->MQWaterDragonTorches;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH] = Region("Water Temple MQ Boss Key Room Switch", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, {[]{return logic->CanHitSwitch() && Here(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, []{return logic->CanUse(RG_DINS_FIRE);});}}),
|
||||
});
|
||||
|
||||
//this exists for the crates in preparation for clips through the grate
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT] = Region("Water Temple MQ Boss Key Room Pit", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->CanHitSwitch(ED_BOOMERANG);}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST] = Region("Water Temple MQ Boss Key Room Chest", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_BOSS_KEY_CHEST, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH, {[]{return logic->CanHitSwitch(ED_BOMB_THROW) || logic->CanUse(RG_HOVER_BOOTS);}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT, {[]{return true;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && (logic->HasItem(RG_BRONZE_SCALE) || (logic->WaterTimer() >= 24 && logic->CanUse(RG_LONGSHOT))));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH] = Region("Water Temple MQ B1 Gate Switch", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {
|
||||
//Events
|
||||
//If the water is low, the switch is underwater and needs irons to press, otherwise, the water is too low to climb up and you need irons to hookshot a target
|
||||
//If a glitch clips through the gate on low, have it logically press the switch and let entrance logic enter
|
||||
EventAccess(&logic->MQWaterB1Switch, {[]{return logic->CanUse(RG_IRON_BOOTS);}}),
|
||||
}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterB1Switch && (logic->MQWaterLevel(WL_LOW) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 16));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->HasItem(RG_BRONZE_SCALE) && (logic->MQWaterLevel(WL_LOW) || logic->WaterTimer() >= 24);}})
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM] = Region("Water Temple MQ Triangle Torch Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterB1Switch &&
|
||||
((logic->MQWaterLevel(WL_LOW) && logic->HasItem(RG_GOLDEN_SCALE)) ||
|
||||
(logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 40 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_LONGSHOT))));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, {[]{return logic->CanUse(RG_FIRE_ARROWS) &&
|
||||
((logic->IsAdult && logic->CanUse(RG_HOVER_BOOTS)) || (logic->CanUse(RG_LONGSHOT) && Here(RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE, []{return logic->ScarecrowsSong();})));}})
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE] = Region("Water Temple MQ Triangle Torch Cage", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_TRIPLE_WALL_TORCH, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),
|
||||
}, {});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM] = Region("Water Temple MQ Crates Whirlpools Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
//we can backflip over the spikes, but land in water.
|
||||
Entrance(RR_WATER_TEMPLE_MQ_MAIN, {[]{return logic->MQWaterB1Switch && logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 24 && (logic->CanUse(RG_LONGSHOT) || logic->HasItem(RG_BRONZE_SCALE));}}),
|
||||
//Child can use the crate to get the height to make it with hovers, but it's annoyingly tight so would be a trick
|
||||
Entrance(RR_WATER_TEMPLE_MQ_SINGLE_STALFOS_ROOM, {[]{return logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 &&
|
||||
//We're putting the requirement to get out of the water here as the scarecrow method in includes hook which satisfies it
|
||||
((logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP)) && (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_BRONZE_SCALE))) ||
|
||||
(Here(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, []{return logic->ScarecrowsSong();}) && logic->CanUse(RG_HOOKSHOT)));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_4_TORCH_ROOM, {[]{return logic->IsAdult &&
|
||||
(logic->CanUse(RG_HOVER_BOOTS) || ctx->GetTrickOption(RT_WATER_NORTH_BASEMENT_LEDGE_JUMP) ||
|
||||
(Here(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, []{return logic->ScarecrowsSong();}) && logic->CanUse(RG_HOOKSHOT)));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE, {[]{return ctx->GetTrickOption(RT_WATER_MQ_LOCKED_GS) && (logic->CanUse(RG_IRON_BOOTS) && logic->CanUse(RG_HOOKSHOT));}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_SINGLE_STALFOS_ROOM] = Region("Water Temple MQ Single Stalfos Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_FREESTANDING_KEY, true),
|
||||
}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, {[]{return logic->HasItem(RG_SILVER_SCALE) || (logic->IsChild && logic->HasItem(RG_BRONZE_SCALE)) ||
|
||||
(logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_HOOKSHOT)));}})
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_4_TORCH_ROOM] = Region("Water Temple MQ 4 Torch Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM, {[]{return (logic->IsAdult && (logic->CanUse(RG_HOVER_BOOTS) || logic->CanJumpslash())) ||
|
||||
(logic->HasItem(RG_BRONZE_SCALE) || (logic->CanUse(RG_IRON_BOOTS) && logic->WaterTimer() >= 8 && logic->CanUse(RG_HOOKSHOT) ));}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, {[]{return logic->CanHitSwitch() && logic->HasFireSource();}})
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_DODONGO_ROOM] = Region("Water Temple MQ Dodongo Room", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
|
||||
//Exits
|
||||
Entrance(RR_WATER_TEMPLE_MQ_4_TORCH_ROOM, {[]{return (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) &&
|
||||
Here(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);});}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE, {[]{return (logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_HOVER_BOOTS)) &&
|
||||
Here(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, []{return logic->CanKillEnemy(RE_DODONGO, ED_CLOSE, true, 5);});}})
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE] = Region("Water Temple MQ Basement Gated Areas", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
|
||||
//Locations
|
||||
LOCATION(RC_WATER_TEMPLE_MQ_GS_FREESTANDING_KEY_AREA, logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA)),
|
||||
}, {
|
||||
Entrance(RR_WATER_TEMPLE_MQ_DODONGO_ROOM, {[]{return true;}})
|
||||
});
|
||||
}
|
||||
|
||||
/*---------------------------
|
||||
@ -307,9 +661,9 @@ void RegionTable_Init_WaterTemple() {
|
||||
Region("Water Temple Boss Entryway", "Water Temple", {RA_WATER_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {},
|
||||
{
|
||||
// Exits
|
||||
Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, { [] { return ctx->GetDungeon(WATER_TEMPLE)->IsVanilla() && false; } }),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_LOBBY, { [] { return ctx->GetDungeon(WATER_TEMPLE)->IsMQ() && false; } }),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ROOM, { [] { return true; } }),
|
||||
Entrance(RR_WATER_TEMPLE_PRE_BOSS_ROOM, {[]{return ctx->GetDungeon(WATER_TEMPLE)->IsVanilla() && false;}}),
|
||||
Entrance(RR_WATER_TEMPLE_MQ_BOSS_DOOR, {[]{return ctx->GetDungeon(WATER_TEMPLE)->IsMQ() && false;}}),
|
||||
Entrance(RR_WATER_TEMPLE_BOSS_ROOM, {[]{return true;}}),
|
||||
});
|
||||
|
||||
areaTable[RR_WATER_TEMPLE_BOSS_ROOM] = Region("Water Temple Boss Room", "Water Temple", {}, NO_DAY_NIGHT_CYCLE,
|
||||
|
@ -92,12 +92,8 @@ ItemOverride& Context::GetItemOverride(size_t locKey) {
|
||||
void Context::PlaceItemInLocation(const RandomizerCheck locKey, const RandomizerGet item, const bool applyEffectImmediately,
|
||||
const bool setHidden) {
|
||||
const auto loc = GetItemLocation(locKey);
|
||||
SPDLOG_DEBUG("\n");
|
||||
SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish());
|
||||
SPDLOG_DEBUG(" placed at ");
|
||||
SPDLOG_DEBUG(StaticData::GetLocation(locKey)->GetName());
|
||||
SPDLOG_DEBUG("\n\n");
|
||||
|
||||
SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish() + " placed at " + StaticData::GetLocation(locKey)->GetName() + "\n");
|
||||
|
||||
if (applyEffectImmediately || mSettings->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS) || mSettings->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
|
||||
StaticData::RetrieveItem(item).ApplyEffect();
|
||||
}
|
||||
|
@ -923,7 +923,7 @@ int EntranceShuffler::ShuffleAllEntrances() {
|
||||
{ EntranceType::Interior, RR_MARKET_POTION_SHOP, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_POTION_SHOP } },
|
||||
{ { EntranceType::Interior, RR_THE_MARKET, RR_MARKET_TREASURE_CHEST_GAME, ENTR_TREASURE_BOX_SHOP_0 },
|
||||
{ EntranceType::Interior, RR_MARKET_TREASURE_CHEST_GAME, RR_THE_MARKET, ENTR_MARKET_DAY_OUTSIDE_TREASURE_BOX_SHOP } },
|
||||
{ { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_BOMBCHU_SHOP, ENTR_BOMBCHU_SHOP_0 },
|
||||
{ { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_BOMBCHU_SHOP, ENTR_BOMBCHU_SHOP_1 },
|
||||
{ EntranceType::Interior, RR_MARKET_BOMBCHU_SHOP, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_BOMBCHU_SHOP } },
|
||||
{ { EntranceType::Interior, RR_MARKET_BACK_ALLEY, RR_MARKET_MAN_IN_GREEN_HOUSE, ENTR_BACK_ALLEY_MAN_IN_GREEN_HOUSE },
|
||||
{ EntranceType::Interior, RR_MARKET_MAN_IN_GREEN_HOUSE, RR_MARKET_BACK_ALLEY, ENTR_BACK_ALLEY_DAY_OUTSIDE_MAN_IN_GREEN_HOUSE } },
|
||||
|
@ -674,7 +674,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
}
|
||||
break;
|
||||
case VB_MOVE_MIDO_IN_KOKIRI_FOREST:
|
||||
if (RAND_GET_OPTION(RSK_FOREST) == RO_FOREST_OPEN) {
|
||||
if (RAND_GET_OPTION(RSK_FOREST) == RO_FOREST_OPEN && gSaveContext.cutsceneIndex == 0) {
|
||||
*should = true;
|
||||
}
|
||||
break;
|
||||
@ -829,7 +829,7 @@ void RandomizerOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_l
|
||||
Actor_Kill(&item00->actor);
|
||||
*should = false;
|
||||
} else if (item00->actor.params == ITEM00_SOH_GIVE_ITEM_ENTRY) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
if (item00->itemEntry.modIndex == MOD_NONE) {
|
||||
if (item00->itemEntry.getItemId == GI_SWORD_BGS) {
|
||||
gSaveContext.bgsFlag = true;
|
||||
|
@ -59,6 +59,7 @@ namespace Rando {
|
||||
case RG_PROGRESSIVE_NUT_UPGRADE:
|
||||
case RG_NUTS:
|
||||
return CurrentUpgrade(UPG_NUTS);
|
||||
//RANDOTODO handle cases where the scarecrow is persistent between age better when OI is added
|
||||
case RG_SCARECROW:
|
||||
return ScarecrowsSong() && CanUse(RG_HOOKSHOT);
|
||||
case RG_DISTANT_SCARECROW:
|
||||
@ -433,12 +434,15 @@ namespace Rando {
|
||||
case ED_LONG_JUMPSLASH:
|
||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
killed = killed || CanUse(RG_BOMB_BAG);
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||
killed = killed || CanUse(RG_BOMB_BAG) || CanUse(RG_DINS_FIRE);
|
||||
//RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || CanUse(RG_DINS_FIRE);
|
||||
[[fallthrough]];
|
||||
case ED_HOOKSHOT:
|
||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||
//RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
@ -450,6 +454,7 @@ namespace Rando {
|
||||
}
|
||||
return killed;
|
||||
case RE_DODONGO:
|
||||
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || (quantity <= 5 && CanUse(RG_STICKS)) || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW);
|
||||
case RE_LIZALFOS:
|
||||
return CanJumpslash() || HasExplosives() || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_FAIRY_BOW);
|
||||
case RE_KEESE:
|
||||
@ -465,9 +470,13 @@ namespace Rando {
|
||||
case ED_LONG_JUMPSLASH:
|
||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
//RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||
killed = killed || CanUse(RG_BOOMERANG) || (!inWater && CanUse(RG_BOMB_BAG));
|
||||
//RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || CanUse(RG_BOOMERANG);
|
||||
[[fallthrough]];
|
||||
case ED_HOOKSHOT:
|
||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||
@ -495,8 +504,31 @@ namespace Rando {
|
||||
return CanDamage();
|
||||
case RE_STALFOS:
|
||||
//RANDOTODO Add trick to kill stalfos with sticks, and a second one for bombs without stunning. Higher ammo logic for bombs is also plausible
|
||||
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_MEGATON_HAMMER) || CanUse(RG_FAIRY_BOW) || CanUse(RG_BOMBCHU_5) ||
|
||||
(quantity <= 2 && !timer && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG)) || (quantity <= 1 && CanUse(RG_STICKS));
|
||||
switch (distance){
|
||||
case ED_CLOSE:
|
||||
case ED_SHORT_JUMPSLASH:
|
||||
killed = CanUse(RG_MEGATON_HAMMER) || CanUse(RG_KOKIRI_SWORD);
|
||||
[[fallthrough]];
|
||||
case ED_MASTER_SWORD_JUMPSLASH:
|
||||
killed = killed || CanUse(RG_MASTER_SWORD);
|
||||
[[fallthrough]];
|
||||
case ED_LONG_JUMPSLASH:
|
||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || (quantity <= 1 && CanUse(RG_STICKS));
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
killed = killed || (quantity <= 2 && !timer && !inWater && (CanUse(RG_NUTS) || HookshotOrBoomerang()) && CanUse(RG_BOMB_BAG));
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
case ED_HOOKSHOT:
|
||||
//RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
case ED_FAR:
|
||||
killed = killed || CanUse(RG_FAIRY_BOW);
|
||||
break;
|
||||
}
|
||||
return killed;
|
||||
//Needs 16 bombs, but is in default logic in N64, probably because getting the hits is quite easy.
|
||||
//bow and sling can wake them and damage after they shed their armour, so could reduce ammo requirements for explosives to 10.
|
||||
//requires 8 sticks to kill so would be a trick unless we apply higher stick bag logic
|
||||
@ -510,7 +542,9 @@ namespace Rando {
|
||||
return CanUse(RG_MEGATON_HAMMER) || CanUse(RG_HOOKSHOT) || (HasExplosives() && (CanJumpslashExceptHammer() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOOMERANG)));
|
||||
case RE_WOLFOS:
|
||||
case RE_WHITE_WOLFOS:
|
||||
case RE_WALLMASTER:
|
||||
return CanJumpslash() || CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT) || CanUse(RG_BOMBCHU_5) || CanUse(RG_DINS_FIRE) || (CanUse(RG_BOMB_BAG) && (CanUse(RG_NUTS) || CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG)));
|
||||
case RE_GIBDO:
|
||||
case RE_REDEAD:
|
||||
return CanJumpslash() || CanUse(RG_DINS_FIRE);
|
||||
case RE_MEG:
|
||||
@ -542,10 +576,11 @@ namespace Rando {
|
||||
case ED_LONG_JUMPSLASH:
|
||||
killed = killed || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||
case ED_BOMB_THROW:
|
||||
//RANDOTODO test dins and chu range in a practical example
|
||||
killed = killed || (!inWater && CanUse(RG_BOMB_BAG));
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
case ED_HOOKSHOT:
|
||||
//RANDOTODO test dins, bomb and chu range in a practical example
|
||||
killed = killed || CanUse(RG_HOOKSHOT) || (wallOrFloor && CanUse(RG_BOMBCHU_5));
|
||||
@ -561,6 +596,30 @@ namespace Rando {
|
||||
case RE_BIG_OCTO:
|
||||
//If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigains anyway. Bunny makes it free
|
||||
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD);
|
||||
case RE_GANONDORF:
|
||||
// RANDOTODO: Trick to use hammer (no jumpslash) or stick (only jumpslash) instead of a sword to reflect the energy ball
|
||||
// and either of them regardless of jumpslashing to damage and kill ganondorf
|
||||
|
||||
// Bottle is not taken into account since a sword, hammer or stick are required
|
||||
// for killing ganondorf and all of those can reflect the energy ball
|
||||
// This will not be the case once ammo logic in taken into account as
|
||||
// sticks are limited and using a bottle might become a requirement in that case
|
||||
return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_LIGHT_ARROWS) && (CanUse(RG_KOKIRI_SWORD) || CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD));
|
||||
case RE_GANON:
|
||||
return HasBossSoul(RG_GANON_SOUL) && CanUse(RG_MASTER_SWORD);
|
||||
case RE_DARK_LINK:
|
||||
//RANDOTODO Dark link is buggy right now, retest when he is not
|
||||
return CanJumpslash() || CanUse(RG_FAIRY_BOW);
|
||||
case RE_ANUBIS:
|
||||
//there's a restoration that allows beating them with mirror shield + some way to trigger thier attack
|
||||
return HasFireSource();
|
||||
case RE_BEAMOS:
|
||||
return HasExplosives();
|
||||
case RE_PURPLE_LEEVER:
|
||||
//dies on it's own, so this is the conditions to spawn it (killing 10 normal leevers)
|
||||
//Sticks and Ice arrows work but will need ammo capacity logic
|
||||
//other mothods can damage them but not kill them, and they run when hit, making them impractical
|
||||
return CanUse(RG_MASTER_SWORD) || CanUse(RG_BIGGORON_SWORD);
|
||||
default:
|
||||
SPDLOG_ERROR("CanKillEnemy reached `default`.");
|
||||
assert(false);
|
||||
@ -596,12 +655,17 @@ namespace Rando {
|
||||
case RE_ARMOS:
|
||||
case RE_FREEZARD:
|
||||
case RE_SPIKE:
|
||||
case RE_DARK_LINK:
|
||||
case RE_ANUBIS:
|
||||
case RE_WALLMASTER:
|
||||
case RE_PURPLE_LEEVER:
|
||||
return true;
|
||||
case RE_BIG_SKULLTULA:
|
||||
//hammer jumpslash can pass, but only on flat land where you can kill with hammer swing
|
||||
return CanUse(RG_NUTS) || CanUse(RG_BOOMERANG);
|
||||
case RE_LIKE_LIKE:
|
||||
return CanUse(RG_HOOKSHOT) || CanUse(RG_BOOMERANG);
|
||||
case RE_GIBDO:
|
||||
case RE_REDEAD:
|
||||
// we need a way to check if suns won't force a reload
|
||||
return CanUse(RG_HOOKSHOT) || CanUse(RG_SUNS_SONG);
|
||||
@ -618,46 +682,56 @@ namespace Rando {
|
||||
}
|
||||
|
||||
//Can we avoid this enemy while climbing up a wall, or doing a difficult platforming challenge?
|
||||
bool Logic::CanAvoidEnemy(RandomizerEnemy enemy) {
|
||||
if (CanKillEnemy(enemy)){
|
||||
return true;
|
||||
}
|
||||
switch(enemy) {
|
||||
case RE_GOLD_SKULLTULA:
|
||||
case RE_GOHMA_LARVA:
|
||||
case RE_LIZALFOS:
|
||||
case RE_DODONGO: //RANDOTODO do dodongos block the way in tight corridors?
|
||||
case RE_BIG_SKULLTULA:
|
||||
case RE_DEAD_HAND:
|
||||
case RE_DEKU_BABA:
|
||||
case RE_WITHERED_DEKU_BABA:
|
||||
case RE_LIKE_LIKE:
|
||||
case RE_STALFOS:
|
||||
case RE_IRON_KNUCKLE:
|
||||
case RE_FLARE_DANCER:
|
||||
case RE_WOLFOS:
|
||||
case RE_WHITE_WOLFOS:
|
||||
case RE_FLOORMASTER:
|
||||
case RE_REDEAD:
|
||||
case RE_MEG:
|
||||
case RE_ARMOS:
|
||||
case RE_GREEN_BUBBLE:
|
||||
case RE_FREEZARD:
|
||||
case RE_SPIKE:
|
||||
case RE_BIG_OCTO:
|
||||
return true;
|
||||
case RE_MAD_SCRUB:
|
||||
case RE_KEESE:
|
||||
case RE_FIRE_KEESE:
|
||||
return CanUse(RG_NUTS);
|
||||
case RE_BLUE_BUBBLE:
|
||||
//RANDOTODO Trick to use shield hylian shield as child to stun these guys
|
||||
return CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield();
|
||||
default:
|
||||
SPDLOG_ERROR("CanPassEnemy reached `default`.");
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
//use grounded if the challenge is such that the enemy interfears even if it cannot hit link out of the air
|
||||
bool Logic::CanAvoidEnemy(RandomizerEnemy enemy, bool grounded, uint8_t quantity) {
|
||||
//DISTANCE AND WALL ASSUMED, add more arguments later if needed
|
||||
if (CanKillEnemy(enemy, ED_CLOSE, true, quantity)){
|
||||
return true;
|
||||
}
|
||||
switch(enemy) {
|
||||
case RE_GOLD_SKULLTULA:
|
||||
case RE_GOHMA_LARVA:
|
||||
case RE_LIZALFOS:
|
||||
case RE_DODONGO:
|
||||
case RE_BIG_SKULLTULA:
|
||||
case RE_DEAD_HAND:
|
||||
case RE_DEKU_BABA:
|
||||
case RE_WITHERED_DEKU_BABA:
|
||||
case RE_LIKE_LIKE:
|
||||
case RE_STALFOS:
|
||||
case RE_IRON_KNUCKLE:
|
||||
case RE_FLARE_DANCER:
|
||||
case RE_WOLFOS:
|
||||
case RE_WHITE_WOLFOS:
|
||||
case RE_FLOORMASTER:
|
||||
case RE_REDEAD:
|
||||
case RE_MEG:
|
||||
case RE_ARMOS:
|
||||
case RE_GREEN_BUBBLE:
|
||||
case RE_FREEZARD:
|
||||
case RE_SPIKE:
|
||||
case RE_BIG_OCTO:
|
||||
case RE_GIBDO:
|
||||
case RE_DARK_LINK:
|
||||
case RE_WALLMASTER:
|
||||
case RE_ANUBIS:
|
||||
case RE_PURPLE_LEEVER:
|
||||
return true;
|
||||
case RE_BEAMOS:
|
||||
return !grounded || CanUse(RG_NUTS) || (quantity == 1 && (CanUse(RG_FAIRY_BOW) || CanUse(RG_FAIRY_SLINGSHOT)));
|
||||
case RE_MAD_SCRUB:
|
||||
return !grounded || CanUse(RG_NUTS);
|
||||
case RE_KEESE:
|
||||
case RE_FIRE_KEESE:
|
||||
return CanUse(RG_NUTS);
|
||||
case RE_BLUE_BUBBLE:
|
||||
//RANDOTODO Trick to use shield hylian shield as child to stun these guys
|
||||
return !grounded || CanUse(RG_NUTS) || HookshotOrBoomerang() || CanStandingShield();
|
||||
default:
|
||||
SPDLOG_ERROR("CanPassEnemy reached `default`.");
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Logic::CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance, bool aboveLink) {
|
||||
@ -675,6 +749,7 @@ namespace Rando {
|
||||
case ED_SHORT_JUMPSLASH:
|
||||
case ED_MASTER_SWORD_JUMPSLASH:
|
||||
case ED_LONG_JUMPSLASH:
|
||||
case ED_BOMB_THROW:
|
||||
case ED_BOOMERANG:
|
||||
drop = drop || CanUse(RG_BOOMERANG);
|
||||
[[fallthrough]];
|
||||
@ -685,9 +760,10 @@ namespace Rando {
|
||||
drop = drop || CanUse(RG_LONGSHOT);
|
||||
[[fallthrough]];
|
||||
case ED_FAR:
|
||||
return drop;
|
||||
break;
|
||||
//RANDOTODO double check all jumpslash kills that might be out of jump/backflip range
|
||||
}
|
||||
return drop;
|
||||
break;
|
||||
case RE_KEESE:
|
||||
case RE_FIRE_KEESE:
|
||||
@ -722,6 +798,35 @@ namespace Rando {
|
||||
return CanDetonateBombFlowers() || HasItem(RG_GORONS_BRACELET);
|
||||
}
|
||||
|
||||
bool Logic::MQWaterLevel(RandoWaterLevel level) {
|
||||
//For ease of reading, I will call the triforce emblem that sets the water to WL_LOW the "Low Emblem", the one that sets it to WL_MID the "Mid Emblem", and the one that sets it to WL_HIGH the "High Emblem"
|
||||
switch(level){
|
||||
//While you have to go through WL_LOW to get to Mid, the requirements for WL_LOW are stricter than WL_MID because you can always go up to WL_MID and then could need to go back to WL_HIGH to reach the Low Emblem again
|
||||
//Thanks to this caveat you need to be able to reach and play ZL to both the High and Low Emblems to have WL_LOW in logic.
|
||||
//Alternativly a way to reach WL_LOW from WL_MID could exist, but all glitchless methods need you to do a Low-locked action
|
||||
case WL_LOW:
|
||||
return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh);
|
||||
case WL_LOW_OR_MID:
|
||||
return (CanWaterTempleHigh && CanWaterTempleLowFromHigh) || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle) || (CanWaterTempleLowFromMid && CanWaterTempleLowFromHigh);
|
||||
//If we can set it to High out of logic we can just repeat what we did to lower the water in the first place as High is the default.
|
||||
//Because of this you only need to be able to use the Low and Mid Emblems, WL_LOW could be skipped if it was ever possible to play ZL underwater.
|
||||
case WL_MID:
|
||||
return CanWaterTempleLowFromHigh && CanWaterTempleMiddle;
|
||||
//Despite being the initial state of water temple, WL_HIGH has the extra requirement of making sure that, if we were to lower the water out of logic, we could put it back to WL_HIGH
|
||||
//However because it is the default state, we do not need to check if we can actually change the water level, only to make sure we can return to WL_HIGH if we found the means to play ZL out of logic.
|
||||
//There are 2 methods to lock yourself out after playing ZL already: Not being able to reach the High Emblem and being unable to replay ZL. (I will be ignoring other-age-access shenanigains)
|
||||
//The former check would simply be a check to see if we can reach High Emblem, but we assume the water is WL_MID (as if we can set it to WL_LOW, we can set it to WL_MID, as Mid Emblem has no requirements)
|
||||
//The latter check can be assumed for now but will want a revisit once OI tricks are added.
|
||||
case WL_HIGH:
|
||||
return ReachedWaterHighEmblem;
|
||||
case WL_HIGH_OR_MID:
|
||||
return ReachedWaterHighEmblem || (CanWaterTempleLowFromHigh && CanWaterTempleMiddle);
|
||||
}
|
||||
SPDLOG_ERROR("MQWaterLevel reached `return false;`. Missing case for a Water Level");
|
||||
assert(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
Logic::Logic() {
|
||||
|
||||
}
|
||||
@ -770,12 +875,14 @@ namespace Rando {
|
||||
case ED_LONG_JUMPSLASH:
|
||||
hit = hit || CanUse(RG_BIGGORON_SWORD) || CanUse(RG_STICKS);
|
||||
[[fallthrough]];
|
||||
case ED_BOMB_THROW:
|
||||
hit = hit || (!inWater && CanUse(RG_BOMB_BAG));
|
||||
[[fallthrough]];
|
||||
case ED_BOOMERANG:
|
||||
//RANDOTODO test bomb and chu range in a practical example
|
||||
hit = hit || CanUse(RG_BOOMERANG) || (!inWater && CanUse(RG_BOMB_BAG)) ;
|
||||
hit = hit || CanUse(RG_BOOMERANG);
|
||||
[[fallthrough]];
|
||||
case ED_HOOKSHOT:
|
||||
//RANDOTODO test bomb and chu range in a practical example
|
||||
//RANDOTODO test chu range in a practical example
|
||||
hit = hit || CanUse(RG_HOOKSHOT) || CanUse(RG_BOMBCHU_5) ;
|
||||
[[fallthrough]];
|
||||
case ED_LONGSHOT:
|
||||
@ -2004,9 +2111,10 @@ namespace Rando {
|
||||
GCWoodsWarpOpen = false;
|
||||
GCDaruniasDoorOpenChild = false;
|
||||
StopGCRollingGoronAsAdult = false;
|
||||
WaterTempleLow = false;
|
||||
WaterTempleMiddle = false;
|
||||
WaterTempleHigh = false;
|
||||
CanWaterTempleLowFromHigh = false;
|
||||
CanWaterTempleLowFromMid = false;
|
||||
CanWaterTempleMiddle = false;
|
||||
CanWaterTempleHigh = false;
|
||||
KakarikoVillageGateOpen = false;
|
||||
KingZoraThawed = false;
|
||||
ForestTempleJoelle = false;
|
||||
@ -2040,6 +2148,16 @@ namespace Rando {
|
||||
JabuNorthTentacle = false;
|
||||
LoweredJabuPath = false;
|
||||
MQJabuLiftRoomCow = false;
|
||||
MQShadowFloorSpikeRupees = false;
|
||||
ShadowShortcutBlock = false;
|
||||
MQWaterStalfosPit = false;
|
||||
MQWaterDragonTorches = false;
|
||||
MQWaterB1Switch = false;
|
||||
//MQWaterPillarSoTBlock = false;
|
||||
MQWaterOpenedPillarB1 = false;
|
||||
MQSpiritCrawlBoulder = false;
|
||||
MQSpiritMapRoomEnemies = false;
|
||||
MQSpirit3SunsEnemies = false;
|
||||
|
||||
StopPerformanceTimer(PT_LOGIC_RESET);
|
||||
}
|
||||
|
@ -118,9 +118,13 @@ class Logic {
|
||||
bool GCWoodsWarpOpen = false;
|
||||
bool GCDaruniasDoorOpenChild = false;
|
||||
bool StopGCRollingGoronAsAdult = false;
|
||||
bool WaterTempleLow = false;
|
||||
bool WaterTempleMiddle = false;
|
||||
bool WaterTempleHigh = false;
|
||||
bool CanWaterTempleLowFromHigh = false;
|
||||
bool CanWaterTempleMiddle = false;
|
||||
bool CanWaterTempleHigh = false;
|
||||
bool CanWaterTempleLowFromMid = false;
|
||||
bool CouldWaterTempleLow = false;
|
||||
bool CouldWaterTempleMiddle = false;
|
||||
bool ReachedWaterHighEmblem = false;
|
||||
bool KakarikoVillageGateOpen = false;
|
||||
bool KingZoraThawed = false;
|
||||
bool ForestTempleJoelle = false;
|
||||
@ -155,6 +159,18 @@ class Logic {
|
||||
bool JabuNorthTentacle = false;
|
||||
bool LoweredJabuPath = false;
|
||||
bool MQJabuLiftRoomCow = false;
|
||||
bool MQShadowFloorSpikeRupees = false;
|
||||
bool ShadowShortcutBlock = false;
|
||||
bool MQWaterStalfosPit = false;
|
||||
bool MQWaterDragonTorches = false;
|
||||
bool MQWaterB1Switch = false;
|
||||
//bool MQWaterPillarSoTBlock = false; should be irrelevant. SHOULD.
|
||||
bool MQWaterOpenedPillarB1 = false;
|
||||
bool MQSpiritCrawlBoulder = false;
|
||||
bool MQSpiritMapRoomEnemies = false;
|
||||
bool MQSpiritTimeTravelChest = false;
|
||||
bool MQSpirit3SunsEnemies = false;
|
||||
bool Spirit1FSilverRupees = false;
|
||||
|
||||
/* --- END OF HELPERS AND LOCATION ACCESS --- */
|
||||
|
||||
@ -170,7 +186,7 @@ class Logic {
|
||||
bool CanEquipSwap(RandomizerGet itemName);
|
||||
bool CanKillEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true, uint8_t quantity = 1, bool timer = false, bool inWater = false);
|
||||
bool CanPassEnemy(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool wallOrFloor = true);
|
||||
bool CanAvoidEnemy(RandomizerEnemy enemy);
|
||||
bool CanAvoidEnemy(RandomizerEnemy enemy, bool grounded = false, uint8_t quantity = 1);
|
||||
bool CanGetEnemyDrop(RandomizerEnemy enemy, EnemyDistance distance = ED_CLOSE, bool aboveLink = false);
|
||||
bool CanBreakMudWalls();
|
||||
bool CanGetDekuBabaSticks();
|
||||
@ -178,6 +194,7 @@ class Logic {
|
||||
bool CanHitEyeTargets();
|
||||
bool CanDetonateBombFlowers();
|
||||
bool CanDetonateUprightBombFlower();
|
||||
bool MQWaterLevel(RandoWaterLevel level);
|
||||
uint8_t BottleCount();
|
||||
uint8_t OcarinaButtons();
|
||||
bool HasBottle();
|
||||
|
@ -751,11 +751,48 @@ typedef enum {
|
||||
RR_WATER_TEMPLE_RIVER,
|
||||
RR_WATER_TEMPLE_PRE_BOSS_ROOM,
|
||||
|
||||
RR_WATER_TEMPLE_MQ_LOBBY,
|
||||
RR_WATER_TEMPLE_MQ_DIVE,
|
||||
RR_WATER_TEMPLE_MQ_LOWERED_WATER_LEVELS,
|
||||
RR_WATER_TEMPLE_MQ_DARK_LINK_REGION,
|
||||
RR_WATER_TEMPLE_MQ_BASEMENT_GATED_AREAS,
|
||||
RR_WATER_TEMPLE_MQ_3F_SOUTH_LEDGE,
|
||||
RR_WATER_TEMPLE_MQ_MAIN,
|
||||
RR_WATER_TEMPLE_MQ_3F_CENTRAL,
|
||||
RR_WATER_TEMPLE_MQ_2F_CENTRAL,
|
||||
RR_WATER_TEMPLE_MQ_2F_CENTRAL_HIGH,
|
||||
RR_WATER_TEMPLE_MQ_HIGH_EMBLEM,
|
||||
RR_WATER_TEMPLE_MQ_3F_NORTH_LEDGE,
|
||||
RR_WATER_TEMPLE_MQ_BOSS_DOOR,
|
||||
RR_WATER_TEMPLE_MQ_EAST_TOWER,
|
||||
RR_WATER_TEMPLE_MQ_EAST_TOWER_1F_ROOM,
|
||||
RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_1F,
|
||||
RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_2F,
|
||||
RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_HIGH,
|
||||
RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1,
|
||||
RR_WATER_TEMPLE_MQ_CENTRAL_PILLAR_B1_FINAL,
|
||||
RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_2F,
|
||||
RR_WATER_TEMPLE_MQ_BEHIND_BLUE_SWITCH_3F,
|
||||
RR_WATER_TEMPLE_MQ_STORAGE_ROOM,
|
||||
RR_WATER_TEMPLE_MQ_2F_SOUTH,
|
||||
RR_WATER_TEMPLE_MQ_2F_SOUTH_CAGE,
|
||||
RR_WATER_TEMPLE_MQ_3F_EAST_LEDGE,
|
||||
RR_WATER_TEMPLE_MQ_WATERFALL,
|
||||
RR_WATER_TEMPLE_MQ_STALFOS_PIT,
|
||||
RR_WATER_TEMPLE_MQ_STALFOS_PIT_POTS,
|
||||
RR_WATER_TEMPLE_MQ_STALFOS_PIT_UPPER,
|
||||
RR_WATER_TEMPLE_MQ_AFTER_DARK_LINK,
|
||||
RR_WATER_TEMPLE_MQ_RIVER_SKULL,
|
||||
RR_WATER_TEMPLE_MQ_RIVER_POTS,
|
||||
RR_WATER_TEMPLE_MQ_DRAGON_ROOM_DOOR,
|
||||
RR_WATER_TEMPLE_MQ_DRAGON_ROOM_TUNNEL,
|
||||
RR_WATER_TEMPLE_MQ_DRAGON_ROOM_ALCOVE,
|
||||
RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_SWITCH,
|
||||
RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_PIT,
|
||||
RR_WATER_TEMPLE_MQ_BOSS_KEY_ROOM_CHEST,
|
||||
RR_WATER_TEMPLE_MQ_B1_GATE_SWITCH,
|
||||
RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_ROOM,
|
||||
RR_WATER_TEMPLE_MQ_TRIANGLE_TORCH_CAGE,
|
||||
RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_ROOM,
|
||||
RR_WATER_TEMPLE_MQ_SINGLE_STALFOS_ROOM,
|
||||
RR_WATER_TEMPLE_MQ_4_TORCH_ROOM,
|
||||
RR_WATER_TEMPLE_MQ_DODONGO_ROOM,
|
||||
RR_WATER_TEMPLE_MQ_CRATES_WHIRLPOOLS_CAGE,
|
||||
|
||||
RR_WATER_TEMPLE_BOSS_ENTRYWAY,
|
||||
RR_WATER_TEMPLE_BOSS_ROOM,
|
||||
@ -771,13 +808,39 @@ typedef enum {
|
||||
RR_SPIRIT_TEMPLE_INSIDE_STATUE_HEAD,
|
||||
|
||||
RR_SPIRIT_TEMPLE_MQ_LOBBY,
|
||||
RR_SPIRIT_TEMPLE_MQ_CHILD,
|
||||
RR_SPIRIT_TEMPLE_MQ_ADULT,
|
||||
RR_SPIRIT_TEMPLE_MQ_SHARED,
|
||||
RR_SPIRIT_TEMPLE_MQ_LOWER_ADULT,
|
||||
RR_SPIRIT_TEMPLE_MQ_BOSS_AREA,
|
||||
RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_1F_WEST,
|
||||
RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_NORTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_1F_GIBDO_ROOM_SOUTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_TURNTABLE_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_NORTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_MAP_ROOM_SOUTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_1F_RUSTED_SWITCH,
|
||||
RR_SPIRIT_TEMPLE_MQ_UNDER_LIKE_LIKE,
|
||||
RR_SPIRIT_TEMPLE_MQ_BROKEN_WALL_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_SUN_BLOCK_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_WEST_IRON_KNUCKLE,
|
||||
RR_SPIRIT_TEMPLE_MQ_SILVER_GAUNTLETS_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_SOUTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_BLOCK_ROOM_NORTH,
|
||||
RR_SPIRIT_TEMPLE_MQ_STATUE_ROOM_EAST,
|
||||
RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_2F,
|
||||
RR_SPIRIT_TEMPLE_MQ_THREE_SUNS_ROOM_1F,
|
||||
RR_SPIRIT_TEMPLE_MQ_1F_EAST,
|
||||
RR_SPIRIT_TEMPLE_MQ_LEEVER_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_SYMPHONY_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_AFTER_SYMPHONY_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_FOUR_BEAMOS_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_SOT_SUN_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_EAST_STAIRS_TO_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_EAST_IRON_KNUCKLE,
|
||||
RR_SPIRIT_TEMPLE_MQ_MIRROR_SHIELD_HAND,
|
||||
RR_SPIRIT_TEMPLE_MQ_3F_GIBDO_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_WALL,
|
||||
RR_SPIRIT_TEMPLE_MQ_4F_CENTRAL,
|
||||
RR_SPIRIT_TEMPLE_MQ_NINE_CHAIRS_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_ROOM,
|
||||
RR_SPIRIT_TEMPLE_MQ_BIG_MIRROR_CAVE,
|
||||
RR_SPIRIT_TEMPLE_MQ_INSIDE_STATUE_HEAD,
|
||||
|
||||
RR_SPIRIT_TEMPLE_BOSS_ENTRYWAY,
|
||||
@ -791,13 +854,28 @@ typedef enum {
|
||||
|
||||
RR_SHADOW_TEMPLE_MQ_ENTRYWAY,
|
||||
RR_SHADOW_TEMPLE_MQ_BEGINNING,
|
||||
RR_SHADOW_TEMPLE_MQ_SPINNER_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_DEAD_HAND_AREA,
|
||||
RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS,
|
||||
RR_SHADOW_TEMPLE_MQ_B2_SPINNING_BLADE_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_SHORTCUT_PATH,
|
||||
RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR,
|
||||
RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT,
|
||||
RR_SHADOW_TEMPLE_MQ_INVISIBLE_BLADES_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_LOWER_HUGE_PIT,
|
||||
RR_SHADOW_TEMPLE_MQ_FALLING_SPIKES_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_UPPER_FALLING_SPIKES_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_FLOOR_SPIKES_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_STALFOS_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_WIND_TUNNEL,
|
||||
RR_SHADOW_TEMPLE_MQ_WIND_HINT_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_B4_GIBDO_ROOM,
|
||||
RR_SHADOW_TEMPLE_MQ_DOCK,
|
||||
RR_SHADOW_TEMPLE_MQ_BEYOND_BOAT,
|
||||
RR_SHADOW_TEMPLE_MQ_ACROSS_CHASM,
|
||||
RR_SHADOW_TEMPLE_MQ_BOSS_DOOR,
|
||||
RR_SHADOW_TEMPLE_MQ_INVISIBLE_MAZE,
|
||||
RR_SHADOW_TEMPLE_MQ_SPIKE_WALLS_ROOM,
|
||||
|
||||
RR_SHADOW_TEMPLE_BOSS_ENTRYWAY,
|
||||
RR_SHADOW_TEMPLE_BOSS_ROOM,
|
||||
@ -873,7 +951,6 @@ typedef enum {
|
||||
RR_GANONS_CASTLE_SHADOW_TRIAL,
|
||||
RR_GANONS_CASTLE_SPIRIT_TRIAL,
|
||||
RR_GANONS_CASTLE_LIGHT_TRIAL,
|
||||
RR_GANONS_CASTLE_TOWER,
|
||||
|
||||
RR_GANONS_CASTLE_MQ_LOBBY,
|
||||
RR_GANONS_CASTLE_MQ_MAIN,
|
||||
@ -902,6 +979,13 @@ typedef enum {
|
||||
RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_BOULDER_ROOM_BACK,
|
||||
RR_GANONS_CASTLE_MQ_LIGHT_TRIAL_FINAL_ROOM,
|
||||
|
||||
RR_GANONS_TOWER_FLOOR_1,
|
||||
RR_GANONS_TOWER_FLOOR_2,
|
||||
RR_GANONS_TOWER_FLOOR_3,
|
||||
RR_GANONS_TOWER_GANONDORF_LAIR,
|
||||
RR_GANONS_CASTLE_ESCAPE,
|
||||
RR_GANONS_CASTLE_GANON_ARENA,
|
||||
|
||||
RR_MARKER_AREAS_END, // Used for area key count
|
||||
|
||||
// DUNGEONS
|
||||
@ -4509,6 +4593,14 @@ typedef enum {
|
||||
RE_WHITE_WOLFOS,
|
||||
RE_STINGER,
|
||||
RE_BIG_OCTO,
|
||||
RE_GIBDO,
|
||||
RE_GANONDORF,
|
||||
RE_GANON,
|
||||
RE_DARK_LINK,
|
||||
RE_ANUBIS,
|
||||
RE_BEAMOS,
|
||||
RE_WALLMASTER,
|
||||
RE_PURPLE_LEEVER,
|
||||
} RandomizerEnemy;
|
||||
|
||||
//RANDOTODO compare child long jumpslash range with adult short
|
||||
@ -4519,12 +4611,21 @@ typedef enum {
|
||||
ED_MASTER_SWORD_JUMPSLASH,
|
||||
//sticks or BGS
|
||||
ED_LONG_JUMPSLASH,
|
||||
ED_BOMB_THROW,
|
||||
ED_BOOMERANG,
|
||||
ED_HOOKSHOT,
|
||||
ED_LONGSHOT,
|
||||
ED_FAR,
|
||||
} EnemyDistance;
|
||||
|
||||
typedef enum {
|
||||
WL_LOW,
|
||||
WL_MID,
|
||||
WL_HIGH,
|
||||
WL_LOW_OR_MID,
|
||||
WL_HIGH_OR_MID
|
||||
} RandoWaterLevel;
|
||||
|
||||
#define ENTRANCE_GROTTO_LOAD_START 0x0700
|
||||
#define ENTRANCE_GROTTO_EXIT_START 0x0800
|
||||
|
||||
|
@ -198,7 +198,7 @@ void Entrance_Init(void) {
|
||||
bossSceneSaveDeathWarps[bossScene - SCENE_DEKU_TREE_BOSS] = saveWarpEntrance;
|
||||
}
|
||||
|
||||
//Overwrite grotto related indices
|
||||
// Overwrite grotto related indices
|
||||
if (originalIndex >= ENTRANCE_GROTTO_EXIT_START) {
|
||||
Grotto_SetExitOverride(originalIndex, overrideIndex);
|
||||
continue;
|
||||
@ -226,7 +226,7 @@ void Entrance_Init(void) {
|
||||
|
||||
s16 indicesToSilenceBackgroundMusic[2] = {
|
||||
// The lost woods music playing near the GC Woods Warp keeps playing
|
||||
// in the next area if the bvackground music is allowed to keep playing
|
||||
// in the next area if the background music is allowed to keep playing
|
||||
entranceOverrideTable[ENTR_LOST_WOODS_TUNNEL_SHORTCUT], // Goron City -> Lost Woods override
|
||||
|
||||
// If Malon is singing at night, then her singing will be transferred
|
||||
@ -452,7 +452,19 @@ void Entrance_SetWarpSongEntrance(void) {
|
||||
}
|
||||
|
||||
void Entrance_OverrideBlueWarp(void) {
|
||||
// Handles first time entering bluewarp (with item give)
|
||||
// Remap child 2nd visits in adult dungeons for warp pad -> bluewarp
|
||||
if (gSaveContext.entranceIndex == ENTR_SACRED_FOREST_MEADOW_WARP_PAD) {
|
||||
gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP;
|
||||
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_CRATER_WARP_PAD) {
|
||||
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP;
|
||||
} else if (gSaveContext.entranceIndex == ENTR_LAKE_HYLIA_WARP_PAD) {
|
||||
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP;
|
||||
} else if (gSaveContext.entranceIndex == ENTR_DESERT_COLOSSUS_WARP_PAD) {
|
||||
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP;
|
||||
} else if (gSaveContext.entranceIndex == ENTR_GRAVEYARD_WARP_PAD) {
|
||||
gSaveContext.entranceIndex = ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP;
|
||||
}
|
||||
|
||||
switch (gSaveContext.entranceIndex) {
|
||||
case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp
|
||||
case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp
|
||||
@ -465,20 +477,6 @@ void Entrance_OverrideBlueWarp(void) {
|
||||
gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handles second+ times entering bluewarp
|
||||
switch (gPlayState->nextEntranceIndex) {
|
||||
case ENTR_KOKIRI_FOREST_DEKU_TREE_BLUE_WARP: // Gohma blue warp
|
||||
case ENTR_DEATH_MOUNTAIN_TRAIL_DODONGO_BLUE_WARP: // KD blue warp
|
||||
case ENTR_ZORAS_FOUNTAIN_JABU_JABU_BLUE_WARP: // Barinade blue warp
|
||||
case ENTR_SACRED_FOREST_MEADOW_FOREST_TEMPLE_BLUE_WARP: // Phantom Ganon blue warp
|
||||
case ENTR_DEATH_MOUNTAIN_CRATER_FIRE_TEMPLE_BLUE_WARP: // Volvagia blue warp
|
||||
case ENTR_LAKE_HYLIA_WATER_TEMPLE_BLUE_WARP: // Morpha blue warp
|
||||
case ENTR_DESERT_COLOSSUS_SPIRIT_TEMPLE_BLUE_WARP: // Bongo-Bongo blue warp
|
||||
case ENTR_GRAVEYARD_SHADOW_TEMPLE_BLUE_WARP: // Twinrova blue warp
|
||||
gPlayState->nextEntranceIndex = Entrance_OverrideNextIndex(gPlayState->nextEntranceIndex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Entrance_EnableFW(void) {
|
||||
|
@ -99,6 +99,10 @@ void Grotto_InitExitAndLoadLists(void) {
|
||||
grottoLoadList[i] = ENTRANCE_GROTTO_LOAD_START + i;
|
||||
grottoExitList[i] = ENTRANCE_GROTTO_EXIT_START + i;
|
||||
}
|
||||
|
||||
grottoId = 0xFF;
|
||||
lastEntranceType = NOT_GROTTO;
|
||||
overridingNextEntrance = false;
|
||||
}
|
||||
|
||||
void Grotto_SetExitOverride(s16 originalIndex, s16 overrideIndex) {
|
||||
|
@ -445,6 +445,7 @@ void Settings::CreateOptions() {
|
||||
mTrickOptions[RT_WATER_BK_REGION] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple Boss Key Region with Hover Boots", "With precise Hover Boots movement it is possible to reach the boss key chest's region without needing the Longshot. It is not necessary to take damage from the spikes. The Gold Skulltula Token in the following room can also be obtained with just the Hover Boots.");
|
||||
mTrickOptions[RT_WATER_NORTH_BASEMENT_LEDGE_JUMP] = TrickOption::LogicTrick(RCQUEST_BOTH, RA_WATER_TEMPLE, {Tricks::Tag::INTERMEDIATE}, false, "Water Temple North Basement Ledge with Precise Jump", "In the northern basement there's a ledge from where, in vanilla Water Temple, boulders roll out into the room. Normally to jump directly to this ledge logically requires the Hover Boots, but with precise jump, it can be done without them. This trick applies to both Vanilla and Master Quest.");
|
||||
mTrickOptions[RT_WATER_BK_JUMP_DIVE] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Boss Key Jump Dive", "Stand on the very edge of the raised corridor leading from the push block room to the rolling boulder corridor. Face the gold skulltula on the waterfall and jump over the boulder corridor floor into the pool of water, swimming right once underwater. This allows access to the boss key room without Iron boots.");
|
||||
//Also used in MQ logic, but won't be relevent unless a way to enter tower without irons exists (likely a clip + swim)
|
||||
mTrickOptions[RT_WATER_FW_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Farore\'s Wind", "If you set Farore's Wind inside the central pillar and then return to that warp point after raising the water to the highest level, you can obtain this Skulltula Token with Hookshot or Boomerang.");
|
||||
mTrickOptions[RT_WATER_IRONS_CENTRAL_GS] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::NOVICE}, false, "Water Temple Central Pillar GS with Iron Boots", "After opening the middle water level door into the central pillar, the door will stay unbarred so long as you do not leave the room -- even if you were to raise the water up to the highest level. With the Iron Boots to go through the door after the water has been raised, you can obtain the Skulltula Token with the Hookshot.");
|
||||
mTrickOptions[RT_WATER_CENTRAL_BOW] = TrickOption::LogicTrick(RCQUEST_VANILLA, RA_WATER_TEMPLE, {Tricks::Tag::ADVANCED}, false, "Water Temple Central Bow Target without Longshot or Hover Boots", "A very precise Bow shot can hit the eye switch from the floor above. Then, you can jump down into the hallway and make through it before the gate closes. It can also be done as child, using the Slingshot instead of the Bow.");
|
||||
|
@ -14,6 +14,7 @@ extern "C" {
|
||||
#include "src/overlays/actors/ovl_En_Owl/z_en_owl.h"
|
||||
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
||||
#include "src/overlays/actors/ovl_En_Ma1/z_en_ma1.h"
|
||||
#include "src/overlays/actors/ovl_En_Ru2/z_en_ru2.h"
|
||||
#include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h"
|
||||
#include "src/overlays/actors/ovl_En_Box/z_en_box.h"
|
||||
#include "src/overlays/actors/ovl_Demo_Im/z_demo_im.h"
|
||||
@ -33,6 +34,8 @@ extern "C" {
|
||||
extern SaveContext gSaveContext;
|
||||
extern PlayState* gPlayState;
|
||||
extern int32_t D_8011D3AC;
|
||||
|
||||
extern void func_80AF36EC(EnRu2* enRu2, PlayState* play);
|
||||
}
|
||||
|
||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex()
|
||||
@ -40,7 +43,7 @@ extern int32_t D_8011D3AC;
|
||||
void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) {
|
||||
if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) {
|
||||
Flags_SetRandomizerInf(RAND_INF_LEARNED_EPONA_SONG);
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
enMa1->actor.flags &= ~ACTOR_FLAG_WILL_TALK;
|
||||
play->msgCtx.ocarinaMode = OCARINA_MODE_04;
|
||||
enMa1->actionFunc = func_80AA0D88;
|
||||
@ -52,7 +55,7 @@ void EnMa1_EndTeachSong(EnMa1* enMa1, PlayState* play) {
|
||||
|
||||
void EnFu_EndTeachSong(EnFu* enFu, PlayState* play) {
|
||||
if (Message_GetState(&gPlayState->msgCtx) == TEXT_STATE_CLOSING) {
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
enFu->actionFunc = EnFu_WaitAdult;
|
||||
enFu->actor.flags &= ~ACTOR_FLAG_WILL_TALK;
|
||||
|
||||
@ -427,7 +430,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
player->stateFlags1 |= PLAYER_STATE1_GETTING_ITEM;
|
||||
|
||||
if (Animation_OnFrame(&demoIm->skelAnime, 25.0f)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_DEKU, &demoIm->actor.projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_DEKU, &demoIm->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(demoImUpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(demoImKillHook);
|
||||
demoImUpdateHook = 0;
|
||||
@ -506,7 +509,7 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO)) {
|
||||
*should = false;
|
||||
Flags_SetEnv(gPlayState, 2);
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -813,6 +816,15 @@ void TimeSaverOnActorInitHandler(void* actorRef) {
|
||||
Actor_Kill(actor);
|
||||
}
|
||||
}
|
||||
|
||||
// Water Temple Ruto cutscene
|
||||
if (actor->id == ACTOR_EN_RU2 && gPlayState->sceneNum == SCENE_WATER_TEMPLE) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
EnRu2* enRu2 = (EnRu2*)actor;
|
||||
func_80AF36EC(enRu2, gPlayState);
|
||||
Actor_Kill(actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimeSaverOnSceneInitHandler(int16_t sceneNum) {
|
||||
|
@ -181,7 +181,7 @@ void RegisterOnInterfaceUpdateHook() {
|
||||
|
||||
if (gPlayState->state.frames % 7 == 0) {
|
||||
if (lostHealth >= 16) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
lostHealth -= 16;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ void Emit(Options notification) {
|
||||
notification.remainingTime = CVarGetFloat(CVAR_SETTING("Notifications.Duration"), 10.0f);
|
||||
}
|
||||
notifications.push_back(notification);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
} // namespace Notification
|
||||
|
@ -1744,7 +1744,7 @@ void DrawCheatsMenu() {
|
||||
UIWidgets::EnhancementSliderFloat("Hookshot Reach Multiplier: %.2fx", "##gCheatHookshotReachMultiplier", CVAR_CHEAT("HookshotReachMultiplier"), 1.0f, 5.0f, "", 1.0f, false);
|
||||
UIWidgets::Spacer(2.0f);
|
||||
if (ImGui::Button("Change Age")) {
|
||||
CVarSetInteger(CVAR_GENERAL("SwitchAge"), 1);
|
||||
SwitchAge();
|
||||
}
|
||||
UIWidgets::Tooltip("Switches Link's age and reloads the area.");
|
||||
UIWidgets::Spacer(2.0f);
|
||||
|
@ -23,6 +23,10 @@ u16 gAudioSEFlagSwapSource[64];
|
||||
u16 gAudioSEFlagSwapTarget[64];
|
||||
u8 gAudioSEFlagSwapMode[64];
|
||||
|
||||
// Zbuffer and Color framebuffer
|
||||
u16 D_0E000000[SCREEN_WIDTH * SCREEN_HEIGHT];
|
||||
u16 D_0F000000[SCREEN_WIDTH * SCREEN_HEIGHT];
|
||||
|
||||
u8 osAppNmiBuffer[2048];
|
||||
|
||||
f32 qNaN0x10000 = 0x7F810000;
|
||||
|
@ -19,19 +19,19 @@ Ship::IResource* OTRPlay_LoadFile(PlayState* play, const char* fileName)
|
||||
return res.get();
|
||||
}
|
||||
|
||||
extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn) {
|
||||
SceneTableEntry* scene = &gSceneTable[sceneNum];
|
||||
extern "C" void OTRPlay_SpawnScene(PlayState* play, s32 sceneId, s32 spawn) {
|
||||
SceneTableEntry* scene = &gSceneTable[sceneId];
|
||||
|
||||
scene->unk_13 = 0;
|
||||
play->loadedScene = scene;
|
||||
play->sceneNum = sceneNum;
|
||||
play->sceneNum = sceneId;
|
||||
play->sceneConfig = scene->config;
|
||||
|
||||
//osSyncPrintf("\nSCENE SIZE %fK\n", (scene->sceneFile.vromEnd - scene->sceneFile.vromStart) / 1024.0f);
|
||||
|
||||
// Scenes considered "dungeon" with a MQ variant
|
||||
int16_t inNonSharedScene = (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_ICE_CAVERN) ||
|
||||
sceneNum == SCENE_GERUDO_TRAINING_GROUND || sceneNum == SCENE_INSIDE_GANONS_CASTLE;
|
||||
int16_t inNonSharedScene = (sceneId >= SCENE_DEKU_TREE && sceneId <= SCENE_ICE_CAVERN) ||
|
||||
sceneId == SCENE_GERUDO_TRAINING_GROUND || sceneId == SCENE_INSIDE_GANONS_CASTLE;
|
||||
|
||||
std::string sceneVersion = "shared";
|
||||
if (inNonSharedScene) {
|
||||
|
@ -3,61 +3,132 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define FILL_ALLOCBLOCK (1 << 0)
|
||||
#define FILL_FREEBLOCK (1 << 1)
|
||||
#define CHECK_FREE_BLOCK (1 << 2)
|
||||
// SOH [General] This file corresponds to decomp's "__osMalloc_gc.c", there's currently no file corresponding to decomp's "__osMalloc_n64.c"
|
||||
|
||||
#define NODE_MAGIC (0x7373)
|
||||
// #region SOH [General] We currently don't set OOT_DEBUG when building so set it here manually
|
||||
#define OOT_DEBUG 1
|
||||
// #endregion
|
||||
|
||||
#define BLOCK_UNINIT_MAGIC (0xAB)
|
||||
#define BLOCK_UNINIT_MAGIC_32 (0xABABABAB)
|
||||
#define BLOCK_ALLOC_MAGIC (0xCD)
|
||||
#define BLOCK_ALLOC_MAGIC_32 (0xCDCDCDCD)
|
||||
#define BLOCK_FREE_MAGIC (0xEF)
|
||||
#define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF)
|
||||
// #region SOH [General] We renamed OoT's memmove to prevent conflicts with the libc version
|
||||
#define memmove oot_memmove
|
||||
// #endregion
|
||||
|
||||
#define FILL_ALLOC_BLOCK_FLAG (1 << 0)
|
||||
#define FILL_FREE_BLOCK_FLAG (1 << 1)
|
||||
#define CHECK_FREE_BLOCK_FLAG (1 << 2)
|
||||
|
||||
#define NODE_MAGIC 0x7373
|
||||
|
||||
#define BLOCK_UNINIT_MAGIC 0xAB
|
||||
#define BLOCK_UNINIT_MAGIC_32 0xABABABAB
|
||||
#define BLOCK_ALLOC_MAGIC 0xCD
|
||||
#define BLOCK_ALLOC_MAGIC_32 0xCDCDCDCD
|
||||
#define BLOCK_FREE_MAGIC 0xEF
|
||||
#define BLOCK_FREE_MAGIC_32 0xEFEFEFEF
|
||||
|
||||
#define NODE_IS_VALID(node) (((node) != NULL) && ((node)->magic == NODE_MAGIC))
|
||||
|
||||
#if OOT_DEBUG
|
||||
|
||||
#define NODE_GET_NEXT(node) ArenaImpl_GetNextBlock(node)
|
||||
#define NODE_GET_PREV(node) ArenaImpl_GetPrevBlock(node)
|
||||
|
||||
#define SET_DEBUG_INFO(node, file, line, arena) ArenaImpl_SetDebugInfo(node, file, line, arena)
|
||||
|
||||
#define FILL_UNINIT_BLOCK(arena, node, size) memset(node, BLOCK_UNINIT_MAGIC, size)
|
||||
|
||||
#define FILL_ALLOC_BLOCK(arena, alloc, size) \
|
||||
if ((arena)->flag & FILL_ALLOC_BLOCK_FLAG) \
|
||||
memset(alloc, BLOCK_ALLOC_MAGIC, size)
|
||||
|
||||
#define FILL_FREE_BLOCK_HEADER(arena, node) \
|
||||
if ((arena)->flag & FILL_FREE_BLOCK_FLAG) \
|
||||
memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode))
|
||||
|
||||
#define FILL_FREE_BLOCK_CONTENTS(arena, node) \
|
||||
if ((arena)->flag & FILL_FREE_BLOCK_FLAG) \
|
||||
memset((void*)((uintptr_t)(node) + sizeof(ArenaNode)), BLOCK_FREE_MAGIC, (node)->size)
|
||||
|
||||
#define CHECK_FREE_BLOCK(arena, node) \
|
||||
if ((arena)->flag & CHECK_FREE_BLOCK_FLAG) \
|
||||
__osMalloc_FreeBlockTest(arena, node)
|
||||
|
||||
#define CHECK_ALLOC_FAILURE(arena, ptr) (void)0
|
||||
|
||||
#else
|
||||
|
||||
#define NODE_GET_NEXT(node) (NODE_IS_VALID((node)->next) ? (node)->next : NULL)
|
||||
#define NODE_GET_PREV(node) (NODE_IS_VALID((node)->prev) ? (node)->prev : NULL)
|
||||
|
||||
#define SET_DEBUG_INFO(node, file, line, arena) (void)0
|
||||
#define FILL_UNINIT_BLOCK(arena, node, size) (void)0
|
||||
#define FILL_ALLOC_BLOCK(arena, alloc, size) (void)0
|
||||
#define FILL_FREE_BLOCK_HEADER(arena, node) (void)0
|
||||
#define FILL_FREE_BLOCK_CONTENTS(arena, node) (void)0
|
||||
#define CHECK_FREE_BLOCK(arena, node) (void)0
|
||||
|
||||
// Number of allocation failures across all arenas.
|
||||
u32 gTotalAllocFailures = 0; // "Arena_failcnt"
|
||||
|
||||
#define CHECK_ALLOC_FAILURE(arena, ptr) \
|
||||
do { \
|
||||
if ((ptr) == NULL) { \
|
||||
gTotalAllocFailures++; \
|
||||
(arena)->allocFailures++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
OSMesg sArenaLockMsg;
|
||||
|
||||
void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size);
|
||||
|
||||
#if OOT_DEBUG
|
||||
u32 __osMalloc_FreeBlockTest_Enable;
|
||||
|
||||
u32 ArenaImpl_GetFillAllocBlock(Arena* arena) {
|
||||
return (arena->flag & FILL_ALLOCBLOCK) != 0;
|
||||
return (arena->flag & FILL_ALLOC_BLOCK_FLAG) != 0;
|
||||
}
|
||||
u32 ArenaImpl_GetFillFreeBlock(Arena* arena) {
|
||||
return (arena->flag & FILL_FREEBLOCK) != 0;
|
||||
return (arena->flag & FILL_FREE_BLOCK_FLAG) != 0;
|
||||
}
|
||||
u32 ArenaImpl_GetCheckFreeBlock(Arena* arena) {
|
||||
return (arena->flag & CHECK_FREE_BLOCK) != 0;
|
||||
return (arena->flag & CHECK_FREE_BLOCK_FLAG) != 0;
|
||||
}
|
||||
|
||||
void ArenaImpl_SetFillAllocBlock(Arena* arena) {
|
||||
arena->flag |= FILL_ALLOCBLOCK;
|
||||
arena->flag |= FILL_ALLOC_BLOCK_FLAG;
|
||||
}
|
||||
void ArenaImpl_SetFillFreeBlock(Arena* arena) {
|
||||
arena->flag |= FILL_FREEBLOCK;
|
||||
arena->flag |= FILL_FREE_BLOCK_FLAG;
|
||||
}
|
||||
void ArenaImpl_SetCheckFreeBlock(Arena* arena) {
|
||||
arena->flag |= CHECK_FREE_BLOCK;
|
||||
arena->flag |= CHECK_FREE_BLOCK_FLAG;
|
||||
}
|
||||
|
||||
void ArenaImpl_UnsetFillAllocBlock(Arena* arena) {
|
||||
arena->flag &= ~FILL_ALLOCBLOCK;
|
||||
arena->flag &= ~FILL_ALLOC_BLOCK_FLAG;
|
||||
}
|
||||
void ArenaImpl_UnsetFillFreeBlock(Arena* arena) {
|
||||
arena->flag &= ~FILL_FREEBLOCK;
|
||||
arena->flag &= ~FILL_FREE_BLOCK_FLAG;
|
||||
}
|
||||
void ArenaImpl_UnsetCheckFreeBlock(Arena* arena) {
|
||||
arena->flag &= ~CHECK_FREE_BLOCK;
|
||||
arena->flag &= ~CHECK_FREE_BLOCK_FLAG;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena* arena) {
|
||||
void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, int line, Arena* arena) {
|
||||
// Upstream TODO: Figure out why uncommenting this crashes
|
||||
/*
|
||||
node->filename = file;
|
||||
node->line = line;
|
||||
node->threadId = osGetThreadId(NULL);
|
||||
node->arena = arena;
|
||||
node->time = osGetTime();
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
void ArenaImpl_LockInit(Arena* arena) {
|
||||
osCreateMesgQueue(&arena->lock, &sArenaLockMsg, 1);
|
||||
}
|
||||
@ -70,6 +141,7 @@ void ArenaImpl_Unlock(Arena* arena) {
|
||||
osRecvMesg(&arena->lock, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
#if OOT_DEBUG
|
||||
ArenaNode* ArenaImpl_GetNextBlock(ArenaNode* node) {
|
||||
ArenaNode* next = node->next;
|
||||
|
||||
@ -91,16 +163,17 @@ ArenaNode* ArenaImpl_GetPrevBlock(ArenaNode* node) {
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
#endif
|
||||
|
||||
ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) {
|
||||
ArenaNode* last = NULL;
|
||||
ArenaNode* iter;
|
||||
|
||||
if (arena != NULL && arena->head != NULL && arena->head->magic == NODE_MAGIC) {
|
||||
if (arena != NULL && NODE_IS_VALID(arena->head)) {
|
||||
iter = arena->head;
|
||||
while (iter != NULL) {
|
||||
last = iter;
|
||||
iter = ArenaImpl_GetNextBlock(iter);
|
||||
iter = NODE_GET_NEXT(last);
|
||||
}
|
||||
}
|
||||
return last;
|
||||
@ -125,7 +198,7 @@ void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size) {
|
||||
size2 = (size - diff) & ~0xF;
|
||||
|
||||
if (size2 > (ptrdiff_t)sizeof(ArenaNode)) {
|
||||
memset(firstNode, BLOCK_UNINIT_MAGIC, size2); // memset
|
||||
FILL_UNINIT_BLOCK(arena, firstNode, size2);
|
||||
firstNode->next = NULL;
|
||||
firstNode->prev = NULL;
|
||||
firstNode->size = size2 - sizeof(ArenaNode);
|
||||
@ -145,6 +218,7 @@ void __osMallocAddBlock(Arena* arena, void* start, ptrdiff_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
#if OOT_DEBUG
|
||||
void ArenaImpl_RemoveAllBlocks(Arena* arena) {
|
||||
ArenaNode* iter;
|
||||
ArenaNode* next;
|
||||
@ -153,23 +227,27 @@ void ArenaImpl_RemoveAllBlocks(Arena* arena) {
|
||||
|
||||
iter = arena->head;
|
||||
while (iter != NULL) {
|
||||
next = ArenaImpl_GetNextBlock(iter);
|
||||
memset(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode)); // memset
|
||||
next = NODE_GET_NEXT(iter);
|
||||
memset(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode));
|
||||
iter = next;
|
||||
}
|
||||
|
||||
ArenaImpl_Unlock(arena);
|
||||
}
|
||||
#endif
|
||||
|
||||
void __osMallocCleanup(Arena* arena) {
|
||||
#if OOT_DEBUG
|
||||
ArenaImpl_RemoveAllBlocks(arena);
|
||||
#endif
|
||||
memset(arena, 0, sizeof(*arena));
|
||||
}
|
||||
|
||||
u8 __osMallocIsInitalized(Arena* arena) {
|
||||
s32 __osMallocIsInitialized(Arena* arena) {
|
||||
return arena->isInit;
|
||||
}
|
||||
|
||||
#if OOT_DEBUG
|
||||
void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node) {
|
||||
ArenaNode* node2 = node;
|
||||
u32* start;
|
||||
@ -194,26 +272,24 @@ void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node) {
|
||||
}
|
||||
}
|
||||
|
||||
void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, s32 line) {
|
||||
void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, int line) {
|
||||
ArenaNode* iter;
|
||||
u32 blockSize;
|
||||
ArenaNode* newNode;
|
||||
void* alloc = NULL;
|
||||
ArenaNode* next;
|
||||
|
||||
iter = arena->head;
|
||||
size = ALIGN16(size);
|
||||
blockSize = ALIGN16(size) + sizeof(ArenaNode);
|
||||
iter = arena->head;
|
||||
|
||||
while (iter != NULL) {
|
||||
if (iter->isFree && iter->size >= size) {
|
||||
if (arena->flag & CHECK_FREE_BLOCK) {
|
||||
__osMalloc_FreeBlockTest(arena, iter);
|
||||
}
|
||||
CHECK_FREE_BLOCK(arena, iter);
|
||||
|
||||
if (blockSize < iter->size) {
|
||||
newNode = (ArenaNode*)((uintptr_t)iter + blockSize);
|
||||
newNode->next = ArenaImpl_GetNextBlock(iter);
|
||||
newNode->next = NODE_GET_NEXT(iter);
|
||||
newNode->prev = iter;
|
||||
newNode->size = iter->size - blockSize;
|
||||
newNode->isFree = true;
|
||||
@ -221,29 +297,27 @@ void* __osMalloc_NoLockDebug(Arena* arena, size_t size, const char* file, s32 li
|
||||
|
||||
iter->next = newNode;
|
||||
iter->size = size;
|
||||
next = ArenaImpl_GetNextBlock(newNode);
|
||||
next = NODE_GET_NEXT(newNode);
|
||||
if (next) {
|
||||
next->prev = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
iter->isFree = false;
|
||||
//ArenaImpl_SetDebugInfo(iter, file, line, arena);
|
||||
SET_DEBUG_INFO(iter, file, line, arena);
|
||||
alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode));
|
||||
if (arena->flag & FILL_ALLOCBLOCK) {
|
||||
memset(alloc, BLOCK_ALLOC_MAGIC, size);
|
||||
}
|
||||
FILL_ALLOC_BLOCK(arena, alloc, size);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
iter = ArenaImpl_GetNextBlock(iter);
|
||||
iter = NODE_GET_NEXT(iter);
|
||||
}
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
void* __osMallocDebug(Arena* arena, size_t size, const char* file, s32 line) {
|
||||
void* __osMallocDebug(Arena* arena, size_t size, const char* file, int line) {
|
||||
void* alloc;
|
||||
|
||||
ArenaImpl_Lock(arena);
|
||||
@ -253,7 +327,7 @@ void* __osMallocDebug(Arena* arena, size_t size, const char* file, s32 line) {
|
||||
return alloc;
|
||||
}
|
||||
|
||||
void* __osMallocRDebug(Arena* arena, size_t size, const char* file, s32 line) {
|
||||
void* __osMallocRDebug(Arena* arena, size_t size, const char* file, int line) {
|
||||
ArenaNode* iter;
|
||||
ArenaNode* newNode;
|
||||
u32 blockSize;
|
||||
@ -266,21 +340,19 @@ void* __osMallocRDebug(Arena* arena, size_t size, const char* file, s32 line) {
|
||||
|
||||
while (iter != NULL) {
|
||||
if (iter->isFree && iter->size >= size) {
|
||||
if (arena->flag & CHECK_FREE_BLOCK) {
|
||||
__osMalloc_FreeBlockTest(arena, iter);
|
||||
}
|
||||
CHECK_FREE_BLOCK(arena, iter);
|
||||
|
||||
blockSize = ALIGN16(size) + sizeof(ArenaNode);
|
||||
if (blockSize < iter->size) {
|
||||
newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size));
|
||||
newNode->next = ArenaImpl_GetNextBlock(iter);
|
||||
newNode->next = NODE_GET_NEXT(iter);
|
||||
newNode->prev = iter;
|
||||
newNode->size = size;
|
||||
newNode->magic = NODE_MAGIC;
|
||||
|
||||
iter->next = newNode;
|
||||
iter->size -= blockSize;
|
||||
next = ArenaImpl_GetNextBlock(newNode);
|
||||
next = NODE_GET_NEXT(newNode);
|
||||
if (next) {
|
||||
next->prev = newNode;
|
||||
}
|
||||
@ -288,21 +360,21 @@ void* __osMallocRDebug(Arena* arena, size_t size, const char* file, s32 line) {
|
||||
}
|
||||
|
||||
iter->isFree = false;
|
||||
//ArenaImpl_SetDebugInfo(iter, file, line, arena);
|
||||
SET_DEBUG_INFO(iter, file, line, arena);
|
||||
allocR = (void*)((uintptr_t)iter + sizeof(ArenaNode));
|
||||
if (arena->flag & FILL_ALLOCBLOCK) {
|
||||
memset(allocR, BLOCK_ALLOC_MAGIC, size);
|
||||
}
|
||||
FILL_ALLOC_BLOCK(arena, allocR, size);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
iter = ArenaImpl_GetPrevBlock(iter);
|
||||
iter = NODE_GET_PREV(iter);
|
||||
}
|
||||
|
||||
ArenaImpl_Unlock(arena);
|
||||
|
||||
return allocR;
|
||||
}
|
||||
#endif
|
||||
|
||||
void* __osMalloc_NoLock(Arena* arena, size_t size) {
|
||||
ArenaNode* iter;
|
||||
@ -311,20 +383,17 @@ void* __osMalloc_NoLock(Arena* arena, size_t size) {
|
||||
void* alloc = NULL;
|
||||
ArenaNode* next;
|
||||
|
||||
iter = arena->head;
|
||||
size = ALIGN16(size);
|
||||
blockSize = ALIGN16(size) + sizeof(ArenaNode);
|
||||
iter = arena->head;
|
||||
|
||||
while (iter != NULL) {
|
||||
|
||||
if (iter->isFree && iter->size >= size) {
|
||||
if (arena->flag & CHECK_FREE_BLOCK) {
|
||||
__osMalloc_FreeBlockTest(arena, iter);
|
||||
}
|
||||
CHECK_FREE_BLOCK(arena, iter);
|
||||
|
||||
if (blockSize < iter->size) {
|
||||
newNode = (ArenaNode*)((uintptr_t)iter + blockSize);
|
||||
newNode->next = ArenaImpl_GetNextBlock(iter);
|
||||
newNode->next = NODE_GET_NEXT(iter);
|
||||
newNode->prev = iter;
|
||||
newNode->size = iter->size - blockSize;
|
||||
newNode->isFree = true;
|
||||
@ -332,24 +401,25 @@ void* __osMalloc_NoLock(Arena* arena, size_t size) {
|
||||
|
||||
iter->next = newNode;
|
||||
iter->size = size;
|
||||
next = ArenaImpl_GetNextBlock(newNode);
|
||||
next = NODE_GET_NEXT(newNode);
|
||||
if (next) {
|
||||
next->prev = newNode;
|
||||
}
|
||||
}
|
||||
|
||||
iter->isFree = false;
|
||||
//ArenaImpl_SetDebugInfo(iter, NULL, 0, arena);
|
||||
SET_DEBUG_INFO(iter, NULL, 0, arena);
|
||||
alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode));
|
||||
if (arena->flag & FILL_ALLOCBLOCK) {
|
||||
memset(alloc, BLOCK_ALLOC_MAGIC, size);
|
||||
}
|
||||
FILL_ALLOC_BLOCK(arena, alloc, size);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
iter = ArenaImpl_GetNextBlock(iter);
|
||||
iter = NODE_GET_NEXT(iter);
|
||||
}
|
||||
|
||||
CHECK_ALLOC_FAILURE(arena, alloc);
|
||||
|
||||
return alloc;
|
||||
}
|
||||
|
||||
@ -365,32 +435,33 @@ void* __osMalloc(Arena* arena, size_t size) {
|
||||
|
||||
void* __osMallocR(Arena* arena, size_t size) {
|
||||
ArenaNode* iter;
|
||||
ArenaNode* allocNode;
|
||||
ArenaNode* newNode;
|
||||
u32 blockSize;
|
||||
ArenaNode* next;
|
||||
void* alloc = NULL;
|
||||
u32 blockSize;
|
||||
|
||||
size = ALIGN16(size);
|
||||
blockSize = ALIGN16(size) + sizeof(ArenaNode);
|
||||
ArenaImpl_Lock(arena);
|
||||
iter = ArenaImpl_GetLastBlock(arena);
|
||||
|
||||
while (iter != NULL) {
|
||||
if (iter->isFree && iter->size >= size) {
|
||||
if (arena->flag & CHECK_FREE_BLOCK) {
|
||||
__osMalloc_FreeBlockTest(arena, iter);
|
||||
}
|
||||
CHECK_FREE_BLOCK(arena, iter);
|
||||
|
||||
blockSize = ALIGN16(size) + sizeof(ArenaNode);
|
||||
if (blockSize < iter->size) {
|
||||
newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size));
|
||||
newNode->next = ArenaImpl_GetNextBlock(iter);
|
||||
allocNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size));
|
||||
allocNode->next = NODE_GET_NEXT(iter);
|
||||
|
||||
newNode = allocNode;
|
||||
newNode->prev = iter;
|
||||
newNode->size = size;
|
||||
newNode->magic = NODE_MAGIC;
|
||||
|
||||
iter->next = newNode;
|
||||
iter->size -= blockSize;
|
||||
next = ArenaImpl_GetNextBlock(newNode);
|
||||
next = NODE_GET_NEXT(newNode);
|
||||
if (next) {
|
||||
next->prev = newNode;
|
||||
}
|
||||
@ -398,15 +469,16 @@ void* __osMallocR(Arena* arena, size_t size) {
|
||||
}
|
||||
|
||||
iter->isFree = false;
|
||||
//ArenaImpl_SetDebugInfo(iter, NULL, 0, arena);
|
||||
SET_DEBUG_INFO(iter, NULL, 0, arena);
|
||||
alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode));
|
||||
if (arena->flag & FILL_ALLOCBLOCK) {
|
||||
memset(alloc, BLOCK_ALLOC_MAGIC, size);
|
||||
}
|
||||
FILL_ALLOC_BLOCK(arena, alloc, size);
|
||||
break;
|
||||
}
|
||||
iter = ArenaImpl_GetPrevBlock(iter);
|
||||
iter = NODE_GET_PREV(iter);
|
||||
}
|
||||
|
||||
CHECK_ALLOC_FAILURE(arena, alloc);
|
||||
|
||||
ArenaImpl_Unlock(arena);
|
||||
|
||||
return alloc;
|
||||
@ -416,14 +488,13 @@ void __osFree_NoLock(Arena* arena, void* ptr) {
|
||||
ArenaNode* node;
|
||||
ArenaNode* next;
|
||||
ArenaNode* prev;
|
||||
ArenaNode* newNext;
|
||||
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode));
|
||||
if (node == NULL || node->magic != NODE_MAGIC) {
|
||||
if (!NODE_IS_VALID(node)) {
|
||||
// "__osFree: Unauthorized release (%08x)"
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x)\n" VT_RST, ptr);
|
||||
return;
|
||||
@ -432,34 +503,32 @@ void __osFree_NoLock(Arena* arena, void* ptr) {
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x)\n" VT_RST, ptr); // "__osFree: Double release (%08x)"
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
#if OOT_DEBUG
|
||||
/*
|
||||
if (arena != node->arena && arena != NULL) {
|
||||
// "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)"
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena,
|
||||
node->arena);
|
||||
return;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
next = ArenaImpl_GetNextBlock(node);
|
||||
prev = ArenaImpl_GetPrevBlock(node);
|
||||
|
||||
next = NODE_GET_NEXT(node);
|
||||
prev = NODE_GET_PREV(node);
|
||||
node->isFree = true;
|
||||
//ArenaImpl_SetDebugInfo(node, NULL, 0, arena);
|
||||
SET_DEBUG_INFO(node, NULL, 0, arena);
|
||||
|
||||
if (arena->flag & FILL_FREEBLOCK) {
|
||||
memset((uintptr_t)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size);
|
||||
}
|
||||
FILL_FREE_BLOCK_CONTENTS(arena, node);
|
||||
|
||||
newNext = next;
|
||||
if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) {
|
||||
newNext = ArenaImpl_GetNextBlock(next);
|
||||
ArenaNode* newNext = NODE_GET_NEXT(next);
|
||||
if (newNext != NULL) {
|
||||
newNext->prev = node;
|
||||
}
|
||||
|
||||
node->size += next->size + sizeof(ArenaNode);
|
||||
if (arena->flag & FILL_FREEBLOCK) {
|
||||
memset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
|
||||
}
|
||||
FILL_FREE_BLOCK_HEADER(arena, next);
|
||||
node->next = newNext;
|
||||
next = newNext;
|
||||
}
|
||||
@ -470,9 +539,7 @@ void __osFree_NoLock(Arena* arena, void* ptr) {
|
||||
}
|
||||
prev->next = next;
|
||||
prev->size += node->size + sizeof(ArenaNode);
|
||||
if (arena->flag & FILL_FREEBLOCK) {
|
||||
memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
|
||||
}
|
||||
FILL_FREE_BLOCK_HEADER(arena, node);
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,7 +549,8 @@ void __osFree(Arena* arena, void* ptr) {
|
||||
ArenaImpl_Unlock(arena);
|
||||
}
|
||||
|
||||
void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
|
||||
#if OOT_DEBUG
|
||||
void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, int line) {
|
||||
ArenaNode* node;
|
||||
ArenaNode* next;
|
||||
ArenaNode* prev;
|
||||
@ -493,7 +561,7 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
|
||||
}
|
||||
|
||||
node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode));
|
||||
if (node == NULL || node->magic != NODE_MAGIC) {
|
||||
if (!NODE_IS_VALID(node)) {
|
||||
// "__osFree: Unauthorized release (%08x)"
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line);
|
||||
return;
|
||||
@ -503,34 +571,32 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line);
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
|
||||
/*
|
||||
if (arena != node->arena && arena != NULL) {
|
||||
// "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)"
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena,
|
||||
node->arena);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
next = ArenaImpl_GetNextBlock(node);
|
||||
prev = ArenaImpl_GetPrevBlock(node);
|
||||
node->isFree = true;
|
||||
//ArenaImpl_SetDebugInfo(node, file, line, arena);
|
||||
*/
|
||||
|
||||
if (arena->flag & FILL_FREEBLOCK) {
|
||||
memset((uintptr_t)node + sizeof(ArenaNode), BLOCK_FREE_MAGIC, node->size);
|
||||
}
|
||||
next = NODE_GET_NEXT(node);
|
||||
prev = NODE_GET_PREV(node);
|
||||
node->isFree = true;
|
||||
SET_DEBUG_INFO(node, file, line, arena);
|
||||
|
||||
FILL_FREE_BLOCK_CONTENTS(arena, node);
|
||||
|
||||
newNext = node->next;
|
||||
if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) {
|
||||
newNext = ArenaImpl_GetNextBlock(next);
|
||||
newNext = NODE_GET_NEXT(next);
|
||||
if (newNext != NULL) {
|
||||
newNext->prev = node;
|
||||
}
|
||||
|
||||
node->size += next->size + sizeof(ArenaNode);
|
||||
if (arena->flag & FILL_FREEBLOCK) {
|
||||
memset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
|
||||
}
|
||||
FILL_FREE_BLOCK_HEADER(arena, next);
|
||||
node->next = newNext;
|
||||
next = newNext;
|
||||
}
|
||||
@ -541,21 +607,20 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
|
||||
}
|
||||
prev->next = next;
|
||||
prev->size += node->size + sizeof(ArenaNode);
|
||||
if (arena->flag & FILL_FREEBLOCK) {
|
||||
memset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
|
||||
}
|
||||
FILL_FREE_BLOCK_HEADER(arena, node);
|
||||
}
|
||||
}
|
||||
|
||||
void __osFreeDebug(Arena* arena, void* ptr, const char* file, s32 line) {
|
||||
void __osFreeDebug(Arena* arena, void* ptr, const char* file, int line) {
|
||||
ArenaImpl_Lock(arena);
|
||||
__osFree_NoLockDebug(arena, ptr, file, line);
|
||||
ArenaImpl_Unlock(arena);
|
||||
}
|
||||
#endif
|
||||
|
||||
void* __osRealloc(Arena* arena, void* ptr, size_t newSize) {
|
||||
void* newAlloc;
|
||||
ArenaNode* node;
|
||||
void* newAlloc;
|
||||
ArenaNode* next;
|
||||
ArenaNode* newNext;
|
||||
ArenaNode* overNext;
|
||||
@ -582,20 +647,20 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) {
|
||||
// "Does nothing because the memory block size does not change"
|
||||
osSyncPrintf("メモリブロックサイズが変わらないためなにもしません\n");
|
||||
} else if (node->size < newSize) {
|
||||
next = ArenaImpl_GetNextBlock(node);
|
||||
next = NODE_GET_NEXT(node);
|
||||
sizeDiff = newSize - node->size;
|
||||
if ((uintptr_t)next == ((uintptr_t)node + node->size + sizeof(ArenaNode)) && next->isFree && next->size >= sizeDiff) {
|
||||
// "Merge because there is a free block after the current memory block"
|
||||
osSyncPrintf("現メモリブロックの後ろにフリーブロックがあるので結合します\n");
|
||||
next->size -= sizeDiff;
|
||||
overNext = ArenaImpl_GetNextBlock(next);
|
||||
overNext = NODE_GET_NEXT(next);
|
||||
newNext = (ArenaNode*)((uintptr_t)next + sizeDiff);
|
||||
if (overNext != NULL) {
|
||||
overNext->prev = newNext;
|
||||
}
|
||||
node->next = newNext;
|
||||
node->size = newSize;
|
||||
func_801068B0(newNext, next, sizeof(ArenaNode)); // memcpy
|
||||
memmove(node->next, next, sizeof(ArenaNode));
|
||||
} else {
|
||||
// "Allocate a new memory block and move the contents"
|
||||
osSyncPrintf("新たにメモリブロックを確保して内容を移動します\n");
|
||||
@ -607,7 +672,7 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) {
|
||||
ptr = newAlloc;
|
||||
}
|
||||
} else if (newSize < node->size) {
|
||||
next2 = ArenaImpl_GetNextBlock(node);
|
||||
next2 = NODE_GET_NEXT(node);
|
||||
if (next2 != NULL && next2->isFree) {
|
||||
blockSize = ALIGN16(newSize) + sizeof(ArenaNode);
|
||||
// "Increased free block behind current memory block"
|
||||
@ -618,7 +683,7 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) {
|
||||
newNext2->size += node->size - newSize;
|
||||
node->next = newNext2;
|
||||
node->size = newSize;
|
||||
overNext2 = ArenaImpl_GetNextBlock(newNext2);
|
||||
overNext2 = NODE_GET_NEXT(newNext2);
|
||||
if (overNext2 != NULL) {
|
||||
overNext2->prev = newNext2;
|
||||
}
|
||||
@ -627,14 +692,14 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) {
|
||||
// "Generated because there is no free block after the current memory block"
|
||||
osSyncPrintf("現メモリブロックの後ろにフリーブロックがないので生成します\n");
|
||||
newNext2 = (ArenaNode*)((uintptr_t)node + blockSize);
|
||||
newNext2->next = ArenaImpl_GetNextBlock(node);
|
||||
newNext2->next = NODE_GET_NEXT(node);
|
||||
newNext2->prev = node;
|
||||
newNext2->size = node->size - blockSize;
|
||||
newNext2->isFree = true;
|
||||
newNext2->magic = NODE_MAGIC;
|
||||
node->next = newNext2;
|
||||
node->size = newSize;
|
||||
overNext2 = ArenaImpl_GetNextBlock(newNext2);
|
||||
overNext2 = NODE_GET_NEXT(newNext2);
|
||||
if (overNext2 != NULL) {
|
||||
overNext2->prev = newNext2;
|
||||
}
|
||||
@ -644,15 +709,19 @@ void* __osRealloc(Arena* arena, void* ptr, size_t newSize) {
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_ALLOC_FAILURE(arena, ptr);
|
||||
}
|
||||
ArenaImpl_Unlock(arena);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* __osReallocDebug(Arena* arena, void* ptr, size_t newSize, const char* file, s32 line) {
|
||||
#if OOT_DEBUG
|
||||
void* __osReallocDebug(Arena* arena, void* ptr, size_t newSize, const char* file, int line) {
|
||||
return __osRealloc(arena, ptr, newSize);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc) {
|
||||
ArenaNode* iter;
|
||||
@ -674,12 +743,13 @@ void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAll
|
||||
*outAlloc += iter->size;
|
||||
}
|
||||
|
||||
iter = ArenaImpl_GetNextBlock(iter);
|
||||
iter = NODE_GET_NEXT(iter);
|
||||
}
|
||||
|
||||
ArenaImpl_Unlock(arena);
|
||||
}
|
||||
|
||||
#if OOT_DEBUG
|
||||
void __osDisplayArena(Arena* arena) {
|
||||
size_t freeSize;
|
||||
size_t allocatedSize;
|
||||
@ -687,7 +757,7 @@ void __osDisplayArena(Arena* arena) {
|
||||
ArenaNode* iter;
|
||||
ArenaNode* next;
|
||||
|
||||
if (!__osMallocIsInitalized(arena)) {
|
||||
if (!__osMallocIsInitialized(arena)) {
|
||||
osSyncPrintf("アリーナは初期化されていません\n"); // "Arena is not initalized"
|
||||
return;
|
||||
}
|
||||
@ -710,12 +780,14 @@ void __osDisplayArena(Arena* arena) {
|
||||
(next == NULL) ? '$' : (iter != next->prev ? '!' : ' '),
|
||||
iter->isFree ? "空き" : "確保", //? "Free" : "Secure"
|
||||
iter->size);
|
||||
#if 0
|
||||
|
||||
/*
|
||||
if (!iter->isFree) {
|
||||
osSyncPrintf(" [%016llu:%2d:%s:%d]", OS_CYCLES_TO_NSEC(iter->time), iter->threadId,
|
||||
iter->filename != NULL ? iter->filename : "**NULL**", iter->line);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
osSyncPrintf("\n");
|
||||
|
||||
if (iter->isFree) {
|
||||
@ -742,6 +814,7 @@ void __osDisplayArena(Arena* arena) {
|
||||
|
||||
ArenaImpl_Unlock(arena);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ArenaImpl_FaultClient(Arena* arena) {
|
||||
size_t freeSize;
|
||||
@ -751,7 +824,7 @@ void ArenaImpl_FaultClient(Arena* arena) {
|
||||
ArenaNode* next;
|
||||
|
||||
FaultDrawer_Printf("ARENA INFO (0x%08x)\n", arena);
|
||||
if (!__osMallocIsInitalized(arena)) {
|
||||
if (!__osMallocIsInitialized(arena)) {
|
||||
FaultDrawer_Printf("Arena is uninitalized\n", arena);
|
||||
return;
|
||||
}
|
||||
@ -793,7 +866,7 @@ void ArenaImpl_FaultClient(Arena* arena) {
|
||||
FaultDrawer_Printf("Largest Free Block Size %08x\n", maxFree);
|
||||
}
|
||||
|
||||
u32 __osCheckArena(Arena* arena) {
|
||||
s32 __osCheckArena(Arena* arena) {
|
||||
ArenaNode* iter;
|
||||
u32 error = 0;
|
||||
|
||||
@ -802,13 +875,20 @@ u32 __osCheckArena(Arena* arena) {
|
||||
osSyncPrintf("アリーナの内容をチェックしています... (%08x)\n", arena);
|
||||
iter = arena->head;
|
||||
while (iter != NULL) {
|
||||
if (iter && iter->magic == NODE_MAGIC) {
|
||||
//! @bug: Probably intended to be `!NODE_IS_VALID(iter)`
|
||||
if (NODE_IS_VALID(iter)) {
|
||||
#if OOT_DEBUG
|
||||
// "Oops!! (%08x %08x)"
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "おおっと!! (%08x %08x)\n" VT_RST, iter, iter->magic);
|
||||
osSyncPrintf(VT_COL(RED, WHITE) "おおっと!! (%08x %08x)\n" VT_RST, iter,
|
||||
iter->magic);
|
||||
#else
|
||||
// "Oops!! (%08x %08x)"
|
||||
osSyncPrintf("おおっと!! (%08x %08x)\n", iter, iter->magic);
|
||||
#endif
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
iter = ArenaImpl_GetNextBlock(iter);
|
||||
iter = NODE_GET_NEXT(iter);
|
||||
}
|
||||
if (error == 0) {
|
||||
osSyncPrintf("アリーナはまだ、いけそうです\n"); // "The arena is still going well"
|
||||
@ -818,6 +898,8 @@ u32 __osCheckArena(Arena* arena) {
|
||||
return error;
|
||||
}
|
||||
|
||||
u8 func_800FF334(Arena* arena) {
|
||||
#if OOT_DEBUG
|
||||
u8 ArenaImpl_GetAllocFailures(Arena* arena) {
|
||||
return arena->unk_20;
|
||||
}
|
||||
#endif
|
@ -1,97 +0,0 @@
|
||||
#include "global.h"
|
||||
|
||||
// Note : This file is related to z_vismono, the original name was probably z_vis<something before "mono"
|
||||
// alphabetically>
|
||||
|
||||
Gfx D_8012AC00[] = {
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2),
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsDPPipeSync(),
|
||||
gsDPSetBlendColor(0, 0, 0, 8),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
Gfx D_8012AC28[] = {
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
||||
GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||
GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
Gfx D_8012AC40[] = {
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
||||
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
Gfx D_8012AC58[] = {
|
||||
gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE),
|
||||
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_DISABLE | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2),
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
||||
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
// Init
|
||||
void func_800ACE70(struct_801664F0* this) {
|
||||
this->type = 0;
|
||||
this->setScissor = false;
|
||||
this->color.r = 255;
|
||||
this->color.g = 255;
|
||||
this->color.b = 255;
|
||||
this->color.a = 255;
|
||||
}
|
||||
|
||||
// Destroy
|
||||
void func_800ACE90(struct_801664F0* this) {
|
||||
}
|
||||
|
||||
// Draw
|
||||
void func_800ACE98(struct_801664F0* this, Gfx** gfxp) {
|
||||
Gfx* gfx = *gfxp;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetPrimDepth(gfx++, -1, -1);
|
||||
|
||||
if (this->setScissor == true) {
|
||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
switch (this->type) {
|
||||
case 1:
|
||||
gSPDisplayList(gfx++, D_8012AC40);
|
||||
break;
|
||||
case 2:
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->color.rgba);
|
||||
gSPDisplayList(gfx++, D_8012AC58);
|
||||
break;
|
||||
case 3:
|
||||
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->color.rgba);
|
||||
gSPDisplayList(gfx++, D_8012AC00);
|
||||
break;
|
||||
case 4:
|
||||
gDPSetColor(gfx++, G_SETFOGCOLOR, this->color.rgba);
|
||||
gSPDisplayList(gfx++, D_8012AC28);
|
||||
break;
|
||||
}
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
*gfxp = gfx;
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
#include "global.h"
|
||||
|
||||
// Note : This file is related to z_vismono, the original name was probably z_vis<something after "mono" alphabetically>
|
||||
|
||||
// z-buffer
|
||||
extern u16 D_0E000000[];
|
||||
|
||||
// Init
|
||||
void func_800AD920(struct_80166500* this) {
|
||||
this->useRgba = false;
|
||||
this->setScissor = false;
|
||||
this->primColor.r = 255;
|
||||
this->primColor.g = 255;
|
||||
this->primColor.b = 255;
|
||||
this->primColor.a = 255;
|
||||
this->envColor.a = 255;
|
||||
this->envColor.r = 0;
|
||||
this->envColor.g = 0;
|
||||
this->envColor.b = 0;
|
||||
}
|
||||
|
||||
// Destroy
|
||||
void func_800AD950(struct_80166500* this) {
|
||||
}
|
||||
|
||||
// Draw
|
||||
void func_800AD958(struct_80166500* this, Gfx** gfxp) {
|
||||
Gfx* gfx = *gfxp;
|
||||
|
||||
// OTRTODO
|
||||
#if 0
|
||||
u16* tex = D_0E000000;
|
||||
s32 fmt = this->useRgba == false ? G_IM_FMT_IA : G_IM_FMT_RGBA;
|
||||
s32 y;
|
||||
s32 height = 6;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
if (this->setScissor == true) {
|
||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
gDPSetOtherMode(gfx++,
|
||||
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2);
|
||||
gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT,
|
||||
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT);
|
||||
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba);
|
||||
gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba);
|
||||
|
||||
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
|
||||
gDPLoadTextureBlock(gfx++, tex, fmt, G_IM_SIZ_16b, SCREEN_WIDTH, height, 0, G_TX_NOMIRROR | G_TX_CLAMP,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
gSPTextureRectangle(gfx++, 0, (y) << 2, (SCREEN_WIDTH << 2), (y + height) << 2, G_TX_RENDERTILE, 0, 0,
|
||||
(1 << 10), (1 << 10));
|
||||
tex += SCREEN_WIDTH * height;
|
||||
}
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
*gfxp = gfx;
|
||||
#endif
|
||||
}
|
@ -1648,7 +1648,7 @@ void func_800ED458(s32 arg0) {
|
||||
if ((sCurOcarinaBtnVal != 0xFF) && (sPrevOcarinaNoteVal != sCurOcarinaBtnVal)) {
|
||||
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD07, D_80130F10 - 1);
|
||||
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD05, sCurOcarinaBtnVal);
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &D_801333D4, 4, &D_80130F24, &D_80130F28, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &D_80130F24, &D_80130F28, &gSfxDefaultReverb);
|
||||
} else if ((sPrevOcarinaNoteVal != 0xFF) && (sCurOcarinaBtnVal == 0xFF)) {
|
||||
Audio_StopSfxById(NA_SE_OC_OCARINA);
|
||||
}
|
||||
@ -1791,8 +1791,8 @@ void Audio_OcaPlayback(void) {
|
||||
sStaffPlaybackPos++;
|
||||
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD07, D_80130F10 - 1);
|
||||
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | 0xD05, sDisplayedNoteValue & 0x3F);
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &D_801333D4, 4, &sNormalizedNotePlaybackTone,
|
||||
&sNormalizedNotePlaybackVolume, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_OCARINA, &gSfxDefaultPos, 4, &sNormalizedNotePlaybackTone,
|
||||
&sNormalizedNotePlaybackVolume, &gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_StopSfxById(NA_SE_OC_OCARINA);
|
||||
}
|
||||
@ -3044,7 +3044,7 @@ void AudioDebug_ProcessInput_SndCont(void) {
|
||||
case 2:
|
||||
case 3:
|
||||
Audio_PlaySoundGeneral(((sAudioSndContWork[2] << 12) & 0xFFFF) + sAudioSndContWork[3] + SFX_FLAG,
|
||||
&D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
&gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
break;
|
||||
case 4:
|
||||
func_800F6700(sAudioSndContWork[sAudioSndContSel]);
|
||||
@ -3443,7 +3443,7 @@ void AudioDebug_ProcessInput_SfxParamChg(void) {
|
||||
|
||||
if (CHECK_BTN_ANY(sDebugPadPress, BTN_A)) {
|
||||
sfx = (u16)(sAudioSfxParamChgWork[0] << 12) + sAudioSfxParamChgWork[1] + SFX_FLAG;
|
||||
Audio_PlaySoundGeneral(sfx, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfx, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ANY(sDebugPadPress, BTN_B)) {
|
||||
@ -3974,7 +3974,7 @@ void Audio_PlayFanfare_Rando(GetItemEntry getItem) {
|
||||
|
||||
if (getItem.modIndex == MOD_NONE) {
|
||||
if (((itemId >= ITEM_RUPEE_GREEN) && (itemId <= ITEM_RUPEE_GOLD)) || (itemId == ITEM_HEART)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_BOXITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
if (itemId == ITEM_HEART_CONTAINER ||
|
||||
((itemId == ITEM_HEART_PIECE_2) && ((gSaveContext.inventory.questItems & 0xF0000000) == 0x40000000))) {
|
||||
@ -4046,7 +4046,7 @@ void func_800F4010(Vec3f* pos, u16 sfxId, f32 arg2) {
|
||||
|
||||
D_80131C8C = arg2;
|
||||
sp24 = func_800F3F84(arg2);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb);
|
||||
|
||||
if ((sfxId & 0xF0) == 0xB0) {
|
||||
phi_f0 = 0.3f;
|
||||
@ -4064,22 +4064,22 @@ void func_800F4010(Vec3f* pos, u16 sfxId, f32 arg2) {
|
||||
sfxId2 = NA_SE_PL_METALEFFECT_KID;
|
||||
}
|
||||
D_8016B7AC = (sp24 * 0.7) + 0.3;
|
||||
Audio_PlaySoundGeneral(sfxId2, pos, 4, &D_8016B7B0, &D_8016B7AC, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId2, pos, 4, &D_8016B7B0, &D_8016B7AC, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
void func_800F4138(Vec3f* pos, u16 sfxId, f32 arg2) {
|
||||
func_800F3F84(arg2);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7B0, &D_8016B7A8, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_800F4190(Vec3f* pos, u16 sfxId) {
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801305B0, &D_801333E0, &D_801305B4);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801305B0, &gSfxDefaultFreqAndVolScale, &D_801305B4);
|
||||
}
|
||||
void Audio_PlaySoundRandom(Vec3f* pos, u16 baseSfxId, u8 randLim) {
|
||||
u8 offset = Audio_NextRandom() % randLim;
|
||||
|
||||
Audio_PlaySoundGeneral(baseSfxId + offset, pos, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(baseSfxId + offset, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_800F4254(Vec3f* pos, u8 level) {
|
||||
@ -4088,10 +4088,10 @@ void func_800F4254(Vec3f* pos, u8 level) {
|
||||
D_801305F4 = D_801305E4[level];
|
||||
switch (level) {
|
||||
case 1:
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
break;
|
||||
case 2:
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_SWORD_CHARGE, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4099,7 +4099,7 @@ void func_800F4254(Vec3f* pos, u8 level) {
|
||||
}
|
||||
|
||||
if (level != 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_CHARGE - SFX_FLAG, pos, 4, &D_801305F4, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_CHARGE - SFX_FLAG, pos, 4, &D_801305F4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4111,14 +4111,14 @@ void func_800F436C(Vec3f* pos, u16 sfxId, f32 arg2) {
|
||||
}
|
||||
|
||||
if (D_8016B7D8 > 0.5f) {
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
void func_800F4414(Vec3f* pos, u16 sfxId, f32 arg2) {
|
||||
D_801305B8--;
|
||||
if (D_801305B8 == 0) {
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_8016B7D8, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
|
||||
if (arg2 > 2.0f) {
|
||||
arg2 = 2.0f;
|
||||
@ -4135,17 +4135,17 @@ void func_800F44EC(s8 arg0, s8 arg1) {
|
||||
|
||||
void func_800F4524(Vec3f* pos, u16 sfxId, s8 arg2) {
|
||||
D_8016B7DC = arg2;
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801333E0, &D_801333E0, &D_8016B7DC);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &D_8016B7DC);
|
||||
}
|
||||
|
||||
void func_800F4578(Vec3f* pos, u16 sfxId, f32 arg2) {
|
||||
D_8016B7E0 = arg2;
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801333E0, &D_8016B7E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &D_8016B7E0, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_800F45D0(f32 arg0) {
|
||||
func_800F4414(&D_801333D4, NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG, arg0);
|
||||
func_800F436C(&D_801333D4, 0, (0.15f * arg0) + 1.4f);
|
||||
func_800F4414(&gSfxDefaultPos, NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG, arg0);
|
||||
func_800F436C(&gSfxDefaultPos, 0, (0.15f * arg0) + 1.4f);
|
||||
}
|
||||
|
||||
void Audio_PlaySoundRiver(Vec3f* pos, f32 freqScale) {
|
||||
@ -4156,8 +4156,8 @@ void Audio_PlaySoundRiver(Vec3f* pos, f32 freqScale) {
|
||||
sRiverFreqScaleLerp.remainingFrames = 40;
|
||||
sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40;
|
||||
}
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void Audio_PlaySoundWaterfall(Vec3f* pos, f32 freqScale) {
|
||||
@ -4169,7 +4169,7 @@ void Audio_PlaySoundWaterfall(Vec3f* pos, f32 freqScale) {
|
||||
sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40;
|
||||
}
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value,
|
||||
&sWaterfallFreqScaleLerp.value, &D_801333E8);
|
||||
&sWaterfallFreqScaleLerp.value, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void Audio_StepFreqLerp(FreqLerp* lerp) {
|
||||
@ -4285,8 +4285,8 @@ void func_800F4A70(void) {
|
||||
}
|
||||
|
||||
void Audio_PlaySoundIncreasinglyTransposed(Vec3f* pos, s16 sfxId, u8* semitones) {
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitones[sAudioIncreasingTranspose] + 39], &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitones[sAudioIncreasingTranspose] + 39], &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
|
||||
if (sAudioIncreasingTranspose < 15) {
|
||||
sAudioIncreasingTranspose++;
|
||||
@ -4298,7 +4298,7 @@ void Audio_ResetIncreasingTranspose(void) {
|
||||
}
|
||||
|
||||
void Audio_PlaySoundTransposed(Vec3f* pos, u16 sfxId, s8 semitone) {
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitone + 39], &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &gNoteFrequencies[semitone + 39], &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_800F4C58(Vec3f* pos, u16 sfxId, u8 arg2) {
|
||||
@ -4319,7 +4319,7 @@ void func_800F4C58(Vec3f* pos, u16 sfxId, u8 arg2) {
|
||||
}
|
||||
phi_s1++;
|
||||
}
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_800F4E30(Vec3f* pos, f32 arg1) {
|
||||
@ -4880,10 +4880,10 @@ void func_800F6268(f32 dist, u16 arg1) {
|
||||
void func_800F64E0(u8 arg0) {
|
||||
D_80130608 = arg0;
|
||||
if (arg0 != 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WIN_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WIN_OPEN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Audio_QueueCmdS32(0xF1000000, 0);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WIN_CLOSE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WIN_CLOSE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Audio_QueueCmdS32(0xF2000000, 0);
|
||||
}
|
||||
}
|
||||
@ -4961,7 +4961,7 @@ void Audio_SetBaseFilter(u8 filter) {
|
||||
if (filter == 0) {
|
||||
Audio_StopSfxById(NA_SE_PL_IN_BUBBLE);
|
||||
} else if (sAudioBaseFilter == 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_IN_BUBBLE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_IN_BUBBLE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
sAudioBaseFilter = filter;
|
||||
@ -4994,7 +4994,7 @@ void Audio_PlaySoundGeneralIfNotInCutscene(u16 sfxId, Vec3f* pos, u8 arg2, f32*
|
||||
}
|
||||
|
||||
void Audio_PlaySoundIfNotInCutscene(u16 sfxId) {
|
||||
Audio_PlaySoundGeneralIfNotInCutscene(sfxId, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneralIfNotInCutscene(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_800F6964(u16 arg0) {
|
||||
|
@ -81,13 +81,13 @@ u8 gSfxChannelLayout = 0;
|
||||
|
||||
u16 D_801333D0 = 0;
|
||||
|
||||
Vec3f D_801333D4 = { 0.0f, 0.0f, 0.0f }; // default pos
|
||||
Vec3f gSfxDefaultPos = { 0.0f, 0.0f, 0.0f }; // default pos
|
||||
|
||||
f32 D_801333E0 = 1.0f; // default freqScale
|
||||
f32 gSfxDefaultFreqAndVolScale = 1.0f; // default freqScale
|
||||
|
||||
s32 D_801333E4 = 0; // unused
|
||||
|
||||
s8 D_801333E8 = 0; // default reverbAdd
|
||||
s8 gSfxDefaultReverb = 0; // default reverbAdd
|
||||
|
||||
s32 D_801333EC = 0; // unused
|
||||
|
||||
@ -381,7 +381,7 @@ void Audio_ChooseActiveSounds(u8 bankId)
|
||||
} else if (gSoundBanks[bankId][entryIndex].state != SFX_STATE_EMPTY) {
|
||||
entry = &gSoundBanks[bankId][entryIndex];
|
||||
|
||||
if (&D_801333D4.x == entry[0].posX) {
|
||||
if (&gSfxDefaultPos.x == entry[0].posX) {
|
||||
entry->dist = 0.0f;
|
||||
} else {
|
||||
tempf1 = *entry->posY * 1;
|
||||
|
@ -1,24 +1,33 @@
|
||||
#include "global.h"
|
||||
|
||||
// memmove used in __osMalloc.c
|
||||
void* func_801068B0(void* dst, void* src, size_t size) {
|
||||
u8* spC = dst;
|
||||
u8* sp8 = src;
|
||||
register s32 a3;
|
||||
/**
|
||||
* memmove: copies `len` bytes from memory starting at `src` to memory starting at `dest`.
|
||||
*
|
||||
* Unlike memcpy(), the regions of memory may overlap.
|
||||
*
|
||||
* @param dest address of start of buffer to write to
|
||||
* @param src address of start of buffer to read from
|
||||
* @param len number of bytes to copy.
|
||||
*
|
||||
* @return dest
|
||||
*/
|
||||
void* oot_memmove(void* dest, const void* src, size_t len) {
|
||||
char* d = dest;
|
||||
const char* s = src;
|
||||
|
||||
if (spC == sp8) {
|
||||
return dst;
|
||||
if (d == s) {
|
||||
return dest;
|
||||
}
|
||||
if (spC < sp8) {
|
||||
for (a3 = size--; a3 != 0; a3 = size--) {
|
||||
*spC++ = *sp8++;
|
||||
if (d < s) {
|
||||
while (len--) {
|
||||
*d++ = *s++;
|
||||
}
|
||||
} else {
|
||||
spC += size - 1;
|
||||
sp8 += size - 1;
|
||||
for (a3 = size--; a3 != 0; a3 = size--) {
|
||||
*spC-- = *sp8--;
|
||||
d += len - 1;
|
||||
s += len - 1;
|
||||
while (len--) {
|
||||
*d-- = *s--;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
return dest;
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ void func_800B44E0(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (dbCamera->sub.nPoints < 6) {
|
||||
if (sDbCamAnim.unk_0A != 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
sDbCamAnim.unk_0A = 0;
|
||||
}
|
||||
func_8006376C(0x0D, 0x17, 3, cameraStrings[0]);
|
||||
@ -308,7 +308,7 @@ void func_800B44E0(DbCamera* dbCamera, Camera* cam) {
|
||||
!func_800BB2B4(&sDbCamAnim.lookAtPos, &sDbCamAnim.roll, &sDbCamAnim.fov, dbCamera->sub.lookAt,
|
||||
&sDbCamAnim.keyframe, &sDbCamAnim.curFrame) &&
|
||||
sDbCamAnim.unk_0A == 1) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
sDbCamAnim.unk_04++;
|
||||
|
||||
if (dbCamera->sub.nFrames > 0 && dbCamera->sub.nFrames < sDbCamAnim.unk_04) {
|
||||
@ -536,7 +536,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
dbCamera->unk_40 = -1;
|
||||
dbCamera->sub.demoCtrlActionIdx = 0;
|
||||
sDbCamAnim.unk_0A = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_LOCK_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_LOCK_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else if (dbCamera->unk_38 == -1) {
|
||||
dbCamera->unk_38 = 1;
|
||||
} else {
|
||||
@ -856,22 +856,22 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
dbCamera->unk_1C.z = 0.0f;
|
||||
dbCamera->unk_1C.y = 1.0f;
|
||||
} else if (dbCamera->sub.unk_08 == 2) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->sub.unk_08 = 0;
|
||||
func_800B41DC(dbCamera, dbCamera->sub.unkIdx, cam);
|
||||
} else {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_R) &&
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->sub.nPoints = dbCamera->sub.unkIdx + 1;
|
||||
func_800B4088(dbCamera, cam);
|
||||
} else if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_R)) {
|
||||
if (dbCamera->sub.unkIdx == 0x80) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PUTAWAY, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_PUTAWAY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
func_800B42C0(dbCamera, cam);
|
||||
if (dbCamera->sub.unkIdx == (dbCamera->sub.nPoints - 1)) {
|
||||
dbCamera->sub.unkIdx++;
|
||||
@ -923,7 +923,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
} else {
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CRIGHT) &&
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
osSyncPrintf("@@@\n@@@\n@@@/* *** spline point data ** start here *** */\n@@@\n");
|
||||
DbCamera_PrintPoints("Lookat", dbCamera->sub.nPoints, dbCamera->sub.lookAt);
|
||||
DbCamera_PrintPoints("Position", dbCamera->sub.nPoints, dbCamera->sub.position);
|
||||
@ -932,13 +932,13 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
osSyncPrintf("@@@static short Mode = %d;\n@@@\n", dbCamera->sub.mode);
|
||||
osSyncPrintf("@@@\n@@@\n@@@/* *** spline point data ** finish! *** */\n@@@\n");
|
||||
} else if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CLEFT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->sub.unk_08 = (dbCamera->sub.unk_08 + 1) % 3;
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CUP) &&
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
if (dbCamera->sub.unkIdx > 0) {
|
||||
dbCamera->sub.unkIdx--;
|
||||
} else {
|
||||
@ -946,8 +946,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
} else {
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CUP)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
if (dbCamera->sub.unkIdx > 0) {
|
||||
dbCamera->sub.unkIdx--;
|
||||
} else {
|
||||
@ -968,7 +968,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L) &&
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CDOWN)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
if (dbCamera->sub.unkIdx < (dbCamera->sub.nPoints - 1)) {
|
||||
dbCamera->sub.unkIdx++;
|
||||
} else {
|
||||
@ -976,8 +976,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
} else {
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CDOWN)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
if (dbCamera->sub.unkIdx < (dbCamera->sub.nPoints - 1)) {
|
||||
dbCamera->sub.unkIdx++;
|
||||
} else {
|
||||
@ -1046,8 +1046,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
case 1:
|
||||
dbCamera->unk_3C = true;
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
if (dbCamera->sub.unk_0A == 0) {
|
||||
dbCamera->sub.unk_0A = 5;
|
||||
} else {
|
||||
@ -1055,8 +1055,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
if (dbCamera->sub.unk_0A == 5) {
|
||||
dbCamera->sub.unk_0A = 0;
|
||||
} else {
|
||||
@ -1064,8 +1064,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
switch (dbCamera->sub.unk_0A) {
|
||||
case 1:
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L)) {
|
||||
@ -1114,8 +1114,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_DLEFT)) {
|
||||
if ((D_8012D10C++ % 5) == 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
switch (dbCamera->sub.unk_0A) {
|
||||
@ -1152,8 +1152,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
|
||||
switch (dbCamera->sub.unk_0A) {
|
||||
case 1:
|
||||
@ -1201,8 +1201,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_DRIGHT)) {
|
||||
if ((D_8012D10C++ % 5) == 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
switch (dbCamera->sub.unk_0A) {
|
||||
@ -1353,7 +1353,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) {
|
||||
dbCamera->fov = 60.0f;
|
||||
dbCamera->rollDegrees = dbCamera->roll * 1.40625f;
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CLEFT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->unk_78 = (dbCamera->unk_78 + 1) % 3;
|
||||
dbCamera->unk_38 = -1;
|
||||
}
|
||||
@ -1634,7 +1634,7 @@ void DbCamera_DrawSlotLetters(char* str, s16 y, s16 x, s32 colorId) {
|
||||
void DbCamera_PrintAllCuts(Camera* cam) {
|
||||
s32 i;
|
||||
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
osSyncPrintf("@@@\n@@@\n@@@/* ****** spline point data ** start here ***** */\n@@@\n");
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sDbCameraCuts) - 1; i++) {
|
||||
@ -1777,8 +1777,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
if ((1 << sCurFileIdx) & sMempakFiles) {
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT) ||
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlToggleSwitch ^= 1;
|
||||
}
|
||||
cameraStrings[41][9] = sCurFileIdx + 'A';
|
||||
@ -1791,12 +1791,12 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A)) {
|
||||
if (dbCamera->sub.demoCtrlToggleSwitch == 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlMenu++;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlMenu = 0;
|
||||
}
|
||||
}
|
||||
@ -1812,7 +1812,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlMenu = 0;
|
||||
return 1;
|
||||
}
|
||||
@ -1848,7 +1848,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A) ||
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
if (dbCamera->sub.demoCtrlMenu == DEMO_CTRL_MENU(ACTION_LOAD, MENU_SUCCESS)) {
|
||||
dbCamera->sub.demoCtrlActionIdx = ACTION_E;
|
||||
}
|
||||
@ -1870,7 +1870,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A) ||
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlMenu -= 9;
|
||||
}
|
||||
block_2:
|
||||
@ -1904,8 +1904,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
sp74[i * 2 + 1] = '\0';
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
if (sCurFileIdx >= 4) {
|
||||
sCurFileIdx = 0;
|
||||
} else {
|
||||
@ -1921,8 +1921,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
if (sCurFileIdx <= 0) {
|
||||
sCurFileIdx = 4;
|
||||
} else {
|
||||
@ -1964,25 +1964,25 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
func_8006376C(0x14, 0x1A, 5, cameraStrings[36]);
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx - 1) % 4u;
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx + 1) % 4u;
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlToggleSwitch = 0;
|
||||
dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(dbCamera->sub.demoCtrlActionIdx, MENU_INFO);
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlActionIdx = ACTION_E;
|
||||
return 1;
|
||||
}
|
||||
@ -1994,8 +1994,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP) ||
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) {
|
||||
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlActionIdx = ACTION_E;
|
||||
}
|
||||
return 2;
|
||||
@ -2007,13 +2007,13 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
default: {
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DUP)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_INFO);
|
||||
dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx - 1) % 4u;
|
||||
sCurFileIdx = 0;
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DDOWN)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_INFO);
|
||||
dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx + 1) % 4u;
|
||||
sCurFileIdx = 0;
|
||||
@ -2052,7 +2052,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
if (func_800B91B0(cam, dbCamera) == 0) {
|
||||
Interface_ChangeAlpha(2);
|
||||
ShrinkWindow_SetVal(0);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
OLib_Vec3fDiffToVecSphGeo(&sp5C, &dbCamera->eye, &dbCamera->at);
|
||||
DbCamera_CalcUpFromPitchYawRoll(&dbCamera->unk_1C, sp5C.pitch, sp5C.yaw,
|
||||
@ -2070,7 +2070,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
sDbCamAnim.unk_0A = 1;
|
||||
sDbCamAnim.unk_0C = 0;
|
||||
D_8016110C = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_L)) {
|
||||
@ -2085,15 +2085,15 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
if (sLastFileIdx != -1) {
|
||||
switch (sp74[sCurFileIdx]) {
|
||||
case '?':
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
sDbCameraCuts[idx1] = sDbCameraCuts[idx2];
|
||||
sp74[sCurFileIdx] = '?'; // useless
|
||||
DbCamera_ResetCut(idx2, false);
|
||||
break;
|
||||
case '-':
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
|
||||
sp64 = sDbCameraCuts[idx2];
|
||||
if (sLastFileIdx < sCurFileIdx) {
|
||||
@ -2115,8 +2115,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2125,7 +2125,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_A)) {
|
||||
if (sp74[sCurFileIdx] == '?') {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
sp74[sCurFileIdx] = DbCamera_InitCut(idx1, &dbCamera->sub);
|
||||
if (sp74[sCurFileIdx] == '?') {
|
||||
func_8006376C(0xF, 0x18, 7, cameraStrings[26]);
|
||||
@ -2135,7 +2135,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_B)) {
|
||||
if (sp74[sCurFileIdx] != '?' && sp74[sCurFileIdx] != '-') {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
sp74[sCurFileIdx] = '?';
|
||||
DbCamera_ResetCut(idx1, true);
|
||||
}
|
||||
@ -2143,7 +2143,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_R)) {
|
||||
if (sp74[sCurFileIdx] != '?' && sp74[sCurFileIdx] != '-') {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
|
||||
for (i = 0; i < sDbCameraCuts[idx1].nPoints; i++) {
|
||||
dbCamera->sub.lookAt[i] = sDbCameraCuts[idx1].lookAt[i];
|
||||
@ -2165,7 +2165,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DRIGHT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
if (sCurFileIdx == 0x1E) {
|
||||
sCurFileIdx = 0;
|
||||
} else {
|
||||
@ -2173,7 +2173,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
}
|
||||
}
|
||||
if (CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_DLEFT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
sCurFileIdx = (sCurFileIdx == 0) ? 0x1E : sCurFileIdx - 1;
|
||||
}
|
||||
|
||||
@ -2187,7 +2187,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
DbCamera_PrintAllCuts(cam);
|
||||
} else if (CHECK_BTN_ALL(sPlayState->state.input[2].cur.button, BTN_L) &&
|
||||
CHECK_BTN_ALL(sPlayState->state.input[2].press.button, BTN_CLEFT)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
for (i = 0; i < ARRAY_COUNT(sDbCameraCuts) - 1; i++) {
|
||||
if (sDbCameraCuts[i].nPoints != 0) {
|
||||
osSyncPrintf("\n@@@ /* CUT [%d]\t*/", i);
|
||||
@ -2203,7 +2203,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) {
|
||||
Interface_ChangeAlpha(50);
|
||||
ShrinkWindow_SetVal(0x20);
|
||||
D_8016110C = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
func_8006376C(4, 7, 5, cameraStrings[28]);
|
||||
|
@ -109,5 +109,5 @@ void DebugArena_Cleanup(void) {
|
||||
}
|
||||
|
||||
u8 DebugArena_IsInitalized(void) {
|
||||
return __osMallocIsInitalized(&sDebugArena);
|
||||
return __osMallocIsInitialized(&sDebugArena);
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
|
||||
SpeedMeter D_801664D0;
|
||||
struct_801664F0 D_801664F0;
|
||||
struct_80166500 D_80166500;
|
||||
VisMono sMonoColors;
|
||||
VisCvg sVisCvg;
|
||||
VisZBuf sVisZBuf;
|
||||
VisMono sVisMono;
|
||||
ViMode sViMode;
|
||||
FaultClient sGameFaultClient;
|
||||
u16 sLastButtonPressed;
|
||||
@ -31,41 +31,43 @@ void GameState_FaultPrint(void) {
|
||||
}
|
||||
}
|
||||
|
||||
void GameState_SetFBFilter(Gfx** gfx) {
|
||||
Gfx* gfxP;
|
||||
gfxP = *gfx;
|
||||
void GameState_SetFBFilter(Gfx** gfxP) {
|
||||
Gfx* gfx = *gfxP;
|
||||
|
||||
if ((R_FB_FILTER_TYPE > 0) && (R_FB_FILTER_TYPE < 5)) {
|
||||
D_801664F0.type = R_FB_FILTER_TYPE;
|
||||
D_801664F0.color.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
D_801664F0.color.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
D_801664F0.color.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
D_801664F0.color.a = R_FB_FILTER_A;
|
||||
func_800ACE98(&D_801664F0, &gfxP);
|
||||
} else if ((R_FB_FILTER_TYPE == 5) || (R_FB_FILTER_TYPE == 6)) {
|
||||
D_80166500.useRgba = (R_FB_FILTER_TYPE == 6);
|
||||
D_80166500.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
D_80166500.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
D_80166500.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
D_80166500.primColor.a = R_FB_FILTER_A;
|
||||
D_80166500.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||
D_80166500.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
||||
D_80166500.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
||||
D_80166500.envColor.a = R_FB_FILTER_A;
|
||||
func_800AD958(&D_80166500, &gfxP);
|
||||
} else if (R_FB_FILTER_TYPE == 7) {
|
||||
sMonoColors.unk_00 = 0;
|
||||
sMonoColors.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
sMonoColors.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
sMonoColors.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
sMonoColors.primColor.a = R_FB_FILTER_A;
|
||||
sMonoColors.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||
sMonoColors.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
||||
sMonoColors.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
||||
sMonoColors.envColor.a = R_FB_FILTER_A;
|
||||
VisMono_Draw(&sMonoColors, &gfxP);
|
||||
if ((R_FB_FILTER_TYPE >= FB_FILTER_CVG_RGB) && (R_FB_FILTER_TYPE <= FB_FILTER_CVG_RGB_FOG)) {
|
||||
// Visualize coverage
|
||||
sVisCvg.vis.type = FB_FILTER_TO_CVG_TYPE(R_FB_FILTER_TYPE);
|
||||
sVisCvg.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
sVisCvg.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
sVisCvg.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
sVisCvg.vis.primColor.a = R_FB_FILTER_A;
|
||||
VisCvg_Draw(&sVisCvg, &gfx);
|
||||
} else if ((R_FB_FILTER_TYPE == FB_FILTER_ZBUF_IA) || (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA)) {
|
||||
// Visualize z-buffer
|
||||
sVisZBuf.vis.type = (R_FB_FILTER_TYPE == FB_FILTER_ZBUF_RGBA);
|
||||
sVisZBuf.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
sVisZBuf.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
sVisZBuf.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
sVisZBuf.vis.primColor.a = R_FB_FILTER_A;
|
||||
sVisZBuf.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||
sVisZBuf.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
||||
sVisZBuf.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
||||
sVisZBuf.vis.envColor.a = R_FB_FILTER_A;
|
||||
VisZBuf_Draw(&sVisZBuf, &gfx);
|
||||
} else if (R_FB_FILTER_TYPE == FB_FILTER_MONO) {
|
||||
// Monochrome filter
|
||||
sVisMono.vis.type = 0;
|
||||
sVisMono.vis.primColor.r = R_FB_FILTER_PRIM_COLOR(0);
|
||||
sVisMono.vis.primColor.g = R_FB_FILTER_PRIM_COLOR(1);
|
||||
sVisMono.vis.primColor.b = R_FB_FILTER_PRIM_COLOR(2);
|
||||
sVisMono.vis.primColor.a = R_FB_FILTER_A;
|
||||
sVisMono.vis.envColor.r = R_FB_FILTER_ENV_COLOR(0);
|
||||
sVisMono.vis.envColor.g = R_FB_FILTER_ENV_COLOR(1);
|
||||
sVisMono.vis.envColor.b = R_FB_FILTER_ENV_COLOR(2);
|
||||
sVisMono.vis.envColor.a = R_FB_FILTER_A;
|
||||
VisMono_Draw(&sVisMono, &gfx);
|
||||
}
|
||||
*gfx = gfxP;
|
||||
*gfxP = gfx;
|
||||
}
|
||||
|
||||
void func_800C4344(GameState* gameState) {
|
||||
@ -420,9 +422,9 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
|
||||
|
||||
startTime = endTime;
|
||||
LOG_CHECK_NULL_POINTER("this->cleanup", gameState->destroy);
|
||||
func_800ACE70(&D_801664F0);
|
||||
func_800AD920(&D_80166500);
|
||||
VisMono_Init(&sMonoColors);
|
||||
VisCvg_Init(&sVisCvg);
|
||||
VisZBuf_Init(&sVisZBuf);
|
||||
VisMono_Init(&sVisMono);
|
||||
if (SREG(48) == 0) {
|
||||
ViMode_Init(&sViMode);
|
||||
}
|
||||
@ -450,9 +452,9 @@ void GameState_Destroy(GameState* gameState) {
|
||||
}
|
||||
func_800AA0F0();
|
||||
SpeedMeter_Destroy(&D_801664D0);
|
||||
func_800ACE90(&D_801664F0);
|
||||
func_800AD950(&D_80166500);
|
||||
VisMono_Destroy(&sMonoColors);
|
||||
VisCvg_Destroy(&sVisCvg);
|
||||
VisZBuf_Destroy(&sVisZBuf);
|
||||
VisMono_Destroy(&sVisMono);
|
||||
if (SREG(48) == 0) {
|
||||
ViMode_Destroy(&sViMode);
|
||||
}
|
||||
|
@ -300,7 +300,6 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
|
||||
|
||||
GameState_ReqPadData(gameState);
|
||||
GameState_Update(gameState);
|
||||
DrawColViewer();
|
||||
|
||||
OPEN_DISPS(gfxCtx);
|
||||
|
||||
|
@ -107,5 +107,5 @@ void SystemArena_Cleanup(void) {
|
||||
}
|
||||
|
||||
u8 SystemArena_IsInitalized(void) {
|
||||
return __osMallocIsInitalized(&gSystemArena);
|
||||
return __osMallocIsInitialized(&gSystemArena);
|
||||
}
|
||||
|
@ -624,7 +624,7 @@ void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, Pl
|
||||
|
||||
lockOnSfxId = CHECK_FLAG_ALL(actorArg->flags, ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE) ? NA_SE_SY_LOCK_ON
|
||||
: NA_SE_SY_LOCK_ON_HUMAN;
|
||||
func_80078884(lockOnSfxId);
|
||||
Sfx_PlaySfxCentered(lockOnSfxId);
|
||||
}
|
||||
|
||||
targetCtx->targetCenterPos.x = actorArg->world.pos.x;
|
||||
@ -2207,7 +2207,7 @@ void func_8002F7A0(PlayState* play, Actor* actor, f32 arg2, s16 arg3, f32 arg4)
|
||||
|
||||
void Player_PlaySfx(Actor* actor, u16 sfxId) {
|
||||
if (actor->id != ACTOR_PLAYER || sfxId < NA_SE_VO_LI_SWORD_N || sfxId > NA_SE_VO_LI_ELECTRIC_SHOCK_LV_KID) {
|
||||
Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &D_801333E0 , &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale , &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
freqMultiplier = CVarGetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0);
|
||||
if (freqMultiplier <= 0) {
|
||||
@ -2215,12 +2215,12 @@ void Player_PlaySfx(Actor* actor, u16 sfxId) {
|
||||
}
|
||||
// Authentic behavior uses D_801333E0 for both freqScale and a4
|
||||
// Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &D_801333E0 , &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &freqMultiplier, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, &actor->projectedPos, 4, &freqMultiplier, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
void Audio_PlayActorSound2(Actor* actor, u16 sfxId) {
|
||||
func_80078914(&actor->projectedPos, sfxId);
|
||||
Sfx_PlaySfxAtPos(&actor->projectedPos, sfxId);
|
||||
}
|
||||
|
||||
void func_8002F850(PlayState* play, Actor* actor) {
|
||||
@ -2236,8 +2236,8 @@ void func_8002F850(PlayState* play, Actor* actor) {
|
||||
sfxId = SurfaceType_GetSfx(&play->colCtx, actor->floorPoly, actor->floorBgId);
|
||||
}
|
||||
|
||||
func_80078914(&actor->projectedPos, NA_SE_EV_BOMB_BOUND);
|
||||
func_80078914(&actor->projectedPos, sfxId + SFX_FLAG);
|
||||
Sfx_PlaySfxAtPos(&actor->projectedPos, NA_SE_EV_BOMB_BOUND);
|
||||
Sfx_PlaySfxAtPos(&actor->projectedPos, sfxId + SFX_FLAG);
|
||||
}
|
||||
|
||||
void func_8002F8F0(Actor* actor, u16 sfxId) {
|
||||
@ -2664,7 +2664,7 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
|
||||
actor = NULL;
|
||||
if (actorCtx->targetCtx.unk_4B != 0) {
|
||||
actorCtx->targetCtx.unk_4B = 0;
|
||||
func_80078884(NA_SE_SY_LOCK_OFF);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_LOCK_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2765,15 +2765,15 @@ void Actor_Draw(PlayState* play, Actor* actor) {
|
||||
|
||||
void func_80030ED8(Actor* actor) {
|
||||
if (actor->flags & ACTOR_FLAG_SFX_AT_POS) {
|
||||
Audio_PlaySoundGeneral(actor->sfx, &actor->projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(actor->sfx, &actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else if (actor->flags & ACTOR_FLAG_SFX_AT_CENTER) {
|
||||
func_80078884(actor->sfx);
|
||||
Sfx_PlaySfxCentered(actor->sfx);
|
||||
} else if (actor->flags & ACTOR_FLAG_SFX_AT_CENTER2) {
|
||||
func_800788CC(actor->sfx);
|
||||
Sfx_PlaySfxCentered2(actor->sfx);
|
||||
} else if (actor->flags & ACTOR_FLAG_SFX_AS_TIMER) {
|
||||
func_800F4C58(&D_801333D4, NA_SE_SY_TIMER - SFX_FLAG, (s8)(actor->sfx - 1));
|
||||
func_800F4C58(&gSfxDefaultPos, NA_SE_SY_TIMER - SFX_FLAG, (s8)(actor->sfx - 1));
|
||||
} else {
|
||||
func_80078914(&actor->projectedPos, actor->sfx);
|
||||
Sfx_PlaySfxAtPos(&actor->projectedPos, actor->sfx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5747,8 +5747,8 @@ void func_80036E50(u16 textId, s16 arg1) {
|
||||
Flags_SetInfTable(INFTABLE_0C);
|
||||
return;
|
||||
case 0x1033:
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
|
||||
Flags_SetInfTable(INFTABLE_0E);
|
||||
return;
|
||||
@ -6211,7 +6211,7 @@ s32 func_80037CB8(PlayState* play, Actor* actor, s16 arg2) {
|
||||
case TEXT_STATE_CHOICE:
|
||||
case TEXT_STATE_EVENT:
|
||||
if (Message_ShouldAdvance(play) && func_80037C94(play, actor, arg2)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
msgCtx->msgMode = MSGMODE_TEXT_CLOSING;
|
||||
ret = true;
|
||||
}
|
||||
|
@ -6168,7 +6168,7 @@ s32 Camera_Demo5(Camera* camera) {
|
||||
|
||||
pad = sDemo5PrevSfxFrame - camera->play->state.frames;
|
||||
if ((pad >= 0x33) || (pad < -0x32)) {
|
||||
func_80078884(camera->data1);
|
||||
Sfx_PlaySfxCentered(camera->data1);
|
||||
}
|
||||
|
||||
sDemo5PrevSfxFrame = camera->play->state.frames;
|
||||
@ -7362,11 +7362,11 @@ s32 Camera_DbgChangeMode(Camera* camera) {
|
||||
if (!gDbgCamEnabled && camera->play->activeCamera == MAIN_CAM) {
|
||||
if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CUP)) {
|
||||
osSyncPrintf("attention sound URGENCY\n");
|
||||
func_80078884(NA_SE_SY_ATTENTION_URGENCY);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_URGENCY);
|
||||
}
|
||||
if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CDOWN)) {
|
||||
osSyncPrintf("attention sound NORMAL\n");
|
||||
func_80078884(NA_SE_SY_ATTENTION_ON);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_ON);
|
||||
}
|
||||
|
||||
if (CHECK_BTN_ALL(D_8015BD7C->state.input[2].press.button, BTN_CRIGHT)) {
|
||||
@ -7783,7 +7783,7 @@ s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags) {
|
||||
if (!((sCameraSettings[camera->setting].unk_00 & 0x3FFFFFFF) & (1 << mode))) {
|
||||
if (mode == CAM_MODE_FIRSTPERSON) {
|
||||
osSyncPrintf("camera: error sound\n");
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ERROR);
|
||||
}
|
||||
|
||||
if (camera->mode != CAM_MODE_NORMAL) {
|
||||
@ -7871,20 +7871,20 @@ s32 Camera_ChangeModeFlags(Camera* camera, s16 mode, u8 flags) {
|
||||
if (camera->status == CAM_STAT_ACTIVE) {
|
||||
switch (modeChangeFlags) {
|
||||
case 1:
|
||||
func_80078884(0);
|
||||
Sfx_PlaySfxCentered(0);
|
||||
break;
|
||||
case 2:
|
||||
if (camera->play->roomCtx.curRoom.behaviorType1 == ROOM_BEHAVIOR_TYPE1_1) {
|
||||
func_80078884(NA_SE_SY_ATTENTION_URGENCY);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_URGENCY);
|
||||
} else {
|
||||
func_80078884(NA_SE_SY_ATTENTION_ON);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_ON);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
func_80078884(NA_SE_SY_ATTENTION_URGENCY);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_URGENCY);
|
||||
break;
|
||||
case 8:
|
||||
func_80078884(NA_SE_SY_ATTENTION_ON);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ATTENTION_ON);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1607,10 +1607,10 @@ void CollisionCheck_HitSolid(PlayState* play, ColliderInfo* info, Collider* coll
|
||||
if (flags == TOUCH_SFX_NORMAL && collider->colType != COLTYPE_METAL) {
|
||||
EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_WHITE, hitPos);
|
||||
if (collider->actor == NULL) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
} else if (flags == TOUCH_SFX_NORMAL) { // collider->colType == COLTYPE_METAL
|
||||
EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_METAL, hitPos);
|
||||
@ -1622,18 +1622,18 @@ void CollisionCheck_HitSolid(PlayState* play, ColliderInfo* info, Collider* coll
|
||||
} else if (flags == TOUCH_SFX_HARD) {
|
||||
EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_WHITE, hitPos);
|
||||
if (collider->actor == NULL) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &collider->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
} else if (flags == TOUCH_SFX_WOOD) {
|
||||
EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_DUST, hitPos);
|
||||
if (collider->actor == NULL) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &collider->actor->projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &collider->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1644,17 +1644,17 @@ void CollisionCheck_HitSolid(PlayState* play, ColliderInfo* info, Collider* coll
|
||||
s32 CollisionCheck_SwordHitAudio(Collider* at, ColliderInfo* acInfo) {
|
||||
if (at->actor != NULL && at->actor->category == ACTORCAT_PLAYER) {
|
||||
if (acInfo->elemType == ELEMTYPE_UNK0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE, &at->actor->projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else if (acInfo->elemType == ELEMTYPE_UNK1) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE_HARD, &at->actor->projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SWORD_STRIKE_HARD, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else if (acInfo->elemType == ELEMTYPE_UNK2) {
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else if (acInfo->elemType == ELEMTYPE_UNK3) {
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_PL_WALK_GROUND - SFX_FLAG, &at->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -1691,7 +1691,7 @@ void CollisionCheck_HitEffects(PlayState* play, Collider* at, ColliderInfo* atIn
|
||||
} else if (sHitInfo[ac->colType].effect == HIT_WOOD) {
|
||||
if (at->actor == NULL) {
|
||||
CollisionCheck_SpawnShieldParticles(play, hitPos);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
CollisionCheck_SpawnShieldParticlesWood(play, hitPos, &at->actor->projectedPos);
|
||||
}
|
||||
@ -1704,10 +1704,10 @@ void CollisionCheck_HitEffects(PlayState* play, Collider* at, ColliderInfo* atIn
|
||||
} else {
|
||||
EffectSsHitMark_SpawnFixedScale(play, EFFECT_HITMARK_WHITE, hitPos);
|
||||
if (ac->actor == NULL) {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &ac->actor->projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_BOUND, &ac->actor->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3460,7 +3460,7 @@ void CollisionCheck_SpawnShieldParticles(PlayState* play, Vec3f* v) {
|
||||
*/
|
||||
void CollisionCheck_SpawnShieldParticlesMetal(PlayState* play, Vec3f* v) {
|
||||
CollisionCheck_SpawnShieldParticles(play, v);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3468,7 +3468,7 @@ void CollisionCheck_SpawnShieldParticlesMetal(PlayState* play, Vec3f* v) {
|
||||
*/
|
||||
void CollisionCheck_SpawnShieldParticlesMetalSound(PlayState* play, Vec3f* v, Vec3f* pos) {
|
||||
CollisionCheck_SpawnShieldParticles(play, v);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, pos, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_SHIELD_REFLECT_SW, pos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3508,7 +3508,7 @@ void CollisionCheck_SpawnShieldParticlesWood(PlayState* play, Vec3f* v, Vec3f* a
|
||||
initWood.lightPoint.z = initWood.position.z;
|
||||
|
||||
Effect_Add(play, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &initWood);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, actorPos, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_REFLECTION_WOOD, actorPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,7 +285,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
|
||||
play->roomCtx.unk_74[0] += 0x14;
|
||||
}
|
||||
if (csCtx->frames == 0x30F) {
|
||||
func_80078884(NA_SE_EV_DEKU_DEATH);
|
||||
Sfx_PlaySfxCentered(NA_SE_EV_DEKU_DEATH);
|
||||
} else if (csCtx->frames == 0x2CD) {
|
||||
play->roomCtx.unk_74[0] = 0;
|
||||
}
|
||||
@ -299,7 +299,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
|
||||
break;
|
||||
case 13:
|
||||
if (play->roomCtx.unk_74[1] == 0) {
|
||||
func_80078884(NA_SE_EV_TRIFORCE_FLASH);
|
||||
Sfx_PlaySfxCentered(NA_SE_EV_TRIFORCE_FLASH);
|
||||
}
|
||||
if (play->roomCtx.unk_74[1] < 0xFF) {
|
||||
play->roomCtx.unk_74[1] += 5;
|
||||
@ -307,7 +307,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
|
||||
break;
|
||||
case 14:
|
||||
if (sp3F != 0) {
|
||||
func_800BC490(play, 1);
|
||||
Play_SetViewpoint(play, 1);
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
@ -350,16 +350,16 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER);
|
||||
break;
|
||||
case 22:
|
||||
D_801614B0.r = 255;
|
||||
D_801614B0.g = 255;
|
||||
D_801614B0.b = 255;
|
||||
D_801614B0.a = 255;
|
||||
gVisMonoColor.r = 255;
|
||||
gVisMonoColor.g = 255;
|
||||
gVisMonoColor.b = 255;
|
||||
gVisMonoColor.a = 255;
|
||||
break;
|
||||
case 23:
|
||||
D_801614B0.r = 255;
|
||||
D_801614B0.g = 180;
|
||||
D_801614B0.b = 100;
|
||||
D_801614B0.a = 255.0f * temp;
|
||||
gVisMonoColor.r = 255;
|
||||
gVisMonoColor.g = 180;
|
||||
gVisMonoColor.b = 100;
|
||||
gVisMonoColor.a = 255.0f * temp;
|
||||
break;
|
||||
case 24:
|
||||
play->roomCtx.curRoom.segment = NULL;
|
||||
@ -412,7 +412,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
|
||||
if (sp3F != 0) {
|
||||
play->envCtx.sandstormState = SANDSTORM_FILL;
|
||||
}
|
||||
func_800788CC(NA_SE_EV_SAND_STORM - SFX_FLAG);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_SAND_STORM - SFX_FLAG);
|
||||
break;
|
||||
case 33:
|
||||
gSaveContext.sunsSongState = SUNSSONG_START;
|
||||
@ -514,7 +514,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
|
||||
CHECK_BTN_ALL(play->state.input[0].press.button, BTN_B) ||
|
||||
CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START)) &&
|
||||
(gSaveContext.fileNum != 0xFEDC) && (play->transitionTrigger == TRANS_TRIGGER_OFF)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
temp = 1;
|
||||
}
|
||||
|
||||
@ -1328,15 +1328,15 @@ void Cutscene_Command_TransitionFX(PlayState* play, CutsceneContext* csCtx, CsCm
|
||||
if (cmd->base == 1) {
|
||||
play->envCtx.screenFillColor[3] = 255.0f * temp;
|
||||
if ((temp == 0.0f) && (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WHITE_OUT_S, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WHITE_OUT_S, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else if ((temp == 0.0f) &&
|
||||
((gSaveContext.entranceIndex == ENTR_TEMPLE_OF_TIME_ENTRANCE) || (gSaveContext.entranceIndex == ENTR_CASTLE_GROUNDS_SOUTH_EXIT) ||
|
||||
(gSaveContext.entranceIndex == ENTR_GREAT_FAIRYS_FOUNTAIN_SPELLS_FARORES_ZF))) {
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WHITE_OUT, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WHITE_OUT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else if ((temp == 0.0f) && (play->sceneNum == SCENE_INSIDE_GANONS_CASTLE)) {
|
||||
func_800788CC(NA_SE_EV_WHITE_OUT);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_WHITE_OUT);
|
||||
}
|
||||
} else {
|
||||
play->envCtx.screenFillColor[3] = (1.0f - temp) * 255.0f;
|
||||
@ -2052,7 +2052,7 @@ void func_80068C3C(PlayState* play, CutsceneContext* csCtx) {
|
||||
|
||||
csCtx->frames++;
|
||||
if (dREG(95) != 0) {
|
||||
Cutscene_ProcessCommands(play, csCtx, D_8012D1F0);
|
||||
Cutscene_ProcessCommands(play, csCtx, gDebugCutsceneScript);
|
||||
} else {
|
||||
Cutscene_ProcessCommands(play, csCtx, play->csCtx.segment);
|
||||
}
|
||||
|
@ -974,7 +974,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
|
||||
if ((*params <= ITEM00_RUPEE_RED) || (*params == ITEM00_RUPEE_ORANGE)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else if (getItemId != GI_NONE) {
|
||||
if (Actor_HasParent(&this->actor, play)) {
|
||||
Flags_SetCollectible(play, this->collectibleFlag);
|
||||
@ -982,7 +982,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
Flags_SetCollectible(play, this->collectibleFlag);
|
||||
|
@ -84,7 +84,7 @@ void TransitionCircle_Start(void* thisx) {
|
||||
} else {
|
||||
this->texY = 0x1F4;
|
||||
if (this->appearanceType == TCA_RIPPLE) {
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_OUT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_OUT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
guPerspective(&this->projection, &this->normal, 60.0f, (4.0f / 3.0f), 10.0f, 12800.0f, 1.0f);
|
||||
@ -109,7 +109,7 @@ void TransitionCircle_Update(void* thisx, s32 updateRate) {
|
||||
if (this->direction != 0) {
|
||||
if (this->texY == 0) {
|
||||
if (this->appearanceType == TCA_RIPPLE) {
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_IN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_OC_SECRET_WARP_IN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
this->texY += this->speed * 3 / updateRate;
|
||||
|
@ -914,10 +914,10 @@ void Environment_Update(PlayState* play, EnvironmentContext* envCtx, LightContex
|
||||
osSyncPrintf("\nnext_zelda_time=[%x]", ((void)0, gSaveContext.nextDayTime));
|
||||
|
||||
if (((void)0, gSaveContext.nextDayTime) == 0xFF0E) {
|
||||
func_80078884(NA_SE_EV_CHICKEN_CRY_M);
|
||||
Sfx_PlaySfxCentered(NA_SE_EV_CHICKEN_CRY_M);
|
||||
gSaveContext.nextDayTime = 0xFFFF;
|
||||
} else if (((void)0, gSaveContext.nextDayTime) == 0xFF0D) {
|
||||
func_800788CC(NA_SE_EV_DOG_CRY_EVENING);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_DOG_CRY_EVENING);
|
||||
gSaveContext.nextDayTime = 0xFFFF;
|
||||
}
|
||||
}
|
||||
@ -2076,7 +2076,7 @@ void func_80075B44(PlayState* play) {
|
||||
break;
|
||||
case 2:
|
||||
if (gSaveContext.dayTime > 0xC000) {
|
||||
func_800788CC(NA_SE_EV_DOG_CRY_EVENING);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_DOG_CRY_EVENING);
|
||||
play->envCtx.unk_E0++;
|
||||
}
|
||||
break;
|
||||
@ -2105,7 +2105,7 @@ void func_80075B44(PlayState* play) {
|
||||
gSaveContext.totalDays++;
|
||||
gSaveContext.bgsDayCount++;
|
||||
gSaveContext.dogIsLost = true;
|
||||
func_80078884(NA_SE_EV_CHICKEN_CRY_M);
|
||||
Sfx_PlaySfxCentered(NA_SE_EV_CHICKEN_CRY_M);
|
||||
if ((Inventory_ReplaceItem(play, ITEM_WEIRD_EGG, ITEM_CHICKEN) ||
|
||||
Inventory_HatchPocketCucco(play)) &&
|
||||
play->csCtx.state == 0 && !Player_InCsMode(play)) {
|
||||
|
@ -572,14 +572,17 @@ void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src) {
|
||||
dst->a = src->a;
|
||||
}
|
||||
|
||||
void func_80078884(u16 sfxId) {
|
||||
Audio_PlaySoundGeneral(sfxId, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
void Sfx_PlaySfxCentered(u16 sfxId) {
|
||||
Audio_PlaySoundGeneral(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_800788CC(u16 sfxId) {
|
||||
Audio_PlaySoundGeneral(sfxId, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
void Sfx_PlaySfxCentered2(u16 sfxId) {
|
||||
Audio_PlaySoundGeneral(sfxId, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
void func_80078914(Vec3f* arg0, u16 sfxId) {
|
||||
Audio_PlaySoundGeneral(sfxId, arg0, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
void Sfx_PlaySfxAtPos(Vec3f* arg0, u16 sfxId) {
|
||||
Audio_PlaySoundGeneral(sfxId, arg0, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
|
@ -648,7 +648,7 @@ void HealthMeter_HandleCriticalAlarm(PlayState* play) {
|
||||
interfaceCtx->unk_22C = 0;
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("LowHpAlarm"), 0) == 0 && !Player_InCsMode(play) && (play->pauseCtx.state == 0) &&
|
||||
(play->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Play_InCsMode(play)) {
|
||||
func_80078884(NA_SE_SY_HITPOINT_ALARM);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_HITPOINT_ALARM);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -106,5 +106,5 @@ void ZeldaArena_Cleanup() {
|
||||
}
|
||||
|
||||
u8 ZeldaArena_IsInitalized() {
|
||||
return __osMallocIsInitalized(&sZeldaArena);
|
||||
return __osMallocIsInitialized(&sZeldaArena);
|
||||
}
|
||||
|
@ -810,10 +810,10 @@ void Minimap_Draw(PlayState* play) {
|
||||
if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) && enableMapToggle) {
|
||||
osSyncPrintf("Game_play_demo_mode_check=%d\n", Play_InCsMode(play));
|
||||
// clang-format off
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8); }
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
R_MINIMAP_DISABLED ^= 1;
|
||||
}
|
||||
@ -965,10 +965,10 @@ void Minimap_Draw(PlayState* play) {
|
||||
|
||||
if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_L) && !Play_InCsMode(play) && enableMapToggle) {
|
||||
// clang-format off
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8); }
|
||||
if (!R_MINIMAP_DISABLED) { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_UP, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
else { Audio_PlaySoundGeneral(NA_SE_SY_CAMERA_ZOOM_DOWN, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
R_MINIMAP_DISABLED ^= 1;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ u8 Message_ShouldAdvance(PlayState* play) {
|
||||
: CHECK_BTN_ALL(input->press.button, BTN_B);
|
||||
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_A) || isB_Held || CHECK_BTN_ALL(input->press.button, BTN_CUP)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
return CHECK_BTN_ALL(input->press.button, BTN_A) || isB_Held || CHECK_BTN_ALL(input->press.button, BTN_CUP);
|
||||
}
|
||||
@ -179,7 +179,7 @@ void Message_CloseTextbox(PlayState* play) {
|
||||
msgCtx->stateTimer = 2;
|
||||
msgCtx->msgMode = MSGMODE_TEXT_CLOSING;
|
||||
msgCtx->textboxEndType = TEXTBOX_ENDTYPE_DEFAULT;
|
||||
Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ void Message_HandleChoiceSelection(PlayState* play, u8 numChoices) {
|
||||
if (msgCtx->choiceIndex > 128) {
|
||||
msgCtx->choiceIndex = 0;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else if ((input->rel.stick_y <= -30 && !sAnalogStickHeld) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DDOWN))) {
|
||||
sAnalogStickHeld = true;
|
||||
@ -203,7 +203,7 @@ void Message_HandleChoiceSelection(PlayState* play, u8 numChoices) {
|
||||
if (msgCtx->choiceIndex > numChoices) {
|
||||
msgCtx->choiceIndex = numChoices;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else if (ABS(input->rel.stick_y) < 30) {
|
||||
sAnalogStickHeld = false;
|
||||
@ -724,7 +724,7 @@ u16 Message_DrawItemIcon(PlayState* play, u16 itemId, Gfx** p, u16 i) {
|
||||
MessageContext* msgCtx = &play->msgCtx;
|
||||
|
||||
// clang-format off
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); }
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
@ -882,7 +882,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
case MESSAGE_BOX_BREAK:
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) {
|
||||
if (!sTextboxSkipped) {
|
||||
Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
msgCtx->msgMode = MSGMODE_TEXT_AWAIT_NEXT;
|
||||
Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_TRIANGLE);
|
||||
} else {
|
||||
@ -899,7 +899,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
case MESSAGE_TEXTID:
|
||||
msgCtx->textboxEndType = TEXTBOX_ENDTYPE_HAS_NEXT;
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) {
|
||||
Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
msgCtx->msgMode = MSGMODE_TEXT_DONE;
|
||||
Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_TRIANGLE);
|
||||
}
|
||||
@ -970,8 +970,8 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
// "Sound (SE)"
|
||||
osSyncPrintf("サウンド(SE)\n");
|
||||
sfxHi = msgCtx->msgBufDecoded[i + 1] << 8;
|
||||
Audio_PlaySoundGeneral(sfxHi | msgCtx->msgBufDecoded[i + 2], &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxHi | msgCtx->msgBufDecoded[i + 2], &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
i += 2;
|
||||
break;
|
||||
@ -980,7 +980,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
break;
|
||||
case MESSAGE_BACKGROUND:
|
||||
// clang-format off
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); }
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) { Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
|
||||
@ -1062,8 +1062,8 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) {
|
||||
msgCtx->msgMode = MSGMODE_TEXT_DONE;
|
||||
if (msgCtx->textboxEndType == TEXTBOX_ENDTYPE_DEFAULT) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_SQUARE);
|
||||
if (play->csCtx.state == 0) {
|
||||
Interface_SetDoAction(play, DO_ACTION_RETURN);
|
||||
@ -1094,7 +1094,7 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
return;
|
||||
case MESSAGE_PERSISTENT:
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING) {
|
||||
Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
msgCtx->msgMode = MSGMODE_TEXT_DONE;
|
||||
msgCtx->textboxEndType = TEXTBOX_ENDTYPE_PERSISTENT;
|
||||
}
|
||||
@ -1105,14 +1105,14 @@ void Message_DrawText(PlayState* play, Gfx** gfxP) {
|
||||
msgCtx->msgMode = MSGMODE_TEXT_DONE;
|
||||
msgCtx->textboxEndType = TEXTBOX_ENDTYPE_EVENT;
|
||||
Font_LoadMessageBoxIcon(font, TEXTBOX_ICON_TRIANGLE);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_END, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
*gfxP = gfx;
|
||||
return;
|
||||
default:
|
||||
if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING && i + 1 == msgCtx->textDrawPos &&
|
||||
msgCtx->textDelayTimer == msgCtx->textDelay) {
|
||||
Audio_PlaySoundGeneral(0, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
Message_DrawTextChar(play, &font->charTexBuf[charTexIdx], &gfx);
|
||||
charTexIdx += FONT_CHAR_TEX_SIZE;
|
||||
@ -1817,7 +1817,7 @@ void Message_StartOcarina(PlayState* play, u16 ocarinaActionId) {
|
||||
osSyncPrintf("ocarina_set 000000000000000000 = %d\n", ocarinaActionId);
|
||||
msgCtx->ocarinaAction = ocarinaActionId;
|
||||
if (ocarinaActionId >= OCARINA_ACTION_CHECK_SARIA && ocarinaActionId <= OCARINA_ACTION_CHECK_STORMS) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
if (ocarinaActionId == OCARINA_ACTION_SCARECROW_PLAYBACK) {
|
||||
Message_OpenText(play, 0x86F); // Ocarina
|
||||
@ -2264,8 +2264,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
if (msgCtx->ocarinaStaff->state < OCARINA_SONG_SARIAS ||
|
||||
msgCtx->ocarinaStaff->state == OCARINA_SONG_SCARECROW) {
|
||||
Audio_OcaSetInstrument(0);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->msgMode = MSGMODE_OCARINA_STARTING;
|
||||
} else {
|
||||
// "Ocarina_Flog Correct Example Performance"
|
||||
@ -2274,15 +2274,15 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
msgCtx->msgMode = MSGMODE_SONG_PLAYED;
|
||||
msgCtx->textBoxType = TEXTBOX_TYPE_OCARINA;
|
||||
msgCtx->stateTimer = 10;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Interface_ChangeAlpha(1);
|
||||
}
|
||||
} else if (msgCtx->ocarinaAction == OCARINA_ACTION_CHECK_SCARECROW) {
|
||||
if (msgCtx->ocarinaStaff->state < OCARINA_SONG_SCARECROW) {
|
||||
Audio_OcaSetInstrument(0);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->stateTimer = 10;
|
||||
msgCtx->msgMode = MSGMODE_OCARINA_FAIL;
|
||||
} else {
|
||||
@ -2292,8 +2292,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
msgCtx->msgMode = MSGMODE_SONG_PLAYED;
|
||||
msgCtx->textBoxType = TEXTBOX_TYPE_OCARINA;
|
||||
msgCtx->stateTimer = 10;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Interface_ChangeAlpha(1);
|
||||
}
|
||||
} else if (msgCtx->ocarinaAction == OCARINA_ACTION_FREE_PLAY) {
|
||||
@ -2303,23 +2303,23 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
msgCtx->msgMode = MSGMODE_SONG_PLAYED;
|
||||
msgCtx->textBoxType = TEXTBOX_TYPE_OCARINA;
|
||||
msgCtx->stateTimer = 10;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
Interface_ChangeAlpha(1);
|
||||
} else {
|
||||
Audio_OcaSetInstrument(0);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->msgMode = MSGMODE_OCARINA_STARTING;
|
||||
}
|
||||
} else if (msgCtx->ocarinaStaff->state == 0xFF) {
|
||||
Audio_OcaSetInstrument(0);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->stateTimer = 10;
|
||||
msgCtx->msgMode = MSGMODE_OCARINA_FAIL;
|
||||
} else if (isB_Held) {
|
||||
@ -2646,11 +2646,11 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
osSyncPrintf("z_message.c 取得メロディ=%d\n", ITEM_SONG_MINUET + msgCtx->ocarinaStaff->state);
|
||||
osSyncPrintf(VT_RST);
|
||||
msgCtx->stateTimer = 20;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else if (msgCtx->ocarinaStaff->state == 0xFF) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->stateTimer = 10;
|
||||
msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_FAIL;
|
||||
}
|
||||
@ -2701,8 +2701,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
msgCtx->ocarinaStaff->state);
|
||||
gSaveContext.scarecrowLongSongSet = true;
|
||||
}
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
osSyncPrintf("aaaaaaaaaaaaaa\n");
|
||||
Audio_OcaSetRecordingState(0);
|
||||
msgCtx->stateTimer = 10;
|
||||
@ -2771,8 +2771,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
msgCtx->stateTimer = 20;
|
||||
gSaveContext.scarecrowSpawnSongSet = true;
|
||||
msgCtx->msgMode = MSGMODE_SCARECROW_RECORDING_DONE;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
osSyncPrintf(VT_FGCOL(YELLOW));
|
||||
osSyncPrintf("\n====================================================================\n");
|
||||
memcpy(gSaveContext.scarecrowSpawnSong, gScarecrowSpawnSongPtr,
|
||||
@ -2786,8 +2786,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
// "Played an existing song!!!"
|
||||
osSyncPrintf("すでに存在する曲吹いた!!! \n");
|
||||
Audio_OcaSetRecordingState(0);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
Message_CloseTextbox(play);
|
||||
msgCtx->msgMode = MSGMODE_SCARECROW_RECORDING_FAILED;
|
||||
}
|
||||
@ -2812,8 +2812,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
break;
|
||||
case MSGMODE_MEMORY_GAME_LEFT_SKULLKID_PLAYING:
|
||||
case MSGMODE_MEMORY_GAME_RIGHT_SKULLKID_PLAYING:
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->ocarinaStaff = Audio_OcaGetDisplayingStaff();
|
||||
if (msgCtx->ocarinaStaff->pos && sOcarinaNoteBufPos == msgCtx->ocarinaStaff->pos - 1) {
|
||||
sOcarinaNoteBuf[msgCtx->ocarinaStaff->pos - 1] = msgCtx->ocarinaStaff->noteIdx;
|
||||
@ -2823,11 +2823,11 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
if (msgCtx->stateTimer == 0) {
|
||||
if (msgCtx->ocarinaStaff->state == 0) {
|
||||
if (msgCtx->msgMode == MSGMODE_MEMORY_GAME_LEFT_SKULLKID_PLAYING) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_2, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_2, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
msgCtx->msgMode++;
|
||||
}
|
||||
@ -2845,8 +2845,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
}
|
||||
break;
|
||||
case MSGMODE_MEMORY_GAME_PLAYER_PLAYING:
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME_LV - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->ocarinaStaff = Audio_OcaGetPlayingStaff();
|
||||
if (msgCtx->ocarinaStaff->pos && sOcarinaNoteBufPos == msgCtx->ocarinaStaff->pos - 1) {
|
||||
sOcarinaNoteBuf[msgCtx->ocarinaStaff->pos - 1] = msgCtx->ocarinaStaff->noteIdx;
|
||||
@ -2857,14 +2857,14 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
// "Musical round failed!!!!!!!!!"
|
||||
osSyncPrintf("輪唱失敗!!!!!!!!!\n");
|
||||
Audio_OcaSetInstrument(0);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_OCARINA_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->stateTimer = 10;
|
||||
play->msgCtx.ocarinaMode = OCARINA_MODE_03;
|
||||
} else if (msgCtx->ocarinaStaff->state == 0xD) {
|
||||
// "Musical round succeeded!!!!!!!!!"
|
||||
osSyncPrintf("輪唱成功!!!!!!!!!\n");
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GET_ITEM, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
msgCtx->msgMode = MSGMODE_MEMORY_GAME_ROUND_SUCCESS;
|
||||
msgCtx->stateTimer = 30;
|
||||
}
|
||||
@ -2880,8 +2880,8 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
|
||||
msgCtx->stateTimer--;
|
||||
if (msgCtx->stateTimer == 0) {
|
||||
if (Audio_OcaMemoryGameGenNote() != 1) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_METRONOME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
msgCtx->ocarinaStaff = Audio_OcaGetPlayingStaff();
|
||||
msgCtx->ocarinaStaff->pos = sOcarinaNoteBufPos = 0;
|
||||
Message_ResetOcarinaNoteState();
|
||||
@ -3342,11 +3342,11 @@ void Message_Update(PlayState* play) {
|
||||
} else if (Message_ShouldAdvanceSilent(play)) {
|
||||
osSyncPrintf("select=%d\n", msgCtx->textboxEndType);
|
||||
if (msgCtx->textboxEndType == TEXTBOX_ENDTYPE_HAS_NEXT) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_PASS, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
Message_ContinueTextbox(play, sNextTextId);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Message_CloseTextbox(play);
|
||||
}
|
||||
}
|
||||
|
@ -471,7 +471,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
|
||||
Play_CameraChangeSetting(play, camIdx, CAM_SET_CS_3);
|
||||
Player_SetCsActionWithHaltedActors(play, &player->actor, 5);
|
||||
OnePointCutscene_SetCsCamPoints(csCam, D_80120304 | 0x2000, D_80120300, D_8012013C, D_8012021C);
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
OnePointCutscene_Vec3sToVec3f(&mainCam->at, &D_8012013C[D_801202FC - 2].pos);
|
||||
OnePointCutscene_Vec3sToVec3f(&mainCam->eye, &D_8012021C[D_801202FC - 2].pos);
|
||||
D_8012013C[D_801202FC - 3].pos.x +=
|
||||
|
@ -1607,10 +1607,8 @@ void Inventory_SwapAgeEquipment(void) {
|
||||
s16 i;
|
||||
u16 shieldEquipValue;
|
||||
|
||||
// Mod Enhancments can utilise the rando flow path
|
||||
if (IS_RANDO || CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) || CVarGetInteger(CVAR_GENERAL("SwitchTimeline"), 0)) {
|
||||
if (IS_RANDO) {
|
||||
Rando_Inventory_SwapAgeEquipment();
|
||||
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2829,12 +2827,12 @@ void Interface_SetNaviCall(PlayState* play, u16 naviCallState) {
|
||||
(play->csCtx.state == CS_STATE_IDLE)) {
|
||||
if (!CVarGetInteger(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 0)) {
|
||||
// clang-format off
|
||||
if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8); }
|
||||
if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }
|
||||
// clang-format on
|
||||
|
||||
if (naviCallState == 0x1D) {
|
||||
func_800F4524(&D_801333D4, NA_SE_VO_NA_HELLO_2, 32);
|
||||
func_800F4524(&gSfxDefaultPos, NA_SE_VO_NA_HELLO_2, 32);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2898,8 +2896,8 @@ s32 Health_ChangeBy(PlayState* play, s16 healthChange) {
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
if (healthChange > 0) { Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8);
|
||||
if (healthChange > 0) { Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else if ((gSaveContext.isDoubleDefenseAcquired != 0) && (healthChange < 0)) {
|
||||
healthChange >>= 1;
|
||||
osSyncPrintf("ハート減少半分!!=%d\n", healthChange); // "Heart decrease halved!!=%d"
|
||||
@ -3079,7 +3077,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) {
|
||||
|
||||
if ((type != 5) && (gSaveContext.magic - amount) < 0) {
|
||||
if (gSaveContext.magicCapacity != 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -3095,7 +3093,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) {
|
||||
gSaveContext.magicState = MAGIC_STATE_CONSUME_SETUP;
|
||||
return 1;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
return false;
|
||||
}
|
||||
case MAGIC_CONSUME_WAIT_NO_PREVIEW:
|
||||
@ -3107,7 +3105,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) {
|
||||
gSaveContext.magicState = MAGIC_STATE_METER_FLASH_3;
|
||||
return true;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
return false;
|
||||
}
|
||||
case MAGIC_CONSUME_LENS:
|
||||
@ -3135,7 +3133,7 @@ s32 Magic_RequestChange(PlayState* play, s16 amount, s16 type) {
|
||||
gSaveContext.magicState = MAGIC_STATE_METER_FLASH_2;
|
||||
return true;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
return false;
|
||||
}
|
||||
case MAGIC_ADD:
|
||||
@ -3219,8 +3217,8 @@ void Interface_UpdateMagicBar(PlayState* play) {
|
||||
gSaveContext.magic += 4;
|
||||
|
||||
if (gSaveContext.gameMode == 0 && gSaveContext.sceneSetupIndex < 4) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
// "Storage MAGIC_NOW=%d (%d)"
|
||||
@ -3321,8 +3319,8 @@ void Interface_UpdateMagicBar(PlayState* play) {
|
||||
!hasLens ||
|
||||
!play->actorCtx.lensActive) {
|
||||
play->actorCtx.lensActive = false;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GLASSMODE_OFF, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GLASSMODE_OFF, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
gSaveContext.magicState = MAGIC_STATE_IDLE;
|
||||
if (CVarGetInteger(CVAR_COSMETIC("Consumable.MagicBorder.Changed"), 0)) {
|
||||
sMagicBorder = CVarGetColor24(CVAR_COSMETIC("Consumable.MagicBorder.Value"), sMagicBorder_ori);
|
||||
@ -3377,7 +3375,7 @@ void Interface_UpdateMagicBar(PlayState* play) {
|
||||
|
||||
case MAGIC_STATE_ADD:
|
||||
gSaveContext.magic += 4;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_GAUGE_UP - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
if (gSaveContext.magic >= gSaveContext.magicTarget) {
|
||||
gSaveContext.magic = gSaveContext.magicTarget;
|
||||
gSaveContext.magicState = gSaveContext.prevMagicState;
|
||||
@ -5798,17 +5796,17 @@ void Interface_Draw(PlayState* play) {
|
||||
D_80125A5C = 0;
|
||||
} else if (gSaveContext.timer1Value > 60) {
|
||||
if (timerDigits[4] == 1) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else if (gSaveContext.timer1Value >= 11) {
|
||||
if (timerDigits[4] & 1) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5855,8 +5853,8 @@ void Interface_Draw(PlayState* play) {
|
||||
D_8015FFE2 = 40;
|
||||
gSaveContext.timer1State = 15;
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5973,17 +5971,17 @@ void Interface_Draw(PlayState* play) {
|
||||
}
|
||||
} else if (gSaveContext.timer2Value > 60) {
|
||||
if (timerDigits[4] == 1) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_MESSAGE_WOMAN, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else if (gSaveContext.timer2Value > 10) {
|
||||
if ((timerDigits[4] & 1)) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &D_801333D4, 4,
|
||||
&D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_E, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else {
|
||||
gSaveContext.timer2Value++;
|
||||
@ -5997,8 +5995,8 @@ void Interface_Draw(PlayState* play) {
|
||||
}
|
||||
|
||||
if ((gSaveContext.timer2Value % 60) == 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &D_801333D4, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_WARNING_COUNT_N, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6363,7 +6361,7 @@ void Interface_Update(PlayState* play) {
|
||||
gSaveContext.health += 4;
|
||||
|
||||
if ((gSaveContext.health & 0xF) < 4) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_HP_RECOVER, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
osSyncPrintf("now_life=%d max_life=%d\n", gSaveContext.health, gSaveContext.healthCapacity);
|
||||
@ -6400,7 +6398,7 @@ void Interface_Update(PlayState* play) {
|
||||
if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) {
|
||||
gSaveContext.rupeeAccumulator--;
|
||||
gSaveContext.rupees++;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
// "Rupee Amount MAX = %d"
|
||||
osSyncPrintf("ルピー数MAX = %d\n", CUR_CAPACITY(UPG_WALLET));
|
||||
@ -6416,11 +6414,11 @@ void Interface_Update(PlayState* play) {
|
||||
gSaveContext.rupees = 0;
|
||||
}
|
||||
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
gSaveContext.rupeeAccumulator++;
|
||||
gSaveContext.rupees--;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else {
|
||||
gSaveContext.rupeeAccumulator = 0;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,5 +58,5 @@ void SoundSource_PlaySfxAtFixedWorldPos(PlayState* play, Vec3f* worldPos, s32 du
|
||||
source->countdown = duration;
|
||||
|
||||
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &source->worldPos, &source->projectedPos);
|
||||
Audio_PlaySoundGeneral(sfxId, &source->projectedPos, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(sfxId, &source->projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
145
soh/src/code/z_viscvg.c
Normal file
145
soh/src/code/z_viscvg.c
Normal file
@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @file z_viscvg.c
|
||||
*
|
||||
* This file implements full-screen frame buffer effects involving the visualization of Coverage in various ways.
|
||||
*
|
||||
* Coverage is roughly how much of a pixel is covered by a primitive; the final coverage for a frame is stored in the
|
||||
* color image alpha component where it is used for antialiasing, see PreRender.c and §15 of the programming manual for
|
||||
* details.
|
||||
*
|
||||
* To understand this file, it is helpful to remember that A_MEM is essentially synonymous with coverage, and that
|
||||
* `GBL_c1/2(p, a, m, b)` usually represents the RDP blender calculation `(p * a + m * b)`.
|
||||
* Note the division step that is often included in the blender calculation is omitted; the division is skipped if
|
||||
* force blending (FORCE_BL) is set, which is the case for all render modes used in this file.
|
||||
*
|
||||
* Coverage is full when not on an edge, while on an edge it is usually lower. Since coverage is treated as an alpha
|
||||
* value, edges of primitives where coverage is lower will show up darker than primitive interiors in all of the
|
||||
* available modes.
|
||||
*
|
||||
* Coverage is abbreviated to "cvg"; "FB RGB" ("framebuffer red/green/blue") is the color the pixel originally had
|
||||
* before the filter is applied.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
/**
|
||||
* Draws only coverage: does not retain any of the original pixel RGB, primColor is used as background color.
|
||||
*/
|
||||
Gfx sCoverageOnlyDL[] = {
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | G_RM_VISCVG | G_RM_VISCVG2),
|
||||
// (blendColor RGB) * (cvg)
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsDPPipeSync(),
|
||||
gsDPSetBlendColor(0, 0, 0, 8),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Draws fog + coverage * RGB of pixels
|
||||
*
|
||||
* @bug This easily overflows the blender because the fog value is added to the coverage value.
|
||||
*/
|
||||
Gfx sCoverageRGBFogDL[] = {
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
||||
GBL_c1(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||
GBL_c2(G_BL_CLR_FOG, G_BL_A_FOG, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||
// (fog RGB) * (fog alpha) + (FB RGB) * (cvg)
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Draws coverage and RGB of pixels
|
||||
*/
|
||||
Gfx sCoverageRGBDL[] = {
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
||||
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||
// (FB RGB) * (cvg)
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Two stage filtering:
|
||||
*
|
||||
* 1. Apply a uniform color filter by transparently blending primColor with original frame. The "cloud surface"
|
||||
* RenderMode is used to preserve the coverage for the second stage.
|
||||
* 2. Second half is the same as `sCoverageRGBDL`'s, i.e. (RGB from stage 1) * cvg
|
||||
*/
|
||||
Gfx sCoverageRGBUniformDL[] = {
|
||||
gsDPSetCombineMode(G_CC_PRIMITIVE, G_CC_PRIMITIVE),
|
||||
gsDPSetOtherMode(G_AD_NOTPATTERN | G_CD_DISABLE | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2),
|
||||
// stage 1 color = (primColor RGB) * (primColor Alpha) + (FB RGB) * (1 - primColor Alpha)
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
|
||||
gsDPSetOtherMode(G_AD_PATTERN | G_CD_MAGICSQ | G_CK_NONE | G_TC_CONV | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | IM_RD | CVG_DST_CLAMP | ZMODE_OPA | FORCE_BL |
|
||||
GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM) |
|
||||
GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_A_MEM)),
|
||||
// final color = (stage 1 RGB) * (cvg)
|
||||
gsDPFillRectangle(0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1),
|
||||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
void VisCvg_Init(VisCvg* this) {
|
||||
this->vis.type = FB_FILTER_NONE;
|
||||
this->vis.scissorType = VIS_NO_SETSCISSOR;
|
||||
this->vis.primColor.r = 255;
|
||||
this->vis.primColor.g = 255;
|
||||
this->vis.primColor.b = 255;
|
||||
this->vis.primColor.a = 255;
|
||||
}
|
||||
|
||||
void VisCvg_Destroy(VisCvg* this) {
|
||||
}
|
||||
|
||||
void VisCvg_Draw(VisCvg* this, Gfx** gfxP) {
|
||||
Gfx* gfx = *gfxP;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
gDPSetPrimDepth(gfx++, 0xFFFF, 0xFFFF);
|
||||
|
||||
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
switch (this->vis.type) {
|
||||
case FB_FILTER_CVG_RGB:
|
||||
gSPDisplayList(gfx++, sCoverageRGBDL);
|
||||
break;
|
||||
|
||||
case FB_FILTER_CVG_RGB_UNIFORM:
|
||||
// Set primitive color for uniform color filter in custom RenderMode
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
|
||||
gSPDisplayList(gfx++, sCoverageRGBUniformDL);
|
||||
break;
|
||||
|
||||
case FB_FILTER_CVG_ONLY:
|
||||
// Set background color for G_RM_VISCVG
|
||||
gDPSetColor(gfx++, G_SETBLENDCOLOR, this->vis.primColor.rgba);
|
||||
gSPDisplayList(gfx++, sCoverageOnlyDL);
|
||||
break;
|
||||
|
||||
case FB_FILTER_CVG_RGB_FOG:
|
||||
// Set fog color for custom RenderMode, needs to be close to 0 to not overflow
|
||||
gDPSetColor(gfx++, G_SETFOGCOLOR, this->vis.primColor.rgba);
|
||||
gSPDisplayList(gfx++, sCoverageRGBFogDL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
*gfxP = gfx;
|
||||
}
|
@ -1,137 +1,218 @@
|
||||
/**
|
||||
* @file z_vismono.c
|
||||
*
|
||||
* This file implements a full-screen framebuffer effect for desaturating the contents of the framebuffer image.
|
||||
*
|
||||
* Broadly, this effect is achieved by reinterpreting the contents of the RGBA16 color image as indices into an IA16
|
||||
* color palette that converts each color into the desaturated equivalent. More precise details can be found in inline
|
||||
* comments.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
#include <string.h>
|
||||
|
||||
#include <string.h> // memset
|
||||
#include <assert.h>
|
||||
#include "soh/framebuffer_effects.h"
|
||||
|
||||
// (Note: 80 = SCREEN_HEIGHT/3, see VisMono_DrawTexture)
|
||||
// This may not have been kept up-to-date with the code, 1+1+1+80*(7+2+2+3)+1+1 makes more sense
|
||||
#define DLSIZE (1 + 3 + 1 + 1 + 80 * (7 + 2 + 2 + 3) + 1)
|
||||
// Upstream TODO: Replace these ones they are served from other headers
|
||||
#define ASSERT(cond, msg, file, line) assert(cond)
|
||||
#define GPACK_IA16(i, a) (((i) << 8) | (a))
|
||||
|
||||
// framebuffer
|
||||
// Height of the fragments the color frame buffer (CFB) is split into.
|
||||
// It is the maximum amount of lines such that all rgba16 SCREEN_WIDTH-long lines fit into
|
||||
// the half of TMEM dedicated to color-indexed data.
|
||||
#define VISMONO_CFBFRAG_HEIGHT ((TMEM_SIZE / 2) / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES))
|
||||
|
||||
// Maximum size of the dlist written by `VisMono_DesaturateDList`.
|
||||
// `VisMono_DesaturateDList` consistently uses `VISMONO_DLSIZE - 2` double words, so this can be 2 less.
|
||||
#define VISMONO_DLSIZE (3 + SCREEN_HEIGHT / VISMONO_CFBFRAG_HEIGHT * (7 + 2 + 2 + 3) + 2 + 2)
|
||||
|
||||
// How much each color component contributes to the desaturated result.
|
||||
// These coefficients are close to what the YUV color space defines Y (luminance) as:
|
||||
// https://en.wikipedia.org/wiki/YUV#Conversion_to/from_RGB
|
||||
#define VISMONO_FAC_RED 2
|
||||
#define VISMONO_FAC_GREEN 4
|
||||
#define VISMONO_FAC_BLUE 1
|
||||
#define VISMONO_FAC_NORM (0x1F * VISMONO_FAC_RED + 0x1F * VISMONO_FAC_GREEN + 0x1F * VISMONO_FAC_BLUE)
|
||||
|
||||
// color framebuffer
|
||||
extern u16 D_0F000000[];
|
||||
|
||||
void VisMono_Init(VisMono* this) {
|
||||
memset(this, 0, sizeof(VisMono));
|
||||
this->unk_00 = 0;
|
||||
this->setScissor = false;
|
||||
this->primColor.r = 255;
|
||||
this->primColor.g = 255;
|
||||
this->primColor.b = 255;
|
||||
this->primColor.a = 255;
|
||||
this->envColor.r = 0;
|
||||
this->envColor.g = 0;
|
||||
this->envColor.b = 0;
|
||||
this->envColor.a = 0;
|
||||
this->vis.type = 0;
|
||||
this->vis.scissorType = VIS_NO_SETSCISSOR;
|
||||
this->vis.primColor.r = 255;
|
||||
this->vis.primColor.g = 255;
|
||||
this->vis.primColor.b = 255;
|
||||
this->vis.primColor.a = 255;
|
||||
this->vis.envColor.r = 0;
|
||||
this->vis.envColor.g = 0;
|
||||
this->vis.envColor.b = 0;
|
||||
this->vis.envColor.a = 0;
|
||||
}
|
||||
|
||||
void VisMono_Destroy(VisMono* this) {
|
||||
SYSTEM_ARENA_FREE_DEBUG(this->monoDl);
|
||||
SYSTEM_ARENA_FREE(this->dList, "../z_vismono.c", 137);
|
||||
}
|
||||
|
||||
void VisMono_UpdateTexture(VisMono* this, u16* tex) {
|
||||
void VisMono_DesaturateTLUT(VisMono* this, u16* tlut) {
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
tex[i] = ((((i >> 3 & 0x1F) * 2 + (i << 2 & 0x1F) * 4) * 0xFF / 0xD9) << 8) |
|
||||
(((i >> 6 & 0x1F) * 4 + (i >> 1 & 0x1F)) * 0xFF / 0xD9);
|
||||
// `tlut[i]` is a IA16 color
|
||||
// `i` corresponds to either byte of a RGBA16 color RRRR_RGGG GGBB_BBBA from the color frame buffer
|
||||
|
||||
// The high byte I (intensity) corresponds to `i` being interpreted as the high byte RRRR_RGGG
|
||||
// I = (RRRRR * FAC_RED + GGG00 * FAC_GREEN) * (255 / FAC_NORM)
|
||||
|
||||
// The low byte A (alpha) corresponds to `i` being interpreted as the low byte GGBB_BBBA
|
||||
// A = (000GG * FAC_GREEN + BBBBB * FAC_BLUE) * (255 / FAC_NORM)
|
||||
|
||||
// Note: I + A = (RRRRR * FAC_RED + GGGGG * FAC_GREEN + BBBBB * FAC_BLUE) * (255 / FAC_NORM)
|
||||
|
||||
tlut[i] = GPACK_IA16(
|
||||
((i >> 3 & 0x1F) * VISMONO_FAC_RED + (i << 2 & 0x1F) * VISMONO_FAC_GREEN) * 255 / VISMONO_FAC_NORM,
|
||||
((i >> 6 & 0x1F) * VISMONO_FAC_GREEN + (i >> 1 & 0x1F) * VISMONO_FAC_BLUE) * 255 / VISMONO_FAC_NORM);
|
||||
}
|
||||
}
|
||||
|
||||
Gfx* VisMono_DrawTexture(VisMono* this, Gfx* gfx)
|
||||
{
|
||||
// OTRTODO
|
||||
#if 1
|
||||
Gfx* VisMono_DesaturateDList(VisMono* this, Gfx* gfx) {
|
||||
s32 y;
|
||||
s32 height = 3;
|
||||
//u16* tex = D_0F000000;
|
||||
u16* tex = SEG_ADDR(0xF, 0);
|
||||
s32 height = VISMONO_CFBFRAG_HEIGHT;
|
||||
u16* cfbFrag = D_0F000000;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
// `G_TT_IA16`: use color-indexed images, and IA16 palettes
|
||||
gDPSetOtherMode(gfx++,
|
||||
G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_IA16 | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_2CYCLE | G_PM_1PRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_IN, G_BL_1) | G_RM_CLD_SURF2);
|
||||
G_AC_NONE | G_ZS_PRIM | G_RM_PASS | G_RM_CLD_SURF2);
|
||||
// First color cycle sums texel 1 alpha and texel 0 color
|
||||
// By using IA16 palettes, this means summing A (from the IA16 color texel 1 maps to)
|
||||
// with I (from the IA16 color texel 0 maps to)
|
||||
gDPSetCombineLERP(gfx++, 1, 0, TEXEL1_ALPHA, TEXEL0, 0, 0, 0, 1, PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, 0,
|
||||
0, 0, PRIMITIVE);
|
||||
|
||||
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
|
||||
gDPLoadTextureBlock(gfx++, tex, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2, height, 0,
|
||||
// Load a few lines of the color frame buffer
|
||||
gDPLoadTextureBlock(gfx++, cfbFrag, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2, height, 0,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK,
|
||||
G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, 80, 0x0, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
|
||||
gDPSetTileSize(gfx++, G_TX_RENDERTILE, (2 << 2), 0, ((SCREEN_WIDTH * 2 + 1) << 2), (2 << 2));
|
||||
// Set texel 0 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT`
|
||||
// Its position in texture image space is shifted along +S by 2
|
||||
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2 * G_IM_SIZ_8b_LINE_BYTES / 8, 0x0, G_TX_RENDERTILE,
|
||||
0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
|
||||
gDPSetTileSize(gfx++, G_TX_RENDERTILE, 2 << 2, 0, (SCREEN_WIDTH * 2 + 1) << 2,
|
||||
(VISMONO_CFBFRAG_HEIGHT - 1) << 2);
|
||||
|
||||
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, 80, 0x0, 1, 1, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
|
||||
gDPSetTileSize(gfx++, 1, (1 << 2), 0, ((SCREEN_WIDTH * 2) << 2), (2 << 2));
|
||||
// Set texel 1 to be a CI8 image with width `SCREEN_WIDTH * 2` and height `VISMONO_CFBFRAG_HEIGHT`
|
||||
// Its position in texture image space is shifted along +S by 1
|
||||
// Note the palette index for this tile has also been incremented from 0 to 1, however the palette index is
|
||||
// ignored for CI8 texture sampling.
|
||||
gDPSetTile(gfx++, G_IM_FMT_CI, G_IM_SIZ_8b, SCREEN_WIDTH * 2 * G_IM_SIZ_8b_LINE_BYTES / 8, 0x0, 1, 1,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, 0, 0, G_TX_NOMIRROR | G_TX_CLAMP, 0, 0);
|
||||
gDPSetTileSize(gfx++, 1, 1 << 2, 0, (SCREEN_WIDTH * 2) << 2, (VISMONO_CFBFRAG_HEIGHT - 1) << 2);
|
||||
|
||||
gSPTextureRectangle(gfx++, 0, y << 2, (SCREEN_WIDTH << 2), (y + height) << 2, G_TX_RENDERTILE, 2 << 5, 0,
|
||||
2 << 10, 1 << 10);
|
||||
tex += SCREEN_WIDTH * height;
|
||||
// Draw a `SCREEN_WIDTH` wide, `height` high rectangle.
|
||||
// Texture coordinate T (vertical) starts at 0 and changes by one each line (dtdy = 1)
|
||||
// Texture coordinate S (horizontal) starts at 2 and changes by two each column (dsdx = 2)
|
||||
|
||||
// Because texel 0 is shifted by 2 and texel 1 only by 1 along +S,
|
||||
// a pixel at S coordinates s = 2+2*n will look at the 2*n-th byte of texel 0 and the 2*n+1-th byte of texel 1.
|
||||
// (in "s = 2+2*n" the first "2" is the starting S coordinate and the second "2" is the dsdx value)
|
||||
|
||||
// The 2*n-th byte of texel 0 is the high byte of the n-th RGBA16 color of the color frame buffer.
|
||||
// The 2*n+1-th byte of texel 1 is the low byte of the n-th RGBA16 color of the color frame buffer.
|
||||
|
||||
// With the TLUT computed by `VisMono_DesaturateTLUT`:
|
||||
// The 2*n-th byte of texel 0 maps to a IA16 color where the high byte I (intensity) corresponds to
|
||||
// the high byte of the n-th RGBA16 color of the color frame buffer.
|
||||
// The 2*n+1-th byte of texel 1 maps to a IA16 color where the low byte A (alpha) corresponds to
|
||||
// the low byte of the n-th RGBA16 color of the color frame buffer.
|
||||
|
||||
// Since the combiner is in part set up to sum texel 0 color (I, intensity) with texel 1 alpha (A, alpha),
|
||||
// the resulting color in the drawn rectangle is a desaturated color as defined by the `VISMONO_FAC_*` values.
|
||||
|
||||
gSPTextureRectangle(gfx++, 0, y << 2, SCREEN_WIDTH << 2, (y + height) << 2, G_TX_RENDERTILE, 2 << 5, 0, 2 << 10,
|
||||
1 << 10);
|
||||
cfbFrag += SCREEN_WIDTH * height;
|
||||
}
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
gSPEndDisplayList(gfx++);
|
||||
#endif
|
||||
return gfx;
|
||||
}
|
||||
|
||||
void VisMono_Draw(VisMono* this, Gfx** gfxp) {
|
||||
Gfx* gfx = *gfxp;
|
||||
void VisMono_Draw(VisMono* this, Gfx** gfxP) {
|
||||
Gfx* gfx = *gfxP;
|
||||
u16* tlut;
|
||||
Gfx* monoDL;
|
||||
Gfx* glistpEnd;
|
||||
Gfx* dList;
|
||||
Gfx* dListEnd;
|
||||
|
||||
// SOH [Port] Implement VisMono by performing a framebuffer copy and redraw with an active
|
||||
// grayscale command to set the mono color
|
||||
FB_CopyToFramebuffer(&gfx, 0, gReusableFrameBuffer, false, NULL);
|
||||
gDPSetGrayscaleColor(gfx++, this->vis.primColor.r, this->vis.primColor.g, this->vis.primColor.b,
|
||||
this->vis.primColor.a);
|
||||
gSPGrayscale(gfx++, true);
|
||||
FB_DrawFromFramebuffer(&gfx, gReusableFrameBuffer, 255);
|
||||
gSPGrayscale(gfx++, false);
|
||||
|
||||
#if 0
|
||||
if (this->tlut) {
|
||||
tlut = this->tlut;
|
||||
} else {
|
||||
tlut = Graph_DlistAlloc(&gfx, 256 * sizeof(u16));
|
||||
VisMono_UpdateTexture(this, tlut);
|
||||
tlut = Graph_DlistAlloc(&gfx, 256 * G_IM_SIZ_16b_BYTES);
|
||||
VisMono_DesaturateTLUT(this, tlut);
|
||||
}
|
||||
|
||||
if (this->monoDl) {
|
||||
monoDL = this->monoDl;
|
||||
if (this->dList) {
|
||||
dList = this->dList;
|
||||
} else {
|
||||
monoDL = Graph_DlistAlloc(&gfx, DLSIZE * sizeof(Gfx));
|
||||
glistpEnd = VisMono_DrawTexture(this, monoDL);
|
||||
dList = Graph_DlistAlloc(&gfx, VISMONO_DLSIZE * sizeof(Gfx));
|
||||
dListEnd = VisMono_DesaturateDList(this, dList);
|
||||
|
||||
if (!(glistpEnd <= monoDL + DLSIZE)) {
|
||||
LOG_ADDRESS("glistp_end", glistpEnd);
|
||||
LOG_ADDRESS("mono_dl", monoDL);
|
||||
LOG_ADDRESS("mono_dl + (1+3+1+1+80*(7+2+2+3)+1)", monoDL + DLSIZE);
|
||||
LOG_ADDRESS("(1+3+1+1+80*(7+2+2+3)+1)", DLSIZE);
|
||||
if (!(dListEnd <= dList + VISMONO_DLSIZE)) {
|
||||
LOG_ADDRESS("glistp_end", dListEnd);
|
||||
LOG_ADDRESS("mono_dl", dList);
|
||||
LOG_ADDRESS("mono_dl + (1+3+1+1+80*(7+2+2+3)+1)", dList + VISMONO_DLSIZE);
|
||||
LOG_ADDRESS("(1+3+1+1+80*(7+2+2+3)+1)", VISMONO_DLSIZE);
|
||||
}
|
||||
assert(glistpEnd <= monoDL + DLSIZE);
|
||||
ASSERT(dListEnd <= dList + VISMONO_DLSIZE, "glistp_end <= mono_dl + DLSIZE", "../z_vismono.c", 262);
|
||||
}
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
if (this->setScissor == true) {
|
||||
|
||||
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->primColor.rgba);
|
||||
gDPSetColor(gfx++, G_SETENVCOLOR, this->envColor.rgba);
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
|
||||
gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba);
|
||||
|
||||
gDPLoadTLUT_pal256(gfx++, tlut);
|
||||
|
||||
gSPDisplayList(gfx++, monoDL);
|
||||
gDPPipeSync(gfx++);
|
||||
gSPDisplayList(gfx++, dList);
|
||||
|
||||
*gfxp = gfx;
|
||||
gDPPipeSync(gfx++);
|
||||
#endif
|
||||
|
||||
*gfxP = gfx;
|
||||
}
|
||||
|
||||
void VisMono_DrawOld(VisMono* this) {
|
||||
Gfx* glistpEnd;
|
||||
Gfx* dListEnd;
|
||||
|
||||
if (!this->tlut) {
|
||||
this->tlut = SYSTEM_ARENA_MALLOC_DEBUG(256 * sizeof(u16));
|
||||
VisMono_UpdateTexture(this, this->tlut);
|
||||
if (this->tlut == NULL) {
|
||||
this->tlut = SYSTEM_ARENA_MALLOC(256 * G_IM_SIZ_16b_BYTES, "../z_vismono.c", 283);
|
||||
VisMono_DesaturateTLUT(this, this->tlut);
|
||||
}
|
||||
|
||||
if (!this->monoDl) {
|
||||
this->monoDl = SYSTEM_ARENA_MALLOC_DEBUG(DLSIZE * sizeof(Gfx));
|
||||
glistpEnd = VisMono_DrawTexture(this, this->monoDl);
|
||||
assert(glistpEnd <= this->monoDl + DLSIZE);
|
||||
if (this->dList == NULL) {
|
||||
this->dList = SYSTEM_ARENA_MALLOC(VISMONO_DLSIZE * sizeof(Gfx), "../z_vismono.c", 289);
|
||||
dListEnd = VisMono_DesaturateDList(this, this->dList);
|
||||
ASSERT(dListEnd <= this->dList + VISMONO_DLSIZE, "glistp_end <= this->mono_dl + DLSIZE", "../z_vismono.c", 292);
|
||||
}
|
||||
}
|
||||
|
116
soh/src/code/z_viszbuf.c
Normal file
116
soh/src/code/z_viszbuf.c
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @file z_viszbuf.c
|
||||
*
|
||||
* This file implements a full-screen framebuffer effect for visualizing the z-buffer (AKA depth buffer), using either
|
||||
* cycling RGBA or a single fading color.
|
||||
*
|
||||
* This is done by reading the z-buffer as if it were a color image, the format of which is specified by the selected
|
||||
* vis type:
|
||||
* - VIS_ZBUF_TYPE_IA : Produces a monotonic fade from primColor to envColor as depth increases.
|
||||
* - VIS_ZBUF_TYPE_RGBA : Produces vibrant almost-periodic-looking bands.
|
||||
*
|
||||
* In both cases this occurs because of the format the depth information takes: it is 18-bit, and is a nonnegative
|
||||
* floating-point number with
|
||||
* bbb mmmmmmmmmmm dd|dd
|
||||
* exponent mantissa dz value (only first 16 bits visible to CPU, the least significant 2 bits of dz are ignored)
|
||||
*
|
||||
* Reading z-buffer as IA16:
|
||||
* bbbmmmmm mmmmmmdd
|
||||
* iiiiiiii aaaaaaaa
|
||||
*
|
||||
* Since floating-point numbers of this format have the same ordering as their binary/hex representation, increasing
|
||||
* the depth also increases the intensity in the IA16 representation and hence the interpolation parameter used to
|
||||
* combine primColor and envColor. The alpha is ignored by the RenderMode.
|
||||
*
|
||||
* Reading z-buffer as RGBA16:
|
||||
* bbbmm mmmmm mmmmd d
|
||||
* rrrrr ggggg bbbbb a
|
||||
*
|
||||
* The red increases monotonically with the depth. The significant visible oscillation is the green component, because
|
||||
* it rolls over every time the second-most-significant bit of the mantissa increments. The blue component oscillates
|
||||
* too rapidly to be particularly visible (it rolls over when the 7th-most-significant bit increments). The alpha is
|
||||
* again ignored by the RenderMode.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
// Height of the fragments the z-buffer is split into.
|
||||
// It is the maximum amount of lines such that all rgba16 SCREEN_WIDTH-long lines fit into TMEM.
|
||||
#define VISZBUF_ZBUFFRAG_HEIGHT (TMEM_SIZE / (SCREEN_WIDTH * G_IM_SIZ_16b_BYTES))
|
||||
|
||||
// z-buffer
|
||||
extern u16 D_0E000000[];
|
||||
|
||||
/**
|
||||
* Initialise to IA type with white and black as default colors.
|
||||
*/
|
||||
void VisZBuf_Init(VisZBuf* this) {
|
||||
this->vis.type = VIS_ZBUF_TYPE_IA;
|
||||
this->vis.scissorType = VIS_NO_SETSCISSOR;
|
||||
|
||||
this->vis.primColor.r = 255;
|
||||
this->vis.primColor.g = 255;
|
||||
this->vis.primColor.b = 255;
|
||||
this->vis.primColor.a = 255;
|
||||
|
||||
// clang-format off
|
||||
this->vis.envColor.r = 0; \
|
||||
this->vis.envColor.g = 0; \
|
||||
this->vis.envColor.b = 0; \
|
||||
this->vis.envColor.a = 255;
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
void VisZBuf_Destroy(VisZBuf* this) {
|
||||
}
|
||||
|
||||
void VisZBuf_Draw(VisZBuf* this, Gfx** gfxP) {
|
||||
Gfx* gfx = *gfxP;
|
||||
s32 pad;
|
||||
u16* zbufFrag = D_0E000000;
|
||||
s32 fmt;
|
||||
s32 y;
|
||||
s32 height;
|
||||
|
||||
if (this->vis.type == VIS_ZBUF_TYPE_IA) {
|
||||
fmt = G_IM_FMT_IA;
|
||||
} else { // VIS_ZBUF_TYPE_RGBA
|
||||
fmt = G_IM_FMT_RGBA;
|
||||
}
|
||||
|
||||
height = VISZBUF_ZBUFFRAG_HEIGHT;
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
// Scissoring is only required if the scissor has not been set prior.
|
||||
if (this->vis.scissorType == VIS_SETSCISSOR) {
|
||||
gDPSetScissor(gfx++, G_SC_NON_INTERLACE, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
}
|
||||
|
||||
// No palette so can use all of TMEM.
|
||||
// G_RM_OPA_SURF discards all information previously in the pixel, and the current alpha, leaving only the color
|
||||
// from this filter.
|
||||
gDPSetOtherMode(gfx++,
|
||||
G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_POINT | G_TT_NONE | G_TL_TILE |
|
||||
G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE,
|
||||
G_AC_NONE | G_ZS_PRIM | G_RM_OPA_SURF | G_RM_OPA_SURF2);
|
||||
|
||||
// LERP between primColor and envColor in 1-cycle mode using the z-buffer value.
|
||||
gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT,
|
||||
PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT);
|
||||
gDPSetColor(gfx++, G_SETPRIMCOLOR, this->vis.primColor.rgba);
|
||||
gDPSetColor(gfx++, G_SETENVCOLOR, this->vis.envColor.rgba);
|
||||
|
||||
for (y = 0; y <= SCREEN_HEIGHT - height; y += height) {
|
||||
// Load a few lines of the z-buffer, as many as can fit in TMEM at once.
|
||||
gDPLoadTextureBlock(gfx++, zbufFrag, fmt, G_IM_SIZ_16b, SCREEN_WIDTH, height, 0, G_TX_NOMIRROR | G_TX_CLAMP,
|
||||
G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
|
||||
|
||||
// Overwrite them with the calculated colors.
|
||||
gSPTextureRectangle(gfx++, 0, y << 2, SCREEN_WIDTH << 2, (y + height) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
|
||||
1 << 10);
|
||||
zbufFrag += SCREEN_WIDTH * height;
|
||||
}
|
||||
|
||||
gDPPipeSync(gfx++);
|
||||
*gfxP = gfx;
|
||||
}
|
@ -181,8 +181,8 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
|
||||
}
|
||||
}
|
||||
this->timer = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_ARROW_STICK_CRE, &this->actor.projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_ARROW_STICK_CRE, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else if (DECR(this->timer) == 0) {
|
||||
grabbed = this->grabbed;
|
||||
if (grabbed != NULL) {
|
||||
@ -278,12 +278,12 @@ void ArmsHook_Shoot(ArmsHook* this, PlayState* play) {
|
||||
}
|
||||
}
|
||||
func_80865044(this);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_STICK_OBJ, &this->actor.projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_STICK_OBJ, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
CollisionCheck_SpawnShieldParticlesMetal(play, &this->actor.world.pos);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_REFLECT, &this->actor.projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_IT_HOOKSHOT_REFLECT, &this->actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
} else if (CHECK_BTN_ANY(play->state.input[0].press.button, (buttonsToCheck))) {
|
||||
this->timer = 0;
|
||||
|
@ -234,7 +234,7 @@ void func_8086EE40(BgBombwall* this, PlayState* play) {
|
||||
func_8086EE94(this, play);
|
||||
|
||||
if (((this->dyna.actor.params >> 0xF) & 1) != 0) {
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,11 +307,11 @@ void BgBreakwall_Wait(BgBreakwall* this, PlayState* play) {
|
||||
gSaveContext.cutsceneTrigger = 1;
|
||||
Player_SetCsActionWithHaltedActors(play, NULL, 0x31);
|
||||
}
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
if (this->dyna.actor.params < 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_TRE_BOX_APPEAR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
|
@ -173,8 +173,8 @@ void BgDdanKd_LowerStairs(BgDdanKd* this, PlayState* play) {
|
||||
func_8003555C(play, &pos1, &sBgDdanKdVelocity, &sBgDdanKdAccel);
|
||||
}
|
||||
Camera_AddQuake(&play->mainCamera, 0, effectStrength * 0.6f, 3);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_PILLAR_SINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_PILLAR_SINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,16 +160,16 @@ void BgDodoago_WaitExplosives(BgDodoago* this, PlayState* play) {
|
||||
((play->roomCtx.unk_74[BGDODOAGO_EYE_RIGHT] == 255) && (this->state == BGDODOAGO_EYE_LEFT))) {
|
||||
Flags_SetSwitch(play, this->dyna.actor.params & 0x3F);
|
||||
this->state = 0;
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
BgDodoago_SetupAction(this, BgDodoago_OpenJaw);
|
||||
OnePointCutscene_Init(play, 3380, 160, &this->dyna.actor, MAIN_CAM);
|
||||
} else if (play->roomCtx.unk_74[this->state] == 0) {
|
||||
OnePointCutscene_Init(play, 3065, 40, &this->dyna.actor, MAIN_CAM);
|
||||
BgDodoago_SetupAction(this, BgDodoago_LightOneEye);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
} else {
|
||||
OnePointCutscene_Init(play, 3065, 20, &this->dyna.actor, MAIN_CAM);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
sBgDodoagoTimer += 30;
|
||||
return;
|
||||
}
|
||||
@ -247,11 +247,11 @@ void BgDodoago_OpenJaw(BgDodoago* this, PlayState* play) {
|
||||
|
||||
if (Math_SmoothStepToS(&this->dyna.actor.shape.rot.x, 0x1333, 110 - this->state, 0x3E8, 0x32) == 0) {
|
||||
BgDodoago_SetupAction(this, BgDodoago_DoNothing);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_STONE_BOUND, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_STONE_BOUND, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_STONE_STATUE_OPEN - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_STONE_STATUE_OPEN - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -221,11 +221,11 @@ void BgGanonOtyuka_Fall(BgGanonOtyuka* this, PlayState* play) {
|
||||
}
|
||||
} else {
|
||||
if (this->dropTimer == 1) {
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_STONEDOOR_STOP, &this->dyna.actor.projectedPos, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_STONEDOOR_STOP, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_BLOCKSINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &D_801333E0,
|
||||
&D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_BLOCKSINK - SFX_FLAG, &this->dyna.actor.projectedPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
Math_ApproachF(&this->dyna.actor.world.pos.y, -1000.0f, 1.0f, this->dyna.actor.speedXZ);
|
||||
Math_ApproachF(&this->dyna.actor.speedXZ, 100.0f, 1.0f, 0.1f);
|
||||
|
@ -123,7 +123,7 @@ void BgGndDarkmeiro_UpdateBlockTimer(BgGndDarkmeiro* this, PlayState* play) {
|
||||
} else {
|
||||
this->actionFlags |= 4;
|
||||
this->timer1 = 304;
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ void BgGndDarkmeiro_UpdateBlockTimer(BgGndDarkmeiro* this, PlayState* play) {
|
||||
} else {
|
||||
this->actionFlags |= 8;
|
||||
this->timer2 = 304;
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_RED_EYE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ void func_8087B284(BgGndSoulmeiro* this, PlayState* play) {
|
||||
if (!Flags_GetSwitch(play, (this->actor.params >> 8) & 0x3F)) {
|
||||
this->actor.draw = BgGndSoulmeiro_Draw;
|
||||
if (this->collider.base.acFlags & AC_HIT) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
this->unk_198 = 40;
|
||||
this->actionFunc = func_8087AF38;
|
||||
} else {
|
||||
|
@ -115,7 +115,7 @@ void func_8087B938(BgHaka* this, PlayState* play) {
|
||||
player->stateFlags2 &= ~PLAYER_STATE2_MOVING_DYNAPOLY;
|
||||
|
||||
if (this->dyna.actor.params == 1) {
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
} else if (!IS_DAY && play->sceneNum == SCENE_GRAVEYARD) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_POH, this->dyna.actor.home.pos.x,
|
||||
this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z, 0, this->dyna.actor.shape.rot.y, 0,
|
||||
@ -124,7 +124,7 @@ void func_8087B938(BgHaka* this, PlayState* play) {
|
||||
|
||||
// un tss un tss
|
||||
if (play->sceneNum == SCENE_GRAVEYARD && allPulled) {
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
func_800F5ACC(NA_BGM_STAFF_2);
|
||||
Actor* actor2 = play->actorCtx.actorLists[ACTORCAT_BG].head;
|
||||
|
||||
@ -196,10 +196,10 @@ void BgHaka_Draw(Actor* thisx, PlayState* play) {
|
||||
play->envCtx.adjLight1Color[0] = newColor.r;
|
||||
play->envCtx.adjLight1Color[1] = newColor.g;
|
||||
play->envCtx.adjLight1Color[2] = newColor.b;
|
||||
D_801614B0.r = newColor.r;
|
||||
D_801614B0.g = newColor.g;
|
||||
D_801614B0.b = newColor.b;
|
||||
D_801614B0.a = 255;
|
||||
gVisMonoColor.r = newColor.r;
|
||||
gVisMonoColor.g = newColor.g;
|
||||
gVisMonoColor.b = newColor.b;
|
||||
gVisMonoColor.a = 255;
|
||||
gDPSetGrayscaleColor(POLY_OPA_DISP++, newColor.r, newColor.g, newColor.b, 255);
|
||||
gSPGrayscale(POLY_OPA_DISP++, true);
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ void BgHakaGate_FloorClosed(BgHakaGate* this, PlayState* play) {
|
||||
sBgPoEventPuzzleState = SKULL_OF_TRUTH_FOUND;
|
||||
this->actionFunc = BgHakaGate_DoNothing;
|
||||
} else {
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ERROR);
|
||||
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_GROUND_GATE_OPEN);
|
||||
func_8003EBF8(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
this->vTimer = 60;
|
||||
|
@ -230,6 +230,6 @@ void BgHakaShip_Draw(Actor* thisx, PlayState* play) {
|
||||
sp2C.z = this->dyna.actor.world.pos.z;
|
||||
|
||||
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sp2C, &this->bellSoundPos);
|
||||
func_80078914(&this->bellSoundPos, NA_SE_EV_SHIP_BELL - SFX_FLAG);
|
||||
Sfx_PlaySfxAtPos(&this->bellSoundPos, NA_SE_EV_SHIP_BELL - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
|
@ -546,7 +546,7 @@ void BgHakaTrap_Draw(Actor* thisx, PlayState* play) {
|
||||
sp2C.y = this->dyna.actor.world.pos.y + 110.0f;
|
||||
|
||||
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &sp2C, &this->unk_16C);
|
||||
func_80078914(&this->unk_16C, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG);
|
||||
Sfx_PlaySfxAtPos(&this->unk_16C, NA_SE_EV_BRIDGE_CLOSE - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) {
|
||||
if (sPotsDestroyed == 3) {
|
||||
// All 3 pots destroyed
|
||||
collectibleParams = -1;
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
// Drop rupees
|
||||
for (i = 0; i < 9; i++) {
|
||||
collectible = Item_DropCollectible(play, &spawnPos, i % 3);
|
||||
@ -178,7 +178,7 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) {
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_FIREFLY, this->dyna.actor.world.pos.x,
|
||||
this->dyna.actor.world.pos.y + 80.0f, this->dyna.actor.world.pos.z, 0,
|
||||
this->dyna.actor.shape.rot.y, 0, 2, true);
|
||||
func_80078884(NA_SE_SY_ERROR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_ERROR);
|
||||
} else {
|
||||
// Random rewards
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("NoRandomDrops"), 0)) {
|
||||
@ -192,7 +192,7 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) {
|
||||
} else {
|
||||
collectibleParams = ITEM00_ARROWS_SMALL;
|
||||
}
|
||||
func_80078884(NA_SE_SY_TRE_BOX_APPEAR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR);
|
||||
}
|
||||
} else if (Flags_GetCollectible(play, this->dyna.actor.params) != 0) {
|
||||
// If small key already collected, drop recovery heart instead
|
||||
@ -202,11 +202,11 @@ void BgHakaTubo_DropCollectible(BgHakaTubo* this, PlayState* play) {
|
||||
else {
|
||||
collectibleParams = ITEM00_HEART;
|
||||
}
|
||||
func_80078884(NA_SE_SY_TRE_BOX_APPEAR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR);
|
||||
} else {
|
||||
// Drops a small key and sets a collect flag
|
||||
collectibleParams = ((this->dyna.actor.params & 0x3F) << 8) | ITEM00_SMALL_KEY;
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
}
|
||||
if (collectibleParams != -1) {
|
||||
collectible = Item_DropCollectible(play, &spawnPos, collectibleParams);
|
||||
|
@ -376,7 +376,7 @@ void func_80888A58(BgHidanHamstep* this, PlayState* play) {
|
||||
func_808884C8(this, play);
|
||||
|
||||
if ((this->dyna.actor.params & 0xFF) == 5) {
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
}
|
||||
|
||||
osSyncPrintf("B(%d)\n", this->dyna.actor.params);
|
||||
|
@ -313,7 +313,7 @@ void BgHidanKowarerukabe_Update(Actor* thisx, PlayState* play) {
|
||||
SoundSource_PlaySfxAtFixedWorldPos(play, &this->dyna.actor.world.pos, 40, NA_SE_EV_WALL_BROKEN);
|
||||
}
|
||||
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
return;
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ void BgHidanRock_Draw(Actor* thisx, PlayState* play) {
|
||||
SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &this->dyna.actor.home.pos, &this->unk_170);
|
||||
}
|
||||
|
||||
func_80078914(&this->unk_170, NA_SE_EV_FIRE_PILLAR - SFX_FLAG);
|
||||
Sfx_PlaySfxAtPos(&this->unk_170, NA_SE_EV_FIRE_PILLAR - SFX_FLAG);
|
||||
func_8088BC40(play, this);
|
||||
}
|
||||
}
|
||||
|
@ -428,7 +428,7 @@ void func_808911D4(BgIceShelter* this, PlayState* play) {
|
||||
}
|
||||
|
||||
if (type == 4) {
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
}
|
||||
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
|
@ -275,7 +275,7 @@ void BgJyaMegami_Explode(BgJyaMegami* this, PlayState* play) {
|
||||
func_80033480(play, &sp8C, 100.0f, 1, 150, 100, 1);
|
||||
}
|
||||
if (this->explosionTimer == 60) {
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
}
|
||||
if (this->explosionTimer >= 100) {
|
||||
Actor_Kill(&this->dyna.actor);
|
||||
|
@ -110,7 +110,7 @@ void BgMenkuriEye_Update(Actor* thisx, PlayState* play) {
|
||||
this->framesUntilDisable = 416;
|
||||
if (D_8089C1A0 == 4) {
|
||||
Flags_SetSwitch(play, this->actor.params);
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
}
|
||||
}
|
||||
if (this->framesUntilDisable == -1) {
|
||||
|
@ -475,7 +475,7 @@ void BgMizuBwall_Idle(BgMizuBwall* this, PlayState* play) {
|
||||
this->dList = NULL;
|
||||
BgMizuBwall_SpawnDebris(this, play);
|
||||
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WALL_BROKEN);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_CORRECT_CHIME, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
this->actionFunc = BgMizuBwall_Break;
|
||||
} else if (this->dyna.actor.xzDistToPlayer < 600.0f) {
|
||||
CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base);
|
||||
|
@ -218,7 +218,7 @@ void func_808A3E54(BgMoriHineri* this, PlayState* play) {
|
||||
this->moriHineriObjIdx = objBankIndex;
|
||||
this->dyna.actor.params ^= 1;
|
||||
sBgMoriHineriNextCamIdx = MAIN_CAM;
|
||||
func_80078884(NA_SE_SY_TRE_BOX_APPEAR);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR);
|
||||
} else {
|
||||
this->dyna.actor.draw = NULL;
|
||||
this->actionFunc = func_808A3D58;
|
||||
|
@ -134,9 +134,9 @@ void BgMoriIdomizu_Main(BgMoriIdomizu* this, PlayState* play) {
|
||||
BgMoriIdomizu_SetWaterLevel(play, thisx->world.pos.y);
|
||||
if (this->drainTimer > 0) {
|
||||
if (switchFlagSet) {
|
||||
func_800788CC(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
|
||||
} else {
|
||||
func_800788CC(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,11 +137,11 @@ void BgMoriKaitenkabe_Rotate(BgMoriKaitenkabe* this, PlayState* play) {
|
||||
thisx->home.rot.y -= 0x2000;
|
||||
}
|
||||
thisx->world.rot.y = thisx->shape.rot.y = thisx->home.rot.y;
|
||||
func_800788CC(NA_SE_EV_STONEDOOR_STOP);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_STONEDOOR_STOP);
|
||||
} else {
|
||||
rotY = this->rotYdeg * (0x10000 / 360.0f);
|
||||
thisx->world.rot.y = thisx->shape.rot.y = thisx->home.rot.y + rotY;
|
||||
func_800788CC(NA_SE_EV_WALL_SLIDE - SFX_FLAG);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_WALL_SLIDE - SFX_FLAG);
|
||||
}
|
||||
if (fabsf(this->dyna.unk_150) > 0.001f) {
|
||||
this->dyna.unk_150 = 0.0f;
|
||||
|
@ -133,7 +133,7 @@ void BgMoriRakkatenjo_Wait(BgMoriRakkatenjo* this, PlayState* play) {
|
||||
}
|
||||
}
|
||||
if (this->timer < 20) {
|
||||
func_800788CC(NA_SE_EV_BLOCKSINK - SFX_FLAG);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_BLOCKSINK - SFX_FLAG);
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,7 +156,7 @@ void BgMoriRakkatenjo_Fall(BgMoriRakkatenjo* this, PlayState* play) {
|
||||
} else {
|
||||
if (this->bounceCount == 0) {
|
||||
this->fallCount++;
|
||||
func_800788CC(NA_SE_EV_STONE_BOUND);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EV_STONE_BOUND);
|
||||
func_800AA000(SQ(thisx->yDistToPlayer), 0xFF, 0x14, 0x96);
|
||||
}
|
||||
thisx->world.pos.y =
|
||||
|
@ -343,7 +343,7 @@ void BgPoEvent_BlockIdle(BgPoEvent* this, PlayState* play) {
|
||||
if (amy != NULL) {
|
||||
OnePointCutscene_Init(play, 3170, 30, amy, MAIN_CAM);
|
||||
}
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
gSaveContext.timer1State = 0xA;
|
||||
}
|
||||
} else {
|
||||
@ -538,7 +538,7 @@ void BgPoEvent_PaintingPresent(BgPoEvent* this, PlayState* play) {
|
||||
thisx->world.pos.y - 40.0f, thisx->world.pos.z, 0, thisx->shape.rot.y, 0,
|
||||
thisx->params + ((this->type - 1) << 8), true);
|
||||
OnePointCutscene_Init(play, 3160, 80, thisx, MAIN_CAM);
|
||||
func_80078884(NA_SE_SY_CORRECT_CHIME);
|
||||
Sfx_PlaySfxCentered(NA_SE_SY_CORRECT_CHIME);
|
||||
|
||||
} else {
|
||||
Audio_PlayActorSound2(thisx, NA_SE_EN_PO_LAUGH2);
|
||||
|
@ -150,7 +150,7 @@ void func_808A9234(BgRelayObjects* this, PlayState* play) {
|
||||
func_800AA000(this->dyna.actor.xyzDistToPlayerSq, 180, 20, 100);
|
||||
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONE_BOUND);
|
||||
if (this->unk_169 != play->roomCtx.curRoom.num) {
|
||||
func_800788CC(NA_SE_EN_PO_LAUGH);
|
||||
Sfx_PlaySfxCentered2(NA_SE_EN_PO_LAUGH);
|
||||
this->timer = 5;
|
||||
this->actionFunc = func_808A932C;
|
||||
return;
|
||||
@ -173,7 +173,7 @@ void func_808A932C(BgRelayObjects* this, PlayState* play) {
|
||||
}
|
||||
if (this->timer == 0) {
|
||||
if (!Player_InCsMode(play)) {
|
||||
func_80078884(NA_SE_OC_ABYSS);
|
||||
Sfx_PlaySfxCentered(NA_SE_OC_ABYSS);
|
||||
Play_TriggerRespawn(play);
|
||||
this->actionFunc = BgRelayObjects_DoNothing;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ const ActorInit Bg_Spot01_Idohashira_InitVars = {
|
||||
};
|
||||
|
||||
void BgSpot01Idohashira_PlayBreakSfx1(BgSpot01Idohashira* this) {
|
||||
func_80078914(&this->dyna.actor.projectedPos, NA_SE_EV_BOX_BREAK);
|
||||
Sfx_PlaySfxAtPos(&this->dyna.actor.projectedPos, NA_SE_EV_BOX_BREAK);
|
||||
}
|
||||
|
||||
void BgSpot01Idohashira_PlayBreakSfx2(BgSpot01Idohashira* this, PlayState* play) {
|
||||
|
@ -55,8 +55,8 @@ void func_808ABB84(BgSpot01Idomizu* this, PlayState* play) {
|
||||
}
|
||||
play->colCtx.colHeader->waterBoxes[0].ySurface = this->actor.world.pos.y;
|
||||
if (this->waterHeight < this->actor.world.pos.y) {
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG, &D_801333D4, 4, &D_801333E0, &D_801333E0,
|
||||
&D_801333E8);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
}
|
||||
Math_ApproachF(&this->actor.world.pos.y, this->waterHeight, 1.0f, 2.0f);
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user