mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-30 23:44:28 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a53b363905 | |||
| fae9add351 |
+1
-25
@@ -90,7 +90,6 @@ option(DUSK_ENABLE_SENTRY_NATIVE "Enable sentry-native crash reporting support"
|
||||
option(DUSK_PACKAGE_INSTALL "Install Dusklight with a Linux-native file structure" OFF)
|
||||
option(DUSK_GFX_DEBUG_GROUPS "Report debug groups to the native graphics API" ${DUSK_GFX_DEBUG_GROUPS_DEFAULT})
|
||||
option(DUSK_ENABLE_CODE_MODS "Enable code mods" OFF)
|
||||
option(DUSK_ENABLE_OPUS "Enable loading Opus audio files for mods" ON)
|
||||
|
||||
set(DUSK_HAS_FUNCHOOK OFF)
|
||||
if (DUSK_ENABLE_CODE_MODS AND (NOT APPLE OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
|
||||
@@ -249,25 +248,6 @@ FetchContent_Declare(miniz
|
||||
)
|
||||
|
||||
set(_fetch_content_deps cxxopts json miniz)
|
||||
|
||||
if (DUSK_ENABLE_OPUS)
|
||||
message(STATUS "dusklight: Fetching opusfile")
|
||||
|
||||
# Opusfile options
|
||||
SET(OP_DISABLE_HTTP ON CACHE BOOL "" FORCE)
|
||||
SET(OP_DISABLE_DOCS ON CACHE BOOL "" FORCE)
|
||||
SET(OP_DISABLE_EXAMPLES ON CACHE BOOL "" FORCE)
|
||||
|
||||
message(STATUS "dusklight: Fetching opusfile")
|
||||
FetchContent_Declare(
|
||||
opusfile
|
||||
GIT_REPOSITORY https://github.com/xiph/opusfile.git
|
||||
GIT_TAG 6dfd29e7adb87f2e193575fc3fa88cbf1a0b27df
|
||||
)
|
||||
|
||||
list(APPEND _fetch_content_deps opusfile)
|
||||
endif ()
|
||||
|
||||
if (DUSK_HAS_FUNCHOOK)
|
||||
message(STATUS "dusklight: Fetching funchook")
|
||||
# cmake/PatchFunchook.cmake patches funchook's cmake/capstone.cmake.in to inject a
|
||||
@@ -360,10 +340,6 @@ set(GAME_LIBS aurora::core aurora::gx aurora::gd aurora::si aurora::vi aurora::p
|
||||
if (DUSK_HAS_FUNCHOOK)
|
||||
list(APPEND GAME_LIBS funchook-static)
|
||||
endif ()
|
||||
if (DUSK_ENABLE_OPUS)
|
||||
list(APPEND GAME_LIBS OpusFile::opusfile)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_OPUS=1)
|
||||
endif ()
|
||||
|
||||
if (DUSK_ENABLE_SENTRY_NATIVE)
|
||||
list(APPEND GAME_LIBS sentry)
|
||||
@@ -635,7 +611,7 @@ if (DUSK_ENABLE_CODE_MODS AND CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR
|
||||
add_subdirectory(mods/ao_mod)
|
||||
add_subdirectory(mods/shadow_mod)
|
||||
add_subdirectory(mods/window_demo)
|
||||
add_subdirectory(mods/audio_mod)
|
||||
add_subdirectory(mods/randomizer)
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
#pragma endian big
|
||||
|
||||
#include "std/sys.pat"
|
||||
#include "type/magic.pat"
|
||||
#include "std/array.pat"
|
||||
|
||||
/**
|
||||
* Wrapper for a file-global pointer that allows it to be stored in an array.
|
||||
*/
|
||||
struct Offset<T> {
|
||||
T* offset : u32 [[inline]];
|
||||
};
|
||||
|
||||
struct ItemSoundEffect {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
padding[2];
|
||||
u32 mSwBit;
|
||||
float mPitch;
|
||||
};
|
||||
|
||||
struct ItemSequence {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
u16 mResourceId;
|
||||
};
|
||||
|
||||
struct ItemStream {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
u16 mStreamPanParameters;
|
||||
char* mStreamFilePath[] : u32;
|
||||
};
|
||||
|
||||
struct SoundTableGroupEntry {
|
||||
u8 mTypeId;
|
||||
if (mTypeId == 0x51) {
|
||||
ItemSoundEffect* mOffset : u24 [[inline]];
|
||||
} else if (mTypeId == 0x60) {
|
||||
ItemSequence* mOffset : u24 [[inline]];
|
||||
} else if (mTypeId == 0x70 || mTypeId == 0x71) {
|
||||
ItemStream* mOffset : u24 [[inline]];
|
||||
} else {
|
||||
u24 mOffset;
|
||||
}
|
||||
};
|
||||
|
||||
struct TGroup {
|
||||
u32 mNumItems;
|
||||
padding[4];
|
||||
SoundTableGroupEntry mEntries[mNumItems];
|
||||
};
|
||||
|
||||
struct TSection {
|
||||
u32 mNumGroups;
|
||||
Offset<TGroup> mGroupOffsets[mNumGroups];
|
||||
};
|
||||
|
||||
struct Root {
|
||||
u32 mSectionNumber;
|
||||
Offset<TSection> mSectionOffsets[mSectionNumber];
|
||||
};
|
||||
|
||||
struct THeader {
|
||||
type::Magic<"BST "> mMagic;
|
||||
|
||||
padding[8];
|
||||
Root* mRoot : u32;
|
||||
};
|
||||
|
||||
THeader header @ 0x0;
|
||||
@@ -1,228 +0,0 @@
|
||||
#pragma endian big
|
||||
|
||||
#include "std/sys.pat"
|
||||
#include "type/magic.pat"
|
||||
#include "std/array.pat"
|
||||
|
||||
/*
|
||||
WSYS file
|
||||
The WSYS file contains roughly two sections: WBCT and WINF.
|
||||
WBCT contains the mapping of Wave ID -> wave archives.
|
||||
WINF are the wave archives themselves and their metadata.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wrapper for a file-global pointer that allows it to be stored in an array.
|
||||
*/
|
||||
struct Offset<T> {
|
||||
T* offset : u32 [[inline]];
|
||||
};
|
||||
|
||||
/**
|
||||
* Format that audio data is in..
|
||||
*/
|
||||
enum WaveFormat : u8 {
|
||||
/**
|
||||
* 16-samples-per-9-bytes custom Nintendo ADPCM.
|
||||
*/
|
||||
ADPCM4 = 0,
|
||||
|
||||
/**
|
||||
* 16-samples-per-5-bytes custom Nintendo ADPCM.
|
||||
*/
|
||||
ADPCM2 = 1,
|
||||
|
||||
/**
|
||||
* 8-bit-per-sample PCM.
|
||||
*/
|
||||
PCM8 = 2,
|
||||
|
||||
/**
|
||||
* 16-bit-per-sample PCM.
|
||||
*/
|
||||
PCM16 = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines playback info for a single audio "wave".
|
||||
* This data is stored per archive, making it duplicated (except for mAWOffsetStart)
|
||||
*/
|
||||
struct TWave {
|
||||
padding[1]; // unknown
|
||||
WaveFormat mWaveFormat;
|
||||
|
||||
/**
|
||||
* Key (as in like, the musical term) this sample is in.
|
||||
*/
|
||||
u8 mBaseKey;
|
||||
padding[1];
|
||||
|
||||
/**
|
||||
* Sample rate of the audio in Hz.
|
||||
*/
|
||||
float mSampleRate;
|
||||
|
||||
/**
|
||||
* Position where the sample data starts.
|
||||
* This is in the .aw file for the archive containing this TWave.
|
||||
*/
|
||||
u32 mAWOffsetStart;
|
||||
|
||||
/**
|
||||
* Byte length of the sample data.
|
||||
*/
|
||||
u32 mAWLength;
|
||||
|
||||
/**
|
||||
* Indicates whether the sample should loop or not. All bits appear set if so.
|
||||
*/
|
||||
u32 mLoopFlags;
|
||||
|
||||
/**
|
||||
* Audio sample at which the loop starts.
|
||||
*/
|
||||
u32 mLoopStartSample;
|
||||
|
||||
/**
|
||||
* Audio sample at which the loop ends (and goes back to mLoopStartSample).
|
||||
*/
|
||||
u32 mLoopEndSample;
|
||||
|
||||
/**
|
||||
* Total sample count in this wave.
|
||||
*/
|
||||
u32 mSampleCount;
|
||||
|
||||
/**
|
||||
* Last sample for continuing ADPCM decode after loop.
|
||||
*/
|
||||
s16 mpLast;
|
||||
|
||||
/**
|
||||
* Penult sample for continuing ADPCM decode after loop.
|
||||
*/
|
||||
s16 mpPenult;
|
||||
};
|
||||
|
||||
/**
|
||||
* A single wave archive on disk.
|
||||
* These are paired 1:1 with TCtrlScene objects.
|
||||
*/
|
||||
struct TWaveArchive {
|
||||
/**
|
||||
* Filename of the raw sample data on disc. Relative to /Audiores/Waves/
|
||||
*/
|
||||
char mFileName[0x70];
|
||||
|
||||
/**
|
||||
* Amount of waves in this archive.
|
||||
* Matches the count in the paired TCtrl object.
|
||||
*/
|
||||
u32 mWaveCount;
|
||||
|
||||
/**
|
||||
* Offsets to the wave metadata (not sample data) in the WSYS.
|
||||
* These are paired 1:1 to the TCtrlWaves, and the TCtrlWave contains the actual
|
||||
* "Wave ID" used by the game for lookups.
|
||||
*/
|
||||
Offset<TWave> waveOffsets[mWaveCount];
|
||||
};
|
||||
|
||||
/**
|
||||
* Header containing data for wave archives and their metadata.
|
||||
*/
|
||||
struct TWaveArchiveBank {
|
||||
type::Magic<"WINF"> mMagic;
|
||||
|
||||
/**
|
||||
* Amount of archives in this wave bank.
|
||||
* Matches the value in TCtrlGroup.
|
||||
*/
|
||||
u32 mArchiveCounts;
|
||||
Offset<TWaveArchive> mArchiveOffsets[mArchiveCounts];
|
||||
};
|
||||
|
||||
/**
|
||||
* Definition for a single wave in a control group.
|
||||
*/
|
||||
struct TCtrlWave {
|
||||
/**
|
||||
* Group ID matches the index of the control group this item is referenced by.
|
||||
*/
|
||||
u16 mGroupId;
|
||||
|
||||
/**
|
||||
* Wave ID used by the game to look this wave up.
|
||||
*/
|
||||
u16 mWaveId;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the actual data for a TCtrlScene.
|
||||
* Why is this separate? Who knows.
|
||||
*/
|
||||
struct TCtrl {
|
||||
// Other versions of this struct with different magic (C-EX and C-ST) also exist in the file.
|
||||
// They aren't pointed to so we don't need to worry about them.
|
||||
type::Magic<"C-DF"> mMagic;
|
||||
|
||||
/**
|
||||
* Amount of waves in this group.
|
||||
* Matches the value in TWaveArchive.
|
||||
*/
|
||||
u32 waveCount;
|
||||
Offset<TCtrlWave> mWaveOffsets[waveCount];
|
||||
};
|
||||
|
||||
/**
|
||||
* A single scene or "group" of waves that are loaded at once.
|
||||
*/
|
||||
struct TCtrlScene {
|
||||
type::Magic<"SCNE"> mMagic;
|
||||
|
||||
padding[8]; // unknown
|
||||
TCtrl* mCtrlOffset : u32 [[inline]];
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains the "control" section of the WSYS.
|
||||
*/
|
||||
struct TCtrlGroup {
|
||||
type::Magic<"WBCT"> mMagic;
|
||||
|
||||
padding[4]; // unknown
|
||||
u32 mGroupCount;
|
||||
|
||||
Offset<TCtrlScene> mCtrlSceneOffsets[mGroupCount];
|
||||
};
|
||||
|
||||
struct THeader {
|
||||
type::Magic<"WSYS"> mMagic;
|
||||
|
||||
/**
|
||||
* Size of WSYS in bytes.
|
||||
*/
|
||||
u32 mSize;
|
||||
|
||||
/**
|
||||
* ID of wave bank.
|
||||
* This matches the value passed to the BAA load command.
|
||||
* The game originally does not use this value itself, but Dusklight does rely on it.
|
||||
*/
|
||||
u32 mId;
|
||||
|
||||
/**
|
||||
* Total amount of waves in this wave bank.
|
||||
* (not groups! Waves!)
|
||||
*/
|
||||
u32 mWaveTableSize;
|
||||
|
||||
TWaveArchiveBank* archiveBankOffset : u32;
|
||||
TCtrlGroup* ctrlGroupOffset : u32;
|
||||
};
|
||||
|
||||
THeader header @ 0x0;
|
||||
|
||||
std::assert(
|
||||
header.archiveBankOffset.mArchiveCounts == header.ctrlGroupOffset.mGroupCount,
|
||||
"Control group and archive count does not match!");
|
||||
@@ -1,90 +0,0 @@
|
||||
# JAudio
|
||||
|
||||
**JAudio** is the name for the audio engine used by Twilight Princess (along with many other Nintendo games from the era). TP uses exclusively JAudio v2, while other games use v1 or a mix of v1 and v2 infrastructure. This document will primarily focus on TP's use case, but best efforts will be made to document where behavior is TP-specific.
|
||||
|
||||
## Common concepts
|
||||
|
||||
Audio is almost exclusively
|
||||
|
||||
### `JAISoundID`
|
||||
|
||||
A "sound", be that a _sound effect_ or music, is referenced in-code through the `JAISoundID` type. This is a `u32` that the game uses to look up the relevant sound. The actual value is bitpacked (BE) from the following fields:
|
||||
|
||||
| Type | Field | Description |
|
||||
|-------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `u8` | Section ID | Section of the Sound Table this sound effect is located in. 0 for sound effects, 1 for sequenced music, 2 for streamed music.[^sectionids] |
|
||||
| `u8` | Group ID | ID of group further used to organize inside the Sound Table's Section. Sound effects are grouped into things like "SYSTEM" and "ENEMY", other sections leave this at 0. |
|
||||
| `u16` | "Wave ID" | Index inside the group to look up the sound at.<br/>**Note** that the term "wave" in code is extremely confusing[^waveterm]; it does **not** refer to audio samples ("waves") in the wave banks directly. |
|
||||
|
||||
[^sectionids]: JAudio itself can seemingly work outside this convention, however it is enforced by some TP-specific game code.
|
||||
|
||||
[^waveterm]: Possibly vestigial from JAudio v1, where I believe there were less layers of indirection.
|
||||
|
||||
## Disc files
|
||||
|
||||
All audio data is stored in `/Audiores` on the disc. Files are as follows:
|
||||
|
||||
### `/Audiores/Seqs/Z2SoundSeqs.arc`
|
||||
|
||||
Contains the BMS instructions for all BMS-based music and sound effects. Not all data is kept in memory at once.
|
||||
|
||||
### `/Audiores/Stream/*.ast`
|
||||
|
||||
Contains individual streamed music. Each file is a separate music track. See [this page](https://www.lumasworkshop.com/wiki/AST_(File_Format)) for file format description.
|
||||
|
||||
### `/Audiores/Waves/*.aw`
|
||||
|
||||
Contains audio sample data for sequenced music and sound effects. These files are pure meat, no bone: they are loaded directly into ARAM and all metadata is stored in the BAA WSYS sections.
|
||||
|
||||
Each file contains audio samples for one "scene", with factors like the current level determining what "scenes" are made resident in memory. There is tons of duplicate data between scenes, presumably to increase simplicity and loading performance.
|
||||
|
||||
### `/Audiores/Z2Sound.baa`
|
||||
|
||||
Contains all remaining metadata for the audio system. This is effectively a container for a bunch of different sub-sections. The file starts with a bunch of "commands" that indicate where other data in the file is. Each command has a 4-character identifier and depending on the command will be followed by some extra arguments before the next command.
|
||||
|
||||
The commands used by TP's BAA file are as follows (note that the decompiled code has support for more load commands, which are unused):
|
||||
|
||||
| Command/Argument | Value | Description |
|
||||
|------------------|-----------------|-------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Command | `AA_<` | Start of BAA commands. Must be at the start of the file and only appear once. |
|
||||
| Command | `>_AA` | End of BAA commands. |
|
||||
| Command | `ws `[^spaces] | Wave bank/WSYS data. Defines where audio samples are located on disc. |
|
||||
| Argument | u32 | Wave bank ID, max 255. In TP, 0 is sound effects, 1 is music samples. |
|
||||
| Argument | u32 | File offset for start of `WSYS` data |
|
||||
| Argument | u32 | Bit field selecting which groups (= `.aw` files) to load immediately. TP leaves this at zero.[^32ws] |
|
||||
| Command | `bnk `[^spaces] | Instrument bank/IBNK |
|
||||
| Argument | u32 | Target wave bank ID |
|
||||
| Argument | u32 | File offset for start of `IBNK` data |
|
||||
| Command | `bsc `[^spaces] | Sound effect sequence collection. |
|
||||
| Argument | u32 | File offset for start of `SC` data. |
|
||||
| Argument | u32 | File offset for end of `SC` data. |
|
||||
| Command | `bst `[^spaces] | Sound table. Defines parameters for music and sound effects. |
|
||||
| Argument | u32 | File offset for start of `BST `[^spaces] data. |
|
||||
| Argument | u32 | File offset for end of `BST `[^spaces] data. |
|
||||
| Command | `bstn` | Sound name table. Defines names of all music and sound effects. Present on disc, but loading is disabled on release versions of the game. |
|
||||
| Argument | u32 | File offset for start of `BSTN` data. |
|
||||
| Argument | u32 | File offset for end of `BSTN` data. |
|
||||
| Command | `bfca` | Unknown, something related to initialization of DSP FX data. |
|
||||
| Argument | u32 | File offset for start of `RARC` data. |
|
||||
|
||||
[^spaces]: Padded with spaces.
|
||||
|
||||
[^32ws]: Both of TP's wave banks have far more than 32 groups, and seemingly this mechanism would not be able to deal with that.
|
||||
|
||||
Following is data descriptions for the remaining data in the `.BAA`, as pointed to by the above commands.
|
||||
|
||||
### `WSYS` / Wave banks
|
||||
|
||||
`WSYS` / Wave bank data defines where a set of audio samples can be found on disc. Each wave bank is made of multiple "groups", where each group corresponds to one `.aw` file on disc. Each group has a set of "wave IDs" it contains, along with the metadata (e.g. sample rate) and data offset in the `.aw` file.
|
||||
|
||||
Multiple groups can contain the same wave ID, thus meaning the raw audio samples can be duplicated on disk.
|
||||
|
||||
For the actual binary layout of this data, check [the ImHex pattern](imhex/jaudio/wsys.hexpat)
|
||||
|
||||
*Relevant classes: `JASWSParser`, `JASBasicWaveBank`, `JASSimpleWaveBank`.*
|
||||
|
||||
## Further reading & credits
|
||||
|
||||
* https://www.lumasworkshop.com/wiki/SMR.szs (note that details like the exact layout of the BAA are not the same as TP)
|
||||
* XAYRGA for doing much RE work and making [JAMTools](https://xayr.gay/tools/SoundModdingToolkit/)
|
||||
* The decompiled source code, duh.
|
||||
@@ -1485,10 +1485,6 @@ set(DUSK_FILES
|
||||
src/dusk/mods/log_buffer.hpp
|
||||
src/dusk/mods/manifest.cpp
|
||||
src/dusk/mods/manifest.hpp
|
||||
src/dusk/mods/svc/audio_res/audio_res.hpp
|
||||
src/dusk/mods/svc/audio_res/audio_res.cpp
|
||||
src/dusk/mods/svc/audio_res/wave.cpp
|
||||
src/dusk/mods/svc/audio_res/opus.cpp
|
||||
src/dusk/mods/svc/camera.cpp
|
||||
src/dusk/mods/svc/config.cpp
|
||||
src/dusk/mods/svc/config.hpp
|
||||
@@ -1589,7 +1585,6 @@ set(DUSK_FILES
|
||||
src/helpers/endian.cpp
|
||||
src/helpers/offset_ptr.cpp
|
||||
src/helpers/string.cpp
|
||||
src/helpers/cast.cpp
|
||||
)
|
||||
|
||||
set(DUSK_HTTP_BACKEND_FILES
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
#include "JSystem/JAudio2/JAUAudibleParam.h"
|
||||
#include "JSystem/TPosition3.h"
|
||||
|
||||
#define Z2_AUDIO_PLAYERS 1
|
||||
|
||||
struct Z2Audible;
|
||||
|
||||
struct Z2AudibleAbsPos {
|
||||
@@ -51,14 +49,10 @@ struct Z2AudioCamera {
|
||||
f32 getCamDist() const { return mCamDist; }
|
||||
|
||||
|
||||
/* 0x00 */ JGeometry::TPosition3f32 mViewMatrix;
|
||||
/* 0x00 */ JGeometry::TPosition3f32 field_0x0;
|
||||
/* 0x30 */ JGeometry::TVec3<f32> mVel;
|
||||
/* 0x3C */ JGeometry::TVec3<f32> mPos;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/* 0x48 */ JGeometry::TVec3<f32> mLastPos;
|
||||
/* 0x48 */ JGeometry::TVec3<f32> field_0x48;
|
||||
/* 0x54 */ f32 mFovySin;
|
||||
/* 0x58 */ f32 mVolCenterZ;
|
||||
/* 0x5C */ f32 mTargetVolume;
|
||||
@@ -89,14 +83,14 @@ struct Z2SpotMic {
|
||||
/* 0x04 */ f32 field_0x4;
|
||||
/* 0x08 */ f32 field_0x8;
|
||||
/* 0x0C */ f32 field_0xc;
|
||||
/* 0x10 */ Z2AudioCamera* field_0x10[Z2_AUDIO_PLAYERS];
|
||||
/* 0x10 */ Z2AudioCamera* field_0x10[1];
|
||||
/* 0x14 */ Vec* mPosPtr;
|
||||
/* 0x18 */ f32 field_0x18[Z2_AUDIO_PLAYERS];
|
||||
/* 0x18 */ f32 field_0x18[1];
|
||||
/* 0x1C */ f32 field_0x1c;
|
||||
/* 0x20 */ f32 field_0x20[Z2_AUDIO_PLAYERS];
|
||||
/* 0x20 */ f32 field_0x20[1];
|
||||
/* 0x24 */ bool mIgnoreIfOut;
|
||||
/* 0x25 */ bool mMicOn;
|
||||
/* 0x26 */ bool field_0x26[Z2_AUDIO_PLAYERS];
|
||||
/* 0x26 */ bool field_0x26[1];
|
||||
}; // Size: 0x28
|
||||
|
||||
struct Z2Audience3DSetting {
|
||||
@@ -108,99 +102,62 @@ struct Z2Audience3DSetting {
|
||||
void updateDolbyDist(f32, f32);
|
||||
|
||||
void calcVolumeFactorAll() {
|
||||
mDistanceMaxes[1] = 1.25f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[2] = 1.5f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[3] = 2.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[4] = 3.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[5] = 4.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[6] = 6.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[7] = 8.0f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[8] = 0.9f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[9] = 0.8f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[10] = 0.7f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[11] = 0.6f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[12] = 0.5f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[13] = 0.4f * mDistanceMaxes[0];
|
||||
mDistanceMaxes[14] = 0.3f * mDistanceMaxes[0];
|
||||
field_0x0[1] = 1.25f * field_0x0[0];
|
||||
field_0x0[2] = 1.5f * field_0x0[0];
|
||||
field_0x0[3] = 2.0f * field_0x0[0];
|
||||
field_0x0[4] = 3.0f * field_0x0[0];
|
||||
field_0x0[5] = 4.0f * field_0x0[0];
|
||||
field_0x0[6] = 6.0f * field_0x0[0];
|
||||
field_0x0[7] = 8.0f * field_0x0[0];
|
||||
field_0x0[8] = 0.9f * field_0x0[0];
|
||||
field_0x0[9] = 0.8f * field_0x0[0];
|
||||
field_0x0[10] = 0.7f * field_0x0[0];
|
||||
field_0x0[11] = 0.6f * field_0x0[0];
|
||||
field_0x0[12] = 0.5f * field_0x0[0];
|
||||
field_0x0[13] = 0.4f * field_0x0[0];
|
||||
field_0x0[14] = 0.3f * field_0x0[0];
|
||||
for (int i = 0; i < 15; i++) {
|
||||
mVolumeFactor[i] = (mMinDistanceVolume - 1.0f) / (mDistanceMaxes[i] - mMaxVolumeDistance);
|
||||
field_0x70[i] = (field_0x40 - 1.0f) / (field_0x0[i] - field_0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
void calcPriorityFactorAll() {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
mPriorityFactor[i] = mMaxDistancePriority / (mDistanceMaxes[i] - mMaxVolumeDistance);
|
||||
field_0xac[i] = field_0x64 / (field_0x0[i] - field_0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
void calcFxMixFactorAll() {
|
||||
for (int i = 0; i < 15; i++) {
|
||||
mFxMixFactor[i] = (mMaxDistanceFxMix - mMinDistanceFxMix) / (mDistanceMaxes[i] - mMaxVolumeDistance);
|
||||
field_0xe8[i] = (field_0x54 - field_0x50) / (field_0x0[i] - field_0x3c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum distance a sound can reach before being "far away"
|
||||
* Being far away affects stuff like culling, lowering its priority, forcibly stopping it, etc.
|
||||
* Sounds select which entry they use based on their VolBits.
|
||||
*/
|
||||
/* 0x000 */ f32 mDistanceMaxes[15];
|
||||
|
||||
/**
|
||||
* Distance at which the max volume of a sound is reached.
|
||||
* i.e. sounds do *not* get louder if they get closer than this.
|
||||
*/
|
||||
/* 0x03C */ f32 mMaxVolumeDistance;
|
||||
|
||||
/**
|
||||
* FX Mix value at maximum distance (@ref mDistanceMaxes)
|
||||
*/
|
||||
/* 0x040 */ f32 mMinDistanceVolume;
|
||||
/* 0x044 */ f32 mDolbyFrontDistanceMax;
|
||||
/* 0x048 */ f32 mDolbyBehindDistanceMax;
|
||||
/* 0x04C */ f32 mDolbyCenterValue;
|
||||
|
||||
/**
|
||||
* FX Mix value at minimum distance (@ref mMaxVolumeDistance)
|
||||
*/
|
||||
/* 0x050 */ f32 mMinDistanceFxMix;
|
||||
|
||||
/**
|
||||
* FX Mix value at maximum distance (@ref mDistanceMaxes)
|
||||
*/
|
||||
/* 0x054 */ f32 mMaxDistanceFxMix;
|
||||
/* 0x058 */ f32 mPanFactor;
|
||||
/* 0x05C */ f32 mSonicSpeed; // Used for doppler effect calculations.
|
||||
/* 0x000 */ f32 field_0x0[15];
|
||||
/* 0x03C */ f32 field_0x3c;
|
||||
/* 0x040 */ f32 field_0x40;
|
||||
/* 0x044 */ f32 field_0x44;
|
||||
/* 0x048 */ f32 field_0x48;
|
||||
/* 0x04C */ f32 field_0x4c;
|
||||
/* 0x050 */ f32 field_0x50;
|
||||
/* 0x054 */ f32 field_0x54;
|
||||
/* 0x058 */ f32 field_0x58;
|
||||
/* 0x05C */ f32 field_0x5c;
|
||||
/* 0x060 */ f32 field_0x60;
|
||||
|
||||
/**
|
||||
* Priority that sounds receive when "far away".
|
||||
* @see mDistanceMaxes
|
||||
*/
|
||||
/* 0x064 */ u32 mMaxDistancePriority;
|
||||
/* 0x064 */ u32 field_0x64;
|
||||
/* 0x068 */ f32 field_0x68;
|
||||
/* 0x06C */ f32 field_0x6c;
|
||||
/* 0x070 */ f32 mVolumeFactor[15];
|
||||
/* 0x0AC */ f32 mPriorityFactor[15];
|
||||
/* 0x0E8 */ f32 mFxMixFactor[15];
|
||||
/* 0x070 */ f32 field_0x70[15];
|
||||
/* 0x0AC */ f32 field_0xac[15];
|
||||
/* 0x0E8 */ f32 field_0xe8[15];
|
||||
/* 0x124 */ bool mVolumeDistInit;
|
||||
/* 0x125 */ bool mDolbyDistInit;
|
||||
}; // Size: 0x128
|
||||
|
||||
struct Z2AudibleRelPos {
|
||||
/* 0x00 */ JGeometry::TVec3<f32> mCameraRelative;
|
||||
|
||||
/**
|
||||
* Distance from mCameraRelative. This is from the object root and not the
|
||||
* exact distance used for volume/priority calculations.
|
||||
*/
|
||||
/* 0x0C */ f32 mTrueDistance;
|
||||
|
||||
/**
|
||||
* Distance from mCameraRelative but offset by mVolCenterZ.
|
||||
* This presumably means the distance is more centered on the object than mTrueDistance.
|
||||
*/
|
||||
/* 0x10 */ f32 mCenterDistance;
|
||||
/* 0x00 */ JGeometry::TVec3<f32> field_0x00;
|
||||
/* 0x0C */ f32 field_0xC;
|
||||
/* 0x10 */ f32 field_0x10;
|
||||
};
|
||||
|
||||
struct Z2AudibleChannel {
|
||||
@@ -214,7 +171,7 @@ struct Z2AudibleChannel {
|
||||
}
|
||||
|
||||
/* 0x00 */ JASSoundParams mParams;
|
||||
/* 0x14 */ Z2AudibleRelPos mRelPos;
|
||||
/* 0x14 */ Z2AudibleRelPos field_0x14;
|
||||
/* 0x28 */ f32 field_0x28;
|
||||
/* 0x2c */ f32 mPan;
|
||||
/* 0x30 */ f32 mDolby;
|
||||
@@ -243,8 +200,8 @@ struct Z2Audible : public JAIAudible, public JASPoolAllocObject<Z2Audible> {
|
||||
|
||||
/* 0x10 */ JAUAudibleParam mParam;
|
||||
/* 0x14 */ Z2AudibleAbsPos mAbsPos;
|
||||
/* 0x2C */ Z2AudibleChannel mChannel[Z2_AUDIO_PLAYERS];
|
||||
/* 0x64 */ f32 mMicDistances[Z2_AUDIO_PLAYERS];
|
||||
/* 0x2C */ Z2AudibleChannel mChannel[1];
|
||||
/* 0x64 */ f32 field_0x64[1];
|
||||
};
|
||||
|
||||
struct Z2Audience : public JAIAudience, public JASGlobalInstance<Z2Audience> {
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
s32 getBgmLoadStatus(u32 wave) { return getWaveLoadStatus(wave, 1); }
|
||||
u8 getDemoSeWaveNum() { return loadedDemoWave; }
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* 0x00 */ JAISoundID BGM_ID;
|
||||
/* 0x04 */ int sceneNum;
|
||||
/* 0x08 */ int timer;
|
||||
|
||||
@@ -1291,6 +1291,7 @@ public:
|
||||
}
|
||||
void set(const char*, s8, s16, s8, s8, u8);
|
||||
void offEnable() { enabled = 0; }
|
||||
void onEnable() { enabled = 1; }
|
||||
BOOL isEnable() const { return enabled; }
|
||||
s8 getWipe() const { return wipe; }
|
||||
u8 getWipeSpeed() const { return wipe_speed; }
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace dusk::helpers::alignment {
|
||||
|
||||
/**
|
||||
* Read data from an address that may not be aligned properly.
|
||||
* @tparam T Type of data to read.
|
||||
* @param ptr Address to read from.
|
||||
* @return The copied value.
|
||||
*/
|
||||
template <typename T> requires std::is_trivially_copyable_v<T>
|
||||
[[nodiscard]] constexpr T read_unaligned(u8 const* ptr) {
|
||||
T copy;
|
||||
memcpy(©, ptr, sizeof(T));
|
||||
return copy;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <span>
|
||||
|
||||
/**
|
||||
* Helper functions for performing casts.
|
||||
*/
|
||||
namespace dusk::helpers::cast {
|
||||
/**
|
||||
* Implementation details of dusk::helpers::cast.
|
||||
*/
|
||||
namespace _impl {
|
||||
[[noreturn]] void overrun_high();
|
||||
[[noreturn]] void overrun_low();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
concept IntCastable = std::is_integral_v<T> && std::is_trivially_copyable_v<T>;
|
||||
|
||||
/**
|
||||
* Helper type that allows easily casting between integer types,
|
||||
* that safely aborts if an overflow were to occur.
|
||||
* Usage:
|
||||
* @code
|
||||
* size_t foobar = 20;
|
||||
* int real = bounded_cast(foobar);
|
||||
* @endcode
|
||||
*/
|
||||
template <IntCastable Source>
|
||||
struct bounded_cast {
|
||||
Source src;
|
||||
|
||||
template <IntCastable Target>
|
||||
[[nodiscard]] constexpr operator Target() const {
|
||||
if (std::cmp_greater(src, std::numeric_limits<Target>::max())) [[unlikely]] {
|
||||
_impl::overrun_high();
|
||||
}
|
||||
|
||||
if (std::cmp_less(src, std::numeric_limits<Target>::min())) [[unlikely]] {
|
||||
_impl::overrun_low();
|
||||
}
|
||||
|
||||
return static_cast<Target>(src);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -285,7 +285,6 @@ inline void be_swap(Mtx& val) {
|
||||
}
|
||||
}
|
||||
|
||||
#define LE(T) T
|
||||
#define BE(T) BE<T>
|
||||
#define BE_HOST(T) (T.host())
|
||||
#else
|
||||
|
||||
@@ -101,7 +101,7 @@ struct JAISoundStatus_ {
|
||||
bool isMute() const { return field_0x0.flags.mute; }
|
||||
bool isPaused() const { return field_0x0.flags.paused; }
|
||||
void pauseWhenOut() {
|
||||
field_0x1.flags.mPauseWhenOut = 1;
|
||||
field_0x1.flags.flag3 = 1;
|
||||
}
|
||||
|
||||
/* 0x0 */ union {
|
||||
@@ -120,9 +120,9 @@ struct JAISoundStatus_ {
|
||||
/* 0x1 */ union {
|
||||
u8 value;
|
||||
struct {
|
||||
u8 mComesBack : 1;
|
||||
u8 flag1 : 1;
|
||||
u8 flag2 : 1;
|
||||
u8 mPauseWhenOut : 1;
|
||||
u8 flag3 : 1;
|
||||
u8 flag4 : 1;
|
||||
u8 flag5 : 1;
|
||||
u8 flag6 : 1;
|
||||
@@ -309,7 +309,7 @@ public:
|
||||
bool hasLifeTime() const { return status_.field_0x1.flags.flag2; }
|
||||
|
||||
void removeLifeTime_() {
|
||||
status_.field_0x1.flags.mComesBack = false;
|
||||
status_.field_0x1.flags.flag1 = false;
|
||||
status_.field_0x1.flags.flag2 = 0;
|
||||
}
|
||||
|
||||
@@ -346,7 +346,7 @@ public:
|
||||
|
||||
void setComesBack(bool param_0) {
|
||||
JUT_ASSERT(354, status_.state.flags.calcedOnce == 0);
|
||||
status_.field_0x1.flags.mComesBack = 1;
|
||||
status_.field_0x1.flags.flag1 = 1;
|
||||
if (param_0) {
|
||||
status_.pauseWhenOut();
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
*/
|
||||
struct JAISoundParamsProperty {
|
||||
void init() {
|
||||
mVolume = 1.0f;
|
||||
mFxMix = 0.0f;
|
||||
mPitch = 1.0f;
|
||||
field_0x0 = 1.0f;
|
||||
field_0x4 = 0.0f;
|
||||
field_0x8 = 1.0f;
|
||||
}
|
||||
|
||||
/* 0x00 */ f32 mVolume;
|
||||
/* 0x04 */ f32 mFxMix;
|
||||
/* 0x08 */ f32 mPitch;
|
||||
/* 0x00 */ f32 field_0x0;
|
||||
/* 0x04 */ f32 field_0x4;
|
||||
/* 0x08 */ f32 field_0x8;
|
||||
}; // Size: 0xC
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,27 +12,21 @@ struct JASBasicWaveBank : public JASWaveBank {
|
||||
struct TWaveHandle : public JASWaveHandle {
|
||||
TWaveHandle() { mHeap = NULL; }
|
||||
virtual intptr_t getWavePtr() const;
|
||||
virtual const JASWaveInfo* getWaveInfo() const { return &mWaveInfo; }
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] void const* getAramBaseAddress() const override { return nullptr; }
|
||||
#endif
|
||||
virtual const JASWaveInfo* getWaveInfo() const { return &field_0x4; }
|
||||
bool compareHeap(JASHeap* heap) const { return mHeap == heap;}
|
||||
|
||||
/* 0x04 */ JASWaveInfo mWaveInfo;
|
||||
/* 0x04 */ JASWaveInfo field_0x4;
|
||||
/* 0x28 */ JASHeap* mHeap;
|
||||
};
|
||||
|
||||
struct TGroupWaveInfo {
|
||||
TGroupWaveInfo() {
|
||||
waveId = 0xffff;
|
||||
mOffsetStart = -1;
|
||||
field_0x0 = 0xffff;
|
||||
field_0x4 = -1;
|
||||
}
|
||||
|
||||
/* 0x00 */ u16 waveId;
|
||||
/* 0x04 */ int mOffsetStart;
|
||||
/* 0x00 */ u16 field_0x0;
|
||||
/* 0x04 */ int field_0x4;
|
||||
};
|
||||
|
||||
struct TWaveGroup : JASWaveArc {
|
||||
@@ -50,7 +44,7 @@ struct JASBasicWaveBank : public JASWaveBank {
|
||||
u32 getWaveCount() const { return mWaveCount; }
|
||||
};
|
||||
|
||||
JASBasicWaveBank(IF_DUSK(u32 bankId));
|
||||
JASBasicWaveBank();
|
||||
~JASBasicWaveBank();
|
||||
TWaveGroup* getWaveGroup(u32);
|
||||
void setGroupCount(u32, JKRHeap*);
|
||||
@@ -62,7 +56,7 @@ struct JASBasicWaveBank : public JASWaveBank {
|
||||
JASWaveArc* getWaveArc(u32 param_0) { return getWaveGroup(param_0); }
|
||||
u32 getArcCount() const { return mGroupCount; }
|
||||
|
||||
/* 0x04 */ OSMutex mWaveTableMutex;
|
||||
/* 0x04 */ OSMutex field_0x4;
|
||||
/* 0x1C */ TWaveHandle* mWaveTable;
|
||||
/* 0x20 */ TWaveGroup* mWaveGroupArray;
|
||||
/* 0x24 */ u16 mHandleCount;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "JSystem/JAudio2/JASWaveInfo.h"
|
||||
#include "JSystem/JAudio2/JASDSPInterface.h"
|
||||
#include <os.h>
|
||||
#include <memory>
|
||||
|
||||
struct JASDSPChannel;
|
||||
|
||||
@@ -16,20 +15,6 @@ namespace JASDsp {
|
||||
struct TChannel;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* An object to manage the lifetime of the sample data pointed to by JASChannel.
|
||||
*
|
||||
* JASChannel can (optionally) accept an unique_ptr to an object to this type,
|
||||
* in which case it will be destroyed when the JASChannel is done.
|
||||
*
|
||||
* @see JASChannel::mSampleReference
|
||||
*/
|
||||
struct JASSampleDataReference {
|
||||
virtual ~JASSampleDataReference() = default;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
*
|
||||
@@ -181,23 +166,6 @@ public:
|
||||
u32 field_0x104;
|
||||
};
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* Memory address at which this sound effect should consider ARAM to start.
|
||||
*
|
||||
* By changing this, sound effects can effectively be played back from anywhere in memory,
|
||||
* rather than just the emulated ARAM space.
|
||||
*
|
||||
* If nullptr, the regular emulated ARAM is used.
|
||||
*/
|
||||
void const* mAramBaseAddress;
|
||||
|
||||
/**
|
||||
* @see JASSampleDataReference
|
||||
*/
|
||||
std::unique_ptr<JASSampleDataReference> mSampleReference;
|
||||
#endif
|
||||
|
||||
static DUSK_GAME_DATA OSMessageQueue sBankDisposeMsgQ;
|
||||
static DUSK_GAME_DATA OSMessage sBankDisposeMsg[16];
|
||||
static DUSK_GAME_DATA OSMessage sBankDisposeList[16];
|
||||
|
||||
@@ -109,9 +109,7 @@ namespace JASDsp {
|
||||
* Pitch shift via changing playback speed.
|
||||
*/
|
||||
/* 0x004 */ u16 mPitch;
|
||||
#if !TARGET_PC
|
||||
/* 0x006 */ short _unused1;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set to 1 when playback starts, cleared by DSP later,
|
||||
@@ -120,27 +118,19 @@ namespace JASDsp {
|
||||
* (Corroborated by fields JASAramStream checks never being cleared explicitly by CPU.)
|
||||
*/
|
||||
/* 0x008 */ u16 mResetFlag;
|
||||
#if !TARGET_PC
|
||||
/* 0x00A */ u8 _unused2[0x00C - 0x00A];
|
||||
#endif
|
||||
/* 0x00C */ s16 mPauseFlag;
|
||||
#if !TARGET_PC
|
||||
/* 0x00E */ short _unused3;
|
||||
#endif
|
||||
/* 0x010 */ OutputChannelConfig mOutputChannels[DSP_OUTPUT_CHANNELS];
|
||||
#if !TARGET_PC
|
||||
/* 0x040 */ u8 _unused4[0x050 - 0x040];
|
||||
#endif
|
||||
/* 0x050 */ u16 mAutoMixerPanDolby; // pan is upper 8 bits, dolby lower 8.
|
||||
/* 0x052 */ u16 mAutoMixerFxMix;
|
||||
/* 0x054 */ u16 mAutoMixerInitVolume;
|
||||
/* 0x056 */ u16 mAutoMixerVolume;
|
||||
/* 0x058 */ u16 mAutoMixerBeenSet;
|
||||
#if !TARGET_PC
|
||||
/* 0x05A */ u8 _unused5[0x060 - 0x05A];
|
||||
/* 0x060 */ short field_0x060; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x062 */ u8 _unused6[0x064 - 0x062];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Samples per ADPCM frame for ADPCM audio. Seems just set to 1 for PCM formats.
|
||||
@@ -149,9 +139,7 @@ namespace JASDsp {
|
||||
/* 0x064 */ u16 mSamplesPerBlock;
|
||||
/* 0x066 */ short field_0x066; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x068 */ u32 mSamplePosition; // Only ever initialized by code, name is guess.
|
||||
#if !TARGET_PC
|
||||
/* 0x06C */ u8 _unused7[0x070 - 0x06C];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Current audio read position in ARAM. Updated by DSP.
|
||||
@@ -163,13 +151,11 @@ namespace JASDsp {
|
||||
* Gets written by DSP, but also CPU.
|
||||
*/
|
||||
/* 0x074 */ u32 mSamplesLeft; // Never directly cleared to zero. Seems sus. Cleared by DSP?
|
||||
#if !TARGET_PC
|
||||
/* 0x078 */ short field_0x078[4]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x080 */ short field_0x080[20]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x0A8 */ short field_0x0a8[4]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x0B0 */ u16 field_0x0b0[16]; // Only cleared to zero, presumed used by DSP.
|
||||
/* 0x0D0 */ u8 _unused8[0x100 - 0x0D0];
|
||||
#endif
|
||||
/* 0x100 */ u16 mBytesPerBlock;
|
||||
/* 0x102 */ u16 mLoopFlag;
|
||||
|
||||
@@ -190,26 +176,9 @@ namespace JASDsp {
|
||||
/* 0x118 */ u32 mWaveAramAddress;
|
||||
/* 0x11C */ int mSampleCount;
|
||||
/* 0x120 */ s16 fir_filter_params[8];
|
||||
#if !TARGET_PC
|
||||
/* 0x130 */ u8 _unused9[0x148 - 0x130];
|
||||
#endif
|
||||
/* 0x148 */ s16 iir_filter_params[8];
|
||||
#if !TARGET_PC
|
||||
/* 0x158 */ u8 _unused10[0x180 - 0x158];
|
||||
#endif
|
||||
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* Memory address at which this sound effect should consider ARAM to start.
|
||||
* This means fields like mWaveAramAddress will be relative to this pointer instead.
|
||||
*
|
||||
* By changing this, sound effects can effectively be played back from anywhere in memory,
|
||||
* rather than just the emulated ARAM space.
|
||||
*
|
||||
* If nullptr, the regular emulated ARAM is used.
|
||||
*/
|
||||
void const* mAramBaseAddress;
|
||||
#endif
|
||||
};
|
||||
|
||||
void boot(void (*)(void*));
|
||||
|
||||
@@ -10,18 +10,12 @@ struct JASSimpleWaveBank : JASWaveBank, JASWaveArc {
|
||||
intptr_t getWavePtr() const;
|
||||
TWaveHandle();
|
||||
const JASWaveInfo* getWaveInfo() const;
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] void const* getAramBaseAddress() const override { return nullptr; }
|
||||
#endif
|
||||
|
||||
/* 0x04 */ JASWaveInfo mWaveInfo;
|
||||
/* 0x28 */ JASHeap* mHeap;
|
||||
};
|
||||
|
||||
JASSimpleWaveBank(IF_DUSK(u32 bankId));
|
||||
JASSimpleWaveBank();
|
||||
~JASSimpleWaveBank();
|
||||
void setWaveTableSize(u32, JKRHeap*);
|
||||
JASWaveHandle* getWaveHandle(u32) const;
|
||||
|
||||
@@ -26,9 +26,7 @@ public:
|
||||
};
|
||||
|
||||
struct TCtrlWave {
|
||||
// Wave ID in lower half.
|
||||
// Upper bits appear to be group ID, which is unused by the game code.
|
||||
/* 0x0 */ BE(u32) mWaveAndGroupId;
|
||||
/* 0x0 */ BE(u32) _00;
|
||||
};
|
||||
|
||||
struct TWave {
|
||||
@@ -59,14 +57,13 @@ public:
|
||||
};
|
||||
|
||||
struct TCtrl {
|
||||
/* 0x0 */ BE(u32) mMagic; // 'C-DF'.
|
||||
/* 0x0 */ u8 _00[4];
|
||||
/* 0x4 */ BE(u32) mWaveCount;
|
||||
/* 0x8 */ TOffset<TCtrlWave> mCtrlWaveOffsets[0];
|
||||
};
|
||||
|
||||
struct TCtrlScene {
|
||||
/* 0x0 */ BE(u32) mMagic; // 'SCNE'
|
||||
/* 0x4 */ u8 _00[0x8];
|
||||
/* 0x0 */ u8 _00[0xC];
|
||||
/* 0xC */ TOffset<TCtrl> mCtrlOffset;
|
||||
};
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ struct JASWaveArc : JASDisposer {
|
||||
};
|
||||
|
||||
/* 0x04 */ mutable JASHeap mHeap;
|
||||
/* 0x48 */ u32 mCurrentlyLoaded;
|
||||
/* 0x48 */ u32 _48;
|
||||
/* 0x4C */ volatile s32 mStatus;
|
||||
/* 0x50 */ int mEntryNum;
|
||||
/* 0x54 */ u32 mFileLength;
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
#define JASWAVEINFO_H
|
||||
|
||||
#include <types.h>
|
||||
#include <memory>
|
||||
|
||||
#if TARGET_PC
|
||||
struct JASSampleDataReference;
|
||||
#endif
|
||||
|
||||
struct JASWaveArc;
|
||||
|
||||
@@ -22,7 +17,7 @@ struct JASWaveArc;
|
||||
struct JASWaveInfo {
|
||||
JASWaveInfo() {
|
||||
mBaseKey = 0x3c;
|
||||
mpLoaded = &one;
|
||||
field_0x20 = &one;
|
||||
}
|
||||
|
||||
/* 0x00 */ u8 mWaveFormat;
|
||||
@@ -36,7 +31,7 @@ struct JASWaveInfo {
|
||||
/* 0x18 */ int mSampleCount;
|
||||
/* 0x1C */ s16 mpLast;
|
||||
/* 0x1E */ s16 mpPenult;
|
||||
/* 0x20 */ const u32* mpLoaded;
|
||||
/* 0x20 */ const u32* field_0x20;
|
||||
|
||||
static DUSK_GAME_DATA u32 one;
|
||||
};
|
||||
@@ -50,17 +45,6 @@ public:
|
||||
virtual ~JASWaveHandle() {}
|
||||
virtual const JASWaveInfo* getWaveInfo() const = 0;
|
||||
virtual intptr_t getWavePtr() const = 0;
|
||||
#if TARGET_PC
|
||||
/**
|
||||
* @see JASChannel::mAramBaseAddress
|
||||
*/
|
||||
[[nodiscard]] virtual void const* getAramBaseAddress() const = 0;
|
||||
|
||||
/**
|
||||
* Create a @ref JASSampleDataReference to keep the sample data for this wave alive.
|
||||
*/
|
||||
[[nodiscard]] virtual std::unique_ptr<JASSampleDataReference> getSampleReference() const { return nullptr; }
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -69,12 +53,6 @@ public:
|
||||
*/
|
||||
class JASWaveBank {
|
||||
public:
|
||||
#if TARGET_PC
|
||||
const u32 bankId;
|
||||
|
||||
JASWaveBank(u32 bankId) : bankId(bankId) { }
|
||||
#endif
|
||||
|
||||
virtual ~JASWaveBank() {}
|
||||
virtual JASWaveHandle* getWaveHandle(u32) const = 0;
|
||||
virtual JASWaveArc* getWaveArc(u32) = 0;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
struct JAUAudibleParam {
|
||||
f32 getDopplerPower() const {
|
||||
return field_0x0.bytes.mDopplerPower * (1.0f / 15.0f);
|
||||
return field_0x0.bytes.b0_0 * (1.0f / 15.0f);
|
||||
}
|
||||
|
||||
union {
|
||||
@@ -19,18 +19,14 @@ struct JAUAudibleParam {
|
||||
BE(u16) f1;
|
||||
} half;
|
||||
struct {
|
||||
u8 mDopplerPower : 4;
|
||||
u8 mCalculatePriority : 1;
|
||||
u8 mCalcDistanceVolume : 1;
|
||||
u8 mCalcFxMix : 1;
|
||||
u8 mCullAtMaxDistance : 1;
|
||||
u8 mCalcPan : 1;
|
||||
u8 mCalcDolby : 1;
|
||||
/**
|
||||
* Most bits in this field are unused, 8 indicates clamping of volume
|
||||
* to ensure it doesn't go below 0.2 in mixChannelOut()
|
||||
*/
|
||||
u8 mClampMinVolume : 6;
|
||||
u8 b0_0 : 4;
|
||||
u8 b0_4 : 1;
|
||||
u8 b0_5 : 1;
|
||||
u8 b0_6 : 1;
|
||||
u8 b0_7 : 1;
|
||||
u8 b1_0 : 1;
|
||||
u8 b1_1 : 1;
|
||||
u8 b1_2_7 : 6;
|
||||
u8 b2;
|
||||
u8 b3;
|
||||
} bytes;
|
||||
|
||||
@@ -5,162 +5,16 @@
|
||||
#include "JSystem/JAudio2/JASGadget.h"
|
||||
#include "helpers/endian.h"
|
||||
|
||||
// Constants for TypeIDs of JAUSoundTable entries.
|
||||
|
||||
/**
|
||||
* Used as a test to see if the type ID is valid. All other type IDs contain this bit.
|
||||
*/
|
||||
#define SOUND_TYPEID_VALID 0x40
|
||||
|
||||
/**
|
||||
* Sound is a sound effect.
|
||||
*/
|
||||
#define SOUND_TYPEID_SOUND_EFFECT 0x51
|
||||
|
||||
/**
|
||||
* Sound is a music sequence.
|
||||
*/
|
||||
#define SOUND_TYPEID_SEQUENCE 0x60
|
||||
|
||||
/**
|
||||
* Sound is a streamed music file.
|
||||
*/
|
||||
#define SOUND_TYPEID_STREAM 0x70
|
||||
|
||||
/**
|
||||
* Sound is a streamed music file. Unsure of difference from SOUND_TYPEID_STREAM
|
||||
*/
|
||||
#define SOUND_TYPEID_STREAM_ALT 0x71
|
||||
|
||||
//
|
||||
// Values for mSwBit on sound effect items.
|
||||
//
|
||||
|
||||
/**
|
||||
* Sound is always calculated as max priority (0).
|
||||
*/
|
||||
#define SOUND_SW_ALWAYS_MAX_PRIORITY 0x0000'0001
|
||||
|
||||
/**
|
||||
* Don't calculate volume by distance.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_DISTANCE_VOL 0x0000'0002
|
||||
|
||||
/**
|
||||
* Don't calculate FX mix (reverb) by distance.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_FX_MIX 0x0000'0004
|
||||
|
||||
/**
|
||||
* Offset to shift to access @see SOUND_SW_RANDOM_PITCH_MASK
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_PITCH_OFFSET 4
|
||||
|
||||
/**
|
||||
* 4-bit value (0-15) to control the power of pitch randomization on sound playback.
|
||||
* Code acts different for values above 8, not sure what the exact implication is.
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_PITCH_MASK 0x0000'00F0
|
||||
|
||||
/**
|
||||
* Offset to shift to access @see SOUND_SW_DOPPLER_POWER_MASK
|
||||
*/
|
||||
#define SOUND_SW_DOPPLER_POWER_OFFSET 8
|
||||
|
||||
/**
|
||||
* 4-bit value (0-15) to scale the power of the Doppler effect for this sound.
|
||||
*/
|
||||
#define SOUND_SW_DOPPLER_POWER_MASK 0x0000'0F00
|
||||
|
||||
/**
|
||||
* Don't calculate panning (left/right) values for this sound.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_PAN 0x0000'1000
|
||||
|
||||
/**
|
||||
* Don't calculate Dolby (behind/front) values for this sound.
|
||||
*/
|
||||
#define SOUND_SW_IGNORE_DOLBY 0x0000'2000
|
||||
|
||||
/**
|
||||
* 3-bit mask used to select a volume distance/falloff class for this sound.
|
||||
*/
|
||||
#define SOUND_SW_VOL_DIST_BIT_MASK 0x0007'0000
|
||||
|
||||
/**
|
||||
* Limit minimum volume of this sound (after distance falloff) to 0.2.
|
||||
*/
|
||||
#define SOUND_SW_CLAMP_MIN_VOLUME 0x0008'0000
|
||||
|
||||
/**
|
||||
* 3-bit mask used to select a *different* volume distance/falloff class for this sound.
|
||||
* @see SOUND_SW_VOL_DIST_BIT_MASK must be zero for this to work.
|
||||
*/
|
||||
#define SOUND_SW_VOL_DIST_BIT_2_MASK 0x0070'0000
|
||||
|
||||
/**
|
||||
* Mark sound as "far away" or "culled" when at max distance (selected by distance class).
|
||||
* This affects a bunch of stuff like culling, automatic stopping, priorities, etc.
|
||||
*/
|
||||
#define SOUND_SW_CULL_AT_MAX_DISTANCE 0x0080'0000
|
||||
|
||||
/**
|
||||
* Not sure what this does.
|
||||
* Something causing volume/pan/dolby adjustment in Z2Audible::setOuterParams?
|
||||
*/
|
||||
#define SOUND_SW_VOL_SOMETHING_MASK 0x0F00'0000
|
||||
|
||||
/**
|
||||
* Offset to shift to access @see SOUND_SW_RANDOM_VOLUME_MASK
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_VOLUME_OFFSET 28
|
||||
|
||||
/**
|
||||
* 4-bit value (0-15) to control the power of volume randomization on sound playback.
|
||||
*/
|
||||
#define SOUND_SW_RANDOM_VOLUME_MASK 0xF000'0000
|
||||
|
||||
#define SOUND_VOL_DIST_BIT_MASK_SHIFTED (SOUND_SW_VOL_DIST_BIT_MASK >> 16)
|
||||
#define SOUND_VOL_DIST_BIT_2_MASK_SHIFTED (SOUND_SW_VOL_DIST_BIT_2_MASK >> 16)
|
||||
#define SOUND_VOL_SOMETHING_MASK_SHIFTED (SOUND_SW_VOL_SOMETHING_MASK >> 16)
|
||||
|
||||
/**
|
||||
* @ingroup jsystem-jaudio
|
||||
* A single entry in the sound table.
|
||||
* Fields are interpreted differently depending on the type ID of the entry,
|
||||
* which is not stored in this struct.
|
||||
*
|
||||
*/
|
||||
struct JAUSoundTableItem {
|
||||
u8 mPriority;
|
||||
u8 mVolume;
|
||||
union {
|
||||
/**
|
||||
* For music sequences: the resource ID of the sequence.
|
||||
*/
|
||||
BE(u16) mResourceId;
|
||||
|
||||
/**
|
||||
* For streamed music: bitpacked channel configuration.
|
||||
*/
|
||||
BE(u16) mStreamPanParameters;
|
||||
};
|
||||
union {
|
||||
/**
|
||||
* For sound effects: bitpacked field controlling a *bunch* of audio parameters.
|
||||
*/
|
||||
BE(u32) mSwBit;
|
||||
|
||||
/**
|
||||
* For streamed music: offset (relative to start of BST)
|
||||
* to null-terminated string containing music file path.
|
||||
*/
|
||||
BE(u32) mStreamFilePath;
|
||||
};
|
||||
|
||||
/**
|
||||
* For sound effects: pitch multiplier.
|
||||
*/
|
||||
BE(f32) mPitch;
|
||||
u8 field_0x1;
|
||||
BE(u16) mResourceId;
|
||||
BE(u32) field_0x4;
|
||||
BE(f32) field_0x8;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -170,25 +24,23 @@ struct JAUSoundTableItem {
|
||||
template<typename Root, typename Section, typename Group, typename Typename_0>
|
||||
struct JAUSoundTable_ {
|
||||
JAUSoundTable_() {
|
||||
mData = NULL;
|
||||
mRoot = 0;
|
||||
field_0x0 = NULL;
|
||||
field_0x4 = 0;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
mData = NULL;
|
||||
mRoot = NULL;
|
||||
field_0x0 = NULL;
|
||||
field_0x4 = NULL;
|
||||
}
|
||||
|
||||
void init(const void* dataStart) {
|
||||
mData = dataStart;
|
||||
void init(const void* param_0) {
|
||||
field_0x0 = param_0;
|
||||
// magic number is not in debug rom. I'm not sure what this comparison is (maybe some sort of '' number?)
|
||||
// I also do not know how it is different between JAUSoundTable and JAUSoundNameTable
|
||||
// Future person here: This is checking for either "BST " or "BSTN", with the second two letters in Root::magicNumber().
|
||||
// Idk why the operations here are all weird but I can't use objdiff right now.
|
||||
if (*(BE(u32)*)mData + 0xbdad0000 != Root::magicNumber()) {
|
||||
mData = NULL;
|
||||
if (*(BE(u32)*)field_0x0 + 0xbdad0000 != Root::magicNumber()) {
|
||||
field_0x0 = NULL;
|
||||
} else {
|
||||
mRoot = (Root*)((u8*)mData + *((BE(u32)*)mData + 3));
|
||||
field_0x4 = (Root*)((u8*)field_0x0 + *((BE(u32)*)field_0x0 + 3));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,34 +48,34 @@ struct JAUSoundTable_ {
|
||||
if (index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if ((u32)index >= mRoot->mSectionNumber) {
|
||||
if ((u32)index >= field_0x4->mSectionNumber) {
|
||||
return NULL;
|
||||
}
|
||||
u32 offset = mRoot->mSectionOffsets[index];
|
||||
u32 offset = field_0x4->mSectionOffsets[index];
|
||||
if (offset == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return (Section*)((u8*)mData + offset);
|
||||
return (Section*)((u8*)field_0x0 + offset);
|
||||
}
|
||||
|
||||
Group* getGroup(Section* section, int index) const {
|
||||
Group* getGroup(Section* param_1, int index) const {
|
||||
int iVar1;
|
||||
|
||||
if (index < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if ((u32)index >= section->mNumGroups) {
|
||||
if ((u32)index >= param_1->mNumGroups) {
|
||||
return NULL;
|
||||
}
|
||||
u32 offset = section->getGroupOffset(index);
|
||||
u32 offset = param_1->getGroupOffset(index);
|
||||
if (offset == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return (Group*)((u8*)mData + offset);
|
||||
return (Group*)((u8*)field_0x0 + offset);
|
||||
}
|
||||
|
||||
const void* mData;
|
||||
Root* mRoot;
|
||||
const void* field_0x0;
|
||||
Root* field_0x4;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -231,7 +83,7 @@ struct JAUSoundTable_ {
|
||||
*
|
||||
*/
|
||||
struct JAUSoundTableRoot {
|
||||
static inline u32 magicNumber() { return 'T '; } // Second half of "BST "
|
||||
static inline u32 magicNumber() { return 0x5420; }
|
||||
BE(u32) mSectionNumber;
|
||||
BE(u32) mSectionOffsets[0];
|
||||
};
|
||||
@@ -282,7 +134,7 @@ struct JAUSoundTableGroup {
|
||||
|
||||
BE(u32) mNumItems;
|
||||
BE(u32) field_0x4;
|
||||
u8 mTypeIds[0]; // TODO: Should probably be BE(u32), but I can't objdiff rn.
|
||||
u8 mTypeIds[0];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -290,7 +142,7 @@ struct JAUSoundTableGroup {
|
||||
*
|
||||
*/
|
||||
struct JAUSoundTable : public JASGlobalInstance<JAUSoundTable> {
|
||||
JAUSoundTable(bool setInstance) : JASGlobalInstance<JAUSoundTable>(setInstance) {
|
||||
JAUSoundTable(bool param_0) : JASGlobalInstance<JAUSoundTable>(param_0) {
|
||||
}
|
||||
~JAUSoundTable() {}
|
||||
|
||||
@@ -305,11 +157,11 @@ struct JAUSoundTable : public JASGlobalInstance<JAUSoundTable> {
|
||||
if (offset == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return (JAUSoundTableItem*)((u8*)field_0x0.mData + offset);
|
||||
return (JAUSoundTableItem*)((u8*)field_0x0.field_0x0 + offset);
|
||||
}
|
||||
|
||||
const void* getResource() const { return field_0x0.mData; }
|
||||
bool isValid() const { return field_0x0.mData != NULL; }
|
||||
const void* getResource() const { return field_0x0.field_0x0; }
|
||||
bool isValid() const { return field_0x0.field_0x0 != NULL; }
|
||||
|
||||
JAUSoundTable_<JAUSoundTableRoot,JAUSoundTableSection,JAUSoundTableGroup,void> field_0x0;
|
||||
};
|
||||
@@ -319,7 +171,7 @@ struct JAUSoundTable : public JASGlobalInstance<JAUSoundTable> {
|
||||
*
|
||||
*/
|
||||
struct JAUSoundNameTableRoot {
|
||||
static inline u32 magicNumber() { return 'TN'; } // Second half of "BSTN"
|
||||
static inline u32 magicNumber() { return 0x544e; }
|
||||
BE(u32) mSectionNumber;
|
||||
BE(u32) mSectionOffsets[0];
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ void JAISe::JAISeCategoryMgr_mixOut_(bool param_0, const JASSoundParams& params,
|
||||
if (inner_.field_0x26c) {
|
||||
switch (inner_.track.getStatus()) {
|
||||
case JASTrack::STATUS_STOPPED:
|
||||
if (status_.field_0x1.flags.mComesBack) {
|
||||
if (status_.field_0x1.flags.flag1) {
|
||||
startTrack_(params);
|
||||
} else {
|
||||
stop_JAISound_();
|
||||
@@ -84,8 +84,8 @@ void JAISe::JAISeCategoryMgr_mixOut_(bool param_0, const JASSoundParams& params,
|
||||
startTrack_(params);
|
||||
}
|
||||
}
|
||||
} else if (status_.field_0x1.flags.mComesBack) {
|
||||
if (status_.field_0x1.flags.mPauseWhenOut) {
|
||||
} else if (status_.field_0x1.flags.flag1) {
|
||||
if (status_.field_0x1.flags.flag3) {
|
||||
inner_.track.pause(true);
|
||||
} else {
|
||||
stopTrack_();
|
||||
|
||||
@@ -167,7 +167,7 @@ JAISeMgr::JAISeMgr(bool setInstance) : JASGlobalInstance<JAISeMgr>(setInstance)
|
||||
}
|
||||
|
||||
bool JAISeMgr::isUsingSeqData(const JAISeqDataRegion& seqDataRegion) {
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (mCategoryMgrs[i].JAISeCategoryMgr::isUsingSeqData(seqDataRegion)) {
|
||||
return true;
|
||||
}
|
||||
@@ -177,7 +177,7 @@ bool JAISeMgr::isUsingSeqData(const JAISeqDataRegion& seqDataRegion) {
|
||||
|
||||
int JAISeMgr::releaseSeqData(const JAISeqDataRegion& seqDataRegion) {
|
||||
bool r30 = 0;
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
switch (mCategoryMgrs[i].JAISeCategoryMgr::releaseSeqData(seqDataRegion)) {
|
||||
case 0:
|
||||
return 0;
|
||||
@@ -191,14 +191,14 @@ int JAISeMgr::releaseSeqData(const JAISeqDataRegion& seqDataRegion) {
|
||||
}
|
||||
|
||||
void JAISeMgr::setCategoryArrangement(const JAISeCategoryArrangement& arrangement) {
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mCategoryMgrs[i].setMaxActiveSe(arrangement.mItems[i].mMaxActiveSe);
|
||||
mCategoryMgrs[i].setMaxInactiveSe(arrangement.mItems[i].mMaxInactiveSe);
|
||||
}
|
||||
}
|
||||
|
||||
void JAISeMgr::getCategoryArrangement(JAISeCategoryArrangement* arrangement) {
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
int active = mCategoryMgrs[i].getMaxActiveSe();
|
||||
JUT_ASSERT(299, active <= 255);
|
||||
arrangement->mItems[i].mMaxActiveSe = active;
|
||||
@@ -209,19 +209,19 @@ void JAISeMgr::getCategoryArrangement(JAISeCategoryArrangement* arrangement) {
|
||||
}
|
||||
|
||||
void JAISeMgr::stop() {
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mCategoryMgrs[i].stop();
|
||||
}
|
||||
}
|
||||
|
||||
void JAISeMgr::stopSoundID(JAISoundID id) {
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mCategoryMgrs[i].stopSoundID(id);
|
||||
}
|
||||
}
|
||||
|
||||
void JAISeMgr::initParams() {
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mCategoryMgrs[i].getParams()->init();
|
||||
}
|
||||
}
|
||||
@@ -270,16 +270,16 @@ JAISe* JAISeMgr::newSe_(int category, u32 priority) {
|
||||
|
||||
void JAISeMgr::calc() {
|
||||
mParams.calc();
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mCategoryMgrs[i].JAISeMgr_calc_();
|
||||
}
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mCategoryMgrs[i].JAISeMgr_freeDeadSe_();
|
||||
}
|
||||
}
|
||||
|
||||
void JAISeMgr::mixOut() {
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
mCategoryMgrs[i].JAISeMgr_mixOut_(mParams, mSoundActivity);
|
||||
}
|
||||
}
|
||||
@@ -324,7 +324,7 @@ bool JAISeMgr::startSound(JAISoundID id, JAISoundHandle* handle, const JGeometry
|
||||
|
||||
int JAISeMgr::getNumActiveSe() const {
|
||||
int num = 0;
|
||||
for (int i = 0; i < NUM_CATEGORIES; i++) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
num += mCategoryMgrs[i].getNumSe();
|
||||
}
|
||||
return num;
|
||||
|
||||
@@ -54,9 +54,9 @@ s32 JAISoundStatus_::unlockIfLocked() {
|
||||
}
|
||||
|
||||
void JAISoundParams::mixOutAll(const JASSoundParams& inParams, JASSoundParams* outParams, f32 param_2) {
|
||||
outParams->mVolume = move_.params_.mVolume * (inParams.mVolume * property_.mVolume) * param_2;
|
||||
outParams->mFxMix = move_.params_.mFxMix + (inParams.mFxMix + property_.mFxMix);
|
||||
outParams->mPitch = move_.params_.mPitch * (inParams.mPitch * property_.mPitch);
|
||||
outParams->mVolume = move_.params_.mVolume * (inParams.mVolume * property_.field_0x0) * param_2;
|
||||
outParams->mFxMix = move_.params_.mFxMix + (inParams.mFxMix + property_.field_0x4);
|
||||
outParams->mPitch = move_.params_.mPitch * (inParams.mPitch * property_.field_0x8);
|
||||
outParams->mPan = (inParams.mPan + move_.params_.mPan) - 0.5f;
|
||||
outParams->mDolby = inParams.mDolby + move_.params_.mDolby;
|
||||
}
|
||||
@@ -181,7 +181,7 @@ bool JAISound::calc_JAISound_() {
|
||||
}
|
||||
|
||||
if (audience_ != NULL && audible_ != NULL) {
|
||||
if ((priority_ = audience_->calcPriority(audible_)) == 0xFFFFFFFF && status_.field_0x1.flags.mComesBack == 0) {
|
||||
if ((priority_ = audience_->calcPriority(audible_)) == 0xFFFFFFFF && status_.field_0x1.flags.flag1 == 0) {
|
||||
stop_JAISound_();
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -713,7 +713,7 @@ void JASAramStream::channelStart() {
|
||||
wave_info.mpPenult = 0;
|
||||
// probably a fake match, this should be set in the JASWaveInfo constructor
|
||||
static u32 const one = 1;
|
||||
wave_info.mpLoaded = &one;
|
||||
wave_info.field_0x20 = &one;
|
||||
JASChannel* jc = JKR_NEW JASChannel(channelCallback, this);
|
||||
JUT_ASSERT(963, jc);
|
||||
jc->setPriority(0x7f7f);
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
#include "JSystem/JSystem.h" // IWYU pragma: keep
|
||||
|
||||
#include "JSystem/JAudio2/JASBank.h"
|
||||
|
||||
#include "dusk/mods/svc/audio_res/audio_res.hpp"
|
||||
#include "JSystem/JAudio2/JASAiCtrl.h"
|
||||
#include "JSystem/JAudio2/JASBasicInst.h"
|
||||
#include "JSystem/JAudio2/JASBasicWaveBank.h"
|
||||
#include "JSystem/JAudio2/JASChannel.h"
|
||||
|
||||
using namespace dusk::mods::svc::audio_res;
|
||||
|
||||
// NONMATCHING JASPoolAllocObject_MultiThreaded<_> locations
|
||||
JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8 param_3, u16 param_4,
|
||||
void (*param_5)(u32, JASChannel*, JASDsp::TChannel*, void*),
|
||||
@@ -32,23 +28,12 @@ JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8
|
||||
if (!waveHandle) {
|
||||
return NULL;
|
||||
}
|
||||
#if TARGET_PC
|
||||
auto const key = AudioWaveKey(static_cast<AudioWaveBank>(waveBank->bankId), stack_60.field_0x1a);
|
||||
std::lock_guard lock(s_replacements_mutex);
|
||||
auto const found_replacement = s_replacements.find(key);
|
||||
if (found_replacement != s_replacements.end()) {
|
||||
waveHandle = &found_replacement->second;
|
||||
}
|
||||
|
||||
auto const aramBase = waveHandle->getAramBaseAddress();
|
||||
#endif
|
||||
|
||||
const JASWaveInfo* waveInfo = waveHandle->getWaveInfo();
|
||||
if (!waveInfo) {
|
||||
return NULL;
|
||||
}
|
||||
intptr_t wavePtr = waveHandle->getWavePtr();
|
||||
if (!wavePtr IF_DUSK(&& !aramBase)) {
|
||||
if (!wavePtr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -59,10 +44,6 @@ JASChannel* JASBank::noteOn(JASBank const* param_0, int param_1, u8 param_2, u8
|
||||
channel->setPriority(param_4);
|
||||
channel->field_0xdc.mWaveInfo = *waveInfo;
|
||||
channel->mWaveAramAddress = wavePtr;
|
||||
#if TARGET_PC
|
||||
channel->mAramBaseAddress = aramBase;
|
||||
channel->mSampleReference = waveHandle->getSampleReference();
|
||||
#endif
|
||||
channel->field_0xdc.mChannelType = stack_60.field_0x1c;
|
||||
channel->setBankDisposeID(param_0);
|
||||
channel->setInitPitch(stack_60.mPitch * (waveInfo->mSampleRate / JASDriver::getDacRate()));
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include <stdint.h>
|
||||
|
||||
JASBasicWaveBank::JASBasicWaveBank(IF_DUSK(u32 bankId)) IF_DUSK(: JASWaveBank(bankId)) {
|
||||
JASBasicWaveBank::JASBasicWaveBank() {
|
||||
mWaveTable = NULL;
|
||||
mWaveGroupArray = NULL;
|
||||
mHandleCount = 0;
|
||||
mGroupCount = 0;
|
||||
OSInitMutex(&mWaveTableMutex);
|
||||
OSInitMutex(&field_0x4);
|
||||
}
|
||||
|
||||
JASBasicWaveBank::~JASBasicWaveBank() {
|
||||
@@ -44,13 +44,13 @@ void JASBasicWaveBank::setWaveTableSize(u32 param_0, JKRHeap* param_1) {
|
||||
}
|
||||
|
||||
void JASBasicWaveBank::incWaveTable(JASBasicWaveBank::TWaveGroup const* param_0) {
|
||||
JASMutexLock lock(&mWaveTableMutex);
|
||||
JASMutexLock lock(&field_0x4);
|
||||
for (u32 i = 0; i < param_0->getWaveCount(); i++) {
|
||||
TWaveHandle* handle = mWaveTable + param_0->getWaveID(i);
|
||||
if (!handle->mHeap) {
|
||||
handle->mHeap = ¶m_0->mHeap;
|
||||
handle->mWaveInfo.mpLoaded = ¶m_0->mCurrentlyLoaded;
|
||||
handle->mWaveInfo.mOffsetStart = param_0->mCtrlWaveArray[i].mOffsetStart;
|
||||
handle->field_0x4.field_0x20 = ¶m_0->_48;
|
||||
handle->field_0x4.mOffsetStart = param_0->mCtrlWaveArray[i].field_0x4;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,13 +58,13 @@ void JASBasicWaveBank::incWaveTable(JASBasicWaveBank::TWaveGroup const* param_0)
|
||||
DUSK_GAME_DATA u32 JASBasicWaveBank::mNoLoad;
|
||||
|
||||
void JASBasicWaveBank::decWaveTable(JASBasicWaveBank::TWaveGroup const* param_0) {
|
||||
JASMutexLock lock(&mWaveTableMutex);
|
||||
JASMutexLock lock(&field_0x4);
|
||||
for (u32 i = 0; i < param_0->getWaveCount(); i++) {
|
||||
TWaveHandle* handle = mWaveTable + param_0->getWaveID(i);
|
||||
if (handle->mHeap == ¶m_0->mHeap) {
|
||||
handle->mHeap = NULL;
|
||||
handle->mWaveInfo.mpLoaded = &mNoLoad;
|
||||
handle->mWaveInfo.mOffsetStart = -1;
|
||||
handle->field_0x4.field_0x20 = &mNoLoad;
|
||||
handle->field_0x4.mOffsetStart = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,15 +80,15 @@ JASWaveHandle* JASBasicWaveBank::getWaveHandle(u32 param_0) const {
|
||||
}
|
||||
|
||||
void JASBasicWaveBank::setWaveInfo(JASBasicWaveBank::TWaveGroup* wgrp, int index,
|
||||
u16 waveId, JASWaveInfo const& param_3) {
|
||||
u16 param_2, JASWaveInfo const& param_3) {
|
||||
JUT_ASSERT(204, wgrp);
|
||||
JUT_ASSERT(205, index < wgrp->mWaveCount);
|
||||
JUT_ASSERT(206, index >= 0);
|
||||
mWaveTable[waveId].mWaveInfo = param_3;
|
||||
mWaveTable[waveId].mWaveInfo.mpLoaded = &mNoLoad;
|
||||
mWaveTable[waveId].mWaveInfo.mOffsetStart = -1;
|
||||
wgrp->mCtrlWaveArray[index].waveId = waveId;
|
||||
wgrp->mCtrlWaveArray[index].mOffsetStart = param_3.mOffsetStart;
|
||||
mWaveTable[param_2].field_0x4 = param_3;
|
||||
mWaveTable[param_2].field_0x4.field_0x20 = &mNoLoad;
|
||||
mWaveTable[param_2].field_0x4.mOffsetStart = -1;
|
||||
wgrp->mCtrlWaveArray[index].field_0x0 = param_2;
|
||||
wgrp->mCtrlWaveArray[index].field_0x4 = param_3.mOffsetStart;
|
||||
}
|
||||
|
||||
JASBasicWaveBank::TWaveGroup::TWaveGroup() {
|
||||
@@ -122,7 +122,7 @@ void JASBasicWaveBank::TWaveGroup::onEraseDone() {
|
||||
u32 JASBasicWaveBank::TWaveGroup::getWaveID(int index) const {
|
||||
JUT_ASSERT(298, index < mWaveCount);
|
||||
JUT_ASSERT(299, index >= 0);
|
||||
return mCtrlWaveArray[index].waveId;
|
||||
return mCtrlWaveArray[index].field_0x0;
|
||||
}
|
||||
|
||||
intptr_t JASBasicWaveBank::TWaveHandle::getWavePtr() const {
|
||||
@@ -131,5 +131,5 @@ intptr_t JASBasicWaveBank::TWaveHandle::getWavePtr() const {
|
||||
if (base == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (intptr_t)base + mWaveInfo.mOffsetStart;
|
||||
return (intptr_t)base + field_0x4.mOffsetStart;
|
||||
}
|
||||
|
||||
@@ -26,9 +26,6 @@ JASChannel::JASChannel(Callback i_callback, void* i_callbackData) :
|
||||
mCallback(i_callback),
|
||||
mCallbackData(i_callbackData),
|
||||
mUpdateTimer(0),
|
||||
#if TARGET_PC
|
||||
mAramBaseAddress(nullptr),
|
||||
#endif
|
||||
mBankDisposeID(NULL),
|
||||
mKey(0),
|
||||
mVelocity(0x7f),
|
||||
@@ -240,7 +237,7 @@ s32 JASChannel::initialUpdateDSPChannel(JASDsp::TChannel* i_channel) {
|
||||
mCallback(CB_START, this, i_channel, mCallbackData);
|
||||
}
|
||||
|
||||
if (field_0xdc.mWaveInfo.mpLoaded[0] == 0) {
|
||||
if (field_0xdc.mWaveInfo.field_0x20[0] == 0) {
|
||||
JUT_WARN_DEVICE(346, 2, "%s", "Lost wave data while playing");
|
||||
mDspCh->free();
|
||||
mDspCh = NULL;
|
||||
@@ -259,9 +256,6 @@ s32 JASChannel::initialUpdateDSPChannel(JASDsp::TChannel* i_channel) {
|
||||
switch (field_0xdc.mChannelType) {
|
||||
case 0:
|
||||
i_channel->setWaveInfo(field_0xdc.mWaveInfo, mWaveAramAddress, mSkipSamples);
|
||||
#if TARGET_PC
|
||||
i_channel->mAramBaseAddress = mAramBaseAddress;
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
i_channel->setOscInfo(mOscillatorSomething);
|
||||
@@ -321,7 +315,7 @@ s32 JASChannel::updateDSPChannel(JASDsp::TChannel* i_channel) {
|
||||
mCallback(CB_PLAY, this, i_channel, mCallbackData);
|
||||
}
|
||||
|
||||
if (field_0xdc.mWaveInfo.mpLoaded[0] == 0) {
|
||||
if (field_0xdc.mWaveInfo.field_0x20[0] == 0) {
|
||||
JUT_WARN_DEVICE(456, 2, "%s","Lost wave data while playing");
|
||||
mDspCh->free();
|
||||
mDspCh = NULL;
|
||||
|
||||
@@ -523,12 +523,9 @@ void JASDsp::TChannel::init() {
|
||||
void JASDsp::TChannel::playStart() {
|
||||
JUT_ASSERT(508, dspMutex);
|
||||
field_0x10c = 0;
|
||||
#if !TARGET_PC
|
||||
field_0x060 = 0;
|
||||
#endif
|
||||
mResetFlag = 1;
|
||||
field_0x066 = 0;
|
||||
#if !TARGET_PC
|
||||
int i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
field_0x078[i] = 0;
|
||||
@@ -537,7 +534,6 @@ void JASDsp::TChannel::playStart() {
|
||||
for (i = 0; i < 20; i++) {
|
||||
field_0x080[i] = 0;
|
||||
}
|
||||
#endif
|
||||
mIsActive = 1;
|
||||
}
|
||||
|
||||
@@ -605,11 +601,9 @@ void JASDsp::TChannel::setWaveInfo(JASWaveInfo const& waveInfo, u32 aramAddress,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if !TARGET_PC
|
||||
for (i = 0; i < 16; i++) {
|
||||
field_0x0b0[i] = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "JSystem/JAudio2/JASSimpleWaveBank.h"
|
||||
#include <stdint.h>
|
||||
|
||||
JASSimpleWaveBank::JASSimpleWaveBank(IF_DUSK(u32 bankId)) IF_DUSK(: JASWaveBank(bankId)) {
|
||||
JASSimpleWaveBank::JASSimpleWaveBank() {
|
||||
mWaveTable = NULL;
|
||||
mWaveTableSize = 0;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ JASWaveHandle* JASSimpleWaveBank::getWaveHandle(u32 no) const {
|
||||
|
||||
void JASSimpleWaveBank::setWaveInfo(u32 no, JASWaveInfo const& waveInfo) {
|
||||
mWaveTable[no].mWaveInfo = waveInfo;
|
||||
mWaveTable[no].mWaveInfo.mpLoaded = &mCurrentlyLoaded;
|
||||
mWaveTable[no].mWaveInfo.field_0x20 = &_48;
|
||||
mWaveTable[no].mHeap = &mHeap;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ JASBasicWaveBank* JASWSParser::createBasicWaveBank(void const* stream, JKRHeap*
|
||||
u32 free_size = heap->getFreeSize();
|
||||
|
||||
THeader* header = (THeader*)stream;
|
||||
JASBasicWaveBank* wave_bank = JKR_NEW_ARGS (heap, 0) JASBasicWaveBank IF_DUSK((header->mId));
|
||||
JASBasicWaveBank* wave_bank = JKR_NEW_ARGS (heap, 0) JASBasicWaveBank;
|
||||
if (wave_bank == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ JASBasicWaveBank* JASWSParser::createBasicWaveBank(void const* stream, JKRHeap*
|
||||
wave_info.mpLast = wave->mpLast;
|
||||
wave_info.mpPenult = wave->mpPenult;
|
||||
TCtrlWave* ctrl_wave = ctrl->mCtrlWaveOffsets[j].ptr(header);
|
||||
u16 local_74 = JSULoHalf(ctrl_wave->mWaveAndGroupId);
|
||||
u16 local_74 = JSULoHalf(ctrl_wave->_00);
|
||||
wave_bank->setWaveInfo(wave_group, j, local_74, wave_info);
|
||||
}
|
||||
wave_group->setFileName(archive->mFileName);
|
||||
@@ -82,7 +82,7 @@ JASSimpleWaveBank* JASWSParser::createSimpleWaveBank(void const* stream, JKRHeap
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JASSimpleWaveBank* wave_bank = JKR_NEW_ARGS (heap, 0) JASSimpleWaveBank IF_DUSK((header->mId));
|
||||
JASSimpleWaveBank* wave_bank = JKR_NEW_ARGS (heap, 0) JASSimpleWaveBank;
|
||||
if (wave_bank == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -94,7 +94,7 @@ JASSimpleWaveBank* JASWSParser::createSimpleWaveBank(void const* stream, JKRHeap
|
||||
TWaveArchive* archive = archiveBank->mArchiveOffsets[0].ptr(header);
|
||||
for (int i = 0; i < ctrl->mWaveCount; i++) {
|
||||
TCtrlWave* ctrlWave = ctrl->mCtrlWaveOffsets[i].ptr(header);
|
||||
u32 tmp = JSULoHalf(ctrlWave->mWaveAndGroupId);
|
||||
u32 tmp = JSULoHalf(ctrlWave->_00);
|
||||
if (max < tmp) {
|
||||
max = tmp;
|
||||
}
|
||||
@@ -116,8 +116,8 @@ JASSimpleWaveBank* JASWSParser::createSimpleWaveBank(void const* stream, JKRHeap
|
||||
wave_info.mpLast = wave->mpLast;
|
||||
wave_info.mpPenult = wave->mpPenult;
|
||||
TCtrlWave* ctrl_wave = ctrl->mCtrlWaveOffsets[i].ptr(header);
|
||||
u32 waveId = JSULoHalf(ctrl_wave->mWaveAndGroupId);
|
||||
wave_bank->setWaveInfo(waveId, wave_info);
|
||||
u32 tmp = JSULoHalf(ctrl_wave->_00);
|
||||
wave_bank->setWaveInfo(tmp, wave_info);
|
||||
}
|
||||
wave_bank->setFileName(archive->mFileName);
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ char* JASWaveArcLoader::getCurrentDir() {
|
||||
}
|
||||
|
||||
JASWaveArc::JASWaveArc() : mHeap(this) {
|
||||
mCurrentlyLoaded = 0;
|
||||
_48 = 0;
|
||||
mStatus = 0;
|
||||
mEntryNum = -1;
|
||||
mFileLength = 0;
|
||||
@@ -57,7 +57,7 @@ bool JASWaveArc::loadSetup(u32 param_0) {
|
||||
if (mStatus != 1) {
|
||||
return false;
|
||||
}
|
||||
mCurrentlyLoaded = 1;
|
||||
_48 = 1;
|
||||
mStatus = 2;
|
||||
return true;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ bool JASWaveArc::eraseSetup() {
|
||||
mStatus = 0;
|
||||
return false;
|
||||
}
|
||||
mCurrentlyLoaded = 0;
|
||||
_48 = 0;
|
||||
mStatus = 0;
|
||||
return true;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ void JASWaveArc::loadToAramCallback(void* this_) {
|
||||
|
||||
bool JASWaveArc::sendLoadCmd() {
|
||||
JASMutexLock mutexLock(&mMutex);
|
||||
mCurrentlyLoaded = 0;
|
||||
_48 = 0;
|
||||
mStatus = 1;
|
||||
loadToAramCallbackParams commandInfo;
|
||||
commandInfo.mWavArc = this;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
project(audio_mod CXX)
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(DUSK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../.." CACHE PATH "Path to dusk source root")
|
||||
option(DUSK_MOD_USE_FULL_TREE "Use full build instead of the minimal mod SDK" OFF)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
if (DUSK_MOD_USE_FULL_TREE)
|
||||
add_subdirectory("${DUSK_DIR}" dusk EXCLUDE_FROM_ALL)
|
||||
else ()
|
||||
add_subdirectory("${DUSK_DIR}/sdk" dusk-sdk EXCLUDE_FROM_ALL)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
add_mod(audio_mod
|
||||
SOURCES src/mod.cpp
|
||||
MOD_JSON mod.json
|
||||
RES_DIR res
|
||||
)
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"id": "dev.twilitrealm.audio_mod",
|
||||
"name": "[DEMO] Audio Mod",
|
||||
"version": "1.0.0",
|
||||
"author": "You, the listener",
|
||||
"description": "An example Dusklight mod"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
go.opus and go.wav are licensed CC0, from https://kenney.nl/assets/voiceover-pack
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,39 +0,0 @@
|
||||
#include "mods/service.hpp"
|
||||
#include "mods/svc/audio_res.h"
|
||||
#include "mods/svc/log.h"
|
||||
|
||||
DEFINE_MOD();
|
||||
IMPORT_SERVICE(LogService, svc_log);
|
||||
IMPORT_SERVICE(AudioResService, svc_audio_res);
|
||||
|
||||
extern "C" {
|
||||
|
||||
MOD_EXPORT ModResult mod_initialize(ModError*) {
|
||||
svc_log->info(mod_ctx, "template_mod initialized");
|
||||
AudioWaveHandle handle;
|
||||
svc_audio_res->replace_wave(
|
||||
mod_ctx,
|
||||
SoundEffects,
|
||||
4238,
|
||||
"res/go.opus",
|
||||
nullptr,
|
||||
&handle);
|
||||
svc_audio_res->replace_wave(
|
||||
mod_ctx,
|
||||
SoundEffects,
|
||||
4237,
|
||||
"res/go.opus",
|
||||
nullptr,
|
||||
&handle);
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_update(ModError*) {
|
||||
return MOD_OK;
|
||||
}
|
||||
|
||||
MOD_EXPORT ModResult mod_shutdown(ModError*) {
|
||||
svc_log->info(mod_ctx, "template_mod unloaded");
|
||||
return MOD_OK;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
project(randomizer CXX)
|
||||
|
||||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||
set(DUSK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../.." CACHE PATH "Path to dusk source root")
|
||||
option(DUSK_MOD_USE_FULL_TREE "Use full build instead of the minimal mod SDK" OFF)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
if (DUSK_MOD_USE_FULL_TREE)
|
||||
add_subdirectory("${DUSK_DIR}" dusk EXCLUDE_FROM_ALL)
|
||||
else ()
|
||||
add_subdirectory("${DUSK_DIR}/sdk" dusk-sdk EXCLUDE_FROM_ALL)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Generator dependencies, linked statically into the mod library (no CRT crossing).
|
||||
include(FetchContent)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(YAML_CPP_BUILD_TOOLS OFF CACHE BOOL "" FORCE)
|
||||
set(YAML_CPP_BUILD_CONTRIB OFF CACHE BOOL "" FORCE)
|
||||
set(YAML_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
|
||||
message(STATUS "randomizer: Fetching yaml-cpp")
|
||||
FetchContent_Declare(
|
||||
yaml-cpp
|
||||
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
|
||||
GIT_TAG yaml-cpp-0.9.0
|
||||
)
|
||||
message(STATUS "randomizer: Fetching base64pp")
|
||||
FetchContent_Declare(
|
||||
base64pp
|
||||
GIT_REPOSITORY https://github.com/matheusgomes28/base64pp.git
|
||||
GIT_TAG v0.2.0-rc0
|
||||
)
|
||||
|
||||
message(STATUS "randomizer: Fetching battery-embed")
|
||||
FetchContent_Declare(
|
||||
battery-embed
|
||||
GIT_REPOSITORY https://github.com/batterycenter/embed.git
|
||||
GIT_TAG fdbae3f
|
||||
)
|
||||
|
||||
FetchContent_MakeAvailable(yaml-cpp base64pp battery-embed)
|
||||
|
||||
set(RANDOMIZER_GENERATOR_SOURCES
|
||||
generator/logic/area.cpp
|
||||
generator/logic/dungeon.cpp
|
||||
generator/logic/entrance.cpp
|
||||
generator/logic/entrance_shuffle.cpp
|
||||
generator/logic/fill.cpp
|
||||
generator/logic/flatten/bits.cpp
|
||||
generator/logic/flatten/flatten.cpp
|
||||
generator/logic/flatten/simplify_algebraic.cpp
|
||||
generator/logic/hints.cpp
|
||||
generator/logic/item.cpp
|
||||
generator/logic/item_pool.cpp
|
||||
generator/logic/location.cpp
|
||||
generator/logic/plandomizer.cpp
|
||||
generator/logic/requirement.cpp
|
||||
generator/logic/search.cpp
|
||||
generator/logic/spoiler_log.cpp
|
||||
generator/logic/world.cpp
|
||||
generator/randomizer.cpp
|
||||
generator/seedgen/config.cpp
|
||||
generator/seedgen/seed.cpp
|
||||
generator/seedgen/settings.cpp
|
||||
generator/utility/color.cpp
|
||||
generator/utility/common.cpp
|
||||
generator/utility/endian.cpp
|
||||
generator/utility/file.cpp
|
||||
generator/utility/log.cpp
|
||||
generator/utility/path.cpp
|
||||
generator/utility/platform.cpp
|
||||
generator/utility/random.cpp
|
||||
generator/utility/string.cpp
|
||||
generator/utility/text.cpp
|
||||
generator/utility/time.cpp
|
||||
)
|
||||
|
||||
set(RANDOMIZER_SOURCES
|
||||
src/flags.cpp
|
||||
src/messages.cpp
|
||||
src/randomizer_context.cpp
|
||||
src/stages.cpp
|
||||
src/tools.cpp
|
||||
src/verify_item_functions.cpp
|
||||
src/paths.cpp
|
||||
src/session.cpp
|
||||
)
|
||||
|
||||
add_mod(randomizer
|
||||
FEATURES game
|
||||
SOURCES src/mod.cpp ${RANDOMIZER_GENERATOR_SOURCES} ${RANDOMIZER_SOURCES}
|
||||
MOD_JSON mod.json
|
||||
RES_DIR res
|
||||
)
|
||||
|
||||
target_link_libraries(randomizer PRIVATE yaml-cpp::yaml-cpp base64pp fmt::fmt)
|
||||
|
||||
string(LENGTH "${CMAKE_CURRENT_SOURCE_DIR}/" RANDOMIZER_SOURCE_PATH_SIZE)
|
||||
target_compile_definitions(randomizer PRIVATE
|
||||
RANDO_DATA_PATH="generator/data/"
|
||||
SOURCE_PATH_SIZE=${RANDOMIZER_SOURCE_PATH_SIZE}
|
||||
)
|
||||
|
||||
# Embed the generator's YAML data into the mod library. Paths are relative to this
|
||||
# directory and must match the RANDO_DATA_PATH-based b::embed<> identifiers in code.
|
||||
file(GLOB_RECURSE RANDOMIZER_DATA RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/generator/data/*")
|
||||
b_embed(randomizer "res/shadow_crystal.bti")
|
||||
foreach (RANDOMIZER_FILE IN LISTS RANDOMIZER_DATA)
|
||||
if (RANDOMIZER_FILE MATCHES "^generator/data/tests")
|
||||
continue()
|
||||
endif ()
|
||||
b_embed(randomizer "${RANDOMIZER_FILE}")
|
||||
endforeach ()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,486 @@
|
||||
# Patches for NPC text flows
|
||||
|
||||
# NOTE: All data is expressed in little endian
|
||||
|
||||
0: # zel_00.bmg
|
||||
# Change the following indices of Midna's flows to jump to our custom choices
|
||||
# instead. These are all the flow jumps that normally determine which "Talk to Midna"
|
||||
# text is displayed.
|
||||
- index:
|
||||
- 0x1
|
||||
- 0x9
|
||||
- 0xC
|
||||
- 0x8F
|
||||
- 0x192
|
||||
- 0x1A4
|
||||
- 0x18F
|
||||
- 0x197
|
||||
- 0x1BC
|
||||
- 0x1C9
|
||||
type: event
|
||||
event: 42
|
||||
parameters: 0x00000000
|
||||
next node index: Custom Midna Call Begin
|
||||
|
||||
#1: # zel_01.bmg
|
||||
2: # zel_02.bmg
|
||||
# Patch Barnes branch to see if you can buy the bomb bag to use
|
||||
# query 54 (custom event check) instead of query 22 (how many bomb bags the player has)
|
||||
- index: 0x47C
|
||||
type: branch
|
||||
num results: 2
|
||||
query: 53
|
||||
parameters: 0x004D
|
||||
next node index: 0x340
|
||||
|
||||
#3: # zel_03.bmg
|
||||
4: # zel_04.bmg - Castle Town
|
||||
# Patch Charlo to check for 100 rupees instead of 30
|
||||
- index: 0x34A
|
||||
type: branch
|
||||
num results: 2
|
||||
query: 6
|
||||
parameters: 0x0064
|
||||
next node index: 0x222
|
||||
# Patch Charlo to take 100 rupees from Link instead of 30
|
||||
- index: 0x34E
|
||||
type: event
|
||||
event: 41
|
||||
parameters: 0x00000064
|
||||
next node index: 0x226
|
||||
# Patch Charlo to add 100 rupees to his counter instead of 30
|
||||
- index: 0x357
|
||||
type: event
|
||||
event: 3
|
||||
parameters: 0x00000064
|
||||
next node index: 0x22B
|
||||
# Patch Malo Mart door person to not check for time of day.
|
||||
# Change from branch node that checks time of day to event node
|
||||
# that does nothing.
|
||||
- index: 0x1A5
|
||||
type: event
|
||||
event: 42
|
||||
parameters: 0x00000000
|
||||
next node index: 0x10C
|
||||
|
||||
5: # zel_05.bmg
|
||||
# Patch Yeta flow to always give the map check even if the player has obtained the Ordon Cheese
|
||||
- index: 0x8
|
||||
type: event
|
||||
event: 42
|
||||
parameters: 0x00000000
|
||||
next node index: 0x8
|
||||
|
||||
# Patch Yeta flow to always give the map check even if the player has obtained the Ordon Cheese
|
||||
- index: 0x5
|
||||
type: event
|
||||
event: 42
|
||||
parameters: 0x00000000
|
||||
next node index: 0x3
|
||||
|
||||
# Patch Gor Liggs to not set the flag for the third key shard
|
||||
# Change event index 17 to event index 42 which does nothing
|
||||
- index: 0x258
|
||||
type: event
|
||||
event: 42
|
||||
parameters: 0x00000000
|
||||
next node index: 0x1AC
|
||||
|
||||
#6: # zel_06.bmg
|
||||
#7: # zel_07.bmg
|
||||
#8: # zel_08.bmg
|
||||
|
||||
# Custom Flow Nodes
|
||||
9:
|
||||
# Start of custom midna call tree. Begin by checking if we can change time
|
||||
# of day to see if we show that choice
|
||||
- name: Custom Midna Call Begin
|
||||
type: branch
|
||||
num results: 2
|
||||
query: 54
|
||||
parameters: 0x0000
|
||||
next node index: 0xFFFF
|
||||
results:
|
||||
- Custom Midna Call 3 Choice Select Setup # Can change time of day
|
||||
- Custom Midna Call 2 Choice Select Setup # Can not change time of day
|
||||
|
||||
#################################################
|
||||
# CUSTOM MIDNA CALL 2 CHOICE FLOW #
|
||||
#################################################
|
||||
|
||||
- name: Custom Midna Call 2 Choice Select Setup
|
||||
type: event
|
||||
event: 13
|
||||
parameters: 0x00000003
|
||||
next node index: Custom Midna Call 2 Choice Intro
|
||||
|
||||
- name: Custom Midna Call 2 Choice Intro
|
||||
type: message
|
||||
inf index: Custom Midna Call Need Something Text
|
||||
next flow index: Custom Midna Call 2 Choice
|
||||
|
||||
- name: Custom Midna Call 2 Choice
|
||||
type: message
|
||||
inf index: Custom Midna Call 2 Choice Text
|
||||
next flow index: Custom Midna Call 2 Choice Branch
|
||||
|
||||
- name: Custom Midna Call 2 Choice Branch
|
||||
type: branch
|
||||
num results: 3
|
||||
query: 35
|
||||
parameters: 0x0000
|
||||
next node index: 0xFFFF
|
||||
results:
|
||||
- Custom Midna Call Hints # Hints
|
||||
- Custom Midna Call Return to Spawn Branch # Return to Spawn
|
||||
- 0xFFFF # (B button pressed)
|
||||
|
||||
#################################################
|
||||
# CUSTOM MIDNA CALL 3 CHOICE FLOW #
|
||||
#################################################
|
||||
|
||||
- name: Custom Midna Call 3 Choice Select Setup
|
||||
type: event
|
||||
event: 13
|
||||
parameters: 0x00000004
|
||||
next node index: Custom Midna Call 3 Choice Intro
|
||||
|
||||
- name: Custom Midna Call 3 Choice Intro
|
||||
type: message
|
||||
inf index: Custom Midna Call Need Something Text
|
||||
next flow index: Custom Midna Call 3 Choice
|
||||
|
||||
- name: Custom Midna Call 3 Choice
|
||||
type: message
|
||||
inf index: Custom Midna Call 3 Choice Text
|
||||
next flow index: Custom Midna Call 3 Choice Branch
|
||||
|
||||
- name: Custom Midna Call 3 Choice Branch
|
||||
type: branch
|
||||
num results: 4
|
||||
query: 36
|
||||
parameters: 0x0000
|
||||
next node index: 0xFFFF
|
||||
results:
|
||||
- Custom Midna Call Hints # Hints
|
||||
- Custom Midna Call Change Time # Change time of day
|
||||
- Custom Midna Call Return to Spawn Branch # Return to Spawn
|
||||
- 0xFFFF # (B button pressed)
|
||||
|
||||
#################################################
|
||||
# CUSTOM MIDNA CALL CHOICE OPTIONS #
|
||||
#################################################
|
||||
|
||||
- name: Custom Midna Call Hints
|
||||
type: message
|
||||
inf index: Custom Midna Call Hints Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Custom Midna Call Change Time
|
||||
type: event
|
||||
event: 44
|
||||
parameters: 0x00000000
|
||||
next node index: 0x116
|
||||
|
||||
- name: Custom Midna Call Return to Spawn Branch
|
||||
type: branch
|
||||
num results: 3
|
||||
query: 55
|
||||
parameters: 0x0000
|
||||
next node index: 0xFFFF
|
||||
results:
|
||||
- Return to Spawn Dungeon Choice Select Setup
|
||||
- Return to Spawn Dungeon No Choice Select Setup
|
||||
- Return to Base Spawn
|
||||
|
||||
#################################################
|
||||
# RETURN TO SPAWN DUNGEON CHOICE FLOW #
|
||||
#################################################
|
||||
|
||||
- name: Return to Spawn Dungeon Choice Select Setup
|
||||
type: event
|
||||
event: 13
|
||||
parameters: 0x00000004
|
||||
next node index: Return to Spawn Dungeon Choice Intro
|
||||
|
||||
- name: Return to Spawn Dungeon Choice Intro
|
||||
type: message
|
||||
inf index: Return to Spawn Dungeon Intro Text
|
||||
next flow index: Return to Spawn Dungeon Choice
|
||||
|
||||
- name: Return to Spawn Dungeon Choice
|
||||
type: message
|
||||
inf index: Return to Spawn Dungeon Choice Text
|
||||
next flow index: Return to Spawn Dungeon Choice Branch
|
||||
|
||||
- name: Return to Spawn Dungeon Choice Branch
|
||||
type: branch
|
||||
num results: 4
|
||||
query: 36
|
||||
parameters: 0x0000
|
||||
next node index: 0xFFFF
|
||||
results:
|
||||
- Return to Dungeon Spawn # Dungeon entrance
|
||||
- 0xFFFF # Nevermind
|
||||
- Return to Base Spawn # Spawn
|
||||
- 0xFFFF # (B button pressed)
|
||||
|
||||
#################################################
|
||||
# RETURN TO SPAWN DUNGEON NO CHOICE FLOW #
|
||||
#################################################
|
||||
|
||||
- name: Return to Spawn Dungeon No Choice Select Setup
|
||||
type: event
|
||||
event: 13
|
||||
parameters: 0x00000003
|
||||
next node index: Return to Spawn Dungeon No Choice Intro
|
||||
|
||||
- name: Return to Spawn Dungeon No Choice Intro
|
||||
type: message
|
||||
inf index: Return to Spawn Dungeon Intro Text
|
||||
next flow index: Return to Spawn No Dungeon Choice
|
||||
|
||||
- name: Return to Spawn Dungeon No Choice
|
||||
type: message
|
||||
inf index: Return to Spawn Dungeon No Choice Text
|
||||
next flow index: Return to Spawn Dungeon No Choice Branch
|
||||
|
||||
- name: Return to Spawn Dungeon No Choice Branch
|
||||
type: branch
|
||||
num results: 3
|
||||
query: 35
|
||||
parameters: 0x0000
|
||||
next node index: 0xFFFF
|
||||
results:
|
||||
- 0xFFFF # Nevermind
|
||||
- Return to Base Spawn # Spawn
|
||||
- 0xFFFF # (B button pressed)
|
||||
|
||||
#################################################
|
||||
# RETURN TO SPAWN EVENTS #
|
||||
#################################################
|
||||
|
||||
# Use custom event index 45 to setup returning to spawn. A non-zero
|
||||
# parameter value indicates to try and use a place override if one
|
||||
# exists for the current stage
|
||||
- name: Return to Dungeon Spawn
|
||||
type: event
|
||||
event: 45
|
||||
parameters: 0x00000001
|
||||
next node index: 0x116
|
||||
|
||||
# Use custom event index 45 to setup returning to spawn. A parameter
|
||||
# value of zero indicates to always return to the starting spawn
|
||||
- name: Return to Base Spawn
|
||||
type: event
|
||||
event: 45
|
||||
parameters: 0x00000000
|
||||
next node index: 0x116
|
||||
|
||||
#################################################
|
||||
# HINT SIGNS #
|
||||
#################################################
|
||||
|
||||
- name: Ordon Hint Sign
|
||||
index: 21100
|
||||
type: message
|
||||
inf index: Ordon Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: South Faron Woods Hint Sign
|
||||
index: 21101
|
||||
type: message
|
||||
inf index: South Faron Woods Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Sacred Grove Hint Sign
|
||||
index: 21102
|
||||
type: message
|
||||
inf index: Sacred Grove Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Faron Field Hint Sign
|
||||
index: 21103
|
||||
type: message
|
||||
inf index: Faron Field Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Kakariko Gorge Hint Sign
|
||||
index: 21104
|
||||
type: message
|
||||
inf index: Kakariko Gorge Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Kakariko Village Hint Sign
|
||||
index: 21105
|
||||
type: message
|
||||
inf index: Kakariko Village Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Kakariko Graveyard Hint Sign
|
||||
index: 21106
|
||||
type: message
|
||||
inf index: Kakariko Graveyard Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Eldin Field Hint Sign
|
||||
index: 21107
|
||||
type: message
|
||||
inf index: Eldin Field Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: North Eldin Field Hint Sign
|
||||
index: 21108
|
||||
type: message
|
||||
inf index: North Eldin Field Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Hidden Village Hint Sign
|
||||
index: 21109
|
||||
type: message
|
||||
inf index: Hidden Village Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Lanayru Field Hint Sign
|
||||
index: 21110
|
||||
type: message
|
||||
inf index: Lanayru Field Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Beside Castle Town Hint Sign
|
||||
index: 21111
|
||||
type: message
|
||||
inf index: Beside Castle Town Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Castle Town Center Hint Sign
|
||||
index: 21112
|
||||
type: message
|
||||
inf index: Castle Town Center Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Outside South Castle Town Hint Sign
|
||||
index: 21113
|
||||
type: message
|
||||
inf index: Outside South Castle Town Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Lake Hylia Bridge Hint Sign
|
||||
index: 21114
|
||||
type: message
|
||||
inf index: Lake Hylia Bridge Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Lake Hylia Hint Sign
|
||||
index: 21115
|
||||
type: message
|
||||
inf index: Lake Hylia Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Lanayru Spring Hint Sign
|
||||
index: 21116
|
||||
type: message
|
||||
inf index: Lanayru Spring Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Lake Lantern Cave Hint Sign
|
||||
index: 21117
|
||||
type: message
|
||||
inf index: Lake Lantern Cave Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Fishing Hole Hint Sign
|
||||
index: 21118
|
||||
type: message
|
||||
inf index: Fishing Hole Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Zoras Domain Hint Sign
|
||||
index: 21119
|
||||
type: message
|
||||
inf index: Zoras Domain Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Snowpeak Hint Sign
|
||||
index: 21120
|
||||
type: message
|
||||
inf index: Snowpeak Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Gerudo Desert Hint Sign
|
||||
index: 21121
|
||||
type: message
|
||||
inf index: Gerudo Desert Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Bulblin Camp Hint Sign
|
||||
index: 21122
|
||||
type: message
|
||||
inf index: Bulblin Camp Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Forest Temple Hint Sign
|
||||
index: 21123
|
||||
type: message
|
||||
inf index: Forest Temple Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Goron Mines Hint Sign
|
||||
index: 21124
|
||||
type: message
|
||||
inf index: Goron Mines Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Lakebed Temple Hint Sign
|
||||
index: 21125
|
||||
type: message
|
||||
inf index: Lakebed Temple Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Arbiters Grounds Hint Sign
|
||||
index: 21126
|
||||
type: message
|
||||
inf index: Arbiters Grounds Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Snowpeak Ruins Hint Sign
|
||||
index: 21127
|
||||
type: message
|
||||
inf index: Snowpeak Ruins Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Temple of Time First Hint Sign
|
||||
index: 21128
|
||||
type: message
|
||||
inf index: Temple of Time First Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Temple of Time Second Hint Sign
|
||||
index: 21129
|
||||
type: message
|
||||
inf index: Temple of Time Second Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: City in the Sky Hint Sign
|
||||
index: 21130
|
||||
type: message
|
||||
inf index: City in the Sky Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Palace of Twilight Hint Sign
|
||||
index: 21131
|
||||
type: message
|
||||
inf index: Palace of Twilight Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Hyrule Castle Hint Sign
|
||||
index: 21132
|
||||
type: message
|
||||
inf index: Hyrule Castle Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
|
||||
- name: Cave of Ordeals Hint Sign
|
||||
index: 21133
|
||||
type: message
|
||||
inf index: Cave of Ordeals Hint Sign Text
|
||||
next flow index: 0xFFFF
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,256 @@
|
||||
# Macros are a way to shorten or make more explicit the logical requirements
|
||||
# for certain things. Macros can be used on logic statements like any item and do
|
||||
# not need any code modifications to run. Simply add them here and they can be used
|
||||
# in the world graph files.
|
||||
|
||||
Can Open Doors: Human_Link
|
||||
Can Climb Ladders: Human_Link
|
||||
Can Climb Vines: Human_Link
|
||||
Can Talk to Humans: Human_Link
|
||||
Can Swing on Monkeys: Human_Link
|
||||
Can Pickup Bomblings: Human_Link
|
||||
Can Pull Lakebed Levers: Human_Link
|
||||
Can Pull Blocks: Human_Link
|
||||
Can Ride Boars: Human_Link
|
||||
Can Summon Hawk: Human_Link
|
||||
Can Talk to Animals: Wolf_Link
|
||||
Can Use Senses: Wolf_Link
|
||||
Can Dig: Wolf_Link
|
||||
Can Howl: Wolf_Link
|
||||
Can Sniff: Wolf_Link
|
||||
Can Midna Jump: Wolf_Link
|
||||
Can Use Tightrope: Wolf_Link
|
||||
Not Twilight: Human_Link or Wolf_Link
|
||||
|
||||
Slingshot: Slingshot and 'Can_Refill_Slingshot_Seeds' and Human_Link
|
||||
Lantern: Lantern and 'Can_Refill_Lantern_Oil' and Human_Link
|
||||
Gale Boomerang: Gale_Boomerang and Human_Link
|
||||
Iron Boots: Iron_Boots and Human_Link
|
||||
Bow: Progressive_Bow and 'Can_Refill_Arrows' and Human_Link
|
||||
Regular Bombs: Bomb_Bag and 'Can_Refill_Regular_Bombs' and Human_Link
|
||||
Water Bombs: Bomb_Bag and 'Can_Refill_Water_Bombs' and Human_Link
|
||||
Bombs: Regular_Bombs or Water_Bombs
|
||||
Bomb Arrows: Bow and Bombs
|
||||
Spinner: Spinner and Human_Link
|
||||
Ball and Chain: Ball_and_Chain and Human_Link
|
||||
Zora Armor: Zora_Armor and Human_Link
|
||||
Magic Armor: Magic_Armor and Human_Link
|
||||
Shield: Hylian_Shield or 'Can_Buy_Wooden_Shield'
|
||||
Bottle: Empty_Bottle and Lantern # Can't empty lantern oil from a bottle until you have the lantern
|
||||
Asheis Sketch: Asheis_Sketch and Human_Link
|
||||
Aurus Memo: Aurus_Memo and Human_Link
|
||||
Renados Letter: Renados_Letter and Human_Link
|
||||
Invoice: Invoice and Human_Link
|
||||
Wooden Statue: Wooden_Statue and Human_Link
|
||||
Ilias Charm: Ilias_Charm and Human_Link
|
||||
|
||||
Fishing Rod: Progressive_Fishing_Rod and Human_Link
|
||||
Coral Earring: count(Progressive_Fishing_Rod, 2) and Human_Link
|
||||
Sword: Progressive_Sword and Human_Link
|
||||
Ordon Sword: count(Progressive_Sword, 2) and Human_Link
|
||||
Master Sword: count(Progressive_Sword, 3) and Human_Link
|
||||
Light Sword: count(Progressive_Sword, 4) and Human_Link
|
||||
Big Quiver: count(Progressive_Bow, 2) and 'Can_Refill_Arrows' and Human_Link
|
||||
Giant Quiver: count(Progressive_Bow, 3) and 'Can_Refill_Arrows' and Human_Link
|
||||
Clawshot: Progressive_Clawshot and Human_Link
|
||||
Double Clawshots: count(Progressive_Clawshot, 2) and Human_Link
|
||||
Dominion Rod: Progressive_Dominion_Rod and Human_Link
|
||||
Restored Dominion Rod: count(Progressive_Dominion_Rod, 2) and Human_Link
|
||||
Big Wallet: Progressive_Wallet
|
||||
Giant Wallet: count(Progressive_Wallet, 2)
|
||||
Collosal Wallet: count(Progressive_Wallet, 3)
|
||||
|
||||
Ending Blow: Sword and Progressive_Hidden_Skill
|
||||
Shield Attack: Shield and count(Progressive_Hidden_Skill, 2)
|
||||
Back Slice: Sword and count(Progressive_Hidden_Skill, 3)
|
||||
Helm Splitter: Sword and Shield_Attack and count(Progressive_Hidden_Skill, 4)
|
||||
Mortal Draw: Sword and count(Progressive_Hidden_Skill, 5)
|
||||
Jump Strike: Sword and count(Progressive_Hidden_Skill, 6)
|
||||
Great Spin: Sword and count(Progressive_Hidden_Skill, 7)
|
||||
|
||||
Can Use Back Slice as Sword: Back_Slice_as_Sword == On and count(Progressive_Hidden_Skill, 3)
|
||||
|
||||
Can Do Niche Stuff: Impossible # TODO: Make settings for all of these
|
||||
Can Do Difficult Combat: Impossible # TODO: Make settings for all of these
|
||||
|
||||
Can Use Hot Spring Water: Bottle and 'Can_Buy_Hot_Spring_Water'
|
||||
Can Use Bottled Fairy: Bottle and 'Fairy_Access'
|
||||
# This will have to change if we allow players to start with less than 3 hearts
|
||||
Can Survive Damage: Logic_Damage_Multiplier != OHKO or Can_Use_Bottled_Fairy
|
||||
Can Survive One Bonk: Bonks_Do_Damage == Off or Can_Survive_Damage
|
||||
Can Survive Two Bonks: Bonks_Do_Damage == Off or Logic_Damage_Multiplier != OHKO or
|
||||
(Can_Use_Bottled_Fairy and count(Empty_Bottle, 2))
|
||||
Can Survive Three Bonks: Bonks_Do_Damage == Off or Logic_Damage_Multiplier != OHKO or
|
||||
(Can_Use_Bottled_Fairy and count(Empty_Bottle, 3))
|
||||
Can Smash: Bombs or Ball_and_Chain
|
||||
Can Break Webs: Lantern or Bombs or (Ball_and_Chain and Ball_and_Chain_Webs == On)
|
||||
Can Light Torches: Lantern
|
||||
Can Extinguish Torches: Gale_Boomerang
|
||||
Can Launch Bombs: Bombs and (Gale_Boomerang or Bow)
|
||||
Can Break Monkey Cage: Sword or Iron_Boots or Spinner or Ball_and_Chain or Wolf_Link or Bombs or
|
||||
Bow or Clawshot or (Can_Do_Niche_Stuff and Shield_Attack)
|
||||
Can Cut Hanging Web: Clawshot or Bow or Gale_Boomerang or Ball_and_Chain
|
||||
Can Break Wooden Barrier: Sword or Can_Smash or Wolf_Link or Can_Use_Back_Slice_as_Sword
|
||||
Can Refill Air: Zora_Armor # or glitched logic water bombs
|
||||
Can Cross Quicksand: Wolf_Link or Spinner
|
||||
Can Break Armor: Ball_and_Chain
|
||||
Can Break Ice: Ball_and_Chain
|
||||
Can Launch Canonball: Bombs
|
||||
Can Knock Down Hyrule Castle Painting: Bow or (Can_Do_Niche_Stuff and (Bombs or Jump_Strike))
|
||||
Can Knock Down Hanging Baba: Bow or Clawshot or Gale_Boomerang or Slingshot
|
||||
|
||||
Has Damaging Item: Sword or Ball_and_Chain or Bow or Bombs or Iron_Boots or Wolf_Link or Spinner
|
||||
Can Hit Crystal Switch: Clawshot or Has_Damaging_Item
|
||||
Can Hit Crystal Switch at Range: Clawshot or Bow
|
||||
|
||||
Can Complete MDH: Skip_Midna's_Desparate_Hour == On or ('Can_Access_Castle_Town_South' and 'Can_Complete_Lakebed_Temple')
|
||||
|
||||
|
||||
|
||||
# REGULAR ENEMIES
|
||||
|
||||
# A lot of enemies use this identical logical requirement
|
||||
Can Defeat Generic Enemy: Sword or Ball_and_Chain or Bow or Spinner or Wolf_Link or Bombs or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
|
||||
Can Defeat Shadow Beast: Sword or (Wolf_Link and Can_Complete_MDH)
|
||||
Can Defeat Keese: Sword or Ball_and_Chain or Bow or Spinner or Wolf_Link or Slingshot or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Fire Keese: Can_Defeat_Keese
|
||||
Can Defeat Ice Keese: Can_Defeat_Keese
|
||||
Can Defeat Shadow Keese: Can_Defeat_Keese
|
||||
Can Defeat Rat: Slingshot or Can_Defeat_Generic_Enemy
|
||||
Can Defeat Ghoul Rat: Can_Use_Senses
|
||||
Can Defeat Bokoblin: Can_Defeat_Generic_Enemy or Slingshot
|
||||
Can Defeat Red Bokoblin: Sword or Ball_and_Chain or Giant_Quiver or Wolf_Link or Bombs or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Difficult_Combat and (Iron_Boots or Spinner))
|
||||
Can Defeat Bulblin: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Deku Baba: Sword or Ball_and_Chain or Bow or Spinner or Shield_Attack or Slingshot or Clawshot or Bombs or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Big Baba: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Baba Serpent: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Walltula: Ball_and_Chain or Slingshot or Bow or Gale_Boomerang or Clawshot
|
||||
Can Defeat Skulltula: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Deku Like: Bombs
|
||||
Can Launch Tileworm: Gale_Boomerang
|
||||
Can Defeat Tileworm: Gale_Boomerang and Can_Defeat_Generic_Enemy
|
||||
Can Defeat Stalhound: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Kargarok: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Goron: Sword or Ball_and_Chain or Bow or Spinner or Shield_Attack or Slingshot or Clawshot or Bombs or
|
||||
(Can_Do_Niche_Stuff and Iron_Boots) or (Can_Do_Difficult_Combat and Lantern) or Can_Use_Back_Slice_as_Sword
|
||||
Can Defeat Torch Slug: Sword or Ball_and_Chain or Bow or Wolf_Link or Bombs
|
||||
Can Defeat Dodongo: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Beamos: Ball_and_Chain or Bow or Bombs
|
||||
Can Defeat Leever: Sword or Ball_and_Chain or Bow or Spinner or Wolf_Link or Bombs or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Helmasaur: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Tektite: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Toado: Sword or Ball_and_Chain or Bow or Spinner or Wolf_Link
|
||||
Can Defeat Water Toadpoli: Sword or Ball_and_Chain or Bow or Shield_Attack or (Can_Do_Difficult_Combat and Wolf_Link)
|
||||
Can Defeat Shell Blade: Water_Bombs or (Sword and (Iron_Boots or (Can_Do_Niche_Stuff and Magic_Armor)))
|
||||
Can Defeat Lizalfos: Sword or Ball_and_Chain or Bow or Wolf_Link or Bombs or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Dinalfos: Sword or Ball_and_Chain or Wolf_Link
|
||||
Can Defeat Chu: Can_Defeat_Generic_Enemy or Clawshot
|
||||
Can Defeat Chu Worm: (Bombs or Clawshot) and (Sword or Ball_and_Chain or Bow or Spinner or Wolf_Link or Can_Use_Back_Slice_as_Sword)
|
||||
Can Defeat Bubble: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Fire Bubble: Can_Defeat_Bubble
|
||||
Can Defeat Ice Bubble: Can_Defeat_Bubble
|
||||
Can Defeat Skull Kid: Bow
|
||||
Can Defeat Poe: Can_Use_Senses
|
||||
Can Defeat Stalchild: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Stalfos: Can_Smash
|
||||
Can Defeat Redead Knight: Sword or Ball_and_Chain or Bow or Wolf_Link or Bombs or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat White Wolfos: Sword or Ball_and_Chain or Bow or Spinner or Wolf_Link or Bombs or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Chilfos: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Mini Freezard: Can_Defeat_Generic_Enemy
|
||||
Can Defeat Freezard: Ball_and_Chain
|
||||
Can Defeat Young Gohma: Sword or Ball_and_Chain or Bow or Spinner or Wolf_Link or Bombs or
|
||||
(Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Baby Gohma: Can_Defeat_Generic_Enemy or Slingshot or Clawshot
|
||||
Can Defeat Armos: Can_Defeat_Generic_Enemy or Clawshot
|
||||
Can Defeat Zant Head: Sword or Wolf_Link or Can_Use_Back_Slice_as_Sword
|
||||
|
||||
# MINIBOSSES
|
||||
|
||||
Can Defeat Ook: Sword or Ball_and_Chain or Bow or Wolf_Link or Bombs or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Dangoro: Iron_Boots and (Sword or Wolf_Link or Bomb_Arrows or (Can_Do_Niche_Stuff and Ball_and_Chain))
|
||||
Can Defeat Deku Toad: Sword or Ball_and_Chain or Bow or Wolf_Link or Bombs or
|
||||
Can_Use_Back_Slice_as_Sword or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat King Bulblin Desert: Sword or Ball_and_Chain or Wolf_Link or Giant_Quiver or Can_Use_Back_Slice_as_Sword or
|
||||
(Can_Do_Difficult_Combat and (Spinner or Iron_Boots or Bombs or Big_Quiver))
|
||||
Can Defeat Deathsword: Can_Use_Senses and Sword and (Clawshot or Bow or Gale_Boomerang)
|
||||
Can Defeat Darkhammer: Sword or Ball_and_Chain or Bow or Wolf_Link or Bombs or
|
||||
(Can_Use_Back_Slice_as_Sword and Can_Do_Difficult_Combat) or (Can_Do_Niche_Stuff and Iron_Boots)
|
||||
Can Defeat Darknut: Sword or (Can_Do_Difficult_Combat and (Bombs or Ball_and_Chain))
|
||||
Can Defeat Aerolfos: Clawshot and (Sword or Ball_and_Chain or Wolf_Link or (Can_Do_Niche_Stuff and Iron_Boots))
|
||||
Can Defeat Phantom Zant: Sword or Wolf_Link
|
||||
Can Defeat King Bulblin Castle: Sword or Ball_and_Chain or Wolf_Link or Big_Quiver or (Can_Do_Difficult_Combat and
|
||||
(Spinner or Iron_Boots or Bombs or Can_Use_Back_Slice_as_Sword))
|
||||
|
||||
# BOSSES
|
||||
|
||||
Can Defeat Diababa: Can_Launch_Bombs or (Gale_Boomerang and
|
||||
(Sword or Ball_and_Chain or Wolf_Link or Bombs or
|
||||
(Can_Do_Difficult_Combat and Can_Use_Back_Slice_as_Sword) or (Can_Do_Niche_Stuff and Iron_Boots)))
|
||||
Can Defeat Fyrus: Bow and Iron_Boots and (Sword or (Can_Do_Difficult_Combat and Can_Use_Back_Slice_as_Sword))
|
||||
Can Defeat Morpheel: Iron_Boots and Clawshot and Sword and Can_Refill_Air
|
||||
Can Defeat Stallord: Spinner and (Sword or Can_Do_Difficult_Combat)
|
||||
Can Defeat Blizzeta: Ball_and_Chain
|
||||
Can Defeat Armogohma: Bow and Dominion_Rod
|
||||
Can Defeat Argorok: Double_Clawshots and Ordon_Sword and (Iron_Boots or (Can_Do_Niche_Stuff and Magic_Armor))
|
||||
Can Defeat Zant: Master_Sword and Gale_Boomerang and (Iron_Boots or (Can_Do_Niche_Stuff and Magic_Armor)) and
|
||||
Can_Refill_Air and Clawshot and Ball_and_Chain
|
||||
|
||||
Can Open North Faron Woods Gate: North_Faron_Woods_Gate_Key or Small_Keys == Keysy
|
||||
Can Complete Prologue: Skip_Prologue == On or (Sword and Slingshot and Can_Open_North_Faron_Woods_Gate)
|
||||
|
||||
# You can only use warp portals from certain stages.
|
||||
# 'Can_Warp' is an event added to any logical area
|
||||
# which is part of a stage that players can warp from.
|
||||
Can Use Warp Portals: Wolf_Link and 'Can_Warp' and Can_Complete_Prologue
|
||||
|
||||
Can Free All Monkeys in Forest Temple: "'Can_Free_Monkey_in_Entrance_Room' and 'Can_Free_Monkey_on_Totem' and
|
||||
'Can_Free_Monkey_in_Big_Baba_Room' and 'Can_Free_Monkey_in_West_Tileworm_Room' and
|
||||
'Can_Free_Monkey_in_East_Tileworm_Room' and 'Can_Free_Monkey_in_Dark_Spider_Room' and
|
||||
'Can_Free_Monkey_in_North_Deku_Like_Room'"
|
||||
|
||||
Has Sword For Temple of Time: Temple_of_Time_Sword_Requirement == None or
|
||||
(Temple_of_Time_Sword_Requirement == Wooden_Sword and Sword) or
|
||||
(Temple_of_Time_Sword_Requirement == Ordon_Sword and Ordon_Sword) or
|
||||
(Temple_of_Time_Sword_Requirement == Master_Sword and Master_Sword) or
|
||||
(Temple_of_Time_Sword_Requirement == Light_Sword and Light_Sword)
|
||||
|
||||
Can Complete Faron Twilight: Faron_Twilight_Cleared == On or count(Faron_Twilight_Tear, 16)
|
||||
Can Complete Eldin Twilight: Eldin_Twilight_Cleared == On or count(Eldin_Twilight_Tear, 16)
|
||||
Can Complete Lanayru Twilight: Lanayru_Twilight_Cleared == On or count(Lanayru_Twilight_Tear, 16)
|
||||
Can Complete All Twilight: Can_Complete_Faron_Twilight and Can_Complete_Eldin_Twilight and Can_Complete_Lanayru_Twilight
|
||||
|
||||
Can Defeat Faron Twilit Insect: Twilight
|
||||
Can Defeat Eldin Twilit Insect: Twilight
|
||||
Can Defeat Lanayru Twilit Insect: Twilight and Can_Complete_Eldin_Twilight
|
||||
|
||||
Can Clear Forest: Can_Complete_Faron_Twilight and ('Can_Complete_Forest_Temple' or Faron_Woods_Logic == Open)
|
||||
|
||||
Can Complete All Dungeons: "'Can_Complete_Forest_Temple' and 'Can_Complete_Goron_Mines' and 'Can_Complete_Lakebed_Temple' and
|
||||
'Can_Complete_Arbiters_Grounds' and 'Can_Complete_Snowpeak_Ruins' and 'Can_Complete_Temple_of_Time' and
|
||||
'Can_Complete_City_in_the_Sky' and 'Can_Complete_Palace_of_Twilight'"
|
||||
|
||||
Can Break Hyrule Castle Barrier: Hyrule_Barrier_Requirements == Open or
|
||||
(Hyrule_Barrier_Requirements == Vanilla and 'Can_Complete_Palace_of_Twilight') or
|
||||
(Hyrule_Barrier_Requirements == Fused_Shadows and count(Progressive_Fused_Shadow, Hyrule_Barrier_Fused_Shadows)) or
|
||||
(Hyrule_Barrier_Requirements == Mirror_Shards and count(Progressive_Mirror_Shard, Hyrule_Barrier_Mirror_Shards)) or
|
||||
(Hyrule_Barrier_Requirements == Dungeons and dungeons_completed(Hyrule_Barrier_Dungeons)) or
|
||||
(Hyrule_Barrier_Requirements == Poe_Souls and count(Poe_Soul, Hyrule_Barrier_Poe_Souls)) or
|
||||
(Hyrule_Barrier_Requirements == Hearts and hearts(Hyrule_Barrier_Hearts))
|
||||
|
||||
Can Open Hyrule Castle Big Key Gate: Hyrule_Castle_Big_Key_Requirements == None or
|
||||
(Hyrule_Castle_Big_Key_Requirements == Fused_Shadows and count(Progressive_Fused_Shadow, Hyrule_Castle_Big_Key_Fused_Shadows)) or
|
||||
(Hyrule_Castle_Big_Key_Requirements == Mirror_Shards and count(Progressive_Mirror_Shard, Hyrule_Castle_Big_Key_Mirror_Shards)) or
|
||||
(Hyrule_Castle_Big_Key_Requirements == Dungeons and dungeons_completed(Hyrule_Castle_Big_Key_Dungeons)) or
|
||||
(Hyrule_Castle_Big_Key_Requirements == Poe_Souls and count(Poe_Soul, Hyrule_Castle_Big_Key_Poe_Souls)) or
|
||||
(Hyrule_Castle_Big_Key_Requirements == Hearts and hearts(Hyrule_Castle_Big_Key_Hearts))
|
||||
|
||||
|
||||
Can Talk to Springwater Goron: Nothing # TODO
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,561 @@
|
||||
######################
|
||||
## Logic Settings ##
|
||||
######################
|
||||
|
||||
- Name: Logic Rules
|
||||
Default Option: All Locations Reachable
|
||||
Options:
|
||||
- All Locations Reachable: "Logic is considered when placing items. Tricks and Glitches can be enabled for consideration below."
|
||||
- Beatable Only: "Logic is considered when placing items only until the world is beatable. Remaining items are placed without logic consideration. Tricks and Glitches can be enabled for consideration below."
|
||||
- No Logic: "Maximize randomization, logic is not considered when placing items. MAY BE IMPOSSIBLE TO BEAT."
|
||||
# - Vanilla: "Items are placed in their vanilla locations."
|
||||
|
||||
######################
|
||||
## Access Options ##
|
||||
######################
|
||||
|
||||
- Name: Hyrule Barrier Requirements
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Open: "The barrier around Hyrule Castle is dispelled from the beginning."
|
||||
- Vanilla: "The barrier will be dispelled once Palace of Twilight is cleared."
|
||||
- Fused Shadows: "The barrier will be dispelled once the required number of Fused Shadows have been collected."
|
||||
- Mirror Shards: "The barrier will be dispelled once the required number of Mirror Shards have been collected."
|
||||
- Dungeons: "The barrier will be dispelled once the required number of Dungeons have been cleared."
|
||||
- Poe Souls: "The barrier will be dispelled once the required number of Poe Souls have been collected."
|
||||
- Hearts: "The barrier will be dispelled once the required number of Hearts have been reached."
|
||||
|
||||
- Name: Hyrule Barrier Fused Shadows
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-3: No description available.
|
||||
|
||||
- Name: Hyrule Barrier Mirror Shards
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-4: No description available.
|
||||
|
||||
- Name: Hyrule Barrier Dungeons
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-8: No description available.
|
||||
|
||||
- Name: Hyrule Barrier Poe Souls
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-60: No description available.
|
||||
|
||||
- Name: Hyrule Barrier Hearts
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 4
|
||||
Options:
|
||||
- 4-20: No description available. # Hehe 420
|
||||
|
||||
- Name: Palace of Twilight Requirements
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Open: "The Mirror of Twilight is open at the start of the game."
|
||||
- Fused Shadows: "The player must collect all 3 Fused Shadows."
|
||||
- Mirror Shards: "The player must collect all 4 Mirror Shards."
|
||||
- Vanilla: "The player must complete City in the Sky."
|
||||
|
||||
- Name: Faron Woods Logic
|
||||
Tracker Important: True
|
||||
Default Option: Closed
|
||||
Options:
|
||||
- Closed: "Midna will block the player from leaving Faron Woods until Forest Temple is completed."
|
||||
- Open: "Midna will not prevent the player from leaving Faron Woods."
|
||||
|
||||
- Name: Mirror Chamber Access
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: Open
|
||||
Options:
|
||||
- Open: "The entrance is open and operates like normal. If you start with the Mirror Chamber Portal, you can access the Stallord boss fight without going through Arbiter's Grounds."
|
||||
- Barrier: "A barrier is placed in front of the Mirror Chamber entrance and goes away once Stallord is defeated."
|
||||
- Closed: "The Mirror Chamber is isolated from the world and cannot be reached from the Stallord boss room. To access it, players will either need the portal or access from Palace of Twilight."
|
||||
|
||||
######################
|
||||
## Item Pool ##
|
||||
######################
|
||||
|
||||
- Name: Golden Bugs
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The Golden Bug locations across Hyrule will give the golden bug at that location in the base game."
|
||||
- "On": "The Golden Bug locations across Hyrule will be randomized."
|
||||
|
||||
- Name: Sky Characters
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The Sky Character locations across Hyrule will give Sky Characters."
|
||||
- "On": "The Sky Character locations across Hyrule will be randomized."
|
||||
|
||||
- Name: Gifts From NPCs
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Locations which involve an NPC giving you a gift will give the item expected from the base game."
|
||||
- "On": "Locations which involve an NPC giving you a gift will be randomized."
|
||||
|
||||
- Name: Shop Items
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Shop item locations will contain the item they have in the base game."
|
||||
- "On": "Shop items will be randomized."
|
||||
|
||||
- Name: Hidden Skills
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The golden wolf locations across Hyrule will give you Hidden Skills. You will be required to get at least one of them to obtain the Ending Blow."
|
||||
- "On": "The golden wolf locations across Hyrule will be randomized."
|
||||
|
||||
- Name: Hidden Rupees
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Rupees hidden in tricky locations will not be randomized."
|
||||
- "On": "Rupees hidden in tricky locations will be randomized."
|
||||
|
||||
- Name: Freestanding Rupees
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Rupees out in the open will not be randomized."
|
||||
- "On": "Rupees out in the open will be randomized."
|
||||
|
||||
- Name: Poe Souls
|
||||
Tracker Important: True
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Vanilla: "All poes will give poe souls as the item for beating them."
|
||||
- Overworld: "Overworld poes will give randomized items. Poes in dungeons will still give poe souls."
|
||||
- Dungeon: "Poes in dungeons will give randomized items. Overworld poes will will give poe souls."
|
||||
- All: "All poes will be randomized."
|
||||
|
||||
- Name: Ilia Memory Quest
|
||||
Tracker Important: True
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Vanilla: "The Ilia Memory Quest will work the same way as the base game. You'll start it by beating Temple of Time and then talking to Renado in Kakariko Village."
|
||||
- Letter: "Renado's Letter will be shuffled into the world somewhere. You'll start the quest by finding Renado's Letter and then showing it to Telma in her bar."
|
||||
- Invoice: "The Invoice will be shuffled into the world somewhere. You'll start the quest by finding the Invoice and showing it to the Doctor in Castle Town."
|
||||
- Statue: "The Wooden Statue will be shuffled into the world somewhere. You'll start the quest by finding the Wooden Statue and then showing it to Ilia in Kakariko Village."
|
||||
- Charm: "Ilia's Charm will be shuffled into the world somewhere. You'll start the quest by finding Ilia's Charm and then showing it to Ilia in Kakariko Village to complete the quest."
|
||||
|
||||
- Name: Item Scarcity
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Vanilla: "No changes to the item pool."
|
||||
- Minimal: "Removes unrequired items such as Heart Containers and Pieces, Hawkeye, etc. Has as few items as possible for Bomb Bags, Bows, Hidden Skills, and Wallets. No Magic Armor and 1 Hidden Skill if Glitchless logic."
|
||||
- Plentiful: "One extra copy of major items. There are 17 Heart Containers but no Pieces of Heart. Extra keys if `Keysanity` or `Any Dungeon`."
|
||||
|
||||
- Name: Trap Item Frequency
|
||||
Default Option: None
|
||||
Options:
|
||||
- None: "All items in the game will be genuine."
|
||||
- Few: "Approximately 12.5% of non-major items will be replaced with 'traps' that don't give the item they appear to be."
|
||||
- Many: "Approximately 39.1% of non-major items will be replaced with 'traps' that don't give the item they appear to be."
|
||||
- Mayhem: "Approximately 62.7% of non-major items will be replaced with 'traps' that don't give the item they appear to be."
|
||||
- Nightmare: "All of the non-major items will be replaced with 'traps' that don't give the item they appear to be."
|
||||
|
||||
######################
|
||||
## Dungeon Items ##
|
||||
######################
|
||||
|
||||
- Name: Small Keys
|
||||
Tracker Important: True
|
||||
Default Option: Vanilla
|
||||
Random Low: Own Dungeon
|
||||
Random High: Anywhere
|
||||
Options:
|
||||
- Vanilla: "Small Keys will appear in their vanilla locations."
|
||||
- Own Dungeon: "Small Keys will appear inside their respective dungeon."
|
||||
- Any Dungeon: "Small Keys can appear inside any dungeon."
|
||||
# - Own Region: "Small Keys will appear in their dungeon's region."
|
||||
- Overworld: "Small Keys will only appear in the overworld."
|
||||
- Anywhere: "Small Keys can appear anywhere."
|
||||
- Keysy: "Small Keys will not appear anywhere in the world and their locks will start opened."
|
||||
|
||||
- Name: Big Keys
|
||||
Tracker Important: True
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Vanilla: "Big Keys will appear in their vanilla locations."
|
||||
- Own Dungeon: "Big Keys will appear inside their respective dungeon."
|
||||
- Any Dungeon: "Big Keys can appear inside any dungeon."
|
||||
# - Own Region: "Big Keys appear in their dungeon's region."
|
||||
- Overworld: "Big Keys will only appear in the overworld."
|
||||
- Anywhere: "Big Keys can appear anywhere."
|
||||
- Keysy: "Big Keys will not appear anywhere in the world and boss doors will start opened."
|
||||
|
||||
- Name: Maps and Compasses
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Vanilla: "Maps and Compasses will appear in their vanilla locations."
|
||||
- Own Dungeon: "Maps and Compasses can appear anywhere inside their respective dungeon."
|
||||
- Any Dungeon: "Maps and Compasses can appear inside any dungeon."
|
||||
# - Own Region: "Maps and Compasses will appear in their dungeon's region."
|
||||
- Overworld: "Maps and Compasses will only appear in the overworld."
|
||||
- Anywhere: "Maps and Compasses can appear anywhere."
|
||||
- Start With: "The player starts with all Maps and Compasses."
|
||||
|
||||
- Name: Hyrule Castle Big Key Requirements
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: None
|
||||
Options:
|
||||
- None: "The gate is opened and the key is randomized according to the respective Big Key settings."
|
||||
- Fused Shadows: "The gate will open once the required number of Fused Shadows have been collected."
|
||||
- Mirror Shards: "The gate will open once the required number of Mirror Shards have been collected."
|
||||
- Dungeons: "The gate will open once the required number of Dungeons have been cleared."
|
||||
- Poe Souls: "The gate will open once the required number of Poe Souls have been collected."
|
||||
- Hearts: "The gate will open once the required number of Hearts have been reached."
|
||||
|
||||
- Name: Hyrule Castle Big Key Fused Shadows
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-3: No description available.
|
||||
|
||||
- Name: Hyrule Castle Big Key Mirror Shards
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-4: No description available.
|
||||
|
||||
- Name: Hyrule Castle Big Key Dungeons
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-8: No description available.
|
||||
|
||||
- Name: Hyrule Castle Big Key Poe Souls
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 1
|
||||
Options:
|
||||
- 1-60: No description available.
|
||||
|
||||
- Name: Hyrule Castle Big Key Hearts
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: 4
|
||||
Options:
|
||||
- 4-20: No description available. # Hehe 420
|
||||
|
||||
- Name: Dungeon Rewards Can Be Anywhere
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Dungeon reward items (Fused Shadows and Mirror Shards) will only appear at the end of dungeons."
|
||||
- "On": "Dungeon reward items (Fused Shadows and Mirror Shards) can appear anywhere."
|
||||
|
||||
- Name: No Small Keys on Bosses
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Small keys will not be placed on boss heart container or dungeon reward checks."
|
||||
- "On": "Small keys can potentially be placed on boss heart container or dungeon reward checks. You may be expected to defeat a dungeon's boss before progressing further into the dungeon."
|
||||
|
||||
- Name: Unrequired Dungeons Are Barren
|
||||
Tracker Important: True
|
||||
Default Option: "On"
|
||||
Options:
|
||||
- "Off": "Unrequired dungeons may contain items needed to beat the game."
|
||||
- "On": "Unrequired dungeons will not contain any items necessary to beat the game."
|
||||
|
||||
######################
|
||||
## Timesavers ##
|
||||
######################
|
||||
|
||||
- Name: Skip Prologue
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "You will be required to play through the prologue section of the game to begin the randomizer. This includes everything up to the second goat herding sequence."
|
||||
- "On": "The prologue section of the game will be completed from the start."
|
||||
|
||||
- Name: Faron Twilight Cleared
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "You will be required to complete the Castle Sewers and Faron Twilight section of the game."
|
||||
- "On": "The Castle Sewers and Faron Twilight section of the game will be completed from the start."
|
||||
|
||||
- Name: Eldin Twilight Cleared
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "You will be required to complete the Eldin Twilight section of the game."
|
||||
- "On": "The Eldin Twilight section of the game will be completed from the start."
|
||||
|
||||
- Name: Lanayru Twilight Cleared
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "You will be required to complete the Lanayru Twilight section of the game."
|
||||
- "On": "The Lanayru Twilight section of the game will be completed from the start."
|
||||
|
||||
- Name: Skip Midna's Desparate Hour
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "After completing Lakebed Temple, you will be required to complete the Midna's Desperate Hour section of the game. Note that some overworld poes require Midna's Desperate Hour to be completed before they spawn in."
|
||||
- "On": "The Midna's Desperate Hour section of the game will be completed from the start."
|
||||
|
||||
- Name: Skip Minor Cutscenes
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Minor cutscenes such as area introduction cutscenes and Midna text explanations will not be skipped."
|
||||
- "On": "Minor cutscenes such as area introduction cutscenes and Midna text explanations will not play."
|
||||
|
||||
- Name: Skip Major Cutscenes
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "If you want to skip a skippable cutscene, you must press the start button twice while the cutscene is playing."
|
||||
- "On": "The randomizer will automatically skip any skippable cutscene as fast as possible."
|
||||
|
||||
- Name: Unlock Map Regions
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The map will not start filled in at the beginning of the randomizer. You will have to travel to the different sections of the world to get them on the map."
|
||||
- "On": "The map will start as filled in as possible. Certain sections such as Eldin and Lanayru will only be filled in if their Twilight section is cleared from the start."
|
||||
|
||||
- Name: Open Door of Time
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "You will be required to lead the big statue down the Temple of Time to open the big door at the bottom."
|
||||
- "On": "The big statue will already be set in place at the bottom of the Temple of Time and the door will be opened from the start."
|
||||
|
||||
- Name: Active Goron Mines Magnets
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The switches to activate magnets in Goron Mines will need to be activated manually."
|
||||
- "On": "The switches to activate magnets in Goron Mines will be activated from the start except for the highest one in the main room."
|
||||
|
||||
- Name: Lower Hyrule Castle Chandelier
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The chandeliers in Hyrule Castle will all need to be lowered manually."
|
||||
- "On": "One of the chandeliers in the Hyrule Castle main hall will be lowered from the start. This skips requiring Gale Boomerang and either Lantern or Bow to complete Hyrule Castle."
|
||||
|
||||
- Name: Skip Bridge Donation
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "You will need to donate money at Kakariko Malo Mart to build the bridge between Eldin Field and Castle Town."
|
||||
- "On": "The bridge between Eldin Field and Castle Town will be automatically built after Eldin and Lanayru Twilight are both completed."
|
||||
|
||||
######################
|
||||
# Additional Settings#
|
||||
######################
|
||||
|
||||
- Name: Starting Form
|
||||
Tracker Important: True
|
||||
Default Option: Human
|
||||
Options:
|
||||
- Human: Start as Human Link
|
||||
- Wolf: Start as Wolf Link
|
||||
|
||||
- Name: Bonks Do Damage
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": No description available.
|
||||
- "On": No description available.
|
||||
|
||||
- Name: Starting Time of Day
|
||||
Default Option: Noon
|
||||
Options:
|
||||
- Morning: "Time of day will start at 9am."
|
||||
- Noon: "Time of day will start at noon."
|
||||
- Evening: "Time of day will start at 6pm."
|
||||
- Night: "Time of day will start at midnight."
|
||||
|
||||
- Name: Logic Transform Anywhere
|
||||
Default Option: "On"
|
||||
Options:
|
||||
- "Off": "You will not be expected to transform in places that you normally can't."
|
||||
- "On": "You may be expected to transform in places that require turning on the Dusklight Transform Anywhere setting."
|
||||
|
||||
- Name: Logic Increase Wallet Capacity
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Logic will assume you have the same wallet capacities as the base game."
|
||||
- "On": "Logic will assume that you have the Bigger Wallets Dusklight setting turned on."
|
||||
|
||||
- Name: Logic Damage Multiplier
|
||||
Default Option: Vanilla
|
||||
Options:
|
||||
- Vanilla: "Logic will assume your Dusklight Damage Multiplier is x1."
|
||||
- Double: "Logic will assume your Dusklight Damage Multiplier is x2."
|
||||
- Triple: "Logic will assume your Dusklight Damage Multiplier is x3."
|
||||
- Quadruple: "Logic will assume your Dusklight Damage Multiplier is x4."
|
||||
- OHKO: "Logic will assume your Dusklight Instant Death setting is turned on."
|
||||
|
||||
#############################
|
||||
# Dungeon Entrance Settings #
|
||||
#############################
|
||||
|
||||
- Name: Lakebed Does Not Require Water Bombs
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The entrance to Lakebed Temple will be blocked by a boulder and require using Water Bombs to blow up."
|
||||
- "On": "The rock blocking access to the entrance of Lakebed Temple will be gone, meaning you can get in without Water Bombs."
|
||||
|
||||
- Name: Arbiters Does Not Require Bulblin Camp
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Bulblin Camp will have to be completed to access the entrance to Arbiter's Grounds. This will require finding the Gerudo Desert Bulblin Camp Key."
|
||||
- "On": "Bulblin Camp will be cleared at the start of the randomizer."
|
||||
|
||||
- Name: Snowpeak Does Not Require Reekfish Scent
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Getting the reekfish scent will be required for running through the blizzard on Snowpeak Mountain. Getting the reekfish scent requires the Coral Earring."
|
||||
- "On": "The randomizer will start you with the reekfish scent, meaning you can go through the Snowpeak Mountain blizzard without needing the Coral Earring."
|
||||
|
||||
- Name: Sacred Grove Does Not Require Skull Kid
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Getting through the Lost Woods will require completing the Skull Kid chase sequence."
|
||||
- "On": "The Skull Kid chase sequence in the Lost Woods will start already completed."
|
||||
|
||||
- Name: City Does Not Require Filled Skybook
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "The canon to City in the Sky will spawn in Lake Hylia when the Sky Book has been completed."
|
||||
- "On": "The canon to City in the Sky will be in Lake Hylia from the start."
|
||||
|
||||
- Name: Goron Mines Entrance
|
||||
Tracker Important: True
|
||||
Default Option: Closed
|
||||
Options:
|
||||
- Closed: "Accessing Goron Mines will require climbing up to the Death Mountain Sumo Hall and wrestling with the Goron Elder."
|
||||
- No Wrestling: "Accessing Goron Mines will require climbing up to the Death Mountain Sumo Hall, but wrestling the Goron Elder will not be necessary."
|
||||
- Open: "The elevator shortcut to the Death Mountain Sumo Hall will be open, and can be used to access Goron Mines."
|
||||
|
||||
- Name: Temple of Time Sword Requirement
|
||||
Need In Game: True
|
||||
Tracker Important: True
|
||||
Default Option: None
|
||||
Options:
|
||||
- None: "The door to the past will be open from the start."
|
||||
- Wooden Sword: "The door to the past will require striking at least the Wooden Sword into the Master Sword pedestal."
|
||||
- Ordon Sword: "The door to the past will require striking at least the Ordon Sword into the Master Sword pedestal."
|
||||
- Master Sword: "The door to the past will require striking at least the Master Sword into the Master Sword pedestal."
|
||||
- Light Sword: "The door to the past will require striking the Light Sword into the Master Sword pedestal."
|
||||
|
||||
- Name: Randomize Starting Spawn
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Link will start outside his house."
|
||||
- "On": "Link will start in a random area."
|
||||
|
||||
- Name: Randomize Dungeon Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a dungeon will lead to the vanilla dungeon."
|
||||
- "On": "Entering a dungeon will lead to a random dungeon."
|
||||
- "On + Hyrule Castle": "Entering a dungeon will lead to a random dungeon. Hyrule Castle's entrance will be shuffled as well."
|
||||
|
||||
- Name: Randomize Boss Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a boss door will lead to the intended boss."
|
||||
- "On": "Entering a boss door will lead to a random boss."
|
||||
|
||||
- Name: Randomize Grotto Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a grotto will lead to the intended grotto."
|
||||
- "On": "Entering a grotto will lead to a random grotto."
|
||||
|
||||
- Name: Randomize Cave Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a door or loadzone that leads to a cave area will lead to the intended cave."
|
||||
- "On": "Entering a door or loadzone that leads to a cave area will lead to a random cave."
|
||||
|
||||
- Name: Randomize Interior Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a door or loadzone that leads to an interior area will lead to the intended area."
|
||||
- "On": "Entering a door or loadzone that leads to an interior area will lead to a random intended area."
|
||||
|
||||
- Name: Randomize Overworld Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a loadzone that leads to an overworld area will lead to the intended area."
|
||||
- "On": "Entering a loadzone that leads to an overworld area will lead to a random area."
|
||||
|
||||
- Name: Decouple Double Door Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a left door will lead to the same location as the corresponding right door."
|
||||
- "On": "Entering a left door may lead somewhere different than the corresponding right door (only if the door's type is randomized)."
|
||||
|
||||
- Name: Decouple Entrances
|
||||
Tracker Important: True
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Entering a location and taking the entrance behind you will take you back to where you came from."
|
||||
- "On": "Entering a location and taking the entrance behind you will take you to a random location."
|
||||
|
||||
|
||||
#############################
|
||||
## Logic Tricks ##
|
||||
#############################
|
||||
|
||||
- Name: Back Slice as Sword
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Back Slicing without a sword can be logically required to do damage."
|
||||
- "On": "Back Slicing without a sword can be logically required to do damage."
|
||||
|
||||
- Name: Ball and Chain Webs
|
||||
Default Option: "Off"
|
||||
Options:
|
||||
- "Off": "Ball and Chain will not be required to break webs."
|
||||
- "On": "Ball and Chain may be required to break webs."
|
||||
@@ -0,0 +1,609 @@
|
||||
# Flag values taken from: https://github.com/lunarsoap5/Randomizer-Web-Generator-1/blob/development/Generator/Assets/Flags.cs
|
||||
|
||||
EventFlags:
|
||||
- 0x0382 # Gave wooden sword to Talo. Talked to squirrel outside link's house
|
||||
- 0x0629 # Tame Epona, KB1 trigger activated, Warped Kakariko Bridge Back.
|
||||
- 0x0F40 # Talked to Doctor for the first time.
|
||||
- 0x1208 # Can use Sera's Shop.
|
||||
- 0x1410 # Put Bo outside, ready to wrestle
|
||||
- 0x0F01 # Got Lantern from Coro (Remove when adding Coro checks)
|
||||
- 0x0A2F # Bridge of Eldin Stolen, KB1 defeated, KB1 started
|
||||
- 0x0F68 # Bridge of Eldin Warped Back, forced text when entering dr. clinic, talked to dr before giving invoice
|
||||
- 0x4088 # Saved monkey from puppets, Visited Gerudo Desert for the first time.
|
||||
- 0x4118 # Talked to Fado after Faron and Eldin Twilight
|
||||
- 0x07A0 # Watched Colin CS after KB1, talked to Bo before sumo
|
||||
- 0x2020 # Master Sword Story Progression
|
||||
- 0x2010 # Arbiters Grounds Story Progression
|
||||
- 0x2C10 # Raised the mirror in the Mirror Chamber
|
||||
- 0x1B38 # Skip Monkey Escort
|
||||
- 0x1C20 # Talked to Bo after opening boots chest.
|
||||
- 0x5F20 # Shad leaves sanctuary.
|
||||
- 0xF701 # Add 256 Rupees to Charlo.
|
||||
- 0xF8F4 # Add 244 Rupees to Charlo.
|
||||
- 0x6001 # Talked to Fyer after Lanayru Twilight
|
||||
- 0x3880 # Talked to Jovani after defeating Poe.
|
||||
- 0x2208 # Talked to Yeto on top of the mountain after clearing SPR
|
||||
- 0x3B40 # Won Snowboard race against Yeto.
|
||||
- 0x2F80 # Talked to Goron outside East Castle Town
|
||||
- 0x1C10 # Win Sumo round 1 against Bo
|
||||
- 0x3902 # Released first caught fish in Ordon Day 2
|
||||
- 0x1002 # Talked to Jaggle after climbing vines.
|
||||
- 0x0B20 # Talked to Yeta in Snowpeak for the first time
|
||||
- 0x4308 # Senses unlocked
|
||||
- 0x4610 # Rode Epona back to Link's House
|
||||
- 0x0C10 # Midna accompanies Wolf
|
||||
- Skip_Prologue == On:
|
||||
- 0x0404 # Talked to Uli Day 1.
|
||||
- 0x4510 # Saved Talo
|
||||
- 0x4A60 # Completed Ordon Day 1 and Finished Sword Training.
|
||||
- 0x1601 # Completed Ordon Day 2.
|
||||
- 0x1580 # Watched CS for Goats 2 Done.
|
||||
- Faron_Twilight_Cleared == On:
|
||||
- 0x057F # Midna Charge Unlocked, Finished Sewers, Met Zelda in swers, Midna cut prison chain, watched sewers intro CS, Escaped Cell in Sewers.
|
||||
- 0x0610 # Cleared Faron Twilight
|
||||
- 0x0C08 # Sword and shield removed from wolf's back.
|
||||
- Eldin_Twilight_Cleared == On:
|
||||
- 0x0708 # Cleared Eldin Twilight
|
||||
- 0x0604 # Map Warping unlocked.
|
||||
- Lanayru_Twilight_Cleared == On:
|
||||
- 0x0880 # Zora's Domain Thawed.
|
||||
- 0x0C02 # Lanayru Twilight Story Flag.
|
||||
- 0x0A10 # Defeated Kargarok Rider at Lake (allows player to howl for Kargorok.);
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x0140 # Talked to Yeto First Time.
|
||||
- 0x0390 # Jaggle Calls out to Link, talked to Squirrel as Wolf in Ordon.
|
||||
- 0x06C0 # CS After beating Ordon Shadow, CS after entering Faron Twilight.
|
||||
- 0x0702 # First Time Talking to Gor Coron in Sumo Hall
|
||||
- 0x1501 # Talked to Agitha for the first time.
|
||||
- 0x2001 # Talked to Telma for the first time.
|
||||
- 0x5E10 # Midna text after beating Forest Temple.
|
||||
- 0x1D40 # Listened to Fyer at drained lake.
|
||||
- 0x2201 # Plumm initial CS watched.
|
||||
- 0x2310 # STAR initial CS watched.
|
||||
- 0x2602 # Talked to Yeto on Snowpeak.
|
||||
- 0x2840 # Used Ooccoo for the first time.
|
||||
- 0x3704 # Postman twilight text.
|
||||
- 0x3806 # Hena cabin first time CS, talked to Hena first time.
|
||||
- 0x3A01 # Talked to Ralis in Graveyard for the first time.
|
||||
- 0x4002 # Agreed to help Rusl after Snowpeak Ruins.
|
||||
- 0x4205 # Watched post-ToT Ooccoo CS. Watched Cutscene with Rusl in North Faron Woods.
|
||||
- 0x4508 # Allows postman letters to show up in inventory.
|
||||
- 0x4A10 # Saw Talo in cage CS.
|
||||
- 0x3E02 # City Ooccoo CS watched.
|
||||
- 0x5940 # Met Postman for the first time.
|
||||
- 0x5D40 # Midna text after Kargarok flight.
|
||||
- 0x2502 # Watched cutscene with Yeto on top of mountain
|
||||
- Faron_Woods_Logic == Open:
|
||||
- 0x0602 # Forest Temple Story Flag
|
||||
- 0x0C40 # Talked to Farone after clearing Forest Temple
|
||||
- 0x5E10 # Midna text after Forest Temple completed
|
||||
- Skip_Midna's_Desparate_Hour == On:
|
||||
- 0x0C01 # Midna's Desperate Hour started.
|
||||
- 0x1E08 # Midna's Deseperate Hour Completed.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x0850 # Zora Escort started and completed.
|
||||
- 0x0480 # Told Yeta about pumpkin.
|
||||
- 0x0003 # Yeto put pumpkin and cheese in soup.
|
||||
- 0x1460 # Snowpeak Ruins North and West doors unlocked.
|
||||
- 0x0120 # Told Yeta about cheese
|
||||
- Hyrule_Barrier_Requirements == Open:
|
||||
- 0x4208 # Remove Castle Barrier
|
||||
- Palace_of_Twilight_Requirements == Open:
|
||||
- 0x2B08 # Mirror of Twilight Repaired.
|
||||
- Goron_Mines_Entrance != Closed:
|
||||
- 0x0706 # Talked to Gor Coron, Won Sumo against Gor Coron.
|
||||
- Arbiters_Does_Not_Require_Bulblin_Camp == On:
|
||||
- 0x0B40 # Escaped Burning Tent in Bulblin Camp.
|
||||
- Snowpeak_Does_Not_Require_Reekfish_Scent == On:
|
||||
- 0x6120 # Got the reekfish and smelled it (removes void in Snowpeak).
|
||||
- City_Does_Not_Require_Filled_Skybook == On:
|
||||
- 0x3B08 # Sky Cannon Repaired.
|
||||
- Randomize_Starting_Spawn == On:
|
||||
- 0x057A # Finished Sewers, Midna text after entering Faron Twilight, Met Zelda in sewers, Midna cut prison chain, Watched Sewers intro CS, Escaped cell in sewers.
|
||||
- Ilia_Memory_Quest >= Letter:
|
||||
- 0x2004 # ToT Story Progression Flag
|
||||
- 0x0F80 # Renados Letter Check
|
||||
- Ilia_Memory_Quest >= Statue:
|
||||
- 0x2710 # Showed Invoice to Doctor
|
||||
- 0x2F04 # Got Medicine Scent
|
||||
- 0x2102 # Talked to Louise after Medicine Scent
|
||||
- 0x2204 # Got Wooden Statue
|
||||
- Ilia_Memory_Quest >= Charm:
|
||||
- 0x2340 # Gave statue to Ilia
|
||||
- 0x2E08 # HV barrier removed
|
||||
- 0x2280 # Got Ilia's Charm
|
||||
- Skip_Bridge_Donation == Off:
|
||||
- 0xF901 # Add 256 Rupees to Malo Mart.
|
||||
- 0xFAF4 # Add 244 Rupees to Malo Mart.
|
||||
|
||||
RegionFlags:
|
||||
Ordona Province:
|
||||
Index: 0x00
|
||||
Flags:
|
||||
- 0x57 # Spider on Link's Ladder killed.
|
||||
- 0x63 # Spawn the Chest in Link's House
|
||||
- 0x7E # Midna jumps to Shop unlocked
|
||||
- 0x6B # Ordon Spring Portal.
|
||||
- 0x44 # Midna Text after Ordon Shield (Spawns sword)
|
||||
- 0x46 # Midna Text after Ordon Sword
|
||||
- 0x68 # Approach faron wall with Midna
|
||||
- 0xA0 # Midna allows player to approach Faron Twilight Wall
|
||||
- 0xBA # Explored area outside Link's house as wolf
|
||||
- 0x61 # Defeated first bulblin outside link's house
|
||||
- 0x62 # Defeated second bulblin outside link's house
|
||||
- 0x60 # Defeated Hugo
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x4A # Ordon Day 3 Intro CS.
|
||||
- 0x4C # Knocked down Ordon bee nest CS.
|
||||
- 0x4E # Ordon Ranch first time CS.
|
||||
- 0x53 # Ilia spring CS watched.
|
||||
- 0x54 # Ilia spring CS started.
|
||||
- 0x55 # Ordon Village first time CS.
|
||||
- 0x56 # Ilia spring CS trigger.
|
||||
- 0x68 # Approach Faron Twilgiht with Midna CS.
|
||||
- 0x6E # Enter shield house as wolf CS.
|
||||
- 0x75 # Midna text after hearing Bo and Jaggle talk about the shield.
|
||||
- 0x7C # Midna text before jumping to Ordon Shop roof.
|
||||
- 0x7D # Rusl talking to Uli during wolf night CS.
|
||||
- 0xB8 # Enter Ordon Village as wolf CS.
|
||||
|
||||
Hyrule Castle Sewers and Rooftops:
|
||||
Index: 0x01
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x42 # Midna text after first gate in sewers.
|
||||
- 0x43 # Midna text after exiting to rooftops.
|
||||
- 0x51 # Zelda tower intro CS.
|
||||
- 0x57 # Outside top door intro CS.
|
||||
- 0x5A # Went to the otherside of the fence in sewers CS.
|
||||
- 0x5B # Top of stairway intro CS.
|
||||
- 0x5C # Stairway intro CS.
|
||||
- 0x7B # Midna text when approaching the rooftop guard.
|
||||
|
||||
Faron Woods:
|
||||
Index: 0x02
|
||||
Flags:
|
||||
- 0x63 # Trill lets you shop at his store.
|
||||
- 0x48 # Talked to Coro after bugs
|
||||
- 0x60 # Got Lantern Back from Monkey
|
||||
- 0x61 # Saw bugs move in Coro's house
|
||||
- 0x7D # Talked to Midna about Coro spirit
|
||||
- 0x4E # Saved Monkey from Puppets.
|
||||
- 0x62 # Midna text before jumping to lost woods
|
||||
- 0x95 # Midna text after warping to North Faron for bridge.
|
||||
- 0xBF # Burned First cobweb in faron cave
|
||||
- 0xBE # Burned second cobweb in faron cave
|
||||
- Skip_Prologue == On:
|
||||
- 0x4B # North Faron Gate Unlocked
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x74 # Faron intro CS.
|
||||
- 0x77 # See Faron Light Spirit from afar CS.
|
||||
- 0x7C # Entered mist area as human.
|
||||
- Faron_Twilight_Cleared == On:
|
||||
- 0x46 # Midna jump 1 mist area.
|
||||
- 0x47 # Midna jump 1 mist area.
|
||||
- 0x98 # South Faron Portal.
|
||||
# Re-enable once key situation is sorted out
|
||||
# - Small_Keys == Keysy:
|
||||
# - 0x53 # Coro gate unlocked.
|
||||
# - 0x4B # North Faron Gate Unlocked.
|
||||
|
||||
Kakariko and Death Mountain:
|
||||
Index: 0x03
|
||||
Flags:
|
||||
- 0xB9 # Barnes sells water bombs.
|
||||
- 0xB3 # Colin Rescued CS (Malo Mart is Open).
|
||||
- 0xA4 # Barnes Sells Bombs.
|
||||
- 0x42 # Big Rock fell at DMT
|
||||
- 0xA7 # Unlock Jumps to top of Sanctuary
|
||||
- 0x9A # Kakariko Village intro CS.
|
||||
- 0x54 # Custom flag. Sets the sign in Kak Malo mart slot 1 to appear.
|
||||
- 0x99 # Remove wooden shield from Kak Malo Mart counter.
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x49 # Death mountain intro CS.
|
||||
- 0x83 # Kakariko Graveyard intro CS.
|
||||
- 0x8C # Midna text after Meteor fell.
|
||||
- Eldin_Twilight_Cleared == On:
|
||||
- 0x14 # Collected Tear From Bomb Storage
|
||||
- 0x1A # Collected Tear From Bomb Storage
|
||||
- 0x1B # Collected Tear From Bomb Storage
|
||||
- 0x67 # Ant house entered from top
|
||||
- 0x64 # Ant house box pushed
|
||||
- 0x5E # Defeated Ant house Tears of Light bug
|
||||
- 0x1E # Collected Tear from Ant house
|
||||
- 0xBD # Done Midna jumps in ant house.
|
||||
- Small_Keys == Keysy:
|
||||
- 0xBA # Followed Rutella to graveyard.
|
||||
- 0xB6 # Started Rutella escort.
|
||||
- Goron_Mines_Entrance == Open:
|
||||
- 0x79 # moved death mountain rock to exit
|
||||
- 0x8F # moved death mountain rock to hot spring water
|
||||
- 0xB0 # Goron lets you enter elevator in sumo hall
|
||||
- Ilia_Memory_Quest >= Charm:
|
||||
- 0x70 # Darbus destroyed HV rocks
|
||||
|
||||
Lake Hylia and Zoras Domain:
|
||||
Index: 0x04
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x58 # Talked to Rutella in Lanayru Twilight.
|
||||
- 0x5F # Zora's domain intro CS twilight.
|
||||
- 0x67 # Midna text after jumping to Lake from burning bridge.
|
||||
- 0x6B # Zora's Domain exit flood water cutscene.
|
||||
- 0x72 # Midna text after arriving at frozen Upper Zora River.
|
||||
- 0x91 # Midna text after frozen Zora Domain intro CS.
|
||||
- 0xB0 # Watched CS of Ooccoo running to Sky Cannon.
|
||||
- Lanayru_Twilight_Cleared == On:
|
||||
- 0x7F # Lake Hylia has water on Lake Hylia Map.
|
||||
- Skip_Midna's_Desparate_Hour == On:
|
||||
- 0x51 # Set flag for MDH Cutscene in Lake Hylia
|
||||
- Lakebed_Does_Not_Require_Water_Bombs == On:
|
||||
- 0x70 # Blew up rock in front of lakebed CS.
|
||||
- 0x78 # Blew up rock in front of lakebed.
|
||||
|
||||
# Not sure what Index 5 is
|
||||
|
||||
Hyrule Field:
|
||||
Index: 0x06
|
||||
Flags:
|
||||
- 0x4C # Bridge of Eldin Warped back CS.
|
||||
- 0x7E # Kakariko Gorge placed CS
|
||||
- 0x83 # Set the flag for the Ganon Barriers in Hyrule Field during Eldin Twilight.
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x68 # Midna text after warping Gorge bridge.
|
||||
- 0x7C # Midna text after Lanayru Field twilight CS.
|
||||
- 0x72 # Faron Field intro CS.
|
||||
- 0x40 # Twilight Lanayru Field intro CS.
|
||||
- 0x4F # Cutscene of gate outside Kakariko Village.
|
||||
- 0xB3 # Midna text after entering Lanayru Twilight.
|
||||
- 0xB4 # Midna text when seeing Lanayru Twilight from far away.
|
||||
- 0xB6 # Midna text after entering Eldin Twilight.
|
||||
- 0xB7 # Midna text when seeing Eldin Twilight from far away.
|
||||
- Lanayru_Twilight_Cleared == On:
|
||||
- 0x58 # Lake Hylia has water on Hyrule Field Map
|
||||
- Ilia_Memory_Quest >= Charm:
|
||||
- 0x43 # Remove HV rocks from Hyrule field
|
||||
|
||||
Lost Woods and Sacred Grove:
|
||||
Index: 0x07
|
||||
Flags:
|
||||
- 0x58 # Sacred Grove MS Pedestal Map
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x42 # Midna text after pushing block shortcut as human after Grove 2.
|
||||
- 0x43 # cs after pushing block human
|
||||
- 0x44 # Lost Woods intro CS.
|
||||
- Temple_of_Time_Sword_Requirement == None:
|
||||
- 0x49 # Stairs to Temple of time created.
|
||||
- 0x4A # Struck master sword pedestal with sword.
|
||||
- 0x4B # Stairs and window appear and work properly (Past).
|
||||
- 0xBC # Statue in present is gone. (custom flag)
|
||||
- Sacred_Grove_Does_Not_Require_Skull_Kid == On:
|
||||
- 0xB6 # Skull Kid - Human defeated.
|
||||
- 0xB7 # Lost Woods Turns to day after defeating Skull Kid - Human
|
||||
- 0x5B # Block pushed down
|
||||
- 0x42 # Midna text after block pushed down
|
||||
- 0x43 # cs after pushing block human
|
||||
|
||||
|
||||
Snowpeak Province:
|
||||
Index: 0x08
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x45 # Snowpeak Summit intro CS.
|
||||
- 0x5E # Midna text outside SPR.
|
||||
- 0x5F # Snowpeak intro CS.
|
||||
- Snowpeak_Does_Not_Require_Reekfish_Scent == On:
|
||||
- 0x49 # Snowpeak summit cs.
|
||||
- 0x45 # Snowpeak Summit intro CS.
|
||||
|
||||
Castle Town:
|
||||
Index: 0x09
|
||||
Flags:
|
||||
- 0x40 # Original Jovani Poe killed. It is replaced with a custom actor.
|
||||
- 0x76 # Jovani Chest CS 2
|
||||
- 0x7F # Open Chest to Jovani
|
||||
- 0x7E # Jovani Chest CS
|
||||
- 0x50 # Set flag for Midna breaking Barrier CS.
|
||||
- 0xBC # Spawn Gengle by default as his actor interferes with the poe soul
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x55 # STAR Tent intro CS.
|
||||
- 0x7D # Jovani House intro CS.
|
||||
- Ilia_Memory_Quest >= Statue:
|
||||
- 0x56 # Remove invisible wall from Doctor
|
||||
|
||||
Gerudo Desert:
|
||||
Index: 0x0A
|
||||
Flags:
|
||||
- 0x99 # Desert Entrance CS.
|
||||
- 0x20 # Set Freestanding key flag.
|
||||
- 0x7F # Mirror Raised Cutscene Flag (Places Boar at desert entrance)
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x53 # Mirror Chamber Intro CS.
|
||||
- Arbiters_Does_Not_Require_Bulblin_Camp == On:
|
||||
- 0x43 # Explored part 9 of the Bulblin camp area
|
||||
- 0x44 # Explored part 8 of the Bulblin camp area
|
||||
- 0x45 # Explored part 7 of the Bulblin camp area
|
||||
- 0x46 # Explored part 6 of the Bulblin camp area
|
||||
- 0x47 # Explored part 5 of the Bulblin camp area
|
||||
- 0x4C # Explored part 2 of the Bulblin camp area
|
||||
- 0x4D # Explored part 4 of the Bulblin camp area
|
||||
- 0x4E # Explored part 3 of the Bulblin camp area
|
||||
|
||||
Forest Temple:
|
||||
Index: 0x10
|
||||
Flags:
|
||||
- 0x49 # FT Ook Bridge Destroyed
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x41 # Midna text after getting Boomerang.
|
||||
- 0x42 # Midna text after Ook breaks the bridge.
|
||||
- 0x47 # Midna text after freeing first monkey.
|
||||
- 0x49 # Bridge before Ook broken.
|
||||
- 0x56 # Bokoblins spot Link in windless bridge room.
|
||||
- 0x57 # Turned bridge in windless bridge room.
|
||||
- 0x72 # West Tile Worm room intro CS.
|
||||
- 0x76 # Second monkey room intro CS.
|
||||
- 0x7C # Big Baba room intro CS.
|
||||
- 0x7D # Midna text in room before boss room.
|
||||
- 0x7E # Midna text after saving monkey after defeating Ook.
|
||||
- 0x85 # Midna text after opening hanging chest.
|
||||
- 0x83 # East outside room intro CS.
|
||||
- 0xB6 # Forest Temple intro CS.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x54 # Unlocked door to Second Monkey.
|
||||
- 0x58 # Unlock windless bridge east door.
|
||||
- 0x61 # Opened big baba monkey cage.
|
||||
- 0x74 # Opened tile worm monkey cage.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x48 # Unlocked Forest Temple Boss Door.
|
||||
- 0xED # Got Forest Temple Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Forest Temple Compass.
|
||||
- 0xEF # Got Forest Temple Dungeon Map.
|
||||
|
||||
Goron Mines:
|
||||
Index: 0x11
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x43 # Cut rope of door in outside room CS.
|
||||
- 0x44 # Pressed second button of the main magnet room of the second floor CS trigger.
|
||||
- 0x45 # Pressed third button in entrance room CS.
|
||||
- 0x46 # Pressed second button in entrance room CS.
|
||||
- 0x47 # Cut rope of door in Toadpoli room CS.
|
||||
- 0x4A # Pressed first button of the main magnet room on the second floor CS.
|
||||
- 0x68 # Pressed outside magnet switch for first time CS.
|
||||
- 0x72 # Main magnet room intro CS.
|
||||
- 0x73 # Main magnet room intro CS trigger.
|
||||
- 0x7A # Outside room intro CS.
|
||||
- 0x80 # Room after Bow chest intro CS.
|
||||
- 0x81 # Pulled Beamos in outside room CS.
|
||||
- 0x84 # Open gate in Toadpoli room CS.
|
||||
- 0x85 # Pressed second button in Toadpoli room CS.
|
||||
- 0x88 # Magnet maze room intro CS.
|
||||
- 0x8A # Goron Mines intro CS.
|
||||
- 0x8B # Pressed first button in entrance room CS.
|
||||
- 0x8C # Open gate in entrance room CS.
|
||||
- 0xBC # Main magnet room second floor intro CS.
|
||||
- 0xBD # Main magnet room second floor intro CS trigger.
|
||||
- 0xBE # Hit crystal switch in room after bow chest CS.
|
||||
- 0xBF # Room after Bow chest intro CS trigger.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x60 # Unlock north door in toadpoli room.
|
||||
- 0x62 # Unlock west locked door in main magnet room.
|
||||
- 0x6C # Unlock east outside door.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x48 # Unlocked Goron Mines Boss Door.
|
||||
- 0xED # Got Goron Mines Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Goron Mines Compass.
|
||||
- 0xEF # Got Goron Mines Dungeon Map.
|
||||
- Active_Goron_Mines_Magnets == On:
|
||||
- 0xBB # activated magnet from water before first elder
|
||||
- 0x8F # activated ceiling maze magnet after first elder
|
||||
- 0x5B # activated main magnet room 1st magnet
|
||||
- 0x4A # watched main magnet room 1st magnet cs
|
||||
- 0x61 # activated main magnet room 2nd magnet
|
||||
- 0x44 # watched main magnet room 2nd magnet cs
|
||||
- 0x9E # crystal switch room 1st Iron Boots switch pressed
|
||||
- 0x83 # crystal switch room 1st Iron Boots switch cs shown
|
||||
- 0x82 # crystal switch room 1st magnet active
|
||||
- 0x9F # crystal switch room 2nd Iron Boots switch pressed
|
||||
- 0x85 # crystal switch room 2nd Iron Boots switch cs shown
|
||||
- 0x86 # crystal switch room 2nd magnet active
|
||||
- 0x54 # activated outside room magnet
|
||||
- 0x68 # watched outside room magnet cs
|
||||
- 0x8d # activated east wing dodongo room magnet
|
||||
# Note: the final magnet is not activated because there is a
|
||||
# softlock when you exit the main magnet room through the top door
|
||||
# as wolf while the gate beyond the door in the Dodongo room is not
|
||||
# open. Alternatively if we do open this gate, it leads to much
|
||||
# more complicated logic and some jank where you can walk through
|
||||
# Dangoro while he sits there (and the gate covering the door
|
||||
# animation is also a bit jank). Also you can die during the
|
||||
# Dangoro fight to appear on the north side of his arena. There are
|
||||
# too many nuances for it to be reasonable for glitchless logic,
|
||||
# and also every small key door would require 3 keys.
|
||||
|
||||
Lakebed Temple:
|
||||
Index: 0x12
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x46 # Midna Stalactite text in second room.
|
||||
- 0x7E # Horizontal wheel is turning in east room CS.
|
||||
- 0x7F # Horizontal wheel is turning in east room CS trigger.
|
||||
- 0xA5 # Central room intro CS.
|
||||
- 0xA6 # South bridge to main room intro CS.
|
||||
- 0xA7 # Lakebed Temple intro CS.
|
||||
- 0xAA # Rotate staircase main room CS.
|
||||
- 0xB4 # East water supply Chu Worm CS.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x6B # Unlock east door main room 2F.
|
||||
- 0x7B # Unlocked door in second east room 2F.
|
||||
- 0x7C # Unlocked door before Deku Toad.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x8A # Unlocked Lakebed Temple Boss Door.
|
||||
- 0xED # Got Lakebed Temple Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Lakebed Temple Compass.
|
||||
- 0xEF # Got Lakebed Temple Dungeon Map.
|
||||
|
||||
Arbiters Grounds:
|
||||
Index: 0x13
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x5A # Turn walls in third room Basement second floor CS.
|
||||
- 0x73 # Arbiters Grounds intro CS.
|
||||
- 0x94 # Risen tracks on pilar before boss CS.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x78 # Unlocked door in second east room 2F.
|
||||
- 0x84 # Unlocked door in elevator room 2B.
|
||||
- 0x85 # Unlocked door in first room.
|
||||
- 0x92 # Unlocked door in first east room 1F.
|
||||
- 0x99 # Unlocked door in fourth east room.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x47 # Unlocked Arbiter's Grounds Boss Door.
|
||||
- 0xED # Got Arbiter's Grounds Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Arbiter's Grounds Compass.
|
||||
- 0xEF # Got Arbiter's Grounds Dungeon Map.
|
||||
|
||||
Snowpeak Ruins:
|
||||
Index: 0x14
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x83 # First Floor Northwest room intro CS.
|
||||
- 0xA1 # Midna text after finding Bedroom Key.
|
||||
- 0xA7 # Snowpeak Ruins intro CS.
|
||||
- 0xAA # Freezard in cage CS.
|
||||
- 0xAC # Courtyard intro CS.
|
||||
- 0xAE # Pumpkin room intro CS.
|
||||
- 0xB2 # Midna text after getting Cheese.
|
||||
- 0xB4 # Midna text after getting Pumpkin.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x4D # Unlock North lobby door.
|
||||
- 0x4C # Unlock West lobby door.
|
||||
- 0x6F # Unlock door in southeast room 2F.
|
||||
- 0x73 # Unlock door in east outside hallway.
|
||||
- 0x74 # Unlock west door in courtyard.
|
||||
- 0x70 # Unlock door to lobby from Freezard room.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x57 # Unlocked Snowpeak Ruins Boss Door.
|
||||
- 0xED # Got Snowpeak Ruins Big Key.
|
||||
- 0x56 # Watched CS of Yeta entering boss room.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Snowpeak Ruins Compass.
|
||||
- 0xEF # Got Snowpeak Ruins Dungeon Map.
|
||||
|
||||
Temple of Time:
|
||||
Index: 0x15
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x40 # Midna text telling you to use your senses on the missing statue.
|
||||
- 0x41 # Midna text after using senses on missing statue.
|
||||
- 0x4A # Temple of Time intro CS.
|
||||
- 0x4B # Scales of Time room intro CS.
|
||||
- 0x4C # CS after changing the balance on the scales for the first time.
|
||||
- 0x4D # CS trigger after changing the balance on the scales for the first time.
|
||||
- 0x90 # Pressed button in room 1 for the first time CS.
|
||||
- 0x91 # Pressed the button on the seventh floor for the first time CS.
|
||||
- 0x94 # Pressed the button on the fifth floor for the first time CS.
|
||||
- 0x95 # Pressed buttons on third floor for the first time CS.
|
||||
- 0x96 # Pressed the button on the second floor for the first time CS.
|
||||
- 0x54 # statue getting possessed for the first time cs
|
||||
- Small_Keys == Keysy:
|
||||
- 0x44 # Unlock door in room 1.
|
||||
- 0x42 # Unlock door in room 6 on 8F.
|
||||
- 0x43 # Unlock door in 5F.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x7F # Unlocked Temple of Time Boss Door.
|
||||
- 0xED # Got Temple of Time Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Temple of Time Compass.
|
||||
- 0xEF # Got Temple of Time Dungeon Map.
|
||||
- Open_Door_of_Time == On:
|
||||
- 0x59 # deactivate statue slot in room 1 (opens door and deactivates statue)
|
||||
- 0x80 # open big door in room 1 cs part 2
|
||||
- 0x81 # open big door in room 1 cs part 1
|
||||
- 0xBC # big door in room 1 opens
|
||||
- 0xBE # open big door in room 1 cs part 1 trigger
|
||||
- 0xBD # open big door in room 1 cs part 2 trigger
|
||||
- 0xBF # statue placed in slot in room 1
|
||||
|
||||
City in the Sky:
|
||||
Index: 0x16
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x64 # North wing main room intro CS.
|
||||
- 0x65 # East wing fan room second floor intro CS.
|
||||
- 0x66 # Went beyond first gate outside shop intro CS.
|
||||
- 0x67 # City in The Sky intro CS.
|
||||
- 0x6E # East bridge extended CS.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x59 # Unlock east bridge door.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x58 # Unlocked City in The Sky Boss Door.
|
||||
- 0xED # Got City in The Sky Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got City in The Sky Compass.
|
||||
- 0xEF # Got City in The Sky Dungeon Map.
|
||||
|
||||
Palace of Twilight:
|
||||
Index: 0x17
|
||||
Flags:
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x4D # Phantom Zant 1 CS.
|
||||
- 0x66 # Midna text when west hand steals sol.
|
||||
- 0x6F # Midna text about black fog in west room.
|
||||
- 0x70 # Midna text after finding west sol.
|
||||
- 0x72 # Midna text trigger when seeing a Twili for the first time.
|
||||
- 0x78 # Midna text when seeing a Twili for the first time.
|
||||
- 0x79 # Midna text after Light Sword cutscene.
|
||||
- 0x95 # Midna text after re-entering west wing after sol was stolen.
|
||||
- 0x9E # Midna text at dungeon entrance.
|
||||
- 0xB3 # Watched east wing second room stairs CS.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x57 # Unlock door in north room 3.
|
||||
- 0x58 # Unlock door in east room 2.
|
||||
- 0x59 # Unlock door in west room 2.
|
||||
- 0x6C # Unlock door in north room 2.
|
||||
- 0x7A # Unlock door in norht room 1.
|
||||
- 0x7B # Unlock door in east room 1.
|
||||
- 0x7C # Unlock door in west room 1.
|
||||
- Big_Keys == Keysy:
|
||||
- 0x56 # Unlocked Palace of Twilight Boss Door.
|
||||
- 0xED # Got Palace of Twilight Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Palace of Twilight Compass.
|
||||
- 0xEF # Got Palace of Twilight Dungeon Map.
|
||||
|
||||
Hyrule Castle:
|
||||
Index: 0x18
|
||||
Flags:
|
||||
- 0x4B # Watched CS with Allies in HC.
|
||||
- Skip_Minor_Cutscenes == On:
|
||||
- 0x4F # Hyrule Castle Graveyard intro CS.
|
||||
- 0x8C # East garden intro CS.
|
||||
- 0x8D # East garden intro CS trigger.
|
||||
- 0x77 # Midna text at the east end of the east garden.
|
||||
- 0x82 # South garden intro CS.
|
||||
- 0x99 # Double Darknut room intro CS
|
||||
- 0xA4 # Midna text after Owl Statue chest in graveyard.
|
||||
- 0xB7 # Lit southeast torch in second floor north room for the first time CS.
|
||||
- 0xB8 # Lit northeast torch in second floor north room for the first time CS.
|
||||
- Small_Keys == Keysy:
|
||||
- 0x93 # Unlock door outside 3F.
|
||||
- 0xB0 # Unlock treasure room door.
|
||||
- 0xA3 # Unlock door in south garden.
|
||||
- Big_Keys == Keysy and Hyrule_Castle_Big_Key_Requirements == None:
|
||||
- 0xA1 # Unlocked Hyrule Castle Boss Door.
|
||||
- 0xED # Got Hyrule Castle Big Key.
|
||||
- Maps_and_Compasses == Start_With:
|
||||
- 0xEE # Got Hyrule Castle Compass.
|
||||
- 0xEF # Got Hyrule Castle Dungeon Map.
|
||||
- Lower_Hyrule_Castle_Chandelier == On:
|
||||
- 0x6F # watched double Dinalfos cs 1
|
||||
- 0x70 # watched double Dinalfos cs 2
|
||||
- 0x85 # watched focus on lowered chandelier cs
|
||||
- 0x9D # lower the main hall chandelier
|
||||
- 0xAF # defeated double Dinalfos (opens gates both sides)
|
||||
- Hyrule_Castle_Big_Key_Requirements == None:
|
||||
- 0x94 # Open HC BK gate
|
||||
@@ -0,0 +1,66 @@
|
||||
Seed: TESTTESTTEST
|
||||
Plandomizer: false
|
||||
Generate Spoiler Log: true
|
||||
Arbiters Does Not Require Bulblin Camp: Random
|
||||
Back Slice as Sword: Random
|
||||
Ball and Chain Webs: Random
|
||||
Big Keys: Random
|
||||
Bonks Do Damage: Random
|
||||
City Does Not Require Filled Skybook: Random
|
||||
Damage Multiplier: Random
|
||||
Dungeon Rewards Can Be Anywhere: Random
|
||||
Eldin Twilight Cleared: Random
|
||||
Faron Twilight Cleared: Random
|
||||
Faron Woods Logic: Random
|
||||
Fast Iron Boots: Random
|
||||
Gifts From NPCs: Random
|
||||
Golden Bugs: Random
|
||||
Goron Mines Entrance: Random
|
||||
Hidden Skills: Random
|
||||
Hyrule Barrier Requirements: Random
|
||||
Increase Spinner Speed: Random
|
||||
Increase Wallet Capacity: Random
|
||||
Instant Message Text: Random
|
||||
Item Scarcity: Random
|
||||
Lakebed Does Not Require Water Bombs: Random
|
||||
Lanayru Twilight Cleared: Random
|
||||
Logic Rules: Random
|
||||
Maps and Compasses: Random
|
||||
No Small Keys on Bosses: Random
|
||||
Open Door of Time: Random
|
||||
Palace of Twilight Requirements: Random
|
||||
Poe Souls: Random
|
||||
Quick Transform: Random
|
||||
Random Starting Item Count: 0
|
||||
Randomize Starting Spawn: Random
|
||||
Randomize Dungeon Entrances: Random
|
||||
Randomize Boss Entrances: Random
|
||||
Randomize Grotto Entrances: Random
|
||||
Randomize Cave Entrances: Random
|
||||
Randomize Interior Entrances: Random
|
||||
Randomize Overworld Entrances: Random
|
||||
Decouple Double Door Entrances: Random
|
||||
Decouple Entrances: Random
|
||||
Sacred Grove Does Not Require Skull Kid: Random
|
||||
Shop Items: Random
|
||||
Shops Display The Replaced Item: Random
|
||||
Skip Major Cutscenes: Random
|
||||
Skip Midna's Desparate Hour: Random
|
||||
Skip Minor Cutscenes: Random
|
||||
Skip Prologue: Random
|
||||
Sky Characters: Random
|
||||
Small Keys: Random
|
||||
Snowpeak Does Not Require Reekfish Scent: Random
|
||||
Starting Form: Random
|
||||
Starting Hearts: 3
|
||||
Starting Time of Day: Random
|
||||
Temple of Time Sword Requirement: Random
|
||||
Logic Transform Anywhere: Random
|
||||
Trap Item Frequency: Random
|
||||
Unlock Map Regions: Random
|
||||
Unrequired Dungeons Are Barren: Random
|
||||
trappable_items: major_items
|
||||
Starting Inventory:
|
||||
{}
|
||||
Excluded Locations:
|
||||
[]
|
||||
@@ -0,0 +1,4 @@
|
||||
Seed: TESTTESTTEST
|
||||
Small Keys: Any Dungeon
|
||||
Big Keys: Any Dungeon
|
||||
Maps and Compasses: Any Dungeon
|
||||
@@ -0,0 +1,4 @@
|
||||
Seed: TESTTESTTEST
|
||||
Small Keys: Anywhere
|
||||
Big Keys: Anywhere
|
||||
Maps and Compasses: Anywhere
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Dungeon Rewards Can Be Anywhere: On
|
||||
@@ -0,0 +1,5 @@
|
||||
Seed: TESTTESTTEST
|
||||
Bonks Do Damage: On
|
||||
Damage Multiplier: OHKO
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Eldin Twilight Cleared: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Lanayru Twilight Cleared: On
|
||||
@@ -0,0 +1 @@
|
||||
Seed: TESTTESTTEST
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Twilight Cleared: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Freestanding Rupees: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Gifts From NPCs: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Golden Bugs: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Hidden Rupees: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Hidden Skills: On
|
||||
@@ -0,0 +1,3 @@
|
||||
Seed: TESTTESTTEST
|
||||
Hyrule Barrier Requirements: Dungeons
|
||||
Hyrule Barrier Dungeons: 8
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Hyrule Barrier Requirements: Fused Shadows
|
||||
@@ -0,0 +1,3 @@
|
||||
seed: TESTTESTTEST
|
||||
Hyrule Barrier Requirements: Hearts
|
||||
Hyrule Barrier Hearts: 13
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Hyrule Barrier Requirements: Mirror Shards
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Hyrule Barrier Requirements: Open
|
||||
@@ -0,0 +1,3 @@
|
||||
seed: TESTTESTTEST
|
||||
Hyrule Barrier Requirements: Poe Souls
|
||||
Hyrule Barrier Poe Souls: 30
|
||||
@@ -0,0 +1,4 @@
|
||||
Seed: TESTTESTTEST
|
||||
Small Keys: Keysy
|
||||
Big Keys: Keysy
|
||||
Maps and Compasses: Start With
|
||||
@@ -0,0 +1,16 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Woods Logic: Open
|
||||
Skip Prologue: On
|
||||
Faron Twilight Cleared: On
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
Skip Midna's Desparate Hour: On
|
||||
Randomize Starting Spawn: On
|
||||
Randomize Dungeon Entrances: On
|
||||
Randomize Boss Entrances: On
|
||||
Randomize Grotto Entrances: On
|
||||
Randomize Cave Entrances: On
|
||||
Randomize Interior Entrances: On
|
||||
Randomize Overworld Entrances: On
|
||||
Decouple Double Door Entrances: On
|
||||
Decouple Entrances: On
|
||||
@@ -0,0 +1,15 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Woods Logic: Open
|
||||
Skip Prologue: On
|
||||
Faron Twilight Cleared: On
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
Skip Midna's Desparate Hour: On
|
||||
Randomize Starting Spawn: On
|
||||
Randomize Dungeon Entrances: On
|
||||
Randomize Grotto Entrances: On
|
||||
Randomize Cave Entrances: On
|
||||
Randomize Interior Entrances: On
|
||||
Randomize Overworld Entrances: On
|
||||
Mixed Entrance Pools:
|
||||
[["Dungeon", "Grotto"], ["Overworld", "Cave", "Interior"]]
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Woods Logic: Open
|
||||
@@ -0,0 +1,7 @@
|
||||
Seed: TESTTESTTEST
|
||||
Skip Prologue: On
|
||||
Faron Woods Logic: Open
|
||||
Faron Twilight Cleared: On
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
Unlock Map Regions: On
|
||||
@@ -0,0 +1,4 @@
|
||||
Seed: TESTTESTTEST
|
||||
Small Keys: Overworld
|
||||
Big Keys: Overworld
|
||||
Maps and Compasses: Overworld
|
||||
@@ -0,0 +1,4 @@
|
||||
Seed: TESTTESTTEST
|
||||
Small Keys: Own Dungeon
|
||||
Big Keys: Own Dungeon
|
||||
Maps and Compasses: Own Dungeon
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Palace of Twilight Requirements: Fused Shadows
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Palace of Twilight Requirements: Mirror Shards
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Palace of Twilight Requirements: Open
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Poe Souls: All
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Poe Souls: Dungeon
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Poe Souls: Overworld
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Randomize Boss Entrances: On
|
||||
@@ -0,0 +1,8 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Woods Logic: Open
|
||||
Skip Prologue: On
|
||||
Faron Twilight Cleared: On
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
Skip Midna's Desparate Hour: On
|
||||
Randomize Cave Entrances: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Randomize Dungeon Entrances: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Randomize Grotto Entrances: On
|
||||
@@ -0,0 +1,8 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Woods Logic: Open
|
||||
Skip Prologue: On
|
||||
Faron Twilight Cleared: On
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
Skip Midna's Desparate Hour: On
|
||||
Randomize Interior Entrances: On
|
||||
@@ -0,0 +1,8 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Woods Logic: Open
|
||||
Skip Prologue: On
|
||||
Faron Twilight Cleared: On
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
Skip Midna's Desparate Hour: On
|
||||
Randomize Overworld Entrances: On
|
||||
@@ -0,0 +1,8 @@
|
||||
Seed: TESTTESTTEST
|
||||
Faron Woods Logic: Open
|
||||
Skip Prologue: On
|
||||
Faron Twilight Cleared: On
|
||||
Eldin Twilight Cleared: On
|
||||
Lanayru Twilight Cleared: On
|
||||
Skip Midna's Desparate Hour: On
|
||||
Randomize Starting Spawn: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Item Scarcity: Minimal
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Item Scarcity: Plentiful
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Shop Items: On
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
Seed: TESTTESTTEST
|
||||
Lakebed Does Not Require Water Bombs: On
|
||||
Arbiters Does Not Require Bulblin Camp: On
|
||||
Snowpeak Does Not Require Reekfish Scent: On
|
||||
Sacred Grove Does Not Require Skull Kid: On
|
||||
City Does Not Require Filled Skybook: On
|
||||
Goron Mines Entrance: On
|
||||
Temple of Time Sword Requirement: None
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Skip Midna's Desparate Hour: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Skip Prologue: On
|
||||
@@ -0,0 +1,2 @@
|
||||
Seed: TESTTESTTEST
|
||||
Sky Characters: On
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
Seed: TESTTESTTEST
|
||||
Unrequired Dungeons Are Barren: On
|
||||
Hyrule Barrier Requirements: Mirror Shards
|
||||
@@ -0,0 +1,4 @@
|
||||
Seed: TESTTESTTEST
|
||||
Starting Form: Wolf
|
||||
Skip Prologue: On
|
||||
Faron Woods Logic: Open
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user