Merge branch 'develop-rando' into starting_hearts

This commit is contained in:
Garrett Cox 2024-05-09 20:21:06 -05:00 committed by GitHub
commit 00c3f995e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
547 changed files with 26619 additions and 27146 deletions

View File

@ -1 +1 @@
libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev ninja-build
libusb-dev libusb-1.0-0-dev libsdl2-dev libsdl2-net-dev libpng-dev libglew-dev libzip-dev zipcmp zipmerge ziptool nlohmann-json3-dev libtinyxml2-dev libspdlog-dev ninja-build

View File

@ -47,6 +47,20 @@ jobs:
make -j 10
sudo make install
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
- name: Install latest tinyxml2
run: |
sudo apt-get remove libtinyxml2-dev
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "tinyxml2-10.0.0" ]; then
wget https://github.com/leethomason/tinyxml2/archive/refs/tags/10.0.0.tar.gz
tar -xzf 10.0.0.tar.gz
fi
cd tinyxml2-10.0.0
mkdir build
cd build
cmake ..
make
sudo make install
- name: Generate soh.otr
run: |
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
@ -92,14 +106,14 @@ jobs:
if [ -d /opt/local/ ]; then
echo "MacPorts already installed"
else
wget https://github.com/macports/macports-base/releases/download/v2.7.2/MacPorts-2.7.2-12-Monterey.pkg
sudo installer -pkg ./MacPorts-2.7.2-12-Monterey.pkg -target /
wget https://github.com/macports/macports-base/releases/download/v2.9.3/MacPorts-2.9.3-12-Monterey.pkg
sudo installer -pkg ./MacPorts-2.9.3-12-Monterey.pkg -target /
fi
echo "/opt/local/bin:/opt/local/sbin" >> $GITHUB_PATH
- name: Install dependencies
if: ${{ !vars.MAC_RUNNER }}
run: |
brew uninstall --ignore-dependencies libpng
brew uninstall --ignore-dependencies libpng libzip
sudo port install $(cat .github/workflows/macports-deps.txt)
brew install ninja
- name: Download soh.otr
@ -175,6 +189,51 @@ jobs:
make -j 10
sudo make install
sudo cp -av /usr/local/lib/libSDL* /lib/x86_64-linux-gnu/
- name: Install latest libzip
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) }}
run: |
sudo apt-get remove libzip-dev zipcmp zipmerge ziptool
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "libzip-1.10.1" ]; then
wget https://libzip.org/download/libzip-1.10.1.tar.gz
tar -xzvf libzip-1.10.1.tar.gz
fi
cd libzip-1.10.1
mkdir build
cd build
cmake ..
make
sudo make install
- name: Install latest nlohmann
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) }}
run: |
sudo apt-get remove nlohmann-json3-dev
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "json-3.11.3" ]; then
wget https://github.com/nlohmann/json/archive/refs/tags/v3.11.3.tar.gz
tar -xzvf v3.11.3.tar.gz
fi
cd json-3.11.3
mkdir build
cd build
cmake ..
make
sudo make install
- name: Install latest tinyxml2
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
run: |
sudo apt-get remove libtinyxml2-dev
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
if [ ! -d "tinyxml2-10.0.0" ]; then
wget https://github.com/leethomason/tinyxml2/archive/refs/tags/10.0.0.tar.gz
tar -xzf 10.0.0.tar.gz
fi
cd tinyxml2-10.0.0
mkdir build
cd build
cmake ..
make
sudo make install
- name: Install latest SDL_net
if: ${{ (matrix.os == 'ubuntu-20.04' && !vars.LINUX_COMPATIBILITY_RUNNER) || (matrix.os == 'ubuntu-22.04' && !vars.LINUX_PERFORMANCE_RUNNER) }}
run: |
@ -211,99 +270,6 @@ jobs:
path: |
soh.appimage
readme.txt
build-switch:
needs: generate-soh-otr
runs-on: ${{ (vars.LINUX_RUNNER && fromJSON(vars.LINUX_RUNNER)) || 'ubuntu-latest' }}
container:
image: devkitpro/devkita64:20240120
steps:
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ninja-build
sudo apt-get remove -y cmake
wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.sh -O /tmp/cmake.sh
sudo sh /tmp/cmake.sh --prefix=/usr/local/ --exclude-subdir
- name: Fix dubious ownership error
if: ${{ vars.LINUX_RUNNER }}
run: git config --global --add safe.directory '*'
- uses: actions/checkout@v3
with:
submodules: true
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.11
with:
key: ${{ runner.os }}-switch-ccache-${{ github.ref }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-switch-ccache-${{ github.ref }}
${{ runner.os }}-switch-ccache-
- name: Build SoH
run: |
cmake -H. -Bbuild-switch -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/Switch.cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
cmake --build build-switch --target soh_nro -j3
mv build-switch/soh/*.nro soh.nro
mv README.md readme.txt
- name: Download soh.otr
uses: actions/download-artifact@v4
with:
name: soh.otr
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: soh-switch
path: |
soh.nro
soh.otr
readme.txt
build-wiiu:
needs: generate-soh-otr
runs-on: ${{ (vars.LINUX_RUNNER && fromJSON(vars.LINUX_RUNNER)) || 'ubuntu-latest' }}
container:
image: devkitpro/devkitppc:20230110
steps:
- name: Install dependencies
if: ${{ !vars.LINUX_RUNNER }}
run: |
sudo apt-get update
sudo apt-get install -y ninja-build
sudo apt-get remove -y cmake
wget https://github.com/Kitware/CMake/releases/download/v3.28.3/cmake-3.28.3-linux-x86_64.sh -O /tmp/cmake.sh
sudo sh /tmp/cmake.sh --prefix=/usr/local/ --exclude-subdir
- uses: actions/checkout@v3
with:
submodules: true
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2.11
with:
key: ${{ runner.os }}-wiiu-ccache-${{ github.ref }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-wiiu-ccache-${{ github.ref }}
${{ runner.os }}-wiiu-ccache-
- name: Build SoH
run: |
cmake -H. -Bbuild-wiiu -GNinja -DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/WiiU.cmake -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache
cmake --build build-wiiu --target soh_wuhb --config Release -j3
mv build-wiiu/soh/*.rpx soh.rpx
mv build-wiiu/soh/*.wuhb soh.wuhb
mv README.md readme.txt
env:
DEVKITPRO: /opt/devkitpro
DEVKITPPC: /opt/devkitpro/devkitPPC
- name: Download soh.otr
uses: actions/download-artifact@v4
with:
name: soh.otr
- name: Upload build
uses: actions/upload-artifact@v4
with:
name: soh-wiiu
path: |
soh.rpx
soh.wuhb
soh.otr
readme.txt
build-windows:
needs: generate-soh-otr
runs-on: ${{ (vars.WINDOWS_RUNNER && fromJSON(vars.WINDOWS_RUNNER)) || 'windows-latest' }}

View File

@ -1 +1 @@
libsdl2 +universal libsdl2_net +universal libpng +universal glew +universal
libsdl2 +universal libsdl2_net +universal libpng +universal glew +universal libzip +universal nlohmann-json +universal tinyxml2 +universal

View File

@ -1,3 +1,8 @@
# todo:
# nlohmann
# tinyxml2
# spdlog
name: test-builds-on-distros
on:
workflow_dispatch: # by request
@ -23,31 +28,31 @@ jobs:
if: ${{ matrix.image == 'archlinux:base' }}
run: |
echo arch
echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng sdl2_net boost
echo pacman -S ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
pacman -Syu --noconfirm
pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng sdl2_net boost
pacman -S --noconfirm ${{ matrix.cc }} git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
- name: Install dependencies (dnf)
if: ${{ matrix.image == 'fedora:39' }}
run: |
echo fedora
echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel
echo dnf install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
dnf -y upgrade
dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel
dnf -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
- name: Install dependencies (apt)
if: ${{ matrix.image == 'ubuntu:mantic' || matrix.image == 'debian:bookworm' }}
run: |
echo debian based
echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev
echo apt-get install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
apt-get update
apt-get -y full-upgrade
apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev
apt-get -y install ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'g++') || '' }} git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
- name: Install dependencies (zypper)
if: ${{ matrix.image == 'opensuse/tumbleweed:latest' }}
run: |
echo openSUSE
echo zypper in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel
echo zypper in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
zypper --non-interactive dup
zypper --non-interactive in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel
zypper --non-interactive in ${{ matrix.cc }} ${{ (matrix.cxx == 'g++' && 'gcc-c++') || '' }} ${{ matrix.cc == 'clang' && 'libstdc++-devel' || '' }} git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
- uses: actions/checkout@v3
with:
submodules: true

2
.gitignore vendored
View File

@ -448,5 +448,5 @@ _packages
*/extract_assets_cmake*
/build*
soh/build.c
soh/src/boot/build.c
soh/properties.h

24
CMake/lus-cvars.cmake Normal file
View File

@ -0,0 +1,24 @@
set(CVAR_VSYNC_ENABLED "${CVAR_PREFIX_SETTING}.VsyncEnabled" CACHE STRING "")
set(CVAR_Z_FIGHTING_MODE "${CVAR_PREFIX_SETTING}.ZFightingMode" CACHE STRING "")
set(CVAR_NEW_FILE_DROPPED "${CVAR_PREFIX_GENERAL}.NewFileDropped" CACHE STRING "")
set(CVAR_DROPPED_FILE "${CVAR_PREFIX_GENERAL}.DroppedFile" CACHE STRING "")
set(CVAR_INTERNAL_RESOLUTION "${CVAR_PREFIX_SETTING}.InternalResolution" CACHE STRING "")
set(CVAR_MSAA_VALUE "${CVAR_PREFIX_SETTING}.MSAAValue" CACHE STRING "")
set(CVAR_SDL_WINDOWED_FULLSCREEN "${CVAR_PREFIX_SETTING}.SdlWindowedFullscreen" CACHE STRING "")
set(CVAR_TEXTURE_FILTER "${CVAR_PREFIX_SETTING}.TextureFilter" CACHE STRING "")
set(CVAR_IMGUI_CONTROLLER_NAV "${CVAR_PREFIX_SETTING}.ControlNav" CACHE STRING "")
set(CVAR_CONSOLE_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.Console" CACHE STRING "")
set(CVAR_CONTROLLER_CONFIGURATION_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.ControllerConfiguration" CACHE STRING "")
set(CVAR_CONTROLLER_DISCONNECTED_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.ControllerDisconnected" CACHE STRING "")
set(CVAR_CONTROLLER_REORDERING_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.ControllerReordering" CACHE STRING "")
set(CVAR_GFX_DEBUGGER_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.GfxDebugger" CACHE STRING "")
set(CVAR_STATS_WINDOW_OPEN "${CVAR_PREFIX_WINDOW}.Stats" CACHE STRING "")
set(CVAR_ENABLE_MULTI_VIEWPORTS "${CVAR_PREFIX_SETTING}.EnableMultiViewports" CACHE STRING "")
set(CVAR_LOW_RES_MODE "${CVAR_PREFIX_SETTING}.LowResMode" CACHE STRING "")
set(CVAR_SIMULATED_INPUT_LAG "${CVAR_PREFIX_SETTING}.SimulatedInputLag" CACHE STRING "")
set(CVAR_ALT_ASSETS "${CVAR_PREFIX_ENHANCEMENT}.AltAssets" CACHE STRING "")
set(CVAR_GAME_OVERLAY_FONT "${CVAR_PREFIX_SETTING}.OverlayFont" CACHE STRING "")
set(CVAR_MENU_BAR_OPEN "${CVAR_PREFIX_SETTING}.OpenMenuBar" CACHE STRING "")
set(CVAR_PREFIX_CONTROLLERS "${CVAR_PREFIX_SETTING}.Controllers" CACHE STRING "")
set(CVAR_PREFIX_ADVANCED_RESOLUTION "${CVAR_PREFIX_SETTING}.AdvancedResolution" CACHE STRING "")
include("libultraship/cmake/cvars.cmake")

26
CMake/soh-cvars.cmake Normal file
View File

@ -0,0 +1,26 @@
set(CVAR_PREFIX_RANDOMIZER_ENHANCEMENT "gRandoEnhancements")
set(CVAR_PREFIX_RANDOMIZER_SETTING "gRandoSettings")
set(CVAR_PREFIX_COSMETIC "gCosmetics")
set(CVAR_PREFIX_AUDIO "gAudioEditor")
set(CVAR_PREFIX_CHEAT "gCheats")
set(CVAR_PREFIX_ENHANCEMENT "gEnhancements")
set(CVAR_PREFIX_SETTING "gSettings")
set(CVAR_PREFIX_WINDOW "gOpenWindows")
set(CVAR_PREFIX_TRACKER "gTrackers")
set(CVAR_PREFIX_DEVELOPER_TOOLS "gDeveloperTools")
set(CVAR_PREFIX_GENERAL "gGeneral")
set(CVAR_PREFIX_REMOTE "gRemote")
add_compile_definitions(
CVAR_PREFIX_RANDOMIZER_ENHANCEMENT="${CVAR_PREFIX_RANDOMIZER_ENHANCEMENT}"
CVAR_PREFIX_RANDOMIZER_SETTING="${CVAR_PREFIX_RANDOMIZER_SETTING}"
CVAR_PREFIX_COSMETIC="${CVAR_PREFIX_COSMETIC}"
CVAR_PREFIX_AUDIO="${CVAR_PREFIX_AUDIO}"
CVAR_PREFIX_CHEAT="${CVAR_PREFIX_CHEAT}"
CVAR_PREFIX_ENHANCEMENT="${CVAR_PREFIX_ENHANCEMENT}"
CVAR_PREFIX_SETTING="${CVAR_PREFIX_SETTING}"
CVAR_PREFIX_WINDOW="${CVAR_PREFIX_WINDOW}"
CVAR_PREFIX_TRACKER="${CVAR_PREFIX_TRACKER}"
CVAR_PREFIX_DEVELOPER_TOOLS="${CVAR_PREFIX_DEVELOPER_TOOLS}"
CVAR_PREFIX_GENERAL="${CVAR_PREFIX_GENERAL}"
CVAR_PREFIX_REMOTE="${CVAR_PREFIX_REMOTE}"
)

View File

@ -5,8 +5,10 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
project(Ship VERSION 8.0.4 LANGUAGES C CXX)
set(PROJECT_BUILD_NAME "MacReady Echo" CACHE STRING "")
project(Ship VERSION 8.0.5 LANGUAGES C CXX)
include(CMake/soh-cvars.cmake)
include(CMake/lus-cvars.cmake)
set(PROJECT_BUILD_NAME "MacReady Foxtrot" CACHE STRING "")
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh)
@ -20,7 +22,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(VCPKG_TARGET_TRIPLET x64-windows-static)
vcpkg_bootstrap()
vcpkg_install_packages(zlib bzip2 libpng sdl2 sdl2-net glew glfw3)
vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3 nlohmann-json tinyxml2 spdlog)
if (CMAKE_C_COMPILER_LAUNCHER MATCHES "ccache|sccache")
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT Embedded)

@ -1 +1 @@
Subproject commit e93bd2be062b13106fdb29d98cf4ada4d7ad6827
Subproject commit 3cea9ee7c017d842aa4d9ceeb8d3ffbf29c6effb

2
ZAPDTR

@ -1 +1 @@
Subproject commit eff29036118349e142ee8efca80fd975a2a2b6ff
Subproject commit f38a9c92eb99368c0607acf356d5651ebdc96f51

View File

@ -88,34 +88,34 @@ cd "build/x64"
#### Debian/Ubuntu
```sh
# using gcc
apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev
apt-get install gcc g++ git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
# or using clang
apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libboost-dev libopengl-dev
apt-get install clang git cmake ninja-build lsb-release libsdl2-dev libpng-dev libsdl2-net-dev libzip-dev zipcmp zipmerge ziptool libboost-dev libopengl-dev
```
#### Arch
```sh
# using gcc
pacman -S gcc git cmake ninja lsb-release sdl2 libpng sdl2_net boost
pacman -S gcc git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
# or using clang
pacman -S clang git cmake ninja lsb-release sdl2 libpng sdl2_net boost
pacman -S clang git cmake ninja lsb-release sdl2 libpng libzip sdl2_net boost
```
#### Fedora
```sh
# using gcc
dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel
dnf install gcc gcc-c++ git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
# or using clang
dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel boost-devel
dnf install clang git cmake ninja-build lsb_release SDL2-devel libpng-devel libzip-devel libzip-tools boost-devel
```
#### openSUSE
```sh
# using gcc
zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel boost
zypper in gcc gcc-c++ git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
# or using clang
zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel boost
zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel libzip-devel libzip-tools
```
### Build
@ -123,34 +123,27 @@ zypper in clang libstdc++-devel git cmake ninja SDL2-devel libpng16-devel boost
_Note: If you're using Visual Studio Code, the [CMake Tools plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
```bash
# Clone the repo
# Clone the repo and enter the directory
git clone https://github.com/HarbourMasters/Shipwright.git
cd Shipwright
# Clone the submodules
git submodule update --init
# Copy the baserom to the OTRExporter folder
cp <path to your ROM> OTRExporter
# Generate Ninja project
cmake -H. -Bbuild-cmake -GNinja # -DCMAKE_BUILD_TYPE:STRING=Release (if you're packaging) -DPython3_EXECUTABLE=$(which python3) (if you are using non-standard Python installations such as PyEnv)
# Extract assets & generate OTR (run this anytime you need to regenerate OTR)
cmake --build build-cmake --target ExtractAssets
# Generate soh.otr
cmake --build build-cmake --target GenerateSohOtr
# Compile the project
cmake --build build-cmake # --config Release (if you're packaging)
# Now you can run the executable in ./build-cmake/soh/soh.elf
# To develop the project open the repository in VSCode (or your preferred editor)
# If you need to clean the project you can run
cmake --build build-cmake --target clean
# If you need to regenerate the asset headers to check them into source
cmake --build build-cmake --target ExtractAssetHeaders
# If you need a newer soh.otr only
cmake --build build-cmake --target GenerateSohOtr
```
### Generating a distributable
### Generate a distributable
After compiling the project you can generate a distributable by running of the following:
```bash
# Go to build folder
@ -161,6 +154,20 @@ cpack -G ZIP
cpack -G External (creates appimage)
```
### Additional CMake Targets
#### Clean
```bash
# If you need to clean the project you can run
cmake --build build-cmake --target clean
```
#### Regenerate Asset Headers
```bash
# If you need to regenerate the asset headers to check them into source
cp <path to your ROM> OTRExporter
cmake --build build-cmake --target ExtractAssetHeaders
```
## macOS
Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake` (can be installed via homebrew, macports, etc)

@ -1 +1 @@
Subproject commit a516b66ce0c89fe4e33c55b1fbfbde845d0bf129
Subproject commit 0da318c0f4e431313565cad546fc469b8e850388

View File

@ -92,10 +92,6 @@ if (NOT TARGET libultraship)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libultraship ${CMAKE_BINARY_DIR}/libultraship)
endif()
if (NOT TARGET ZAPDUtils)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils ${CMAKE_BINARY_DIR}/ZAPDUtils)
endif()
if (NOT TARGET ZAPDLib)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
endif()
@ -105,8 +101,8 @@ set(PROJECT_NAME soh)
################################################################################
# Sources
################################################################################
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/build.c.in ${CMAKE_BINARY_DIR}/build.c @ONLY)
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/properties.h.in ${CMAKE_CURRENT_SOURCE_DIR}/properties.h @ONLY)
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/build.c.in ${CMAKE_CURRENT_SOURCE_DIR}/src/boot/build.c @ONLY)
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/properties.h.in ${CMAKE_CURRENT_SOURCE_DIR}/properties.h @ONLY)
set(Header_Files "resource.h")
source_group("headers" FILES ${Header_Files})
@ -217,8 +213,6 @@ source_group("soh\\resource\\importer\\scenecommand" REGULAR_EXPRESSION "soh/res
# src (decomp) {{{
file(GLOB_RECURSE src__ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "src/*.c" "src/*.h")
list(APPEND src__ ${CMAKE_BINARY_DIR}/build.c)
list(APPEND src__ ${CMAKE_CURRENT_SOURCE_DIR}/properties.h)
list(APPEND src__ ${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc)
list(FILTER src__ EXCLUDE REGEX "src/dmadata/*")
list(FILTER src__ EXCLUDE REGEX "src/elf_message/*")
@ -238,7 +232,6 @@ list(REMOVE_ITEM src__ "src/libultra/gu/sqrtf.c")
list(REMOVE_ITEM src__ "src/libultra/gu/us2dex.c")
source_group("src" REGULAR_EXPRESSION "src/*")
source_group("src\\build" FILES ${CMAKE_BINARY_DIR}/build.c ${CMAKE_CURRENT_SOURCE_DIR}/properties.h ${CMAKE_CURRENT_SOURCE_DIR}/Resource.rc)
source_group("src\\boot" REGULAR_EXPRESSION "src/boot/*")
source_group("src\\buffers" REGULAR_EXPRESSION "src/buffers/*")
source_group("src\\code" REGULAR_EXPRESSION "src/code/*")
@ -391,10 +384,8 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/extern/tinyxml2
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/libjpeg/include/
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/libultraship/Lib/spdlog/include/
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic/Fast3D/U64/PR
${CMAKE_CURRENT_SOURCE_DIR}/../libultraship/src/graphic
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPDUtils
${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD/resource/type
${SDL2-INCLUDE}
${SDL2-NET-INCLUDE}
@ -420,6 +411,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
"_UNICODE"
STORMLIB_NO_AUTO_LINK
"_CRT_SECURE_NO_WARNINGS;"
NOMINMAX
)
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
target_compile_definitions(${PROJECT_NAME} PRIVATE
@ -437,6 +429,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
"UNICODE;"
"_UNICODE"
STORMLIB_NO_AUTO_LINK
NOMINMAX
)
endif()
elseif (CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
@ -554,6 +547,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
-Wno-parentheses
-Wno-narrowing
-Wno-missing-braces
-Wno-int-conversion
$<$<COMPILE_LANGUAGE:C>:
-Werror-implicit-function-declaration
-Wno-incompatible-pointer-types
@ -650,15 +644,6 @@ endif()
################################################################################
# Pre build events
################################################################################
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_custom_command_if(
TARGET ${PROJECT_NAME}
PRE_BUILD
COMMANDS
COMMAND $<CONFIG:Debug> copy /b $<SHELL_PATH:${CMAKE_BINARY_DIR}/>build.c +,,
)
endif()
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
add_custom_command(
TARGET ${PROJECT_NAME}
@ -677,7 +662,6 @@ endif()
# Dependencies
################################################################################
add_dependencies(${PROJECT_NAME}
ZAPDUtils
libultraship
)
if(NOT CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
@ -691,7 +675,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
set(ADDITIONAL_LIBRARY_DEPENDENCIES
"libultraship;"
"ZAPDUtils;"
"ZAPDLib;"
"glu32;"
"SDL2::SDL2;"
@ -706,7 +689,6 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32")
set(ADDITIONAL_LIBRARY_DEPENDENCIES
"libultraship;"
"ZAPDUtils;"
"ZAPDLib;"
"glu32;"
"SDL2::SDL2;"
@ -724,7 +706,6 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
find_package(Threads REQUIRED)
set(ADDITIONAL_LIBRARY_DEPENDENCIES
"libultraship;"
"ZAPDUtils;"
SDL2::SDL2
-lglad
Threads::Threads
@ -746,7 +727,6 @@ else()
find_package(Threads REQUIRED)
set(ADDITIONAL_LIBRARY_DEPENDENCIES
"libultraship;"
"ZAPDUtils;"
"ZAPDLib;"
SDL2::SDL2
"$<$<BOOL:${BUILD_REMOTE_CONTROL}>:SDL2_net::SDL2_net>"

View File

@ -0,0 +1,16 @@
<DisplayList Version="0">
<ClearGeometryMode G_LIGHTING="1" />
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_cull" VertexBufferIndex="0" VertexOffset="0" Count="8"/>
<CullDisplayList Start="0" End="7"/>
<CallDisplayList Path="objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_material"/>
<CallDisplayList Path="objects/object_mystery_item/gMysteryItemDL_tri_0"/>
<CallDisplayList Path="objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_light_material"/>
<CallDisplayList Path="objects/object_mystery_item/gMysteryItemDL_tri_1"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,56 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="2" V01="4" V02="3" Flag0="0" V10="0" V11="3" V12="5" Flag1="0"/>
<Triangles2 V00="3" V01="6" V02="5" Flag0="0" V10="3" V11="7" V12="6" Flag1="0"/>
<Triangles2 V00="3" V01="8" V02="7" Flag0="0" V10="3" V11="9" V12="8" Flag1="0"/>
<Triangles2 V00="7" V01="10" V02="6" Flag0="0" V10="7" V11="11" V12="10" Flag1="0"/>
<Triangles2 V00="7" V01="12" V02="11" Flag0="0" V10="13" V11="14" V12="0" Flag1="0"/>
<Triangles2 V00="15" V01="13" V02="0" Flag0="0" V10="16" V11="15" V12="0" Flag1="0"/>
<Triangles2 V00="17" V01="16" V02="0" Flag0="0" V10="0" V11="18" V12="17" Flag1="0"/>
<Triangles2 V00="0" V01="19" V02="18" Flag0="0" V10="0" V11="5" V12="19" Flag1="0"/>
<Triangles2 V00="17" V01="20" V02="16" Flag0="0" V10="20" V11="21" V12="16" Flag1="0"/>
<Triangles2 V00="21" V01="22" V02="16" Flag0="0" V10="21" V11="23" V12="22" Flag1="0"/>
<Triangles2 V00="23" V01="24" V02="22" Flag0="0" V10="23" V11="25" V12="24" Flag1="0"/>
<Triangles2 V00="23" V01="26" V02="25" Flag0="0" V10="23" V11="27" V12="26" Flag1="0"/>
<Triangles2 V00="26" V01="28" V02="25" Flag0="0" V10="15" V11="29" V12="13" Flag1="0"/>
<Triangles2 V00="30" V01="31" V02="15" Flag0="0" V10="16" V11="30" V12="15" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_0" VertexBufferIndex="0" VertexOffset="32" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="4" V12="0" Flag1="0"/>
<Triangles2 V00="5" V01="3" V02="0" Flag0="0" V10="6" V11="7" V12="8" Flag1="0"/>
<Triangles2 V00="9" V01="6" V02="8" Flag0="0" V10="9" V11="8" V12="10" Flag1="0"/>
<Triangles2 V00="9" V01="11" V02="6" Flag0="0" V10="12" V11="13" V12="14" Flag1="0"/>
<Triangles2 V00="15" V01="12" V02="14" Flag0="0" V10="16" V11="15" V12="14" Flag1="0"/>
<Triangles2 V00="17" V01="16" V02="14" Flag0="0" V10="18" V11="17" V12="14" Flag1="0"/>
<Triangles2 V00="19" V01="18" V02="14" Flag0="0" V10="14" V11="20" V12="19" Flag1="0"/>
<Triangles2 V00="14" V01="21" V02="20" Flag0="0" V10="14" V11="22" V12="21" Flag1="0"/>
<Triangles2 V00="14" V01="23" V02="22" Flag0="0" V10="22" V11="24" V12="21" Flag1="0"/>
<Triangles2 V00="21" V01="25" V02="26" Flag0="0" V10="21" V11="26" V12="20" Flag1="0"/>
<Triangles2 V00="26" V01="27" V02="20" Flag0="0" V10="20" V11="28" V12="29" Flag1="0"/>
<Triangles2 V00="20" V01="29" V02="30" Flag0="0" V10="20" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_0" VertexBufferIndex="0" VertexOffset="64" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="3" V12="1" Flag1="0"/>
<Triangles2 V00="3" V01="4" V02="1" Flag0="0" V10="3" V11="5" V12="4" Flag1="0"/>
<Triangles2 V00="5" V01="6" V02="4" Flag0="0" V10="5" V11="7" V12="6" Flag1="0"/>
<Triangles2 V00="6" V01="8" V02="4" Flag0="0" V10="9" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="9" V02="11" Flag0="0" V10="13" V11="12" V12="11" Flag1="0"/>
<Triangles2 V00="14" V01="13" V02="11" Flag0="0" V10="13" V11="15" V12="12" Flag1="0"/>
<Triangles2 V00="13" V01="16" V02="15" Flag0="0" V10="15" V11="17" V12="12" Flag1="0"/>
<Triangles2 V00="12" V01="18" V02="9" Flag0="0" V10="4" V11="19" V12="20" Flag1="0"/>
<Triangles2 V00="4" V01="20" V02="1" Flag0="0" V10="20" V11="21" V12="1" Flag1="0"/>
<Triangles2 V00="22" V01="2" V02="23" Flag0="0" V10="22" V11="23" V12="24" Flag1="0"/>
<Triangles2 V00="25" V01="26" V02="27" Flag0="0" V10="25" V11="27" V12="28" Flag1="0"/>
<Triangles2 V00="27" V01="29" V02="28" Flag0="0" V10="28" V11="30" V12="25" Flag1="0"/>
<Triangle1 V00="28" V01="31" V02="30"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_0" VertexBufferIndex="0" VertexOffset="96" Count="21"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="2" V11="3" V12="4" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="6" V01="8" V02="7" Flag0="0" V10="9" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="9" V01="11" V02="12" Flag0="0" V10="11" V11="13" V12="12" Flag1="0"/>
<Triangles2 V00="12" V01="14" V02="9" Flag0="0" V10="12" V11="15" V12="14" Flag1="0"/>
<Triangles2 V00="12" V01="16" V02="15" Flag0="0" V10="15" V11="17" V12="14" Flag1="0"/>
<Triangles2 V00="14" V01="18" V02="19" Flag0="0" V10="14" V11="19" V12="9" Flag1="0"/>
<Triangle1 V00="19" V01="20" V02="9"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,120 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="30"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="4" V12="5" Flag1="0"/>
<Triangles2 V00="6" V01="7" V02="8" Flag0="0" V10="6" V11="8" V12="9" Flag1="0"/>
<Triangles2 V00="10" V01="11" V02="12" Flag0="0" V10="10" V11="12" V12="13" Flag1="0"/>
<Triangles2 V00="14" V01="15" V02="16" Flag0="0" V10="14" V11="16" V12="17" Flag1="0"/>
<Triangles2 V00="18" V01="19" V02="20" Flag0="0" V10="18" V11="20" V12="21" Flag1="0"/>
<Triangles2 V00="22" V01="23" V02="24" Flag0="0" V10="22" V11="24" V12="25" Flag1="0"/>
<Triangles2 V00="26" V01="27" V02="28" Flag0="0" V10="26" V11="28" V12="29" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="30" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="62" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="94" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="126" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="158" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="190" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="222" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="254" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="286" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="318" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="350" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_mystery_item/gMysteryItemDL_vtx_1" VertexBufferIndex="0" VertexOffset="382" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="8" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="16" V01="17" V02="18" Flag0="0" V10="16" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="24" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,119 @@
<Vertex Version="0">
<Vtx X="12" Y="36" Z="5" S="151" T="-443" R="0" G="0" B="127" A="255"/>
<Vtx X="2" Y="38" Z="5" S="4" T="-461" R="0" G="0" B="127" A="255"/>
<Vtx X="-4" Y="37" Z="5" S="-71" T="-456" R="0" G="0" B="127" A="255"/>
<Vtx X="-13" Y="34" Z="5" S="-197" T="-417" R="0" G="0" B="127" A="255"/>
<Vtx X="-9" Y="36" Z="5" S="-139" T="-441" R="0" G="0" B="127" A="255"/>
<Vtx X="-3" Y="31" Z="5" S="-59" T="-373" R="0" G="0" B="127" A="255"/>
<Vtx X="-11" Y="27" Z="5" S="-157" T="-323" R="0" G="0" B="127" A="255"/>
<Vtx X="-23" Y="24" Z="5" S="-318" T="-281" R="0" G="0" B="127" A="255"/>
<Vtx X="-19" Y="30" Z="5" S="-275" T="-355" R="0" G="0" B="127" A="255"/>
<Vtx X="-17" Y="32" Z="5" S="-242" T="-388" R="0" G="0" B="127" A="255"/>
<Vtx X="-15" Y="22" Z="5" S="-220" T="-239" R="0" G="0" B="127" A="255"/>
<Vtx X="-26" Y="23" Z="5" S="-358" T="-270" R="0" G="0" B="127" A="255"/>
<Vtx X="-25" Y="24" Z="5" S="-357" T="-278" R="0" G="0" B="127" A="255"/>
<Vtx X="22" Y="31" Z="5" S="277" T="-377" R="0" G="0" B="127" A="255"/>
<Vtx X="18" Y="34" Z="5" S="223" T="-416" R="0" G="0" B="127" A="255"/>
<Vtx X="26" Y="23" Z="5" S="331" T="-269" R="0" G="0" B="127" A="255"/>
<Vtx X="22" Y="11" Z="5" S="286" T="-99" R="0" G="0" B="127" A="255"/>
<Vtx X="15" Y="24" Z="5" S="186" T="-275" R="0" G="0" B="127" A="255"/>
<Vtx X="11" Y="29" Z="5" S="132" T="-343" R="0" G="0" B="127" A="255"/>
<Vtx X="5" Y="31" Z="5" S="46" T="-375" R="0" G="0" B="127" A="255"/>
<Vtx X="15" Y="18" Z="5" S="188" T="-193" R="0" G="0" B="127" A="255"/>
<Vtx X="12" Y="13" Z="5" S="151" T="-130" R="0" G="0" B="127" A="255"/>
<Vtx X="11" Y="5" Z="5" S="128" T="-29" R="0" G="0" B="127" A="255"/>
<Vtx X="8" Y="10" Z="5" S="96" T="-85" R="0" G="0" B="127" A="255"/>
<Vtx X="5" Y="2" Z="5" S="55" T="12" R="0" G="0" B="127" A="255"/>
<Vtx X="-4" Y="0" Z="5" S="-76" T="43" R="0" G="0" B="127" A="255"/>
<Vtx X="-2" Y="4" Z="5" S="-44" T="-5" R="0" G="0" B="127" A="255"/>
<Vtx X="2" Y="7" Z="5" S="10" T="-45" R="0" G="0" B="127" A="255"/>
<Vtx X="-4" Y="2" Z="5" S="-64" T="19" R="0" G="0" B="127" A="255"/>
<Vtx X="24" Y="28" Z="5" S="312" T="-329" R="0" G="0" B="127" A="255"/>
<Vtx X="25" Y="15" Z="5" S="324" T="-165" R="0" G="0" B="127" A="255"/>
<Vtx X="26" Y="19" Z="5" S="333" T="-209" R="0" G="0" B="127" A="255"/>
<Vtx X="22" Y="11" Z="5" S="286" T="-99" R="0" G="0" B="127" A="255"/>
<Vtx X="24" Y="13" Z="5" S="308" T="-128" R="0" G="0" B="127" A="255"/>
<Vtx X="25" Y="15" Z="5" S="324" T="-165" R="0" G="0" B="127" A="255"/>
<Vtx X="18" Y="8" Z="5" S="221" T="-58" R="0" G="0" B="127" A="255"/>
<Vtx X="20" Y="9" Z="5" S="258" T="-76" R="0" G="0" B="127" A="255"/>
<Vtx X="11" Y="5" Z="5" S="128" T="-29" R="0" G="0" B="127" A="255"/>
<Vtx X="-5" Y="-4" Z="5" S="-82" T="94" R="0" G="0" B="127" A="255"/>
<Vtx X="2" Y="-4" Z="5" S="14" T="94" R="0" G="0" B="127" A="255"/>
<Vtx X="2" Y="-2" Z="5" S="14" T="76" R="0" G="0" B="127" A="255"/>
<Vtx X="-4" Y="0" Z="5" S="-76" T="43" R="0" G="0" B="127" A="255"/>
<Vtx X="5" Y="2" Z="5" S="55" T="12" R="0" G="0" B="127" A="255"/>
<Vtx X="-5" Y="-2" Z="5" S="-82" T="66" R="0" G="0" B="127" A="255"/>
<Vtx X="-4" Y="37" Z="-5" S="-71" T="-456" R="0" G="0" B="129" A="255"/>
<Vtx X="2" Y="38" Z="-5" S="4" T="-461" R="0" G="0" B="129" A="255"/>
<Vtx X="12" Y="36" Z="-5" S="151" T="-443" R="0" G="0" B="129" A="255"/>
<Vtx X="-9" Y="36" Z="-5" S="-139" T="-441" R="0" G="0" B="129" A="255"/>
<Vtx X="-3" Y="31" Z="-5" S="-59" T="-373" R="0" G="0" B="129" A="255"/>
<Vtx X="5" Y="31" Z="-5" S="46" T="-375" R="0" G="0" B="129" A="255"/>
<Vtx X="11" Y="29" Z="-5" S="132" T="-343" R="0" G="0" B="129" A="255"/>
<Vtx X="15" Y="24" Z="-5" S="186" T="-275" R="0" G="0" B="129" A="255"/>
<Vtx X="22" Y="11" Z="-5" S="286" T="-99" R="0" G="0" B="129" A="255"/>
<Vtx X="26" Y="23" Z="-5" S="331" T="-269" R="0" G="0" B="129" A="255"/>
<Vtx X="22" Y="31" Z="-5" S="277" T="-377" R="0" G="0" B="129" A="255"/>
<Vtx X="18" Y="34" Z="-5" S="223" T="-416" R="0" G="0" B="129" A="255"/>
<Vtx X="24" Y="28" Z="-5" S="312" T="-329" R="0" G="0" B="129" A="255"/>
<Vtx X="26" Y="19" Z="-5" S="333" T="-209" R="0" G="0" B="129" A="255"/>
<Vtx X="25" Y="15" Z="-5" S="324" T="-165" R="0" G="0" B="129" A="255"/>
<Vtx X="24" Y="13" Z="-5" S="308" T="-128" R="0" G="0" B="129" A="255"/>
<Vtx X="20" Y="9" Z="-5" S="258" T="-76" R="0" G="0" B="129" A="255"/>
<Vtx X="18" Y="8" Z="-5" S="221" T="-58" R="0" G="0" B="129" A="255"/>
<Vtx X="11" Y="5" Z="-5" S="128" T="-29" R="0" G="0" B="129" A="255"/>
<Vtx X="12" Y="13" Z="-5" S="151" T="-130" R="0" G="0" B="129" A="255"/>
<Vtx X="11" Y="5" Z="-5" S="128" T="-29" R="0" G="0" B="129" A="255"/>
<Vtx X="8" Y="10" Z="-5" S="96" T="-85" R="0" G="0" B="129" A="255"/>
<Vtx X="12" Y="13" Z="-5" S="151" T="-130" R="0" G="0" B="129" A="255"/>
<Vtx X="5" Y="2" Z="-5" S="55" T="12" R="0" G="0" B="129" A="255"/>
<Vtx X="-4" Y="0" Z="-5" S="-76" T="43" R="0" G="0" B="129" A="255"/>
<Vtx X="2" Y="-2" Z="-5" S="14" T="76" R="0" G="0" B="129" A="255"/>
<Vtx X="-5" Y="-4" Z="-5" S="-82" T="94" R="0" G="0" B="129" A="255"/>
<Vtx X="2" Y="-4" Z="-5" S="14" T="94" R="0" G="0" B="129" A="255"/>
<Vtx X="-5" Y="-2" Z="-5" S="-82" T="66" R="0" G="0" B="129" A="255"/>
<Vtx X="-17" Y="32" Z="-5" S="-242" T="-388" R="0" G="0" B="129" A="255"/>
<Vtx X="-13" Y="34" Z="-5" S="-197" T="-417" R="0" G="0" B="129" A="255"/>
<Vtx X="-9" Y="36" Z="-5" S="-139" T="-441" R="0" G="0" B="129" A="255"/>
<Vtx X="-23" Y="24" Z="-5" S="-318" T="-281" R="0" G="0" B="129" A="255"/>
<Vtx X="-11" Y="27" Z="-5" S="-157" T="-323" R="0" G="0" B="129" A="255"/>
<Vtx X="-3" Y="31" Z="-5" S="-59" T="-373" R="0" G="0" B="129" A="255"/>
<Vtx X="-26" Y="23" Z="-5" S="-358" T="-270" R="0" G="0" B="129" A="255"/>
<Vtx X="-15" Y="22" Z="-5" S="-217" T="-248" R="0" G="0" B="129" A="255"/>
<Vtx X="-25" Y="24" Z="-5" S="-357" T="-278" R="0" G="0" B="129" A="255"/>
<Vtx X="-19" Y="30" Z="-5" S="-275" T="-355" R="0" G="0" B="129" A="255"/>
<Vtx X="-4" Y="2" Z="-5" S="-64" T="19" R="0" G="0" B="129" A="255"/>
<Vtx X="-2" Y="4" Z="-5" S="-44" T="-5" R="0" G="0" B="129" A="255"/>
<Vtx X="2" Y="7" Z="-5" S="10" T="-45" R="0" G="0" B="129" A="255"/>
<Vtx X="22" Y="11" Z="-5" S="286" T="-99" R="0" G="0" B="129" A="255"/>
<Vtx X="15" Y="18" Z="-5" S="188" T="-193" R="0" G="0" B="129" A="255"/>
<Vtx X="15" Y="24" Z="-5" S="186" T="-275" R="0" G="0" B="129" A="255"/>
<Vtx X="-5" Y="-19" Z="-5" S="-376" T="51" R="0" G="0" B="129" A="255"/>
<Vtx X="-2" Y="-18" Z="-5" S="-341" T="36" R="0" G="0" B="129" A="255"/>
<Vtx X="1" Y="-18" Z="-5" S="-301" T="42" R="0" G="0" B="129" A="255"/>
<Vtx X="4" Y="-22" Z="-5" S="-256" T="101" R="0" G="0" B="129" A="255"/>
<Vtx X="3" Y="-20" Z="-5" S="-271" T="65" R="0" G="0" B="129" A="255"/>
<Vtx X="-3" Y="-28" Z="-5" S="-360" T="179" R="0" G="0" B="129" A="255"/>
<Vtx X="2" Y="-27" Z="-5" S="-284" T="170" R="0" G="0" B="129" A="255"/>
<Vtx X="4" Y="-22" Z="-5" S="-256" T="101" R="0" G="0" B="129" A="255"/>
<Vtx X="4" Y="-25" Z="-5" S="-262" T="141" R="0" G="0" B="129" A="255"/>
<Vtx X="2" Y="-27" Z="-5" S="-284" T="170" R="0" G="0" B="129" A="255"/>
<Vtx X="0" Y="-29" Z="-5" S="-320" T="185" R="0" G="0" B="129" A="255"/>
<Vtx X="-3" Y="-28" Z="-5" S="-360" T="179" R="0" G="0" B="129" A="255"/>
<Vtx X="-6" Y="-27" Z="-5" S="-390" T="157" R="0" G="0" B="129" A="255"/>
<Vtx X="-7" Y="-24" Z="-5" S="-405" T="122" R="0" G="0" B="129" A="255"/>
<Vtx X="-5" Y="-19" Z="-5" S="-376" T="51" R="0" G="0" B="129" A="255"/>
<Vtx X="-6" Y="-21" Z="-5" S="-399" T="82" R="0" G="0" B="129" A="255"/>
<Vtx X="1" Y="-18" Z="5" S="-301" T="42" R="0" G="0" B="127" A="255"/>
<Vtx X="-2" Y="-18" Z="5" S="-341" T="36" R="0" G="0" B="127" A="255"/>
<Vtx X="-5" Y="-19" Z="5" S="-376" T="51" R="0" G="0" B="127" A="255"/>
<Vtx X="-7" Y="-24" Z="5" S="-405" T="122" R="0" G="0" B="127" A="255"/>
<Vtx X="-6" Y="-21" Z="5" S="-399" T="82" R="0" G="0" B="127" A="255"/>
<Vtx X="2" Y="-27" Z="5" S="-284" T="170" R="0" G="0" B="127" A="255"/>
<Vtx X="-3" Y="-28" Z="5" S="-360" T="179" R="0" G="0" B="127" A="255"/>
<Vtx X="-6" Y="-27" Z="5" S="-390" T="157" R="0" G="0" B="127" A="255"/>
<Vtx X="0" Y="-29" Z="5" S="-320" T="185" R="0" G="0" B="127" A="255"/>
<Vtx X="4" Y="-25" Z="5" S="-262" T="141" R="0" G="0" B="127" A="255"/>
<Vtx X="4" Y="-22" Z="5" S="-256" T="101" R="0" G="0" B="127" A="255"/>
<Vtx X="3" Y="-20" Z="5" S="-271" T="65" R="0" G="0" B="127" A="255"/>
</Vertex>

View File

@ -0,0 +1,416 @@
<Vertex Version="0">
<Vtx X="-11" Y="16" Z="0" S="-168" T="-172" R="87" G="234" B="90" A="255"/>
<Vtx X="-11" Y="19" Z="0" S="-158" T="-209" R="87" G="234" B="90" A="255"/>
<Vtx X="-15" Y="22" Z="5" S="-217" T="-248" R="87" G="234" B="90" A="255"/>
<Vtx X="-15" Y="22" Z="-5" S="-220" T="-239" R="87" G="234" B="166" A="255"/>
<Vtx X="-11" Y="19" Z="0" S="-158" T="-209" R="87" G="234" B="166" A="255"/>
<Vtx X="-11" Y="16" Z="0" S="-168" T="-172" R="87" G="234" B="166" A="255"/>
<Vtx X="2" Y="43" Z="0" S="6" T="-529" R="250" G="90" B="90" A="255"/>
<Vtx X="-5" Y="42" Z="0" S="-81" T="-522" R="250" G="90" B="90" A="255"/>
<Vtx X="-4" Y="37" Z="5" S="-71" T="-456" R="250" G="90" B="90" A="255"/>
<Vtx X="2" Y="38" Z="5" S="4" T="-461" R="250" G="90" B="90" A="255"/>
<Vtx X="14" Y="41" Z="0" S="167" T="-509" R="10" G="89" B="90" A="255"/>
<Vtx X="2" Y="43" Z="0" S="6" T="-529" R="10" G="89" B="90" A="255"/>
<Vtx X="2" Y="38" Z="5" S="4" T="-461" R="10" G="89" B="90" A="255"/>
<Vtx X="12" Y="36" Z="5" S="151" T="-443" R="10" G="89" B="90" A="255"/>
<Vtx X="-5" Y="42" Z="0" S="-81" T="-522" R="237" G="88" B="90" A="255"/>
<Vtx X="-11" Y="41" Z="0" S="-159" T="-505" R="237" G="88" B="90" A="255"/>
<Vtx X="-9" Y="36" Z="5" S="-139" T="-441" R="237" G="88" B="90" A="255"/>
<Vtx X="-4" Y="37" Z="5" S="-71" T="-456" R="237" G="88" B="90" A="255"/>
<Vtx X="20" Y="39" Z="0" S="255" T="-475" R="32" G="84" B="90" A="255"/>
<Vtx X="14" Y="41" Z="0" S="167" T="-509" R="32" G="84" B="90" A="255"/>
<Vtx X="12" Y="36" Z="5" S="151" T="-443" R="32" G="84" B="90" A="255"/>
<Vtx X="18" Y="34" Z="5" S="223" T="-416" R="32" G="84" B="90" A="255"/>
<Vtx X="-11" Y="41" Z="0" S="-159" T="-505" R="223" G="83" B="90" A="255"/>
<Vtx X="-16" Y="39" Z="0" S="-228" T="-477" R="223" G="83" B="90" A="255"/>
<Vtx X="-13" Y="34" Z="5" S="-197" T="-417" R="223" G="83" B="90" A="255"/>
<Vtx X="-9" Y="36" Z="5" S="-139" T="-441" R="223" G="83" B="90" A="255"/>
<Vtx X="-16" Y="39" Z="0" S="-228" T="-477" R="208" G="76" B="90" A="255"/>
<Vtx X="-20" Y="36" Z="0" S="-285" T="-441" R="208" G="76" B="90" A="255"/>
<Vtx X="-17" Y="32" Z="5" S="-242" T="-388" R="208" G="76" B="90" A="255"/>
<Vtx X="-13" Y="34" Z="5" S="-197" T="-417" R="208" G="76" B="90" A="255"/>
<Vtx X="25" Y="35" Z="0" S="324" T="-425" R="52" G="73" B="90" A="255"/>
<Vtx X="20" Y="39" Z="0" S="255" T="-475" R="52" G="73" B="90" A="255"/>
<Vtx X="18" Y="34" Z="5" S="223" T="-416" R="52" G="73" B="90" A="255"/>
<Vtx X="22" Y="31" Z="5" S="277" T="-377" R="52" G="73" B="90" A="255"/>
<Vtx X="-20" Y="36" Z="0" S="-285" T="-441" R="192" G="63" B="90" A="255"/>
<Vtx X="-23" Y="33" Z="0" S="-329" T="-396" R="192" G="63" B="90" A="255"/>
<Vtx X="-19" Y="30" Z="5" S="-275" T="-355" R="192" G="63" B="90" A="255"/>
<Vtx X="-17" Y="32" Z="5" S="-242" T="-388" R="192" G="63" B="90" A="255"/>
<Vtx X="29" Y="30" Z="0" S="373" T="-360" R="72" G="53" B="90" A="255"/>
<Vtx X="25" Y="35" Z="0" S="324" T="-425" R="72" G="53" B="90" A="255"/>
<Vtx X="22" Y="31" Z="5" S="277" T="-377" R="72" G="53" B="90" A="255"/>
<Vtx X="24" Y="28" Z="5" S="312" T="-329" R="72" G="53" B="90" A="255"/>
<Vtx X="-23" Y="33" Z="0" S="-329" T="-396" R="178" G="45" B="90" A="255"/>
<Vtx X="-26" Y="29" Z="0" S="-358" T="-346" R="178" G="45" B="90" A="255"/>
<Vtx X="-23" Y="24" Z="5" S="-318" T="-281" R="178" G="45" B="90" A="255"/>
<Vtx X="-19" Y="30" Z="5" S="-275" T="-355" R="178" G="45" B="90" A="255"/>
<Vtx X="-26" Y="29" Z="0" S="-358" T="-346" R="250" G="90" B="90" A="255"/>
<Vtx X="-30" Y="29" Z="0" S="-416" T="-342" R="250" G="90" B="90" A="255"/>
<Vtx X="-25" Y="24" Z="5" S="-357" T="-278" R="250" G="90" B="90" A="255"/>
<Vtx X="-23" Y="24" Z="5" S="-318" T="-281" R="250" G="90" B="90" A="255"/>
<Vtx X="-30" Y="29" Z="0" S="-416" T="-342" R="167" G="11" B="90" A="255"/>
<Vtx X="-31" Y="19" Z="0" S="-433" T="-214" R="167" G="11" B="90" A="255"/>
<Vtx X="-26" Y="23" Z="5" S="-358" T="-270" R="167" G="11" B="90" A="255"/>
<Vtx X="-25" Y="24" Z="5" S="-357" T="-278" R="167" G="11" B="90" A="255"/>
<Vtx X="31" Y="24" Z="0" S="398" T="-280" R="86" G="27" B="90" A="255"/>
<Vtx X="29" Y="30" Z="0" S="373" T="-360" R="86" G="27" B="90" A="255"/>
<Vtx X="24" Y="28" Z="5" S="312" T="-329" R="86" G="27" B="90" A="255"/>
<Vtx X="26" Y="23" Z="5" S="331" T="-269" R="86" G="27" B="90" A="255"/>
<Vtx X="-2" Y="26" Z="0" S="-43" T="-306" R="2" G="166" B="90" A="255"/>
<Vtx X="4" Y="26" Z="0" S="35" T="-308" R="2" G="166" B="90" A="255"/>
<Vtx X="5" Y="31" Z="5" S="46" T="-375" R="2" G="166" B="90" A="255"/>
<Vtx X="-3" Y="31" Z="5" S="-59" T="-373" R="2" G="166" B="90" A="255"/>
<Vtx X="4" Y="26" Z="0" S="35" T="-308" R="225" G="172" B="90" A="255"/>
<Vtx X="8" Y="25" Z="0" S="91" T="-287" R="225" G="172" B="90" A="255"/>
<Vtx X="11" Y="29" Z="5" S="132" T="-343" R="225" G="172" B="90" A="255"/>
<Vtx X="5" Y="31" Z="5" S="46" T="-375" R="225" G="172" B="90" A="255"/>
<Vtx X="-7" Y="23" Z="0" S="-112" T="-271" R="40" G="176" B="90" A="255"/>
<Vtx X="-2" Y="26" Z="0" S="-43" T="-306" R="40" G="176" B="90" A="255"/>
<Vtx X="-3" Y="31" Z="5" S="-59" T="-373" R="40" G="176" B="90" A="255"/>
<Vtx X="-11" Y="27" Z="5" S="-157" T="-323" R="40" G="176" B="90" A="255"/>
<Vtx X="8" Y="25" Z="0" S="91" T="-287" R="186" G="200" B="90" A="255"/>
<Vtx X="10" Y="22" Z="0" S="120" T="-251" R="186" G="200" B="90" A="255"/>
<Vtx X="15" Y="24" Z="5" S="186" T="-275" R="186" G="200" B="90" A="255"/>
<Vtx X="11" Y="29" Z="5" S="132" T="-343" R="186" G="200" B="90" A="255"/>
<Vtx X="26" Y="23" Z="5" S="331" T="-269" R="90" G="2" B="90" A="255"/>
<Vtx X="26" Y="19" Z="5" S="333" T="-209" R="90" G="2" B="90" A="255"/>
<Vtx X="31" Y="18" Z="0" S="400" T="-203" R="90" G="2" B="90" A="255"/>
<Vtx X="31" Y="24" Z="0" S="398" T="-280" R="90" G="2" B="90" A="255"/>
<Vtx X="-11" Y="19" Z="0" S="-158" T="-209" R="70" G="202" B="91" A="255"/>
<Vtx X="-7" Y="23" Z="0" S="-112" T="-271" R="70" G="202" B="91" A="255"/>
<Vtx X="-11" Y="27" Z="5" S="-157" T="-323" R="70" G="202" B="91" A="255"/>
<Vtx X="-15" Y="22" Z="5" S="-220" T="-239" R="70" G="202" B="91" A="255"/>
<Vtx X="10" Y="22" Z="0" S="120" T="-251" R="166" G="255" B="90" A="255"/>
<Vtx X="10" Y="19" Z="0" S="120" T="-211" R="166" G="255" B="90" A="255"/>
<Vtx X="15" Y="18" Z="5" S="188" T="-193" R="166" G="255" B="90" A="255"/>
<Vtx X="15" Y="24" Z="5" S="186" T="-275" R="166" G="255" B="90" A="255"/>
<Vtx X="-31" Y="19" Z="0" S="-433" T="-214" R="242" G="167" B="90" A="255"/>
<Vtx X="-11" Y="16" Z="0" S="-168" T="-172" R="242" G="167" B="90" A="255"/>
<Vtx X="-15" Y="22" Z="5" S="-217" T="-248" R="242" G="167" B="90" A="255"/>
<Vtx X="-26" Y="23" Z="5" S="-358" T="-270" R="242" G="167" B="90" A="255"/>
<Vtx X="10" Y="19" Z="0" S="120" T="-211" R="179" G="46" B="90" A="255"/>
<Vtx X="9" Y="16" Z="0" S="99" T="-174" R="179" G="46" B="90" A="255"/>
<Vtx X="12" Y="13" Z="5" S="151" T="-130" R="179" G="46" B="90" A="255"/>
<Vtx X="15" Y="18" Z="5" S="188" T="-193" R="179" G="46" B="90" A="255"/>
<Vtx X="30" Y="14" Z="0" S="389" T="-145" R="88" G="239" B="90" A="255"/>
<Vtx X="31" Y="18" Z="0" S="400" T="-203" R="88" G="239" B="90" A="255"/>
<Vtx X="26" Y="19" Z="5" S="333" T="-209" R="88" G="239" B="90" A="255"/>
<Vtx X="25" Y="15" Z="5" S="324" T="-165" R="88" G="239" B="90" A="255"/>
<Vtx X="9" Y="16" Z="0" S="99" T="-174" R="199" G="70" B="90" A="255"/>
<Vtx X="6" Y="14" Z="0" S="60" T="-143" R="199" G="70" B="90" A="255"/>
<Vtx X="8" Y="10" Z="5" S="96" T="-85" R="199" G="70" B="90" A="255"/>
<Vtx X="12" Y="13" Z="5" S="151" T="-130" R="199" G="70" B="90" A="255"/>
<Vtx X="28" Y="10" Z="0" S="366" T="-94" R="82" G="220" B="90" A="255"/>
<Vtx X="30" Y="14" Z="0" S="389" T="-145" R="82" G="220" B="90" A="255"/>
<Vtx X="25" Y="15" Z="5" S="324" T="-165" R="82" G="220" B="90" A="255"/>
<Vtx X="24" Y="13" Z="5" S="308" T="-128" R="82" G="220" B="90" A="255"/>
<Vtx X="6" Y="14" Z="0" S="60" T="-143" R="218" G="81" B="90" A="255"/>
<Vtx X="-1" Y="11" Z="0" S="-24" T="-103" R="218" G="81" B="90" A="255"/>
<Vtx X="2" Y="7" Z="5" S="10" T="-45" R="218" G="81" B="90" A="255"/>
<Vtx X="8" Y="10" Z="5" S="96" T="-85" R="218" G="81" B="90" A="255"/>
<Vtx X="26" Y="7" Z="0" S="335" T="-52" R="72" G="202" B="90" A="255"/>
<Vtx X="28" Y="10" Z="0" S="366" T="-94" R="72" G="202" B="90" A="255"/>
<Vtx X="24" Y="13" Z="5" S="308" T="-128" R="72" G="202" B="90" A="255"/>
<Vtx X="22" Y="11" Z="5" S="286" T="-99" R="72" G="202" B="90" A="255"/>
<Vtx X="-1" Y="11" Z="0" S="-24" T="-103" R="203" G="73" B="90" A="255"/>
<Vtx X="-6" Y="7" Z="0" S="-90" T="-54" R="203" G="73" B="90" A="255"/>
<Vtx X="-2" Y="4" Z="5" S="-44" T="-5" R="203" G="73" B="90" A="255"/>
<Vtx X="2" Y="7" Z="5" S="10" T="-45" R="203" G="73" B="90" A="255"/>
<Vtx X="-6" Y="7" Z="0" S="-90" T="-54" R="187" G="58" B="90" A="255"/>
<Vtx X="-8" Y="5" Z="0" S="-120" T="-18" R="187" G="58" B="90" A="255"/>
<Vtx X="-4" Y="2" Z="5" S="-64" T="19" R="187" G="58" B="90" A="255"/>
<Vtx X="-2" Y="4" Z="5" S="-44" T="-5" R="187" G="58" B="90" A="255"/>
<Vtx X="23" Y="5" Z="0" S="294" T="-19" R="57" G="186" B="90" A="255"/>
<Vtx X="26" Y="7" Z="0" S="335" T="-52" R="57" G="186" B="90" A="255"/>
<Vtx X="22" Y="11" Z="5" S="286" T="-99" R="57" G="186" B="90" A="255"/>
<Vtx X="20" Y="9" Z="5" S="258" T="-76" R="57" G="186" B="90" A="255"/>
<Vtx X="19" Y="3" Z="0" S="246" T="4" R="39" G="175" B="90" A="255"/>
<Vtx X="23" Y="5" Z="0" S="294" T="-19" R="39" G="175" B="90" A="255"/>
<Vtx X="20" Y="9" Z="5" S="258" T="-76" R="39" G="175" B="90" A="255"/>
<Vtx X="18" Y="8" Z="5" S="221" T="-58" R="39" G="175" B="90" A="255"/>
<Vtx X="-8" Y="5" Z="0" S="-120" T="-18" R="176" G="41" B="90" A="255"/>
<Vtx X="-9" Y="2" Z="0" S="-139" T="19" R="176" G="41" B="90" A="255"/>
<Vtx X="-4" Y="0" Z="5" S="-76" T="43" R="176" G="41" B="90" A="255"/>
<Vtx X="-4" Y="2" Z="5" S="-64" T="19" R="176" G="41" B="90" A="255"/>
<Vtx X="13" Y="1" Z="0" S="155" T="33" R="27" G="170" B="90" A="255"/>
<Vtx X="19" Y="3" Z="0" S="246" T="4" R="27" G="170" B="90" A="255"/>
<Vtx X="18" Y="8" Z="5" S="221" T="-58" R="27" G="170" B="90" A="255"/>
<Vtx X="11" Y="5" Z="5" S="128" T="-29" R="27" G="170" B="90" A="255"/>
<Vtx X="-9" Y="2" Z="0" S="-139" T="19" R="168" G="21" B="90" A="255"/>
<Vtx X="-10" Y="-1" Z="0" S="-149" T="58" R="168" G="21" B="90" A="255"/>
<Vtx X="-5" Y="-2" Z="5" S="-82" T="66" R="168" G="21" B="90" A="255"/>
<Vtx X="-4" Y="0" Z="5" S="-76" T="43" R="168" G="21" B="90" A="255"/>
<Vtx X="9" Y="-1" Z="0" S="103" T="62" R="44" G="177" B="90" A="255"/>
<Vtx X="13" Y="1" Z="0" S="155" T="33" R="44" G="177" B="90" A="255"/>
<Vtx X="11" Y="5" Z="5" S="128" T="-29" R="44" G="177" B="90" A="255"/>
<Vtx X="5" Y="2" Z="5" S="55" T="12" R="44" G="177" B="90" A="255"/>
<Vtx X="-10" Y="-1" Z="0" S="-149" T="58" R="166" G="0" B="90" A="255"/>
<Vtx X="-10" Y="-9" Z="0" S="-150" T="161" R="166" G="0" B="90" A="255"/>
<Vtx X="-5" Y="-4" Z="5" S="-82" T="94" R="166" G="0" B="90" A="255"/>
<Vtx X="-5" Y="-2" Z="5" S="-82" T="66" R="166" G="0" B="90" A="255"/>
<Vtx X="7" Y="-4" Z="0" S="81" T="96" R="76" G="208" B="90" A="255"/>
<Vtx X="9" Y="-1" Z="0" S="103" T="62" R="76" G="208" B="90" A="255"/>
<Vtx X="5" Y="2" Z="5" S="55" T="12" R="76" G="208" B="90" A="255"/>
<Vtx X="2" Y="-2" Z="5" S="14" T="76" R="76" G="208" B="90" A="255"/>
<Vtx X="-10" Y="-9" Z="0" S="-150" T="161" R="0" G="166" B="90" A="255"/>
<Vtx X="7" Y="-9" Z="0" S="81" T="161" R="0" G="166" B="90" A="255"/>
<Vtx X="2" Y="-4" Z="5" S="14" T="94" R="0" G="166" B="90" A="255"/>
<Vtx X="-5" Y="-4" Z="5" S="-82" T="94" R="0" G="166" B="90" A="255"/>
<Vtx X="7" Y="-9" Z="0" S="81" T="161" R="90" G="0" B="90" A="255"/>
<Vtx X="7" Y="-4" Z="0" S="81" T="96" R="90" G="0" B="90" A="255"/>
<Vtx X="2" Y="-2" Z="5" S="14" T="76" R="90" G="0" B="90" A="255"/>
<Vtx X="2" Y="-4" Z="5" S="14" T="94" R="90" G="0" B="90" A="255"/>
<Vtx X="2" Y="38" Z="-5" S="4" T="-461" R="250" G="90" B="166" A="255"/>
<Vtx X="-4" Y="37" Z="-5" S="-71" T="-456" R="250" G="90" B="166" A="255"/>
<Vtx X="-5" Y="42" Z="0" S="-81" T="-522" R="250" G="90" B="166" A="255"/>
<Vtx X="2" Y="43" Z="0" S="6" T="-529" R="250" G="90" B="166" A="255"/>
<Vtx X="12" Y="36" Z="-5" S="151" T="-443" R="10" G="89" B="166" A="255"/>
<Vtx X="2" Y="38" Z="-5" S="4" T="-461" R="10" G="89" B="166" A="255"/>
<Vtx X="2" Y="43" Z="0" S="6" T="-529" R="10" G="89" B="166" A="255"/>
<Vtx X="14" Y="41" Z="0" S="167" T="-509" R="10" G="89" B="166" A="255"/>
<Vtx X="-4" Y="37" Z="-5" S="-71" T="-456" R="237" G="88" B="166" A="255"/>
<Vtx X="-9" Y="36" Z="-5" S="-139" T="-441" R="237" G="88" B="166" A="255"/>
<Vtx X="-11" Y="41" Z="0" S="-159" T="-505" R="237" G="88" B="166" A="255"/>
<Vtx X="-5" Y="42" Z="0" S="-81" T="-522" R="237" G="88" B="166" A="255"/>
<Vtx X="18" Y="34" Z="-5" S="223" T="-416" R="32" G="84" B="166" A="255"/>
<Vtx X="12" Y="36" Z="-5" S="151" T="-443" R="32" G="84" B="166" A="255"/>
<Vtx X="14" Y="41" Z="0" S="167" T="-509" R="32" G="84" B="166" A="255"/>
<Vtx X="20" Y="39" Z="0" S="255" T="-475" R="32" G="84" B="166" A="255"/>
<Vtx X="-9" Y="36" Z="-5" S="-139" T="-441" R="223" G="83" B="166" A="255"/>
<Vtx X="-13" Y="34" Z="-5" S="-197" T="-417" R="223" G="83" B="166" A="255"/>
<Vtx X="-16" Y="39" Z="0" S="-228" T="-477" R="223" G="83" B="166" A="255"/>
<Vtx X="-11" Y="41" Z="0" S="-159" T="-505" R="223" G="83" B="166" A="255"/>
<Vtx X="-13" Y="34" Z="-5" S="-197" T="-417" R="208" G="76" B="166" A="255"/>
<Vtx X="-17" Y="32" Z="-5" S="-242" T="-388" R="208" G="76" B="166" A="255"/>
<Vtx X="-20" Y="36" Z="0" S="-285" T="-441" R="208" G="76" B="166" A="255"/>
<Vtx X="-16" Y="39" Z="0" S="-228" T="-477" R="208" G="76" B="166" A="255"/>
<Vtx X="22" Y="31" Z="-5" S="277" T="-377" R="52" G="73" B="166" A="255"/>
<Vtx X="18" Y="34" Z="-5" S="223" T="-416" R="52" G="73" B="166" A="255"/>
<Vtx X="20" Y="39" Z="0" S="255" T="-475" R="52" G="73" B="166" A="255"/>
<Vtx X="25" Y="35" Z="0" S="324" T="-425" R="52" G="73" B="166" A="255"/>
<Vtx X="-17" Y="32" Z="-5" S="-242" T="-388" R="192" G="63" B="166" A="255"/>
<Vtx X="-19" Y="30" Z="-5" S="-275" T="-355" R="192" G="63" B="166" A="255"/>
<Vtx X="-23" Y="33" Z="0" S="-329" T="-396" R="192" G="63" B="166" A="255"/>
<Vtx X="-20" Y="36" Z="0" S="-285" T="-441" R="192" G="63" B="166" A="255"/>
<Vtx X="24" Y="28" Z="-5" S="312" T="-329" R="72" G="53" B="166" A="255"/>
<Vtx X="22" Y="31" Z="-5" S="277" T="-377" R="72" G="53" B="166" A="255"/>
<Vtx X="25" Y="35" Z="0" S="324" T="-425" R="72" G="53" B="166" A="255"/>
<Vtx X="29" Y="30" Z="0" S="373" T="-360" R="72" G="53" B="166" A="255"/>
<Vtx X="-19" Y="30" Z="-5" S="-275" T="-355" R="178" G="45" B="166" A="255"/>
<Vtx X="-23" Y="24" Z="-5" S="-318" T="-281" R="178" G="45" B="166" A="255"/>
<Vtx X="-26" Y="29" Z="0" S="-358" T="-346" R="178" G="45" B="166" A="255"/>
<Vtx X="-23" Y="33" Z="0" S="-329" T="-396" R="178" G="45" B="166" A="255"/>
<Vtx X="-23" Y="24" Z="-5" S="-318" T="-281" R="250" G="90" B="166" A="255"/>
<Vtx X="-25" Y="24" Z="-5" S="-357" T="-278" R="250" G="90" B="166" A="255"/>
<Vtx X="-30" Y="29" Z="0" S="-416" T="-342" R="250" G="90" B="166" A="255"/>
<Vtx X="-26" Y="29" Z="0" S="-358" T="-346" R="250" G="90" B="166" A="255"/>
<Vtx X="-25" Y="24" Z="-5" S="-357" T="-278" R="167" G="11" B="166" A="255"/>
<Vtx X="-26" Y="23" Z="-5" S="-358" T="-270" R="167" G="11" B="166" A="255"/>
<Vtx X="-31" Y="19" Z="0" S="-433" T="-214" R="167" G="11" B="166" A="255"/>
<Vtx X="-30" Y="29" Z="0" S="-416" T="-342" R="167" G="11" B="166" A="255"/>
<Vtx X="26" Y="23" Z="-5" S="331" T="-269" R="86" G="27" B="166" A="255"/>
<Vtx X="24" Y="28" Z="-5" S="312" T="-329" R="86" G="27" B="166" A="255"/>
<Vtx X="29" Y="30" Z="0" S="373" T="-360" R="86" G="27" B="166" A="255"/>
<Vtx X="31" Y="24" Z="0" S="398" T="-280" R="86" G="27" B="166" A="255"/>
<Vtx X="-3" Y="31" Z="-5" S="-59" T="-373" R="2" G="166" B="166" A="255"/>
<Vtx X="5" Y="31" Z="-5" S="46" T="-375" R="2" G="166" B="166" A="255"/>
<Vtx X="4" Y="26" Z="0" S="35" T="-308" R="2" G="166" B="166" A="255"/>
<Vtx X="-2" Y="26" Z="0" S="-43" T="-306" R="2" G="166" B="166" A="255"/>
<Vtx X="5" Y="31" Z="-5" S="46" T="-375" R="225" G="172" B="166" A="255"/>
<Vtx X="11" Y="29" Z="-5" S="132" T="-343" R="225" G="172" B="166" A="255"/>
<Vtx X="8" Y="25" Z="0" S="91" T="-287" R="225" G="172" B="166" A="255"/>
<Vtx X="4" Y="26" Z="0" S="35" T="-308" R="225" G="172" B="166" A="255"/>
<Vtx X="-11" Y="27" Z="-5" S="-157" T="-323" R="40" G="176" B="166" A="255"/>
<Vtx X="-3" Y="31" Z="-5" S="-59" T="-373" R="40" G="176" B="166" A="255"/>
<Vtx X="-2" Y="26" Z="0" S="-43" T="-306" R="40" G="176" B="166" A="255"/>
<Vtx X="-7" Y="23" Z="0" S="-112" T="-271" R="40" G="176" B="166" A="255"/>
<Vtx X="11" Y="29" Z="-5" S="132" T="-343" R="186" G="200" B="166" A="255"/>
<Vtx X="15" Y="24" Z="-5" S="186" T="-275" R="186" G="200" B="166" A="255"/>
<Vtx X="10" Y="22" Z="0" S="120" T="-251" R="186" G="200" B="166" A="255"/>
<Vtx X="8" Y="25" Z="0" S="91" T="-287" R="186" G="200" B="166" A="255"/>
<Vtx X="31" Y="24" Z="0" S="398" T="-280" R="90" G="2" B="166" A="255"/>
<Vtx X="31" Y="18" Z="0" S="400" T="-203" R="90" G="2" B="166" A="255"/>
<Vtx X="26" Y="19" Z="-5" S="333" T="-209" R="90" G="2" B="166" A="255"/>
<Vtx X="26" Y="23" Z="-5" S="331" T="-269" R="90" G="2" B="166" A="255"/>
<Vtx X="-15" Y="22" Z="-5" S="-220" T="-239" R="70" G="202" B="165" A="255"/>
<Vtx X="-11" Y="27" Z="-5" S="-157" T="-323" R="70" G="202" B="165" A="255"/>
<Vtx X="-7" Y="23" Z="0" S="-112" T="-271" R="70" G="202" B="165" A="255"/>
<Vtx X="-11" Y="19" Z="0" S="-158" T="-209" R="70" G="202" B="165" A="255"/>
<Vtx X="15" Y="24" Z="-5" S="186" T="-275" R="166" G="255" B="166" A="255"/>
<Vtx X="15" Y="18" Z="-5" S="188" T="-193" R="166" G="255" B="166" A="255"/>
<Vtx X="10" Y="19" Z="0" S="120" T="-211" R="166" G="255" B="166" A="255"/>
<Vtx X="10" Y="22" Z="0" S="120" T="-251" R="166" G="255" B="166" A="255"/>
<Vtx X="-26" Y="23" Z="-5" S="-358" T="-270" R="242" G="167" B="166" A="255"/>
<Vtx X="-15" Y="22" Z="-5" S="-217" T="-248" R="242" G="167" B="166" A="255"/>
<Vtx X="-11" Y="16" Z="0" S="-168" T="-172" R="242" G="167" B="166" A="255"/>
<Vtx X="-31" Y="19" Z="0" S="-433" T="-214" R="242" G="167" B="166" A="255"/>
<Vtx X="15" Y="18" Z="-5" S="188" T="-193" R="179" G="46" B="166" A="255"/>
<Vtx X="12" Y="13" Z="-5" S="151" T="-130" R="179" G="46" B="166" A="255"/>
<Vtx X="9" Y="16" Z="0" S="99" T="-174" R="179" G="46" B="166" A="255"/>
<Vtx X="10" Y="19" Z="0" S="120" T="-211" R="179" G="46" B="166" A="255"/>
<Vtx X="25" Y="15" Z="-5" S="324" T="-165" R="88" G="239" B="166" A="255"/>
<Vtx X="26" Y="19" Z="-5" S="333" T="-209" R="88" G="239" B="166" A="255"/>
<Vtx X="31" Y="18" Z="0" S="400" T="-203" R="88" G="239" B="166" A="255"/>
<Vtx X="30" Y="14" Z="0" S="389" T="-145" R="88" G="239" B="166" A="255"/>
<Vtx X="12" Y="13" Z="-5" S="151" T="-130" R="199" G="70" B="166" A="255"/>
<Vtx X="8" Y="10" Z="-5" S="96" T="-85" R="199" G="70" B="166" A="255"/>
<Vtx X="6" Y="14" Z="0" S="60" T="-143" R="199" G="70" B="166" A="255"/>
<Vtx X="9" Y="16" Z="0" S="99" T="-174" R="199" G="70" B="166" A="255"/>
<Vtx X="24" Y="13" Z="-5" S="308" T="-128" R="82" G="220" B="166" A="255"/>
<Vtx X="25" Y="15" Z="-5" S="324" T="-165" R="82" G="220" B="166" A="255"/>
<Vtx X="30" Y="14" Z="0" S="389" T="-145" R="82" G="220" B="166" A="255"/>
<Vtx X="28" Y="10" Z="0" S="366" T="-94" R="82" G="220" B="166" A="255"/>
<Vtx X="8" Y="10" Z="-5" S="96" T="-85" R="218" G="81" B="166" A="255"/>
<Vtx X="2" Y="7" Z="-5" S="10" T="-45" R="218" G="81" B="166" A="255"/>
<Vtx X="-1" Y="11" Z="0" S="-24" T="-103" R="218" G="81" B="166" A="255"/>
<Vtx X="6" Y="14" Z="0" S="60" T="-143" R="218" G="81" B="166" A="255"/>
<Vtx X="22" Y="11" Z="-5" S="286" T="-99" R="72" G="202" B="166" A="255"/>
<Vtx X="24" Y="13" Z="-5" S="308" T="-128" R="72" G="202" B="166" A="255"/>
<Vtx X="28" Y="10" Z="0" S="366" T="-94" R="72" G="202" B="166" A="255"/>
<Vtx X="26" Y="7" Z="0" S="335" T="-52" R="72" G="202" B="166" A="255"/>
<Vtx X="2" Y="7" Z="-5" S="10" T="-45" R="203" G="73" B="166" A="255"/>
<Vtx X="-2" Y="4" Z="-5" S="-44" T="-5" R="203" G="73" B="166" A="255"/>
<Vtx X="-6" Y="7" Z="0" S="-90" T="-54" R="203" G="73" B="166" A="255"/>
<Vtx X="-1" Y="11" Z="0" S="-24" T="-103" R="203" G="73" B="166" A="255"/>
<Vtx X="-2" Y="4" Z="-5" S="-44" T="-5" R="187" G="58" B="166" A="255"/>
<Vtx X="-4" Y="2" Z="-5" S="-64" T="19" R="187" G="58" B="166" A="255"/>
<Vtx X="-8" Y="5" Z="0" S="-120" T="-18" R="187" G="58" B="166" A="255"/>
<Vtx X="-6" Y="7" Z="0" S="-90" T="-54" R="187" G="58" B="166" A="255"/>
<Vtx X="20" Y="9" Z="-5" S="258" T="-76" R="57" G="186" B="166" A="255"/>
<Vtx X="22" Y="11" Z="-5" S="286" T="-99" R="57" G="186" B="166" A="255"/>
<Vtx X="26" Y="7" Z="0" S="335" T="-52" R="57" G="186" B="166" A="255"/>
<Vtx X="23" Y="5" Z="0" S="294" T="-19" R="57" G="186" B="166" A="255"/>
<Vtx X="18" Y="8" Z="-5" S="221" T="-58" R="39" G="175" B="166" A="255"/>
<Vtx X="20" Y="9" Z="-5" S="258" T="-76" R="39" G="175" B="166" A="255"/>
<Vtx X="23" Y="5" Z="0" S="294" T="-19" R="39" G="175" B="166" A="255"/>
<Vtx X="19" Y="3" Z="0" S="246" T="4" R="39" G="175" B="166" A="255"/>
<Vtx X="-4" Y="2" Z="-5" S="-64" T="19" R="176" G="41" B="166" A="255"/>
<Vtx X="-4" Y="0" Z="-5" S="-76" T="43" R="176" G="41" B="166" A="255"/>
<Vtx X="-9" Y="2" Z="0" S="-139" T="19" R="176" G="41" B="166" A="255"/>
<Vtx X="-8" Y="5" Z="0" S="-120" T="-18" R="176" G="41" B="166" A="255"/>
<Vtx X="11" Y="5" Z="-5" S="128" T="-29" R="27" G="170" B="166" A="255"/>
<Vtx X="18" Y="8" Z="-5" S="221" T="-58" R="27" G="170" B="166" A="255"/>
<Vtx X="19" Y="3" Z="0" S="246" T="4" R="27" G="170" B="166" A="255"/>
<Vtx X="13" Y="1" Z="0" S="155" T="33" R="27" G="170" B="166" A="255"/>
<Vtx X="-4" Y="0" Z="-5" S="-76" T="43" R="168" G="21" B="166" A="255"/>
<Vtx X="-5" Y="-2" Z="-5" S="-82" T="66" R="168" G="21" B="166" A="255"/>
<Vtx X="-10" Y="-1" Z="0" S="-149" T="58" R="168" G="21" B="166" A="255"/>
<Vtx X="-9" Y="2" Z="0" S="-139" T="19" R="168" G="21" B="166" A="255"/>
<Vtx X="5" Y="2" Z="-5" S="55" T="12" R="44" G="177" B="166" A="255"/>
<Vtx X="11" Y="5" Z="-5" S="128" T="-29" R="44" G="177" B="166" A="255"/>
<Vtx X="13" Y="1" Z="0" S="155" T="33" R="44" G="177" B="166" A="255"/>
<Vtx X="9" Y="-1" Z="0" S="103" T="62" R="44" G="177" B="166" A="255"/>
<Vtx X="-5" Y="-2" Z="-5" S="-82" T="66" R="166" G="0" B="166" A="255"/>
<Vtx X="-5" Y="-4" Z="-5" S="-82" T="94" R="166" G="0" B="166" A="255"/>
<Vtx X="-10" Y="-9" Z="0" S="-150" T="161" R="166" G="0" B="166" A="255"/>
<Vtx X="-10" Y="-1" Z="0" S="-149" T="58" R="166" G="0" B="166" A="255"/>
<Vtx X="2" Y="-2" Z="-5" S="14" T="76" R="76" G="208" B="166" A="255"/>
<Vtx X="5" Y="2" Z="-5" S="55" T="12" R="76" G="208" B="166" A="255"/>
<Vtx X="9" Y="-1" Z="0" S="103" T="62" R="76" G="208" B="166" A="255"/>
<Vtx X="7" Y="-4" Z="0" S="81" T="96" R="76" G="208" B="166" A="255"/>
<Vtx X="-5" Y="-4" Z="-5" S="-82" T="94" R="0" G="166" B="166" A="255"/>
<Vtx X="2" Y="-4" Z="-5" S="14" T="94" R="0" G="166" B="166" A="255"/>
<Vtx X="7" Y="-9" Z="0" S="81" T="161" R="0" G="166" B="166" A="255"/>
<Vtx X="-10" Y="-9" Z="0" S="-150" T="161" R="0" G="166" B="166" A="255"/>
<Vtx X="2" Y="-4" Z="-5" S="14" T="94" R="90" G="0" B="166" A="255"/>
<Vtx X="2" Y="-2" Z="-5" S="14" T="76" R="90" G="0" B="166" A="255"/>
<Vtx X="7" Y="-4" Z="0" S="81" T="96" R="90" G="0" B="166" A="255"/>
<Vtx X="7" Y="-9" Z="0" S="81" T="161" R="90" G="0" B="166" A="255"/>
<Vtx X="3" Y="-13" Z="0" S="-274" T="-22" R="11" G="89" B="90" A="255"/>
<Vtx X="-3" Y="-12" Z="0" S="-350" T="-32" R="11" G="89" B="90" A="255"/>
<Vtx X="-2" Y="-18" Z="5" S="-341" T="36" R="11" G="89" B="90" A="255"/>
<Vtx X="1" Y="-18" Z="5" S="-301" T="42" R="11" G="89" B="90" A="255"/>
<Vtx X="-3" Y="-12" Z="0" S="-350" T="-32" R="221" G="83" B="90" A="255"/>
<Vtx X="-8" Y="-15" Z="0" S="-418" T="-4" R="221" G="83" B="90" A="255"/>
<Vtx X="-5" Y="-19" Z="5" S="-376" T="51" R="221" G="83" B="90" A="255"/>
<Vtx X="-2" Y="-18" Z="5" S="-341" T="36" R="221" G="83" B="90" A="255"/>
<Vtx X="7" Y="-17" Z="0" S="-216" T="23" R="55" G="71" B="90" A="255"/>
<Vtx X="3" Y="-13" Z="0" S="-274" T="-22" R="55" G="71" B="90" A="255"/>
<Vtx X="1" Y="-18" Z="5" S="-301" T="42" R="55" G="71" B="90" A="255"/>
<Vtx X="3" Y="-20" Z="5" S="-271" T="65" R="55" G="71" B="90" A="255"/>
<Vtx X="-8" Y="-15" Z="0" S="-418" T="-4" R="185" G="55" B="90" A="255"/>
<Vtx X="-11" Y="-19" Z="0" S="-463" T="55" R="185" G="55" B="90" A="255"/>
<Vtx X="-6" Y="-21" Z="5" S="-399" T="82" R="185" G="55" B="90" A="255"/>
<Vtx X="-5" Y="-19" Z="5" S="-376" T="51" R="185" G="55" B="90" A="255"/>
<Vtx X="9" Y="-22" Z="0" S="-188" T="92" R="83" G="34" B="90" A="255"/>
<Vtx X="7" Y="-17" Z="0" S="-216" T="23" R="83" G="34" B="90" A="255"/>
<Vtx X="3" Y="-20" Z="5" S="-271" T="65" R="83" G="34" B="90" A="255"/>
<Vtx X="4" Y="-22" Z="5" S="-256" T="101" R="83" G="34" B="90" A="255"/>
<Vtx X="-11" Y="-19" Z="0" S="-463" T="55" R="167" G="11" B="90" A="255"/>
<Vtx X="-12" Y="-25" Z="0" S="-473" T="131" R="167" G="11" B="90" A="255"/>
<Vtx X="-7" Y="-24" Z="5" S="-405" T="122" R="167" G="11" B="90" A="255"/>
<Vtx X="-6" Y="-21" Z="5" S="-399" T="82" R="167" G="11" B="90" A="255"/>
<Vtx X="9" Y="-27" Z="0" S="-198" T="168" R="89" G="245" B="90" A="255"/>
<Vtx X="9" Y="-22" Z="0" S="-188" T="92" R="89" G="245" B="90" A="255"/>
<Vtx X="4" Y="-22" Z="5" S="-256" T="101" R="89" G="245" B="90" A="255"/>
<Vtx X="4" Y="-25" Z="5" S="-262" T="141" R="89" G="245" B="90" A="255"/>
<Vtx X="-12" Y="-25" Z="0" S="-473" T="131" R="173" G="221" B="90" A="255"/>
<Vtx X="-10" Y="-30" Z="0" S="-444" T="200" R="173" G="221" B="90" A="255"/>
<Vtx X="-6" Y="-27" Z="5" S="-390" T="157" R="173" G="221" B="90" A="255"/>
<Vtx X="-7" Y="-24" Z="5" S="-405" T="122" R="173" G="221" B="90" A="255"/>
<Vtx X="5" Y="-32" Z="0" S="-242" T="225" R="71" G="201" B="90" A="255"/>
<Vtx X="9" Y="-27" Z="0" S="-198" T="168" R="71" G="201" B="90" A="255"/>
<Vtx X="4" Y="-25" Z="5" S="-262" T="141" R="71" G="201" B="90" A="255"/>
<Vtx X="2" Y="-27" Z="5" S="-284" T="170" R="71" G="201" B="90" A="255"/>
<Vtx X="-10" Y="-30" Z="0" S="-444" T="200" R="202" G="184" B="90" A="255"/>
<Vtx X="-5" Y="-33" Z="0" S="-386" T="244" R="202" G="184" B="90" A="255"/>
<Vtx X="-3" Y="-28" Z="5" S="-360" T="179" R="202" G="184" B="90" A="255"/>
<Vtx X="-6" Y="-27" Z="5" S="-390" T="157" R="202" G="184" B="90" A="255"/>
<Vtx X="0" Y="-34" Z="0" S="-311" T="253" R="34" G="173" B="90" A="255"/>
<Vtx X="5" Y="-32" Z="0" S="-242" T="225" R="34" G="173" B="90" A="255"/>
<Vtx X="2" Y="-27" Z="5" S="-284" T="170" R="34" G="173" B="90" A="255"/>
<Vtx X="0" Y="-29" Z="5" S="-320" T="185" R="34" G="173" B="90" A="255"/>
<Vtx X="-5" Y="-33" Z="0" S="-386" T="244" R="245" G="167" B="90" A="255"/>
<Vtx X="0" Y="-34" Z="0" S="-311" T="253" R="245" G="167" B="90" A="255"/>
<Vtx X="0" Y="-29" Z="5" S="-320" T="185" R="245" G="167" B="90" A="255"/>
<Vtx X="-3" Y="-28" Z="5" S="-360" T="179" R="245" G="167" B="90" A="255"/>
<Vtx X="1" Y="-18" Z="-5" S="-301" T="42" R="11" G="89" B="166" A="255"/>
<Vtx X="-2" Y="-18" Z="-5" S="-341" T="36" R="11" G="89" B="166" A="255"/>
<Vtx X="-3" Y="-12" Z="0" S="-350" T="-32" R="11" G="89" B="166" A="255"/>
<Vtx X="3" Y="-13" Z="0" S="-274" T="-22" R="11" G="89" B="166" A="255"/>
<Vtx X="-2" Y="-18" Z="-5" S="-341" T="36" R="221" G="83" B="166" A="255"/>
<Vtx X="-5" Y="-19" Z="-5" S="-376" T="51" R="221" G="83" B="166" A="255"/>
<Vtx X="-8" Y="-15" Z="0" S="-418" T="-4" R="221" G="83" B="166" A="255"/>
<Vtx X="-3" Y="-12" Z="0" S="-350" T="-32" R="221" G="83" B="166" A="255"/>
<Vtx X="3" Y="-20" Z="-5" S="-271" T="65" R="55" G="71" B="166" A="255"/>
<Vtx X="1" Y="-18" Z="-5" S="-301" T="42" R="55" G="71" B="166" A="255"/>
<Vtx X="3" Y="-13" Z="0" S="-274" T="-22" R="55" G="71" B="166" A="255"/>
<Vtx X="7" Y="-17" Z="0" S="-216" T="23" R="55" G="71" B="166" A="255"/>
<Vtx X="-5" Y="-19" Z="-5" S="-376" T="51" R="185" G="55" B="166" A="255"/>
<Vtx X="-6" Y="-21" Z="-5" S="-399" T="82" R="185" G="55" B="166" A="255"/>
<Vtx X="-11" Y="-19" Z="0" S="-463" T="55" R="185" G="55" B="166" A="255"/>
<Vtx X="-8" Y="-15" Z="0" S="-418" T="-4" R="185" G="55" B="166" A="255"/>
<Vtx X="4" Y="-22" Z="-5" S="-256" T="101" R="83" G="34" B="166" A="255"/>
<Vtx X="3" Y="-20" Z="-5" S="-271" T="65" R="83" G="34" B="166" A="255"/>
<Vtx X="7" Y="-17" Z="0" S="-216" T="23" R="83" G="34" B="166" A="255"/>
<Vtx X="9" Y="-22" Z="0" S="-188" T="92" R="83" G="34" B="166" A="255"/>
<Vtx X="-6" Y="-21" Z="-5" S="-399" T="82" R="167" G="11" B="166" A="255"/>
<Vtx X="-7" Y="-24" Z="-5" S="-405" T="122" R="167" G="11" B="166" A="255"/>
<Vtx X="-12" Y="-25" Z="0" S="-473" T="131" R="167" G="11" B="166" A="255"/>
<Vtx X="-11" Y="-19" Z="0" S="-463" T="55" R="167" G="11" B="166" A="255"/>
<Vtx X="4" Y="-25" Z="-5" S="-262" T="141" R="89" G="245" B="166" A="255"/>
<Vtx X="4" Y="-22" Z="-5" S="-256" T="101" R="89" G="245" B="166" A="255"/>
<Vtx X="9" Y="-22" Z="0" S="-188" T="92" R="89" G="245" B="166" A="255"/>
<Vtx X="9" Y="-27" Z="0" S="-198" T="168" R="89" G="245" B="166" A="255"/>
<Vtx X="-7" Y="-24" Z="-5" S="-405" T="122" R="173" G="221" B="166" A="255"/>
<Vtx X="-6" Y="-27" Z="-5" S="-390" T="157" R="173" G="221" B="166" A="255"/>
<Vtx X="-10" Y="-30" Z="0" S="-444" T="200" R="173" G="221" B="166" A="255"/>
<Vtx X="-12" Y="-25" Z="0" S="-473" T="131" R="173" G="221" B="166" A="255"/>
<Vtx X="2" Y="-27" Z="-5" S="-284" T="170" R="71" G="201" B="166" A="255"/>
<Vtx X="4" Y="-25" Z="-5" S="-262" T="141" R="71" G="201" B="166" A="255"/>
<Vtx X="9" Y="-27" Z="0" S="-198" T="168" R="71" G="201" B="166" A="255"/>
<Vtx X="5" Y="-32" Z="0" S="-242" T="225" R="71" G="201" B="166" A="255"/>
<Vtx X="-6" Y="-27" Z="-5" S="-390" T="157" R="202" G="184" B="166" A="255"/>
<Vtx X="-3" Y="-28" Z="-5" S="-360" T="179" R="202" G="184" B="166" A="255"/>
<Vtx X="-5" Y="-33" Z="0" S="-386" T="244" R="202" G="184" B="166" A="255"/>
<Vtx X="-10" Y="-30" Z="0" S="-444" T="200" R="202" G="184" B="166" A="255"/>
<Vtx X="0" Y="-29" Z="-5" S="-320" T="185" R="34" G="173" B="166" A="255"/>
<Vtx X="2" Y="-27" Z="-5" S="-284" T="170" R="34" G="173" B="166" A="255"/>
<Vtx X="5" Y="-32" Z="0" S="-242" T="225" R="34" G="173" B="166" A="255"/>
<Vtx X="0" Y="-34" Z="0" S="-311" T="253" R="34" G="173" B="166" A="255"/>
<Vtx X="-3" Y="-28" Z="-5" S="-360" T="179" R="245" G="167" B="166" A="255"/>
<Vtx X="0" Y="-29" Z="-5" S="-320" T="185" R="245" G="167" B="166" A="255"/>
<Vtx X="0" Y="-34" Z="0" S="-311" T="253" R="245" G="167" B="166" A="255"/>
<Vtx X="-5" Y="-33" Z="0" S="-386" T="244" R="245" G="167" B="166" A="255"/>
</Vertex>

View File

@ -0,0 +1,10 @@
<Vertex Version="0">
<Vtx X="-31" Y="-34" Z="-5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
<Vtx X="-31" Y="-34" Z="5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
<Vtx X="-31" Y="43" Z="5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
<Vtx X="-31" Y="43" Z="-5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
<Vtx X="31" Y="-34" Z="-5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
<Vtx X="31" Y="-34" Z="5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
<Vtx X="31" Y="43" Z="5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
<Vtx X="31" Y="43" Z="-5" S="-16" T="-16" R="0" G="0" B="0" A="0"/>
</Vertex>

View File

@ -0,0 +1,21 @@
<DisplayList Version="0">
<PipeSync/>
<SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_SHADE" D0="G_CCMUX_0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_TEXTURE_GEN="1" G_SHADING_SMOOTH="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_FOG_SHADE_A="1" G_RM_AA_ZB_OPA_SURF2="1" />
<Texture S="1984" T="1984" Level="0" Tile="0" On="1"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_mystery_item/noise_tex" Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_LOAD_BLOCK" Line="0" TMem="0" Tile="7" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<LoadSync/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="511" Dxt="512"/>
<PipeSync/>
<SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b" Line="4" TMem="0" Tile="0" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="124" Lrt="124"/>
<SetPrimColor M="0" L="0" R="220" G="220" B="220" A="255"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,21 @@
<DisplayList Version="0">
<PipeSync/>
<SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_SHADE" D0="G_CCMUX_0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_TEXTURE_GEN="1" G_SHADING_SMOOTH="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_FOG_SHADE_A="1" G_RM_AA_ZB_OPA_SURF2="1" />
<Texture S="1984" T="1984" Level="0" Tile="0" On="1"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_mystery_item/noise_tex" Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_LOAD_BLOCK" Line="0" TMem="0" Tile="7" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<LoadSync/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="511" Dxt="512"/>
<PipeSync/>
<SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b" Line="4" TMem="0" Tile="0" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="124" Lrt="124"/>
<SetPrimColor M="0" L="0" R="114" G="114" B="114" A="255"/>
<EndDisplayList/>
</DisplayList>

View File

@ -77,6 +77,9 @@ static const ALIGN_ASSET(2) char gBossSoulSkullDL[] = dgBossSoulSkullDL;
#define dgFishingPoleGiDL "__OTR__objects/object_gi_fishing_pole/gFishingPoleGiDL"
static const ALIGN_ASSET(2) char gFishingPoleGiDL[] = dgFishingPoleGiDL;
#define dgMysteryItemDL "__OTR__objects/object_mystery_item/gMysteryItemDL"
static const ALIGN_ASSET(2) char gMysteryItemDL[] = dgMysteryItemDL;
// overlays
#define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx"
static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx;

View File

@ -46,10 +46,18 @@ template<> struct is_char_type<std::byte>: public boost::true_type {};
#endif // #if !BOOST_VERSION_HAS_HASH_RANGE
#if BOOST_USE_STD_TYPES
#define BOOST_ENABLE_IF std::enable_if
#define BOOST_IS_SAME std::is_same
#else
#define BOOST_ENABLE_IF boost::enable_if_
#define BOOST_IS_SAME is_same
#endif
template<class It>
inline typename boost::enable_if_<
inline typename BOOST_ENABLE_IF<
is_char_type<typename std::iterator_traits<It>::value_type>::value &&
is_same<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value,
BOOST_IS_SAME<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag>::value,
std::size_t>::type
hash_range_32( uint32_t seed, It first, It last )
{
@ -114,4 +122,7 @@ std::size_t>::type
} // namespace hash_detail
} // namespace boost
#undef BOOST_ENABLE_IF
#undef BOOST_IS_SAME
#endif // #ifndef BOOST_HASH_DETAIL_HASH_RANGE_32_HPP

View File

@ -23,6 +23,18 @@
#endif // #if !BOOST_VERSION_HAS_HASH_RANGE
#if BOOST_USE_STD_TYPES
#define BOOST_ENABLE_IF std::enable_if
#define BOOST_IS_INTEGRAL hash_detail::is_integral
#define BOOST_IS_UNSIGNED is_unsigned
#define BOOST_MAKE_UNSIGNED make_unsigned
#else
#define BOOST_ENABLE_IF boost::enable_if_
#define BOOST_IS_INTEGRAL boost::is_integral
#define BOOST_IS_UNSIGNED boost::is_unsigned
#define BOOST_MAKE_UNSIGNED boost::make_unsigned
#endif
namespace boost
{
@ -36,7 +48,7 @@ namespace boost
{
template<class T,
bool bigger_than_size_t = (sizeof(T) > sizeof(uint32_t)),
bool is_unsigned = boost::is_unsigned<T>::value,
bool is_unsigned = BOOST_IS_UNSIGNED<T>::value,
std::size_t size_t_bits = sizeof(uint32_t) * CHAR_BIT,
std::size_t type_bits = sizeof(T) * CHAR_BIT>
struct hash_integral_impl_32;
@ -53,7 +65,7 @@ namespace boost
{
static uint32_t fn( T v )
{
typedef typename boost::make_unsigned<T>::type U;
typedef typename BOOST_MAKE_UNSIGNED<T>::type U;
if( v >= 0 )
{
@ -97,7 +109,7 @@ namespace boost
} // namespace hash_detail
template <typename T>
typename boost::enable_if_<boost::is_integral<T>::value, uint32_t>::type
typename BOOST_ENABLE_IF<BOOST_IS_INTEGRAL<T>::value, uint32_t>::type
hash_value_32( T v )
{
return hash_detail::hash_integral_impl_32<T>::fn( v );
@ -106,7 +118,7 @@ namespace boost
// contiguous ranges (string, vector, array)
#if BOOST_VERSION_HAS_HASH_RANGE
template <typename T>
typename boost::enable_if_<container_hash::is_contiguous_range<T>::value, uint32_t>::type
typename BOOST_ENABLE_IF<container_hash::is_contiguous_range<T>::value, uint32_t>::type
hash_value_32( T const& v )
{
return boost::hash_range_32( v.data(), v.data() + v.size() );
@ -168,5 +180,9 @@ namespace boost
} // namespace boost
#undef BOOST_HASH_CHAR_TRAITS
#undef BOOST_ENABLE_IF
#undef BOOST_IS_INTEGRAL
#undef BOOST_IS_UNSIGNED
#undef BOOST_MAKE_UNSIGNED
#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_32_HPP

View File

@ -6,4 +6,6 @@
#define BOOST_VERSION_HAS_HASH_RANGE ((BOOST_VERSION / 100 % 1000) >= 81)
#define BOOST_USE_STD_TYPES ((BOOST_VERSION / 100 % 1000) >= 84)
#endif // #ifndef BOOST_CONTAINER_HASH_VERSION_HPP

View File

@ -183,6 +183,8 @@ void __osSetWatchLo(u32);
EnItem00* Item_DropCollectible(PlayState* play, Vec3f* spawnPos, s16 params);
EnItem00* Item_DropCollectible2(PlayState* play, Vec3f* spawnPos, s16 params);
void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry giEntry);
void EnItem00_SetupAction(EnItem00* this, EnItem00ActionFunc actionFunc);
void func_8001E5C8(EnItem00* this, PlayState* play);
void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnPos, s16 params);
void EffectBlure_ChangeType(EffectBlure* this, int type);
void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2);
@ -415,6 +417,7 @@ f32 Actor_WorldDistXZToPoint(Actor* actor, Vec3f* refPoint);
void func_8002DBD0(Actor* actor, Vec3f* result, Vec3f* arg2);
f32 Actor_HeightDiff(Actor* actorA, Actor* actorB);
f32 Player_GetHeight(Player* player);
s32 Player_ActionChange_2(Player* player, PlayState* play);
f32 func_8002DCE4(Player* player);
s32 func_8002DD6C(Player* player);
s32 func_8002DD78(Player* player);
@ -426,7 +429,7 @@ void Actor_MountHorse(PlayState* play, Player* player, Actor* horse);
s32 func_8002DEEC(Player* player);
void func_8002DF18(PlayState* play, Player* player);
s32 func_8002DF38(PlayState* play, Actor* actor, u8 csMode);
s32 func_8002DF54(PlayState* play, Actor* actor, u8 arg2);
s32 Player_SetCsActionWithHaltedActors(PlayState* play, Actor* actor, u8 arg2);
void func_8002DF90(DynaPolyActor* dynaActor);
void func_8002DFA4(DynaPolyActor* dynaActor, f32 arg1, s16 arg2);
s32 Player_IsFacingActor(Actor* actor, s16 angle, PlayState* play);
@ -454,11 +457,11 @@ u32 Actor_TextboxIsClosing(Actor* actor, PlayState* play);
s8 func_8002F368(PlayState* play);
void Actor_GetScreenPos(PlayState* play, Actor* actor, s16* x, s16* y);
u32 Actor_HasParent(Actor* actor, PlayState* play);
// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename func_8002F434 and func_8002F554.
// TODO: Rename the follwing 3 functions using whatever scheme we use when we rename Actor_OfferGetItem and func_8002F554.
s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry);
s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEntry, f32 xzRange, f32 yRange);
s32 GiveItemEntryFromActorWithFixedRange(Actor* actor, PlayState* play, GetItemEntry getItemEntry);
s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange);
s32 Actor_OfferGetItem(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32 yRange);
void func_8002F554(Actor* actor, PlayState* play, s32 getItemId);
void func_8002F580(Actor* actor, PlayState* play);
u32 Actor_HasNoParent(Actor* actor, PlayState* play);
@ -572,8 +575,6 @@ void Flags_UnsetRandomizerInf(RandomizerInf flag);
u16 func_80037C30(PlayState* play, s16 arg1);
s32 func_80037D98(PlayState* play, Actor* actor, s16 arg2, s32* arg3);
s32 func_80038290(PlayState* play, Actor* actor, Vec3s* arg2, Vec3s* arg3, Vec3f arg4);
GetItemEntry GetChestGameRandoGetItem(s8 room, s16 ogDrawId, PlayState* play);
s16 GetChestGameRandoGiDrawId(s8 room, s16 ogDrawId, PlayState* play);
// ? func_80038600(?);
u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList*);
@ -1106,6 +1107,7 @@ s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input);
u8 PlayerGrounded(Player* player);
void Player_SetBootData(PlayState* play, Player* player);
s32 Player_InBlockingCsMode(PlayState* play, Player* player);
s32 Player_TryCsAction(PlayState* play, Actor* actor, s32 csAction);
s32 Player_InCsMode(PlayState* play);
s32 func_8008E9C4(Player* player);
s32 Player_IsChildWithHylianShield(Player* player);
@ -1230,8 +1232,8 @@ Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a);
void Gfx_SetupFrame(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b);
void func_80095974(GraphicsContext* gfxCtx);
void func_80095AA0(PlayState* play, Room* room, Input* arg2, UNK_TYPE arg3);
void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 mode0,
u16 tlutCount, f32 frameX, f32 frameY);
void Room_DrawBackground2D(Gfx** gfxP, void* tex, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tlutMode,
u16 tlutCount, f32 offsetX, f32 offsetY);
void func_80096FD4(PlayState* play, Room* room);
u32 func_80096FE8(PlayState* play, RoomContext* roomCtx);
s32 func_8009728C(PlayState* play, RoomContext* roomCtx, s32 roomNum);
@ -1828,8 +1830,8 @@ MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line);
void Matrix_SetTranslateScaleMtx2(Mtx* mtx, f32 scaleX, f32 scaleY, f32 scaleZ, f32 translateX, f32 translateY,
f32 translateZ);
uintptr_t SysUcode_GetUCodeBoot(void);
uintptr_t SysUcode_GetUCodeBootSize(void);
uintptr_t SysUcode_GetUCode(void);
size_t SysUcode_GetUCodeBootSize(void);
uint32_t SysUcode_GetUCode(void);
uintptr_t SysUcode_GetUCodeData(void);
void func_800D2E30(UnkRumbleStruct* arg0);
void func_800D3140(UnkRumbleStruct* arg0);
@ -2354,7 +2356,6 @@ s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check);
s32 __osGetId(OSPfs* pfs);
s32 __osCheckId(OSPfs* pfs);
s32 __osPfsRWInode(OSPfs* pfs, __OSInode* inode, u8 flag, u8 bank);
void guMtxL2F(MtxF* m1, Mtx* m2);
s32 osPfsFindFile(OSPfs* pfs, u16 companyCode, u32 gameCode, u8* gameName, u8* extName, s32* fileNo);
s32 osAfterPreNMI(void);
s32 osContStartQuery(OSMesgQueue* mq);
@ -2408,7 +2409,6 @@ u32 __osSpGetStatus(void);
void __osSpSetStatus(u32 status);
void osWritebackDCacheAll(void);
OSThread* __osGetCurrFaultedThread(void);
void guMtxF2L(MtxF* m1, Mtx* m2);
// ? __d_to_ll(?);
// ? __f_to_ll(?);
// ? __d_to_ull(?);

View File

@ -172,7 +172,8 @@ extern "C"
extern u8 gWalkSpeedToggle2;
extern f32 iceTrapScale;
extern f32 triforcePieceScale;
extern f32 mysteryItemScale;
extern const s16 D_8014A6C0[];
#define gTatumsPerBeat (D_8014A6C0[1])
extern const AudioContextInitSizes D_8014A6C4;

View File

@ -266,7 +266,12 @@ typedef enum {
/* 0x17 */ ITEM00_TUNIC_ZORA,
/* 0x18 */ ITEM00_TUNIC_GORON,
/* 0x19 */ ITEM00_BOMBS_SPECIAL,
/* 0x20 */ ITEM00_BOMBCHU,
/* 0x1A */ ITEM00_BOMBCHU,
/* 0x1B */ ITEM00_SOH_DUMMY,
/* 0x1C */ ITEM00_SOH_GIVE_ITEM_ENTRY,
/* 0x1D */ ITEM00_SOH_GIVE_ITEM_ENTRY_GI,
/* 0x1E */ ITEM00_MAX,
/* 0xFF */ ITEM00_NONE = 0xFF
} Item00Type;
struct EnItem00;
@ -284,10 +289,13 @@ typedef struct EnItem00 {
/* 0x15A */ s16 unk_15A;
/* 0x15C */ f32 scale;
/* 0x160 */ ColliderCylinder collider;
s16 ogParams;
// #region SOH [Randomizer]
GetItemEntry randoGiEntry;
RandomizerCheck randoCheck;
RandomizerInf randoInf;
/* */ s16 ogParams;
/* */ GetItemEntry itemEntry;
// #endregion
} EnItem00; // size = 0x1AC
// Only A_OBJ_SIGNPOST_OBLONG and A_OBJ_SIGNPOST_ARROW are used in room files.

View File

@ -283,7 +283,7 @@ typedef struct {
// #endregion
// #region SOH [Randomizer]
// Upstream TODO: Move these to their own struct or name to more obviously specific to Randomizer
/* */ u16 randomizerInf[16];
/* */ u16 randomizerInf[17];
/* */ u8 mqDungeonCount;
/* */ u16 adultTradeItems;
/* */ u8 triforcePiecesCollected;

View File

@ -7,68 +7,6 @@ export RESPATH="${SNAME%/MacOS*}/Resources"
export LIBPATH="${SNAME%/MacOS*}/Frameworks"
export DYLD_FALLBACK_LIBRARY_PATH="$LIBPATH"
remap_hashes ()
{
# Remap v64 and n64 hashes to their z64 hash equivalent
# ZAPD will handle converting the data into z64 format
case "$ROMHASH" in
a9059b56e761c9034fbe02fe4c24985aaa835dac) # v64
ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099
;;
24708102dc504d3f375a37f4ae4e149c167dc515) # n64
ROMHASH=cee6bc3c2a634b41728f2af8da54d9bf8cc14099
;;
580dd0bd1b6d2c51cc20a764eece84dba558964c) # v64
ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4
;;
d6342c59007e57c1194661ec6880b2f078403f4e) # n64
ROMHASH=0227d7c0074f2d0ac935631990da8ec5914597b4
;;
d0bdc2eb320668b4ba6893b9aefe4040a73123ff) # v64
ROMHASH=328a1f1beba30ce5e178f031662019eb32c5f3b5
;;
4946ab250f6ac9b32d76b21f309ebb8ebc8103d2) # n64
ROMHASH=328a1f1beba30ce5e178f031662019eb32c5f3b5
;;
663c34f1b2c05a09e5beffe4d0dcd440f7d49dc7) # v64
ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012
;;
24c73d378b0620a380ce5ef9f2b186c6c157a68b) # n64
ROMHASH=cfbb98d392e4a9d39da8285d10cbef3974c2f012
;;
8ebf2e29313f44f2d49e5b4191971d09919e8e48) # v64
ROMHASH=f46239439f59a2a594ef83cf68ef65043b1bffe2
;;
4264bf7b875737b8fae77d52322a5099d051fc11) # n64
ROMHASH=f46239439f59a2a594ef83cf68ef65043b1bffe2
;;
973bc6fe56010a8d646166a1182a81b4f13b8cf9) # v64
ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03
;;
d327752c46edc70ff3668b9514083dbbee08927c) # v64
ROMHASH=50bebedad9e0f10746a52b07239e47fa6c284d03
;;
ecdeb1747560834e079c22243febea7f6f26ba3b) # v64
ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da
;;
f19f8662ec7abee29484a272a6fda53e39efe0f1) # n64
ROMHASH=079b855b943d6ad8bd1eb026c0ed169ecbdac7da
;;
ab519ce04a33818ce2c39b3c514a751d807a494a) # v64
ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6
;;
c19a34f7646305e1755249fca2071e178bd7cd00) # n64
ROMHASH=cfecfdc58d650e71a200c81f033de4e6d617a9f6
;;
25e8ae79ea0839ca5c984473f7460d8040c36f9c) # v64
ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f
;;
166c02770d67fcc3954c443eb400a6a3573d3fc0) # n64
ROMHASH=517bd9714c73cb96c21e7c2ef640d7b55186102f
;;
esac
}
if [ ! -e "$SHIP_HOME" ]; then mkdir "$SHIP_HOME"; fi
if [ ! -e "$SHIP_HOME"/mods ]; then
@ -76,178 +14,6 @@ if [ ! -e "$SHIP_HOME"/mods ]; then
touch "$SHIP_HOME"/mods/custom_otr_files_go_here.txt
fi
# If either OTR doesn't exist kick off the OTR gen process
if [ ! -e "$SHIP_HOME"/oot.otr ] || [ ! -e "$SHIP_HOME"/oot-mq.otr ]; then
# If no ROMs exist kick off the file selection prompts
while [ ! -e "$SHIP_HOME"/*.*64 ] && [ ! -e "$SHIP_HOME"/oot*.otr ]; do
SHOULD_PROMPT_FOR_ROM=1
while [ $SHOULD_PROMPT_FOR_ROM -eq 1 ]; do
SHOULD_PROMPT_FOR_ROM=0
# Use osascript to prompt the user to chose a file
DROPROM=`osascript <<-EOF
set romFile to choose file of type {"b64","n64","v64","z64"} with prompt "Please select your ROM:"
return POSIX path of romFile
EOF`
# If no rom was selected, the user cancelled, so exit
if [[ -z $DROPROM ]] && [[ -z "$UPLOAD_ANOTHER_RESULT" ]]; then
echo "No ROM selected. Exiting..."
exit 1
elif [[ -z $DROPROM ]]; then
break;
fi
# If an invalid rom was selected, let the user know and ask to try again
ROMHASH="$(shasum "$DROPROM" | awk '{ print $1 }')"
remap_hashes
case "$ROMHASH" in
cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
ROM_TYPE=0;;
0227d7c0074f2d0ac935631990da8ec5914597b4)
ROM_TYPE=0;;
328a1f1beba30ce5e178f031662019eb32c5f3b5)
ROM_TYPE=0;;
cfbb98d392e4a9d39da8285d10cbef3974c2f012)
ROM_TYPE=0;;
f46239439f59a2a594ef83cf68ef65043b1bffe2)
ROM_TYPE=1;;
50bebedad9e0f10746a52b07239e47fa6c284d03)
ROM_TYPE=1;;
079b855b943d6ad8bd1eb026c0ed169ecbdac7da)
ROM_TYPE=1;;
cfecfdc58d650e71a200c81f033de4e6d617a9f6)
ROM_TYPE=1;;
517bd9714c73cb96c21e7c2ef640d7b55186102f)
ROM_TYPE=1;;
*)
TRY_AGAIN_RESULT=`osascript <<-EOF
set alertText to "Incompatible ROM hash"
set alertMessage to "Incompatible ROM provided, would you like to try again?"
return display alert alertText \
message alertMessage \
as critical \
buttons {"Cancel", "Try Again"}
EOF`
if [[ "$TRY_AGAIN_RESULT" == "button returned:Try Again" ]]; then
SHOULD_PROMPT_FOR_ROM=1
continue;
else
echo "No ROM selected. Exiting..."
exit 1
fi
esac
cp "$DROPROM" "$SHIP_HOME"
# Ask user if they would also like to select the other variant (MQ/Vanilla)
if [ $ROM_TYPE -eq 0 ] && [[ -z "$UPLOAD_ANOTHER_RESULT" ]]; then
UPLOAD_ANOTHER_RESULT=`osascript <<-EOF
set alertText to "Success"
set alertMessage to "Would you also like to provide a Master Quest ROM?"
return display alert alertText \
message alertMessage \
buttons {"No", "Yes"}
EOF`
elif [[ -z "$UPLOAD_ANOTHER_RESULT" ]]; then
UPLOAD_ANOTHER_RESULT=`osascript <<-EOF
set alertText to "Success"
set alertMessage to "Would you also like to provide a Vanilla (Non Master Quest) ROM?"
return display alert alertText \
message alertMessage \
buttons {"No", "Yes"}
EOF`
fi
if [[ "$UPLOAD_ANOTHER_RESULT" == "button returned:Yes" ]]; then
UPLOAD_ANOTHER_RESULT="button returned:No"
SHOULD_PROMPT_FOR_ROM=1
continue;
fi
break
done
done
# At this point we should now have 1 or more valid roms in $SHIP_HOME directory
# Prepare tmp dir
for ROMPATH in "$SHIP_HOME"/*.*64
do
ASSETDIR="$(mktemp -d /tmp/assets-XXXXX)"
export ASSETDIR
cp -r "$RESPATH/assets" "$ASSETDIR"
mkdir -p "$ASSETDIR"/tmp
cp "$ROMPATH" "$ASSETDIR"/tmp/rom.z64
cd "$ASSETDIR" || return
# If an invalid rom was detected, let the user know
ROMHASH="$(shasum "$ASSETDIR"/tmp/rom.z64 | awk '{ print $1 }')"
remap_hashes
case "$ROMHASH" in
cee6bc3c2a634b41728f2af8da54d9bf8cc14099)
ROM=GC_NMQ_D
OTRNAME="oot.otr";;
0227d7c0074f2d0ac935631990da8ec5914597b4)
ROM=GC_NMQ_PAL_F
OTRNAME="oot.otr";;
328a1f1beba30ce5e178f031662019eb32c5f3b5)
ROM=N64_PAL_10
OTRNAME="oot.otr";;
cfbb98d392e4a9d39da8285d10cbef3974c2f012)
ROM=N64_PAL_11
OTRNAME="oot.otr";;
f46239439f59a2a594ef83cf68ef65043b1bffe2)
ROM=GC_MQ_PAL_F
OTRNAME="oot-mq.otr";;
50bebedad9e0f10746a52b07239e47fa6c284d03)
ROM=GC_MQ_D
OTRNAME="oot-mq.otr";;
079b855b943d6ad8bd1eb026c0ed169ecbdac7da)
ROM=GC_MQ_D
OTRNAME="oot-mq.otr";;
cfecfdc58d650e71a200c81f033de4e6d617a9f6)
ROM=GC_MQ_D
OTRNAME="oot-mq.otr";;
517bd9714c73cb96c21e7c2ef640d7b55186102f)
ROM=GC_MQ_D
OTRNAME="oot-mq.otr";;
*)
osascript -e 'display notification "One or more invalid ROM provided" with title "Ship Of Harkinian"'
rm -r "$ASSETDIR"
cd "$SNAME"
continue;
esac
# Only generate OTR if we don't have on of this type yet
if [ -e "$SHIP_HOME"/"$OTRNAME" ]; then
rm -r "$ASSETDIR"
cd "$SNAME"
continue;
fi
osascript -e 'display notification "Generating OTR..." with title "Ship Of Harkinian"'
assets/extractor/ZAPD.out ed -i assets/extractor/xmls/"${ROM}" -b tmp/rom.z64 -fl assets/extractor/filelists -o placeholder -osf placeholder -gsf 1 -rconf assets/extractor/Config_"${ROM}".xml -se OTR --portVer "@CMAKE_PROJECT_VERSION@"
if [ -e "$ASSETDIR"/oot.otr ]; then
osascript -e 'display notification "OTR successfully generated" with title "Ship Of Harkinian"'
cp "$ASSETDIR"/oot.otr "$SHIP_HOME"/"$OTRNAME"
rm -r "$ASSETDIR"
cd "$SNAME"
fi
done
if [ ! -e "$SHIP_HOME"/oot*.otr ]; then
osascript -e 'display notification "OTR failed to generate" with title "Ship Of Harkinian"'
exit 1;
fi
fi
cd "$SNAME"
"$RESPATH"/soh-macos
exit

View File

@ -2,9 +2,10 @@
#include "sequence.h"
#include "sfx.h"
#include <vector>
#include <Utils/StringHelper.h>
#include <utils/StringHelper.h>
#include <libultraship/bridge.h>
#include <libultraship/classes.h>
#include <soh/OTRGlobals.h>
#include <locale>
#include <filesystem>
@ -330,11 +331,13 @@ AudioCollection::AudioCollection() {
}
std::string AudioCollection::GetCvarKey(std::string sfxKey) {
return "gAudioEditor.ReplacedSequences." + sfxKey + ".value";
auto prefix = CVAR_AUDIO("ReplacedSequences.");
return prefix + sfxKey + ".value";
}
std::string AudioCollection::GetCvarLockKey(std::string sfxKey) {
return "gAudioEditor.ReplacedSequences." + sfxKey + ".locked";
auto prefix = std::string(CVAR_AUDIO("ReplacedSequences."));
return prefix + sfxKey + ".locked";
}
void AudioCollection::AddToCollection(char* otrPath, uint16_t seqNum) {
@ -362,7 +365,7 @@ uint16_t AudioCollection::GetReplacementSequence(uint16_t seqId) {
// for Hyrule Field instead. Otherwise, leave it alone, so that without any sfx editor modifications we will
// play the normal track as usual.
if (seqId == NA_BGM_FIELD_MORNING) {
if (CVarGetInteger("gAudioEditor.ReplacedSequences.NA_BGM_FIELD_LOGIC.value", NA_BGM_FIELD_LOGIC) != NA_BGM_FIELD_LOGIC) {
if (CVarGetInteger(CVAR_AUDIO("ReplacedSequences.NA_BGM_FIELD_LOGIC.value"), NA_BGM_FIELD_LOGIC) != NA_BGM_FIELD_LOGIC) {
seqId = NA_BGM_FIELD_LOGIC;
}
}
@ -381,19 +384,19 @@ uint16_t AudioCollection::GetReplacementSequence(uint16_t seqId) {
}
void AudioCollection::RemoveFromShufflePool(SequenceInfo* seqInfo) {
const std::string cvarKey = "gAudioEditor.Excluded." + seqInfo->sfxKey;
const std::string cvarKey = std::string(CVAR_AUDIO("Excluded.")) + seqInfo->sfxKey;
excludedSequences.insert(seqInfo);
includedSequences.erase(seqInfo);
CVarSetInteger(cvarKey.c_str(), 1);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
void AudioCollection::AddToShufflePool(SequenceInfo* seqInfo) {
const std::string cvarKey = "gAudioEditor.Excluded." + seqInfo->sfxKey;
const std::string cvarKey = std::string(CVAR_AUDIO("Excluded.")) + seqInfo->sfxKey;
includedSequences.insert(seqInfo);
excludedSequences.erase(seqInfo);
CVarClear(cvarKey.c_str());
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
void AudioCollection::InitializeShufflePool() {
@ -401,7 +404,7 @@ void AudioCollection::InitializeShufflePool() {
for (auto& [seqId, seqInfo] : sequenceMap) {
if (!seqInfo.canBeUsedAsReplacement) continue;
const std::string cvarKey = "gAudioEditor.Excluded." + seqInfo.sfxKey;
const std::string cvarKey = std::string(CVAR_AUDIO("Excluded.")) + seqInfo.sfxKey;
if (CVarGetInteger(cvarKey.c_str(), 0)) {
excludedSequences.insert(&seqInfo);
} else {

View File

@ -1,3 +1,4 @@
#pragma once
#ifdef __cplusplus
#include <map>
#include <string>

View File

@ -9,7 +9,7 @@
#include <functions.h>
#include "../randomizer/3drando/random.hpp"
#include "../../OTRGlobals.h"
#include <Utils/StringHelper.h>
#include <utils/StringHelper.h>
#include "../../UIWidgets.hpp"
#include "AudioCollection.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
@ -163,17 +163,17 @@ void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequence
const std::string stopButton = ICON_FA_STOP + hiddenKey;
const std::string previewButton = ICON_FA_PLAY + hiddenKey;
if (CVarGetInteger("gAudioEditor.Playing", 0) == sequenceId) {
if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) == sequenceId) {
if (ImGui::Button(stopButton.c_str())) {
func_800F5C2C();
CVarSetInteger("gAudioEditor.Playing", 0);
CVarSetInteger(CVAR_AUDIO("Playing"), 0);
}
UIWidgets::Tooltip("Stop Preview");
} else {
if (ImGui::Button(previewButton.c_str())) {
if (CVarGetInteger("gAudioEditor.Playing", 0) != 0) {
if (CVarGetInteger(CVAR_AUDIO("Playing"), 0) != 0) {
func_800F5C2C();
CVarSetInteger("gAudioEditor.Playing", 0);
CVarSetInteger(CVAR_AUDIO("Playing"), 0);
} else {
if (sequenceType == SEQ_SFX || sequenceType == SEQ_VOICE) {
Audio_PlaySoundGeneral(sequenceId, &pos, 4, &freqScale, &freqScale, &reverbAdd);
@ -183,7 +183,7 @@ void DrawPreviewButton(uint16_t sequenceId, std::string sfxKey, SeqType sequence
} else {
// TODO: Cant do both here, so have to click preview button twice
PreviewSequence(sequenceId);
CVarSetInteger("gAudioEditor.Playing", sequenceId);
CVarSetInteger(CVAR_AUDIO("Playing"), sequenceId);
}
}
}
@ -203,7 +203,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
ResetGroup(map, type);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
ReplayCurrentBGM();
@ -214,7 +214,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
RandomizeGroup(type);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
ReplayCurrentBGM();
@ -225,7 +225,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
LockGroup(map, type);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
ReplayCurrentBGM();
@ -236,7 +236,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
auto currentBGM = func_800FA0B4(SEQ_PLAYER_BGM_MAIN);
auto prevReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
UnlockGroup(map, type);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
auto curReplacement = AudioCollection::Instance->GetReplacementSequence(currentBGM);
if (type == SEQ_BGM_WORLD && prevReplacement != curReplacement) {
ReplayCurrentBGM();
@ -281,7 +281,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
if (ImGui::Selectable(seqData.label.c_str())) {
CVarSetInteger(cvarKey.c_str(), value);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
UpdateCurrentBGM(defaultValue, type);
}
@ -301,7 +301,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
if (ImGui::Button(resetButton.c_str())) {
CVarClear(cvarKey.c_str());
CVarClear(cvarLockKey.c_str());
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
UpdateCurrentBGM(defaultValue, seqData.category);
}
UIWidgets::Tooltip("Reset to default");
@ -322,7 +322,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
if (locked) {
CVarClear(cvarLockKey.c_str());
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
UpdateCurrentBGM(defaultValue, type);
}
}
@ -335,7 +335,7 @@ void Draw_SfxTab(const std::string& tabId, SeqType type) {
} else {
CVarSetInteger(cvarLockKey.c_str(), 1);
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
UIWidgets::Tooltip(locked ? "Sound locked" : "Sound unlocked");
}
@ -411,7 +411,7 @@ void DrawTypeChip(SeqType type) {
void AudioEditorRegisterOnSceneInitHook() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
if (CVarGetInteger("gAudioEditor.RandomizeAllOnNewScene", 0)) {
if (CVarGetInteger(CVAR_AUDIO("RandomizeAllOnNewScene"), 0)) {
AudioEditor_RandomizeAll();
}
});
@ -492,18 +492,18 @@ void AudioEditor::DrawElement() {
ImGui::TableNextColumn();
if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) {
ImGui::PushItemWidth(-FLT_MIN);
UIWidgets::EnhancementCheckbox("Disable Enemy Proximity Music", "gEnemyBGMDisable");
UIWidgets::EnhancementCheckbox("Disable Enemy Proximity Music", CVAR_AUDIO("EnemyBGMDisable"));
UIWidgets::InsertHelpHoverText(
"Disables the music change when getting close to enemies. Useful for hearing "
"your custom music for each scene more often.");
UIWidgets::EnhancementCheckbox("Disable Leading Music in Lost Woods", "gLostWoodsConsistentVolume");
UIWidgets::EnhancementCheckbox("Disable Leading Music in Lost Woods", CVAR_AUDIO("LostWoodsConsistentVolume"));
UIWidgets::InsertHelpHoverText(
"Disables the volume shifting in the Lost Woods. Useful for hearing "
"your custom music in the Lost Woods if you don't need the navigation assitance "
"the volume changing provides. If toggling this while in the Lost Woods, reload "
"the area for the effect to kick in."
);
UIWidgets::EnhancementCheckbox("Display Sequence Name on Overlay", "gSeqNameOverlay");
UIWidgets::EnhancementCheckbox("Display Sequence Name on Overlay", CVAR_AUDIO("SeqNameOverlay"));
UIWidgets::InsertHelpHoverText(
"Displays the name of the current sequence in the corner of the screen whenever a new sequence "
"is loaded to the main sequence player (does not apply to fanfares or enemy BGM)."
@ -511,28 +511,28 @@ void AudioEditor::DrawElement() {
ImGui::SameLine();
ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
UIWidgets::EnhancementSliderInt("Overlay Duration: %d seconds", "##SeqNameOverlayDuration",
"gSeqNameOverlayDuration", 1, 10, "", 5);
CVAR_AUDIO("SeqNameOverlayDuration"), 1, 10, "", 5);
ImGui::PopItemWidth();
ImGui::NewLine();
ImGui::PopItemWidth();
UIWidgets::EnhancementSliderFloat("Link's voice pitch multiplier: %.1f %%", "##linkVoiceFreqMultiplier",
"gLinkVoiceFreqMultiplier", 0.4, 2.5, "", 1.0, true, true);
CVAR_AUDIO("LinkVoiceFreqMultiplier"), 0.4, 2.5, "", 1.0, true, true);
ImGui::SameLine();
const std::string resetButton = "Reset##linkVoiceFreqMultiplier";
if (ImGui::Button(resetButton.c_str())) {
CVarSetFloat("gLinkVoiceFreqMultiplier", 1.0f);
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
ImGui::NewLine();
UIWidgets::EnhancementCheckbox("Randomize All Music and Sound Effects on New Scene", "gAudioEditor.RandomizeAllOnNewScene");
UIWidgets::EnhancementCheckbox("Randomize All Music and Sound Effects on New Scene", CVAR_AUDIO("RandomizeAllOnNewScene"));
UIWidgets::Tooltip("Enables randomizing all unlocked music and sound effects when you enter a new scene.");
ImGui::NewLine();
ImGui::PushItemWidth(-FLT_MIN);
UIWidgets::PaddedSeparator();
UIWidgets::PaddedText("The following options are experimental and may cause music\nto sound odd or have other undesireable effects.");
UIWidgets::EnhancementCheckbox("Lower Octaves of Unplayable High Notes", "gExperimentalOctaveDrop");
UIWidgets::EnhancementCheckbox("Lower Octaves of Unplayable High Notes", CVAR_AUDIO("ExperimentalOctaveDrop"));
UIWidgets::InsertHelpHoverText("Some custom sequences may have notes that are too high for the game's audio "
"engine to play. Enabling this checkbox will cause these notes to drop a "
"couple of octaves so they can still harmonize with the other notes of the "
@ -710,7 +710,14 @@ void AudioEditor_RandomizeAll() {
RandomizeGroup(type);
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
ReplayCurrentBGM();
}
void AudioEditor_RandomizeGroup(SeqType group) {
RandomizeGroup(group);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
ReplayCurrentBGM();
}
@ -719,7 +726,14 @@ void AudioEditor_ResetAll() {
ResetGroup(AudioCollection::Instance->GetAllSequences(), type);
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
ReplayCurrentBGM();
}
void AudioEditor_ResetGroup(SeqType group) {
ResetGroup(AudioCollection::Instance->GetAllSequences(), group);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
ReplayCurrentBGM();
}
@ -728,7 +742,7 @@ void AudioEditor_LockAll() {
LockGroup(AudioCollection::Instance->GetAllSequences(), type);
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
void AudioEditor_UnlockAll() {
@ -736,5 +750,5 @@ void AudioEditor_UnlockAll() {
UnlockGroup(AudioCollection::Instance->GetAllSequences(), type);
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}

View File

@ -7,11 +7,12 @@
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include <ImGui/imgui.h>
#include <imgui.h>
#include "AudioCollection.h"
class AudioEditor : public LUS::GuiWindow {
class AudioEditor : public Ship::GuiWindow {
public:
using LUS::GuiWindow::GuiWindow;
using GuiWindow::GuiWindow;
void DrawElement() override;
void InitElement() override;
@ -20,7 +21,9 @@ class AudioEditor : public LUS::GuiWindow {
};
void AudioEditor_RandomizeAll();
void AudioEditor_RandomizeGroup(SeqType group);
void AudioEditor_ResetAll();
void AudioEditor_ResetGroup(SeqType group);
void AudioEditor_LockAll();
void AudioEditor_UnlockAll();

View File

@ -9,6 +9,7 @@
#include <string.h>
#include <stdarg.h>
#include <z64.h>
#include "soh/OTRGlobals.h"
uint8_t gLoadFileSelect = 0, gSkipLogoTest = 0;
@ -21,15 +22,15 @@ static BootCommand sCommands[] = { { "--skiplogo", BootCommands_Command_SkipLogo
void BootCommands_Init()
{
// Clears vars to prevent randomizer menu from being disabled
CVarClear("gRandoGenerating"); // Clear when a crash happened during rando seed generation
CVarClear("gNewSeedGenerated");
CVarClear("gOnFileSelectNameEntry"); // Clear when soh is killed on the file name entry page
CVarClear("gBetterDebugWarpScreenMQMode");
CVarClear("gBetterDebugWarpScreenMQModeScene");
CVarClear("gCheatEasyPauseBufferLastInputs");
CVarClear("gCheatEasyPauseBufferTimer");
CVarClear(CVAR_GENERAL("RandoGenerating")); // Clear when a crash happened during rando seed generation
CVarClear(CVAR_GENERAL("NewSeedGenerated"));
CVarClear(CVAR_GENERAL("OnFileSelectNameEntry")); // Clear when soh is killed on the file name entry page
CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQMode"));
CVarClear(CVAR_GENERAL("BetterDebugWarpScreenMQModeScene"));
CVarClear(CVAR_GENERAL("CheatEasyPauseBufferLastInputs"));
CVarClear(CVAR_GENERAL("CheatEasyPauseBufferTimer"));
#if defined(__SWITCH__) || defined(__WIIU__)
CVarRegisterInteger("gControlNav", 1); // always enable controller nav on switch/wii u
CVarRegisterInteger(CVAR_IMGUI_CONTROLLER_NAV, 1); // always enable controller nav on switch/wii u
#endif
}

View File

@ -129,15 +129,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) {
// Spawn blue warps in Chamber of Sages based on what bosses have been defeated.
if (gSaveContext.linkAge == LINK_AGE_CHILD) {
// Forest Medallion (Gohma)
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE)) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false);
}
// Fire Medallion (King Dodongo)
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN)) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false);
}
// Water Medallion (Barinade)
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY)) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false);
}
} else {
@ -146,15 +146,15 @@ void BossRush_SpawnBlueWarps(PlayState* play) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -199, 6, 0, 0, 0, 0, -1, false);
}
// Forest Medallion (Phantom Ganondorf)
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE)) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, -100, 6, -170, 0, 0, 0, -1, false);
}
// Fire Medallion (Volvagia)
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE)) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 100, 6, -170, 0, 0, 0, -1, false);
}
// Water Medallion (Morpha)
if (!Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)) {
if (!Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) {
Actor_Spawn(&play->actorCtx, play, ACTOR_DOOR_WARP1, 199, 6, 0, 0, 0, 0, -1, false);
}
// Spirit Medallion (Twinrova)
@ -242,22 +242,22 @@ void BossRush_HandleCompleteBoss(PlayState* play) {
gSaveContext.isBossRushPaused = 1;
switch (play->sceneNum) {
case SCENE_DEKU_TREE_BOSS:
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE);
Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP);
break;
case SCENE_DODONGOS_CAVERN_BOSS:
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN);
Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP);
break;
case SCENE_JABU_JABU_BOSS:
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY);
Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP);
break;
case SCENE_FOREST_TEMPLE_BOSS:
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE);
Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
break;
case SCENE_FIRE_TEMPLE_BOSS:
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE);
Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP);
break;
case SCENE_WATER_TEMPLE_BOSS:
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE);
Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP);
break;
case SCENE_SPIRIT_TEMPLE_BOSS:
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE);
@ -432,13 +432,13 @@ void BossRush_InitSave() {
// Set flags and Link's age based on chosen settings.
if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_ADULT ||
gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DEKU_TREE);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY);
Flags_SetEventChkInf(EVENTCHKINF_USED_DEKU_TREE_BLUE_WARP);
Flags_SetEventChkInf(EVENTCHKINF_USED_DODONGOS_CAVERN_BLUE_WARP);
Flags_SetEventChkInf(EVENTCHKINF_USED_JABU_JABUS_BELLY_BLUE_WARP);
if (gSaveContext.bossRushOptions[BR_OPTIONS_BOSSES] == BR_CHOICE_BOSSES_GANONDORF_GANON) {
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE);
Flags_SetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
Flags_SetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP);
Flags_SetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE);
Flags_SetRandomizerInf(RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE);
}

View File

@ -0,0 +1,56 @@
#include <libultraship/bridge.h>
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/Enhancements/enhancementTypes.h"
extern "C" {
#include "macros.h"
#include "variables.h"
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
}
void CheatsOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, void* opt) {
switch (id) {
case VB_DEKU_STICK_BREAK: {
if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
*should = false;
}
break;
}
case VB_DEKU_STICK_BE_ON_FIRE: {
if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) == DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE) {
Player* player = GET_PLAYER(gPlayState);
player->unk_860 = 200; // Keeps the stick's flame lit
player->unk_85C = 1.0f; // Ensures the stick is the proper length
*should = true;
}
break;
}
case VB_DEKU_STICK_BURN_OUT: {
if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
*should = false;
}
break;
}
case VB_DEKU_STICK_BURN_DOWN: {
if (CVarGetInteger(CVAR_CHEAT("DekuStickCheat"), DEKU_STICK_NORMAL) != DEKU_STICK_NORMAL) {
*should = false;
}
break;
}
}
}
static uint32_t onVanillaBehaviorHook = 0;
void CheatsRegisterHooks() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) mutable {
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
onVanillaBehaviorHook = 0;
onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(CheatsOnVanillaBehaviorHandler);
});
}

View File

@ -0,0 +1,6 @@
#ifndef CHEAT_HOOK_HANDLERS_H
#define CHEAT_HOOK_HANDLERS_H
void CheatsRegisterHooks();
#endif // CHEAT_HOOK_HANDLERS_H

View File

@ -3,10 +3,11 @@
#include "public/bridge/consolevariablebridge.h"
#include "libultraship/libultra/controller.h"
#include "Context.h"
#include "soh/OTRGlobals.h"
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include <ImGui/imgui.h>
#include <imgui.h>
#include <spdlog/spdlog.h>
#include <cmath>
@ -46,77 +47,77 @@ void InputViewer::RenderButton(std::string btnTexture, std::string btnOutlineTex
// Render Outline based on settings
if (outlineMode == BUTTON_OUTLINE_ALWAYS_SHOWN || (outlineMode == BUTTON_OUTLINE_NOT_PRESSED && !state) ||
(outlineMode == BUTTON_OUTLINE_PRESSED && state)) {
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnOutlineTexture), size,
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnOutlineTexture), size,
ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
}
// Render button if pressed
if (state) {
ImGui::SetCursorPos(pos);
ImGui::SetNextItemAllowOverlap();
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnTexture), size,
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(btnTexture), size,
ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
}
}
void InputViewer::DrawElement() {
if (CVarGetInteger("gOpenWindows.InputViewer", 0)) {
if (CVarGetInteger(CVAR_WINDOW("InputViewer"), 0)) {
static bool sButtonTexturesLoaded = false;
if (!sButtonTexturesLoaded) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage(
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage(
"Input-Viewer-Background", "textures/buttons/InputViewerBackground.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn", "textures/buttons/ABtn.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn", "textures/buttons/BBtn.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn", "textures/buttons/LBtn.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn", "textures/buttons/RBtn.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn", "textures/buttons/ZBtn.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn", "textures/buttons/ABtn.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn", "textures/buttons/BBtn.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn", "textures/buttons/LBtn.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn", "textures/buttons/RBtn.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn", "textures/buttons/ZBtn.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn",
"textures/buttons/StartBtn.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left", "textures/buttons/CLeft.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right", "textures/buttons/CRight.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up", "textures/buttons/CUp.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down", "textures/buttons/CDown.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left", "textures/buttons/CLeft.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right", "textures/buttons/CRight.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up", "textures/buttons/CUp.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down", "textures/buttons/CDown.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick",
"textures/buttons/AnalogStick.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left",
"textures/buttons/DPadLeft.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right",
"textures/buttons/DPadRight.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up", "textures/buttons/DPadUp.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up", "textures/buttons/DPadUp.png");
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down",
"textures/buttons/DPadDown.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick",
"textures/buttons/RightStick.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("A-Btn Outline",
"textures/buttons/ABtnOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("B-Btn Outline",
"textures/buttons/BBtnOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("L-Btn Outline",
"textures/buttons/LBtnOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("R-Btn Outline",
"textures/buttons/RBtnOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Z-Btn Outline",
"textures/buttons/ZBtnOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Start-Btn Outline",
"textures/buttons/StartBtnOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Left Outline",
"textures/buttons/CLeftOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Right Outline",
"textures/buttons/CRightOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Up Outline",
"textures/buttons/CUpOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("C-Down Outline",
"textures/buttons/CDownOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Analog-Stick Outline",
"textures/buttons/AnalogStickOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Left Outline",
"textures/buttons/DPadLeftOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Right Outline",
"textures/buttons/DPadRightOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Up Outline",
"textures/buttons/DPadUpOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Dpad-Down Outline",
"textures/buttons/DPadDownOutline.png");
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick Outline",
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadTextureFromRawImage("Right-Stick Outline",
"textures/buttons/RightStickOutline.png");
sButtonTexturesLoaded = true;
}
@ -125,23 +126,23 @@ void InputViewer::DrawElement() {
ImVec2 size = ImGui::GetContentRegionAvail();
#ifdef __WIIU__
const float scale = CVarGetFloat("gInputViewer.Scale", 1.0f) * 2.0f;
const float scale = CVarGetFloat(CVAR_INPUT_VIEWER("Scale"), 1.0f) * 2.0f;
#else
const float scale = CVarGetFloat("gInputViewer.Scale", 1.0f);
const float scale = CVarGetFloat(CVAR_INPUT_VIEWER("Scale"), 1.0f);
#endif
const int showAnalogAngles = CVarGetInteger("gInputViewer.AnalogAngles.Enabled", 0);
const int buttonOutlineMode = CVarGetInteger("gInputViewer.ButtonOutlineMode", BUTTON_OUTLINE_NOT_PRESSED);
const int showAnalogAngles = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0);
const int buttonOutlineMode = CVarGetInteger(CVAR_INPUT_VIEWER("ButtonOutlineMode"), BUTTON_OUTLINE_NOT_PRESSED);
ImVec2 bgSize = LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureSize("Input-Viewer-Background");
ImVec2 bgSize = Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureSize("Input-Viewer-Background");
ImVec2 scaledBGSize = ImVec2(bgSize.x * scale, bgSize.y * scale);
ImGui::SetNextWindowSize(ImVec2(
scaledBGSize.x + 20,
scaledBGSize.y +
(showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale * CVarGetFloat("gInputViewer.AnalogAngles.Scale", 1.0f) + 20));
(showAnalogAngles ? ImGui::CalcTextSize("X").y : 0) * scale * CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f) + 20));
ImGui::SetNextWindowContentSize(
ImVec2(scaledBGSize.x, scaledBGSize.y + (showAnalogAngles ? 15 : 0) * scale *
CVarGetFloat("gInputViewer.AnalogAngles.Scale", 1.0f)));
CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f)));
ImGui::SetNextWindowPos(
ImVec2(mainPos.x + size.x - scaledBGSize.x - 30, mainPos.y + size.y - scaledBGSize.y - 30),
ImGuiCond_FirstUseEver);
@ -149,13 +150,13 @@ void InputViewer::DrawElement() {
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
OSContPad* pads = LUS::Context::GetInstance()->GetControlDeck()->GetPads();
OSContPad* pads = Ship::Context::GetInstance()->GetControlDeck()->GetPads();
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoScrollbar |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground |
ImGuiWindowFlags_NoFocusOnAppearing;
if (!CVarGetInteger("gInputViewer.EnableDragging", 1)) {
if (!CVarGetInteger(CVAR_INPUT_VIEWER("EnableDragging"), 1)) {
windowFlags |= ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove;
}
@ -163,68 +164,68 @@ void InputViewer::DrawElement() {
ImGui::SetCursorPos(ImVec2(10, 10));
const ImVec2 aPos = ImGui::GetCursorPos();
if (CVarGetInteger("gInputViewer.ShowBackground", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("ShowBackground"), 1)) {
ImGui::SetNextItemAllowOverlap();
// Background
ImGui::Image(
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Input-Viewer-Background"),
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Input-Viewer-Background"),
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
}
// A/B
if (CVarGetInteger("gInputViewer.BBtn", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("BBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("B-Btn", "B-Btn Outline", pads[0].button & BTN_B, scaledBGSize, buttonOutlineMode);
}
if (CVarGetInteger("gInputViewer.ABtn", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("ABtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("A-Btn", "A-Btn Outline", pads[0].button & BTN_A, scaledBGSize, buttonOutlineMode);
}
// C buttons
if (CVarGetInteger("gInputViewer.CUp", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("CUp"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Up", "C-Up Outline", pads[0].button & BTN_CUP, scaledBGSize, buttonOutlineMode);
}
if (CVarGetInteger("gInputViewer.CLeft", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("CLeft"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Left", "C-Left Outline", pads[0].button & BTN_CLEFT, scaledBGSize, buttonOutlineMode);
}
if (CVarGetInteger("gInputViewer.CRight", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("CRight"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Right", "C-Right Outline", pads[0].button & BTN_CRIGHT, scaledBGSize,
buttonOutlineMode);
}
if (CVarGetInteger("gInputViewer.CDown", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("CDown"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("C-Down", "C-Down Outline", pads[0].button & BTN_CDOWN, scaledBGSize, buttonOutlineMode);
}
// L/R/Z
if (CVarGetInteger("gInputViewer.LBtn", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("LBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("L-Btn", "L-Btn Outline", pads[0].button & BTN_L, scaledBGSize, buttonOutlineMode);
}
if (CVarGetInteger("gInputViewer.RBtn", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("RBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("R-Btn", "R-Btn Outline", pads[0].button & BTN_R, scaledBGSize, buttonOutlineMode);
}
if (CVarGetInteger("gInputViewer.ZBtn", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("ZBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Z-Btn", "Z-Btn Outline", pads[0].button & BTN_Z, scaledBGSize, buttonOutlineMode);
}
// Start
if (CVarGetInteger("gInputViewer.StartBtn", 1)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("StartBtn"), 1)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Start-Btn", "Start-Btn Outline", pads[0].button & BTN_START, scaledBGSize,
@ -232,7 +233,7 @@ void InputViewer::DrawElement() {
}
// Dpad
if (CVarGetInteger("gInputViewer.Dpad", 0)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("Dpad"), 0)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
RenderButton("Dpad-Left", "Dpad-Left Outline", pads[0].button & BTN_DLEFT, scaledBGSize,
@ -255,84 +256,84 @@ void InputViewer::DrawElement() {
// Analog Stick
const int analogOutlineMode =
CVarGetInteger("gInputViewer.AnalogStick.OutlineMode", STICK_MODE_ALWAYS_SHOWN);
const float maxStickDistance = CVarGetInteger("gInputViewer.AnalogStick.Movement", 12);
CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), STICK_MODE_ALWAYS_SHOWN);
const float maxStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.Movement"), 12);
if (analogOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
(analogOutlineMode == STICK_MODE_HIDDEN_IN_DEADZONE && !analogStickIsInDeadzone)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
ImGui::Image(
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick Outline"),
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick Outline"),
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
}
const int analogStickMode =
CVarGetInteger("gInputViewer.AnalogStick.VisibilityMode", STICK_MODE_ALWAYS_SHOWN);
CVarGetInteger(CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), STICK_MODE_ALWAYS_SHOWN);
if (analogStickMode == STICK_MODE_ALWAYS_SHOWN ||
(analogStickMode == STICK_MODE_HIDDEN_IN_DEADZONE && !analogStickIsInDeadzone)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(
ImVec2(aPos.x + maxStickDistance * ((float)(pads[0].stick_x) / MAX_AXIS_RANGE) * scale,
aPos.y - maxStickDistance * ((float)(pads[0].stick_y) / MAX_AXIS_RANGE) * scale));
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick"),
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Analog-Stick"),
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
}
// Right Stick
const float maxRightStickDistance = CVarGetInteger("gInputViewer.RightStick.Movement", 7);
const float maxRightStickDistance = CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.Movement"), 7);
const int rightOutlineMode =
CVarGetInteger("gInputViewer.RightStick.OutlineMode", STICK_MODE_ALWAYS_HIDDEN);
CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), STICK_MODE_ALWAYS_HIDDEN);
if (rightOutlineMode == STICK_MODE_ALWAYS_SHOWN ||
(rightOutlineMode == STICK_MODE_HIDDEN_IN_DEADZONE && !rightStickIsInDeadzone)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(aPos);
ImGui::Image(
LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick Outline"),
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick Outline"),
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
}
const int rightStickMode =
CVarGetInteger("gInputViewer.RightStick.VisibilityMode", STICK_MODE_ALWAYS_HIDDEN);
CVarGetInteger(CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), STICK_MODE_ALWAYS_HIDDEN);
if (rightStickMode == STICK_MODE_ALWAYS_SHOWN ||
(rightStickMode == STICK_MODE_HIDDEN_IN_DEADZONE && !rightStickIsInDeadzone)) {
ImGui::SetNextItemAllowOverlap();
ImGui::SetCursorPos(
ImVec2(aPos.x + maxRightStickDistance * ((float)(pads[0].right_stick_x) / MAX_AXIS_RANGE) * scale,
aPos.y - maxRightStickDistance * ((float)(pads[0].right_stick_y) / MAX_AXIS_RANGE) * scale));
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick"),
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Right-Stick"),
scaledBGSize, ImVec2(0, 0), ImVec2(1.0f, 1.0f), ImVec4(255, 255, 255, 255));
}
// Analog stick angle text
if (showAnalogAngles) {
ImGui::SetCursorPos(ImVec2(aPos.x + 10 + CVarGetInteger("gInputViewer.AnalogAngles.Offset", 0) * scale,
ImGui::SetCursorPos(ImVec2(aPos.x + 10 + CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0) * scale,
scaledBGSize.y + aPos.y + 10));
// Scale font with input viewer scale
float oldFontScale = ImGui::GetFont()->Scale;
ImGui::GetFont()->Scale *= scale * CVarGetFloat("gInputViewer.AnalogAngles.Scale", 1.0f);
ImGui::GetFont()->Scale *= scale * CVarGetFloat(CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 1.0f);
ImGui::PushFont(ImGui::GetFont());
// Calculate polar R coordinate from X and Y angles, squared to avoid sqrt
const float rSquared = pads[0].stick_x * pads[0].stick_x + pads[0].stick_y * pads[0].stick_y;
// ESS range
const int range1Min = CVarGetInteger("gInputViewer.AnalogAngles.Range1.Min", 8);
const int range1Max = CVarGetInteger("gInputViewer.AnalogAngles.Range1.Max", 27);
const int range1Min = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Min"), 8);
const int range1Max = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Max"), 27);
// Walking speed range
const int range2Min = CVarGetInteger("gInputViewer.AnalogAngles.Range2.Min", 27);
const int range2Max = CVarGetInteger("gInputViewer.AnalogAngles.Range2.Max", 62);
const int range2Min = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Min"), 27);
const int range2Max = CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Max"), 62);
// Push color based on angle ranges
if (CVarGetInteger("gInputViewer.AnalogAngles.Range1.Enabled", 0) &&
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0) &&
(rSquared >= (range1Min * range1Min)) && (rSquared < (range1Max * range1Max))) {
ImGui::PushStyleColor(
ImGuiCol_Text,
color2Vec(CVarGetColor("gInputViewer.AnalogAngles.Range1.Color", vec2Color(range1Color))));
} else if (CVarGetInteger("gInputViewer.AnalogAngles.Range2.Enabled", 0) &&
color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), vec2Color(range1Color))));
} else if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0) &&
(rSquared >= (range2Min * range2Min)) && (rSquared < (range2Max * range2Max))) {
ImGui::PushStyleColor(
ImGuiCol_Text,
color2Vec(CVarGetColor("gInputViewer.AnalogAngles.Range2.Color", vec2Color(range2Color))));
color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), vec2Color(range2Color))));
} else {
ImGui::PushStyleColor(ImGuiCol_Text, color2Vec(CVarGetColor("gInputViewer.AnalogAngles.TextColor",
ImGui::PushStyleColor(ImGuiCol_Text, color2Vec(CVarGetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor"),
vec2Color(textColor))));
}
@ -363,60 +364,60 @@ void InputViewerSettingsWindow::DrawElement() {
if (ImGui::Begin("Input Viewer Settings", &mIsVisible)) {
// gInputViewer.Scale
UIWidgets::EnhancementSliderFloat("Input Viewer Scale: %.2f", "##Input", "gInputViewer.Scale", 0.1f, 5.0f, "",
UIWidgets::EnhancementSliderFloat("Input Viewer Scale: %.2f", "##Input", CVAR_INPUT_VIEWER("Scale"), 0.1f, 5.0f, "",
1.0f, false, true);
UIWidgets::Tooltip("Sets the on screen size of the input viewer");
// gInputViewer.EnableDragging
UIWidgets::EnhancementCheckbox("Enable Dragging", "gInputViewer.EnableDragging", false, "",
UIWidgets::EnhancementCheckbox("Enable Dragging", CVAR_INPUT_VIEWER("EnableDragging"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
UIWidgets::PaddedSeparator(true, true);
// gInputViewer.ShowBackground
UIWidgets::EnhancementCheckbox("Show Background Layer", "gInputViewer.ShowBackground", false, "",
UIWidgets::EnhancementCheckbox("Show Background Layer", CVAR_INPUT_VIEWER("ShowBackground"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
UIWidgets::PaddedSeparator(true, true);
if (ImGui::CollapsingHeader("Buttons")) {
// gInputViewer.ABtn
UIWidgets::EnhancementCheckbox("Show A-Button Layers", "gInputViewer.ABtn", false, "",
UIWidgets::EnhancementCheckbox("Show A-Button Layers", CVAR_INPUT_VIEWER("ABtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.BBtn
UIWidgets::EnhancementCheckbox("Show B-Button Layers", "gInputViewer.BBtn", false, "",
UIWidgets::EnhancementCheckbox("Show B-Button Layers", CVAR_INPUT_VIEWER("BBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CUp
UIWidgets::EnhancementCheckbox("Show C-Up Layers", "gInputViewer.CUp", false, "",
UIWidgets::EnhancementCheckbox("Show C-Up Layers", CVAR_INPUT_VIEWER("CUp"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CRight
UIWidgets::EnhancementCheckbox("Show C-Right Layers", "gInputViewer.CRight", false, "",
UIWidgets::EnhancementCheckbox("Show C-Right Layers", CVAR_INPUT_VIEWER("CRight"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CDown
UIWidgets::EnhancementCheckbox("Show C-Down Layers", "gInputViewer.CDown", false, "",
UIWidgets::EnhancementCheckbox("Show C-Down Layers", CVAR_INPUT_VIEWER("CDown"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.CLeft
UIWidgets::EnhancementCheckbox("Show C-Left Layers", "gInputViewer.CLeft", false, "",
UIWidgets::EnhancementCheckbox("Show C-Left Layers", CVAR_INPUT_VIEWER("CLeft"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.LBtn
UIWidgets::EnhancementCheckbox("Show L-Button Layers", "gInputViewer.LBtn", false, "",
UIWidgets::EnhancementCheckbox("Show L-Button Layers", CVAR_INPUT_VIEWER("LBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.RBtn
UIWidgets::EnhancementCheckbox("Show R-Button Layers", "gInputViewer.RBtn", false, "",
UIWidgets::EnhancementCheckbox("Show R-Button Layers", CVAR_INPUT_VIEWER("RBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.ZBtn
UIWidgets::EnhancementCheckbox("Show Z-Button Layers", "gInputViewer.ZBtn", false, "",
UIWidgets::EnhancementCheckbox("Show Z-Button Layers", CVAR_INPUT_VIEWER("ZBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.StartBtn
UIWidgets::EnhancementCheckbox("Show Start Button Layers", "gInputViewer.StartBtn", false, "",
UIWidgets::EnhancementCheckbox("Show Start Button Layers", CVAR_INPUT_VIEWER("StartBtn"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, true);
// gInputViewer.Dpad
UIWidgets::EnhancementCheckbox("Show D-Pad Layers", "gInputViewer.Dpad", false, "",
UIWidgets::EnhancementCheckbox("Show D-Pad Layers", CVAR_INPUT_VIEWER("Dpad"), false, "",
UIWidgets::CheckboxGraphics::Checkmark, false);
// gInputViewer.ButtonOutlineMode
UIWidgets::PaddedText("Button Outlines/Backgrounds", true, false);
UIWidgets::EnhancementCombobox("gInputViewer.ButtonOutlineMode", buttonOutlineOptions,
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("ButtonOutlineMode"), buttonOutlineOptions,
BUTTON_OUTLINE_NOT_PRESSED);
UIWidgets::Tooltip(
"Sets the desired visibility behavior for the button outline/background layers. Useful for "
@ -428,21 +429,21 @@ void InputViewerSettingsWindow::DrawElement() {
if (ImGui::CollapsingHeader("Analog Stick")) {
// gInputViewer.AnalogStick.VisibilityMode
UIWidgets::PaddedText("Analog Stick Visibility", true, false);
UIWidgets::EnhancementCombobox("gInputViewer.AnalogStick.VisibilityMode", stickModeOptions,
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.VisibilityMode"), stickModeOptions,
STICK_MODE_ALWAYS_SHOWN);
UIWidgets::Tooltip(
"Determines the conditions under which the moving layer of the analog stick texture is visible.");
// gInputViewer.AnalogStick.OutlineMode
UIWidgets::PaddedText("Analog Stick Outline/Background Visibility", true, false);
UIWidgets::EnhancementCombobox("gInputViewer.AnalogStick.OutlineMode", stickModeOptions,
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("AnalogStick.OutlineMode"), stickModeOptions,
STICK_MODE_ALWAYS_SHOWN);
UIWidgets::Tooltip(
"Determines the conditions under which the analog stick outline/background texture is visible.");
// gInputViewer.AnalogStick.Movement
UIWidgets::EnhancementSliderInt("Analog Stick Movement: %dpx", "##AnalogMovement",
"gInputViewer.AnalogStick.Movement", 0, 200, "", 12, true);
CVAR_INPUT_VIEWER("AnalogStick.Movement"), 0, 200, "", 12, true);
UIWidgets::Tooltip(
"Sets the distance to move the analog stick in the input viewer. Useful for custom input viewers.");
UIWidgets::PaddedSeparator(true, true);
@ -451,21 +452,21 @@ void InputViewerSettingsWindow::DrawElement() {
if (ImGui::CollapsingHeader("Additional (\"Right\") Stick")) {
// gInputViewer.RightStick.VisibilityMode
UIWidgets::PaddedText("Right Stick Visibility", true, false);
UIWidgets::EnhancementCombobox("gInputViewer.RightStick.VisibilityMode", stickModeOptions,
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.VisibilityMode"), stickModeOptions,
STICK_MODE_HIDDEN_IN_DEADZONE);
UIWidgets::Tooltip(
"Determines the conditions under which the moving layer of the right stick texture is visible.");
// gInputViewer.RightStick.OutlineMode
UIWidgets::PaddedText("Right Stick Outline/Background Visibility", true, false);
UIWidgets::EnhancementCombobox("gInputViewer.RightStick.OutlineMode", stickModeOptions,
UIWidgets::EnhancementCombobox(CVAR_INPUT_VIEWER("RightStick.OutlineMode"), stickModeOptions,
STICK_MODE_HIDDEN_IN_DEADZONE);
UIWidgets::Tooltip(
"Determines the conditions under which the right stick outline/background texture is visible.");
// gInputViewer.RightStick.Movement
UIWidgets::EnhancementSliderInt("Right Stick Movement: %dpx", "##RightMovement",
"gInputViewer.RightStick.Movement", 0, 200, "", 7, true);
CVAR_INPUT_VIEWER("RightStick.Movement"), 0, 200, "", 7, true);
UIWidgets::Tooltip(
"Sets the distance to move the right stick in the input viewer. Useful for custom input viewers.");
UIWidgets::PaddedSeparator(true, true);
@ -473,42 +474,42 @@ void InputViewerSettingsWindow::DrawElement() {
if (ImGui::CollapsingHeader("Analog Angle Values")) {
// gAnalogAngles
UIWidgets::EnhancementCheckbox("Show Analog Stick Angle Values", "gInputViewer.AnalogAngles.Enabled");
UIWidgets::EnhancementCheckbox("Show Analog Stick Angle Values", CVAR_INPUT_VIEWER("AnalogAngles.Enabled"));
UIWidgets::Tooltip("Displays analog stick angle values in the input viewer");
if (CVarGetInteger("gInputViewer.AnalogAngles.Enabled", 0)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Enabled"), 0)) {
// gInputViewer.AnalogAngles.TextColor
if (ImGui::ColorEdit4("Text Color", (float*)&textColor)) {
CVarSetColor("gInputViewer.AnalogAngles.TextColor", vec2Color(textColor));
CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.TextColor"), vec2Color(textColor));
}
// gAnalogAngleScale
UIWidgets::EnhancementSliderFloat("Angle Text Scale: %.2f%%", "##AnalogAngleScale",
"gInputViewer.AnalogAngles.Scale", 0.1f, 5.0f, "", 1.0f, true, true);
CVAR_INPUT_VIEWER("AnalogAngles.Scale"), 0.1f, 5.0f, "", 1.0f, true, true);
// gInputViewer.AnalogAngles.Offset
UIWidgets::EnhancementSliderInt("Angle Text Offset: %dpx", "##AnalogAngleOffset",
"gInputViewer.AnalogAngles.Offset", 0, 400, "", 0, true);
CVAR_INPUT_VIEWER("AnalogAngles.Offset"), 0, 400, "", 0, true);
UIWidgets::PaddedSeparator(true, true);
// gInputViewer.AnalogAngles.Range1.Enabled
UIWidgets::EnhancementCheckbox("Highlight ESS Position", "gInputViewer.AnalogAngles.Range1.Enabled");
UIWidgets::EnhancementCheckbox("Highlight ESS Position", CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"));
UIWidgets::Tooltip(
"Highlights the angle value text when the analog stick is in ESS position (on flat ground)");
if (CVarGetInteger("gInputViewer.AnalogAngles.Range1.Enabled", 0)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Enabled"), 0)) {
// gInputViewer.AnalogAngles.Range1.Color
if (ImGui::ColorEdit4("ESS Color", (float*)&range1Color)) {
CVarSetColor("gInputViewer.AnalogAngles.Range1.Color", vec2Color(range1Color));
CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range1.Color"), vec2Color(range1Color));
}
}
UIWidgets::PaddedSeparator(true, true);
// gInputViewer.AnalogAngles.Range2.Enabled
UIWidgets::EnhancementCheckbox("Highlight Walking Speed Angles",
"gInputViewer.AnalogAngles.Range2.Enabled");
CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"));
UIWidgets::Tooltip("Highlights the angle value text when the analog stick is at an angle that would "
"produce a walking speed (on flat ground)\n\n"
"Useful for 1.0 Empty Jumpslash Quick Put Away");
if (CVarGetInteger("gInputViewer.AnalogAngles.Range2.Enabled", 0)) {
if (CVarGetInteger(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Enabled"), 0)) {
// gInputViewer.AnalogAngles.Range2.Color
if (ImGui::ColorEdit4("Walking Speed Color", (float*)&range2Color)) {
CVarSetColor("gInputViewer.AnalogAngles.Range2.Color", vec2Color(range2Color));
CVarSetColor(CVAR_INPUT_VIEWER("AnalogAngles.Range2.Color"), vec2Color(range2Color));
}
}
}

View File

@ -2,6 +2,8 @@
#include <libultraship/libultraship.h>
#define CVAR_INPUT_VIEWER(var) "gInputViewer." var
typedef enum {
BUTTON_OUTLINE_ALWAYS_SHOWN,
BUTTON_OUTLINE_NOT_PRESSED,
@ -15,9 +17,9 @@ typedef enum {
STICK_MODE_ALWAYS_HIDDEN,
} StickMode;
class InputViewer : public LUS::GuiWindow {
class InputViewer : public Ship::GuiWindow {
public:
using LUS::GuiWindow::GuiWindow;
using GuiWindow::GuiWindow;
void InitElement() override {};
void DrawElement() override;
@ -32,9 +34,9 @@ public:
void RenderButton(std::string btn, std::string btnOutline, int state, ImVec2 size, int outlineMode);
};
class InputViewerSettingsWindow : public LUS::GuiWindow {
class InputViewerSettingsWindow : public Ship::GuiWindow {
public:
using LUS::GuiWindow::GuiWindow;
using GuiWindow::GuiWindow;
void InitElement() override {};
void DrawElement() override;

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include <ImGui/imgui.h>
#include <imgui.h>
#include <unordered_map>
#include <string>
#include <vector>
@ -20,7 +20,7 @@ typedef struct {
N64ButtonMask defaultBtn;
} CustomButtonMap;
class SohInputEditorWindow : public LUS::GuiWindow {
class SohInputEditorWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;
~SohInputEditorWindow();
@ -38,14 +38,14 @@ class SohInputEditorWindow : public LUS::GuiWindow {
void UpdateElement() override;
private:
void DrawStickDirectionLine(const char* axisDirectionName, uint8_t port, uint8_t stick, LUS::Direction direction,
void DrawStickDirectionLine(const char* axisDirectionName, uint8_t port, uint8_t stick, Ship::Direction direction,
ImVec4 color);
void DrawButtonLine(const char* buttonName, uint8_t port, uint16_t bitmask, ImVec4 color);
void DrawButtonLineEditMappingButton(uint8_t port, uint16_t bitmask, std::string id);
void DrawButtonLineAddMappingButton(uint8_t port, uint16_t bitmask);
void DrawStickDirectionLineEditMappingButton(uint8_t port, uint8_t stick, LUS::Direction direction, std::string id);
void DrawStickDirectionLineAddMappingButton(uint8_t port, uint8_t stick, LUS::Direction direction);
void DrawStickDirectionLineEditMappingButton(uint8_t port, uint8_t stick, Ship::Direction direction, std::string id);
void DrawStickDirectionLineAddMappingButton(uint8_t port, uint8_t stick, Ship::Direction direction);
void DrawStickSection(uint8_t port, uint8_t stick, int32_t id, ImVec4 color);
void DrawRumbleSection(uint8_t port);
@ -74,20 +74,20 @@ class SohInputEditorWindow : public LUS::GuiWindow {
int32_t mGameInputBlockTimer;
int32_t mMappingInputBlockTimer;
int32_t mRumbleTimer;
std::shared_ptr<LUS::ControllerRumbleMapping> mRumbleMappingToTest;
std::shared_ptr<Ship::ControllerRumbleMapping> mRumbleMappingToTest;
// mBitmaskToMappingIds[port][bitmask] = { id0, id1, ... }
std::unordered_map<uint8_t, std::unordered_map<uint16_t, std::vector<std::string>>> mBitmaskToMappingIds;
// mStickDirectionToMappingIds[port][stick][direction] = { id0, id1, ... }
std::unordered_map<uint8_t,
std::unordered_map<uint8_t, std::unordered_map<LUS::Direction, std::vector<std::string>>>>
std::unordered_map<uint8_t, std::unordered_map<Ship::Direction, std::vector<std::string>>>>
mStickDirectionToMappingIds;
void UpdateBitmaskToMappingIds(uint8_t port);
void UpdateStickDirectionToMappingIds(uint8_t port);
void GetButtonColorsForLUSDeviceIndex(LUS::LUSDeviceIndex lusIndex, ImVec4& buttonColor,
void GetButtonColorsForLUSDeviceIndex(Ship::ShipDeviceIndex lusIndex, ImVec4& buttonColor,
ImVec4& buttonHoveredColor);
void DrawLinkTab();
void DrawIvanTab();
@ -97,7 +97,7 @@ class SohInputEditorWindow : public LUS::GuiWindow {
std::set<uint16_t> mDpadBitmasks;
std::set<uint16_t> mModifierButtonsBitmasks;
void DrawButtonDeviceIcons(uint8_t portIndex, std::set<uint16_t> bitmasks);
void DrawAnalogStickDeviceIcons(uint8_t portIndex, LUS::Stick stick);
void DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::Stick stick);
void DrawRumbleDeviceIcons(uint8_t portIndex);
void DrawGyroDeviceIcons(uint8_t portIndex);
void DrawLEDDeviceIcons(uint8_t portIndex);

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,29 @@
ResourceMgr_UnpatchGfxByName(path, name); \
}
// Not to be confused with tabs, groups are 1:1 with the boxes shown in the UI, grouping them allows us to reset/randomize
// every item in a group at once. If you are looking for tabs they are rendered manually in ImGui in `DrawCosmeticsEditor`
typedef enum {
COSMETICS_GROUP_LINK,
COSMETICS_GROUP_MIRRORSHIELD,
COSMETICS_GROUP_SWORDS,
COSMETICS_GROUP_GLOVES,
COSMETICS_GROUP_EQUIPMENT,
COSMETICS_GROUP_CONSUMABLE,
COSMETICS_GROUP_HUD,
COSMETICS_GROUP_KALEIDO,
COSMETICS_GROUP_TITLE,
COSMETICS_GROUP_NPC,
COSMETICS_GROUP_WORLD,
COSMETICS_GROUP_MAGIC,
COSMETICS_GROUP_ARROWS,
COSMETICS_GROUP_SPIN_ATTACK,
COSMETICS_GROUP_TRAILS,
COSMETICS_GROUP_NAVI,
COSMETICS_GROUP_IVAN,
COSMETICS_GROUP_MAX
} CosmeticGroup;
typedef struct {
const std::string Name;
const std::string ToolTip;
@ -26,10 +49,12 @@ static ImGuiTableColumnFlags FlagsCell = ImGuiTableColumnFlags_WidthStretch | Im
void InitCosmeticsEditor();//Init the menu itself
ImVec4 GetRandomValue(int MaximumPossible);
void CosmeticsEditor_RandomizeAll();
void CosmeticsEditor_RandomizeGroup(CosmeticGroup group);
void CosmeticsEditor_ResetAll();
void CosmeticsEditor_ResetGroup(CosmeticGroup group);
void ApplyOrResetCustomGfxPatches(bool manualChange = true);
class CosmeticsEditorWindow : public LUS::GuiWindow {
class CosmeticsEditorWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

View File

@ -1,5 +1,6 @@
#include <libultraship/bridge.h>
#include <string>
#include "soh/OTRGlobals.h"
extern "C" {
#include <libultraship/libultra.h>
@ -81,7 +82,7 @@ void PatchDekuStickTextureOverflow() {
const char* dlist = gLinkChildLinkDekuStickDL;
int start = 5;
if (!CVarGetInteger("gFixTexturesOOB", 0)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
// Unpatch the other texture fix
for (size_t i = 0; i < 7; i++) {
int instruction = start + (i == 0 ? 0 : i + 1);
@ -121,7 +122,7 @@ void PatchFreezardTextureOverflow() {
char patchNameBuf[24];
// Patch using custom overflowed texture
if (!CVarGetInteger("gFixTexturesOOB", 0)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
// Unpatch the other texture fix
for (size_t i = 0; i < 7; i++) {
int instruction = start + (i == 0 ? 0 : i + 1);
@ -163,7 +164,7 @@ void PatchIronKnuckleTextureOverflow() {
// Until this is solved, Iron Knuckle will be hardcoded to always display with the "authentic" texture fix
// Patch using custom overflowed texture
// if (!CVarGetInteger("gFixTexturesOOB", 0)) {
// if (!CVarGetInteger(CVAR_ENHANCEMENT("FixTexturesOOB"), 0)) {
// Unpatch the other texture fix
for (size_t i = 0; i < 7; i++) {
int instruction = start + (i == 0 ? 0 : i + 1);
@ -222,7 +223,7 @@ void PatchMirroredSoldOutGI() {
G_TX_NOMIRROR | G_TX_CLAMP, 5, 5, G_TX_NOLOD, G_TX_NOLOD),
};
if (CVarGetInteger("gMirroredWorld", 0)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
if (mirroredSoldOutVtx == nullptr) {
// Copy the original vertices that we want to modify (4 at the beginning of the resource)
mirroredSoldOutVtx = (Vtx*)malloc(sizeof(Vtx) * 4);
@ -269,7 +270,7 @@ void PatchMirroredSunSongEtching() {
G_TX_NOMIRROR | G_TX_CLAMP, 7, 5, G_TX_NOLOD, G_TX_NOLOD)
};
if (CVarGetInteger("gMirroredWorld", 0)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0)) {
if (mirroredSunSongVtx == nullptr) {
// Copy the original vertices that we want to modify (4 at the beginning of the resource)
mirroredSunSongVtx = (Vtx*)malloc(sizeof(Vtx) * 4);

View File

@ -179,7 +179,7 @@ CrowdControl::EffectResult CrowdControl::TranslateGiEnum(GameInteractionEffectQu
CrowdControl::Effect* CrowdControl::ParseMessage(nlohmann::json dataReceived) {
if (!dataReceived.contains("id") || !dataReceived.contains("type")) {
SPDLOG_ERROR("[CrowdControl] Invalid payload received:\n{}", dataReceived);
SPDLOG_ERROR("[CrowdControl] Invalid payload received:\n{}", dataReceived.dump());
return nullptr;
}

View File

@ -3,7 +3,9 @@
#include <algorithm>
#include <stdint.h>
#include <cstring>
#include <string>
#include <map>
#include <spdlog/spdlog.h>
#include <variables.h>
using namespace std::literals::string_literals;
@ -14,9 +16,10 @@ static const std::unordered_map<std::string, char> textBoxSpecialCharacters = {
{ "è", 0x95 }, { "é", 0x96 }, { "ê", 0x97 }, { "ë", 0x98 }, { "ï", 0x99 }, { "ô", 0x9A }, { "ö", 0x9B },
{ "ù", 0x9C }, { "û", 0x9D }, { "ü", 0x9E }
};
static const std::unordered_map<std::string, char> colors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN },
static const std::unordered_map<std::string, std::string> percentColors = { { "w", QM_WHITE }, { "r", QM_RED }, { "g", QM_GREEN },
{ "b", QM_BLUE }, { "c", QM_LBLUE }, { "p", QM_PINK },
{ "y", QM_YELLOW }, { "B", QM_BLACK } };
static const std::unordered_map<std::string, ItemID> altarIcons = {
{ "0", ITEM_KOKIRI_EMERALD },
{ "1", ITEM_GORON_RUBY },
@ -33,61 +36,190 @@ static const std::unordered_map<std::string, ItemID> altarIcons = {
{ "c", ITEM_OCARINA_FAIRY },
{ "i", ITEM_OCARINA_TIME },
{ "L", ITEM_BOW_ARROW_LIGHT },
{ "k", ITEM_TUNIC_KOKIRI }
{ "k", ITEM_TUNIC_KOKIRI },
{ "m", ITEM_DUNGEON_MAP },
{ "C", ITEM_COMPASS },
{ "s", ITEM_SKULL_TOKEN },
{ "g", ITEM_MASK_GORON }
};
static std::map<std::string, int> pixelWidthTable = {
{ " ", 6 }, { "!", 6 }, { "\"", 5 }, { "#", 7 }, { "$", 7 }, { "%", 11 }, { "&", 9 }, { "\'", 3 },
{ "(", 6 }, { ")", 6 }, { "*", 6 }, { "+", 7 }, { ",", 3 }, { "-", 5 }, { ".", 3 }, { "/", 7 },
{ "0", 8 }, { "1", 4 }, { "2", 7 }, { "3", 7 }, { "4", 8 }, { "5", 7 }, { "6", 7 }, { "7", 7 },
{ "8", 7 }, { "9", 7 }, { ":", 5 }, { ";", 5 }, { "<", 7 }, { "=", 9 }, { ">", 7 }, { "?", 9 },
{ "@", 10 }, { "A", 9 }, { "B", 7 }, { "C", 9 }, { "D", 9 }, { "E", 6 }, { "F", 6 }, { "G", 9 },
{ "H", 8 }, { "I", 3 }, { "J", 6 }, { "K", 8 }, { "L", 6 }, { "M", 10 }, { "N", 9 }, { "O", 10 },
{ "P", 7 }, { "Q", 10 }, { "R", 8 }, { "S", 8 }, { "T", 7 }, { "U", 8 }, { "V", 9 }, { "W", 12 },
{ "X", 9 }, { "Y", 8 }, { "Z", 8 }, { "[", 6 }, { "\\", 8 }, { "]", 6 }, { "^", 8 }, { "_", 7 },
{ "`", 4 }, { "a", 6 }, { "b", 7 }, { "c", 6 }, { "d", 7 }, { "e", 7 }, { "f", 5 }, { "g", 7 },
{ "h", 6 }, { "i", 3 }, { "j", 5 }, { "k", 6 }, { "l", 3 }, { "m", 9 }, { "n", 7 }, { "o", 7 },
{ "p", 7 }, { "q", 7 }, { "r", 6 }, { "s", 6 }, { "t", 6 }, { "u", 6 }, { "v", 7 }, { "w", 9 },
{ "x", 6 }, { "y", 7 }, { "z", 6 }, { "{", 6 }, { "¦", 4 }, { "}", 6 }, { "¡", 5 }, { "¢", 7 },
{ "£", 8 }, { "¤", 7 }, { "¥", 8 }, { "|", 4 }, { "§", 12 }, { "¨", 12 }, { "©", 10 }, { "ª", 5 },
{ "«", 8 }, { "¬", 7 }, { "\u00AD", 6 }, { "®", 10 }, { "¯", 8 }, { "°", 12 }, { "±", 12 }, { "²", 5 },
{ "³", 5 }, { "µ", 6 }, { "", 8 }, { "·", 4 }, { "¹", 4 }, { "º", 5 }, { "»", 9 }, { "¼", 9 },
{ "½", 9 }, { "¾", 10 }, { "¿", 7 }, { "À", 11 }, { "Á", 9 }, { "Â", 9 }, { "Ã", 9 }, { "Ä", 9 },
{ "Å", 9 }, { "Æ", 12 }, { "Ç", 9 }, { "È", 6 }, { "É", 6 }, { "Ê", 6 }, { "Ë", 6 }, { "Ì", 5 },
{ "Í", 5 }, { "Î", 5 }, { "Ï", 5 }, { "Ð", 10 }, { "Ñ", 9 }, { "Ò", 10 }, { "Ó", 10 }, { "Ô", 10 },
{ "Õ", 10 }, { "Ö", 10 }, { "×", 9 }, { "Ø", 10 }, { "Ù", 8 }, { "Ú", 8 }, { "Û", 8 }, { "Ü", 8 },
{ "Ý", 10 }, { "Þ", 8 }, { "ß", 7 }, { "à", 6 }, { "á", 6 }, { "â", 6 }, { "ã", 6 }, { "ä", 6 },
{ "å", 6 }, { "æ", 11 }, { "ç", 6 }, { "è", 7 }, { "é", 7 }, { "ê", 7 }, { "ë", 7 }, { "ì", 5 },
{ "í", 5 }, { "î", 5 }, { "ï", 5 }, { "ð", 7 }, { "ñ", 7 }, { "ò", 7 }, { "ó", 7 }, { "ô", 7 },
{ "õ", 7 }, { "ö", 7 }, { "÷", 11 }, { "ø", 9 }, { "ù", 7 }, { "ú", 7 }, { "û", 7 }, { "ü", 7 },
{ "ý", 8 }, { "þ", 8 }, { "ÿ", 8 }, { "Œ", 11 }, { "œ", 11 }, { "", 5 }, { "", 5 }, { "", 10 },
{ "Ÿ", 10 }, { "~", 8 }
};
CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, TextBoxType type_,
TextBoxPosition position_)
: english(std::move(english_)), german(std::move(german_)), french(std::move(french_)), type(type_),
position(position_) {
: type(type_), position(position_){
messages[LANGUAGE_ENG] = std::move(english_);
messages[LANGUAGE_GER] = std::move(german_);
messages[LANGUAGE_FRA] = std::move(french_);
}
CustomMessage::CustomMessage(std::string english_, std::string german_, std::string french_, std::vector<std::string> colors_,
std::vector<bool> capital_, TextBoxType type_, TextBoxPosition position_) {
messages[LANGUAGE_ENG] = std::move(english_);
messages[LANGUAGE_GER] = std::move(german_);
messages[LANGUAGE_FRA] = std::move(french_);
colors = colors_;
capital = capital_;
type = type_;
position = position_;
}
CustomMessage::CustomMessage(std::string english_, TextBoxType type_, TextBoxPosition position_)
: type(type_), position(position_) {
messages[LANGUAGE_ENG] = std::move(english_);
}
CustomMessage::CustomMessage(std::string english_, std::vector<std::string> colors_, std::vector<bool> capital_, TextBoxType type_, TextBoxPosition position_){
messages[LANGUAGE_ENG] = std::move(english_);
colors = colors_;
capital = capital_;
type = type_;
position = position_;
}
CustomMessage::CustomMessage(Text text, TextBoxType type_,TextBoxPosition position_)
: english(text.GetEnglish()), german(text.GetGerman()), french(text.GetFrench()), type(type_),
position(position_) {
: type(type_), position(position_) {
messages[LANGUAGE_ENG] = text.GetEnglish();
messages[LANGUAGE_GER] = text.GetGerman();
messages[LANGUAGE_FRA] = text.GetFrench();
}
const std::string& CustomMessage::GetEnglish() const {
return english;
const std::string CustomMessage::GetEnglish(MessageFormat format) const {
return GetForLanguage(LANGUAGE_ENG, format);
}
const std::string& CustomMessage::GetFrench() const {
if (french.length() > 0) {
return french;
}
return english;
const std::string CustomMessage::GetGerman(MessageFormat format) const {
return GetForLanguage(LANGUAGE_GER, format);
}
const std::string& CustomMessage::GetGerman() const {
if (german.length() > 0) {
return german;
const std::string CustomMessage::GetFrench(MessageFormat format) const {
return GetForLanguage(LANGUAGE_FRA, format);
}
const std::string CustomMessage::GetForCurrentLanguage(MessageFormat format) const {
return GetForLanguage(gSaveContext.language, format);
}
const std::string CustomMessage::GetForLanguage(uint8_t language, MessageFormat format) const {
std::string output = messages[language].length() > 0 ? messages[language] : messages[LANGUAGE_ENG];
ProcessMessageFormat(output, format);
return output;
}
const std::vector<std::string> CustomMessage::GetAllMessages(MessageFormat format) const{
std::vector<std::string> output = messages;
for (auto str : output){
ProcessMessageFormat(str, format);
}
return english;
return output;
}
void CustomMessage::ProcessMessageFormat(std::string& str, MessageFormat format) const {
if (format == MF_FORMATTED){
FormatString(str);
} else if (format == MF_CLEAN){
CleanString(str);
} else if (format == MF_AUTO_FORMAT){
AutoFormatString(str);
}
}
const std::vector<bool>& CustomMessage::GetCapital() const {
return capital;
}
void CustomMessage::SetCapital(std::vector<bool> capital_){
capital = capital_;
}
const std::vector<std::string>& CustomMessage::GetColors() const {
return colors;
}
void CustomMessage::SetColors(std::vector<std::string> colors_){
colors = colors_;
}
const TextBoxType& CustomMessage::GetTextBoxType() const {
return type;
}
void CustomMessage::SetTextBoxType(TextBoxType boxType){
type = boxType;
}
const TextBoxPosition& CustomMessage::GetTextBoxPosition() const {
return position;
}
CustomMessage CustomMessage::operator+(const CustomMessage& right) const {
return CustomMessage(english + right.GetEnglish(), german + right.GetGerman(), french + right.GetFrench());
std::vector<std::string> newColors = colors;
std::vector<std::string> rColors = right.GetColors();
for (auto color: rColors){
newColors.push_back(color);
}
std::vector<bool> newCapital = capital;
newCapital.insert(capital.end(), right.GetCapital().begin(), right.GetCapital().end());
return CustomMessage(messages[LANGUAGE_ENG] + right.GetEnglish(MF_RAW),
messages[LANGUAGE_GER] + right.GetGerman(MF_RAW),
messages[LANGUAGE_FRA] + right.GetFrench(MF_RAW),
newColors, newCapital, type, position);
}
CustomMessage CustomMessage::operator+(const std::string& right) const {
return CustomMessage(english + right, german + right, french + right);
return CustomMessage(messages[LANGUAGE_ENG] + right, messages[LANGUAGE_GER] + right, messages[LANGUAGE_FRA] + right);
}
void CustomMessage::operator+=(const CustomMessage& right) {
messages[LANGUAGE_ENG] += right.GetEnglish(MF_RAW);
messages[LANGUAGE_GER] += right.GetGerman(MF_RAW);
messages[LANGUAGE_FRA] += right.GetFrench(MF_RAW);
colors.insert(colors.end(), right.GetColors().begin(), right.GetColors().end());
capital.insert(capital.end(), right.GetCapital().begin(), right.GetCapital().end());
}
void CustomMessage::operator+=(const std::string& right) {
english += right;
french += right;
german += right;
messages[LANGUAGE_ENG] += right;
messages[LANGUAGE_GER] += right;
messages[LANGUAGE_FRA] += right;
}
bool CustomMessage::operator==(const CustomMessage& operand) const {
return english == operand.english;
return messages[LANGUAGE_ENG] == operand.messages[LANGUAGE_ENG];
}
bool CustomMessage::operator==(const std::string& operand) const {
for (auto str: messages){
if (str == operand){
return true;
}
}
return false;
}
bool CustomMessage::operator!=(const CustomMessage& operand) const {
@ -95,83 +227,209 @@ bool CustomMessage::operator!=(const CustomMessage& operand) const {
}
void CustomMessage::Replace(std::string&& oldStr, std::string&& newStr) {
for (std::string* str : { &english, &french, &german }) {
size_t position = str->find(oldStr);
for (std::string& str : messages) {
size_t position = str.find(oldStr);
while (position != std::string::npos) {
str->replace(position, oldStr.length(), newStr);
position = str->find(oldStr);
str.replace(position, oldStr.length(), newStr);
position = str.find(oldStr);
}
}
Format();
}
void CustomMessage::Replace(std::string&& oldStr, std::string&& newEnglish, std::string&& newGerman,
std::string&& newFrench) {
size_t position = 0;
position = english.find(oldStr);
while (position != std::string::npos) {
english.replace(position, oldStr.length(), newEnglish);
position = english.find(oldStr);
void CustomMessage::Replace(std::string&& oldStr, CustomMessage newMessage) {
for (uint8_t language = 0; language < LANGUAGE_MAX; language++) {
size_t position = messages[language].find(oldStr);
while (position != std::string::npos) {
messages[language].replace(position, oldStr.length(), newMessage.messages[language]);
position = messages[language].find(oldStr);
}
}
position = french.find(oldStr);
while (position != std::string::npos) {
french.replace(position, oldStr.length(), newFrench);
position = french.find(oldStr);
}
position = german.find(oldStr);
while (position != std::string::npos) {
german.replace(position, oldStr.length(), newGerman);
position = german.find(oldStr);
}
Format();
}
void CustomMessage::Format(ItemID iid) {
for (std::string* str : { &english, &french, &german }) {
str->insert(0, ITEM_OBTAINED(iid));
for (std::string &str : messages) {
str.insert(0, ITEM_OBTAINED(iid));
size_t start_pos = 0;
std::replace(str->begin(), str->end(), '&', NEWLINE()[0]);
while ((start_pos = str->find('^', start_pos)) != std::string::npos) {
str->replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid));
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
while ((start_pos = str.find('^', start_pos)) != std::string::npos) {
str.replace(start_pos, 1, WAIT_FOR_INPUT() + ITEM_OBTAINED(iid));
start_pos += 3;
}
std::replace(str->begin(), str->end(), '@', PLAYER_NAME()[0]);
std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]);
ReplaceSpecialCharacters(str);
ReplaceColors(str);
ReplaceAltarIcons(str);
}
ReplaceSpecialCharacters();
ReplaceColors();
ReplaceAltarIcons();
*this += MESSAGE_END();
}
void CustomMessage::Format() {
for (std::string* str : { &english, &french, &german }) {
std::replace(str->begin(), str->end(), '&', NEWLINE()[0]);
std::replace(str->begin(), str->end(), '^', WAIT_FOR_INPUT()[0]);
std::replace(str->begin(), str->end(), '@', PLAYER_NAME()[0]);
for (std::string& str : messages) {
FormatString(str);
}
ReplaceSpecialCharacters();
ReplaceColors();
ReplaceAltarIcons();
*this += MESSAGE_END();
}
void CustomMessage::AutoFormat() {
for (std::string& str : messages) {
AutoFormatString(str);
}
}
void CustomMessage::Clean() {
for (std::string& str : messages) {
CleanString(str);
}
}
void CustomMessage::FormatString(std::string& str) const {
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]);
std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]);
ReplaceSpecialCharacters(str);
ReplaceColors(str);
ReplaceAltarIcons(str);
str += MESSAGE_END();
}
void DeleteControlCode(std::string& str, std::string code){
size_t start_pos = 0;
while ((start_pos = str.find(code, start_pos)) != std::string::npos) {
str.replace(start_pos, code.length(), "");
start_pos += code.length();
}
}
void CustomMessage::CleanString(std::string& str) const {
std::replace(str.begin(), str.end(), '&', "\n"[0]);
std::replace(str.begin(), str.end(), '^', " "[0]);
for (const auto& colorPair : percentColors) {
DeleteControlCode(str, "%" + colorPair.first);
}
std::erase(str, '#');
for (const auto& iconPair : altarIcons) {
DeleteControlCode(str, "$" + iconPair.first);
}
}
static size_t NextLineLength(const std::string* textStr, const size_t lastNewline, bool hasIcon = false) {
const size_t maxLinePixelWidth = hasIcon ? 200 : 216;
size_t totalPixelWidth = 0;
size_t currentPos = lastNewline;
// Looping through the string from the lastNewline until the total
// width of counted characters exceeds the maximum pixels in a line.
size_t nextPosJump = 0;
while (totalPixelWidth < maxLinePixelWidth && currentPos < textStr->length()) {
// Skip over control codes
if (textStr->at(currentPos) == '%') {
nextPosJump = 2;
} else if (textStr->at(currentPos) == '$') {
nextPosJump = 2;
} else if (textStr->at(currentPos) == '@') {
nextPosJump = 1;
// Assume worst case for player name 12 * 8 (widest character * longest name length)
totalPixelWidth += 96;
} else {
// Some characters only one byte while others are two bytes
// So check both possibilities when checking for a character
if (pixelWidthTable.count(textStr->substr(currentPos, 1))) {
totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 1)];
nextPosJump = 1;
} else if (pixelWidthTable.count(textStr->substr(currentPos, 2))) {
totalPixelWidth += pixelWidthTable[textStr->substr(currentPos, 2)];
nextPosJump = 2;
} else {
SPDLOG_DEBUG("Table does not contain " + textStr->substr(currentPos, 1) + "/" + textStr->substr(currentPos, 2));
SPDLOG_DEBUG("Full string: " + *textStr);
nextPosJump = 1;
}
}
currentPos += nextPosJump;
}
// return the total number of characters we looped through
if (totalPixelWidth > maxLinePixelWidth && textStr->at(currentPos - nextPosJump) != ' ') {
return currentPos - lastNewline - nextPosJump;
} else {
return currentPos - lastNewline;
}
}
void CustomMessage::AutoFormatString(std::string& str) const {// did I do this right?
ReplaceAltarIcons(str);
ReplaceColors(str);
// insert newlines either manually or when encountering a '&'
size_t lastNewline = 0;
const bool hasIcon = str.find('$', 0) != std::string::npos;
size_t lineLength = NextLineLength(&str, lastNewline, hasIcon);
while (lastNewline + lineLength < str.length()) {
const size_t carrot = str.find('^', lastNewline);
const size_t ampersand = str.find('&', lastNewline);
const size_t lastSpace = str.rfind(' ', lastNewline + lineLength);
const size_t lastPeriod = str.rfind('.', lastNewline + lineLength);
// replace '&' first if it's within the newline range
if (ampersand < lastNewline + lineLength) {
lastNewline = ampersand + 1;
// or move the lastNewline cursor to the next line if a '^' is encountered
} else if (carrot < lastNewline + lineLength) {
lastNewline = carrot + 1;
// some lines need to be split but don't have spaces, look for periods instead
} else if (lastSpace == std::string::npos) {
str.replace(lastPeriod, 1, ".&");
lastNewline = lastPeriod + 2;
} else {
str.replace(lastSpace, 1, "&");
lastNewline = lastSpace + 1;
}
lineLength = NextLineLength(&str, lastNewline, hasIcon);
}
ReplaceSpecialCharacters(str);
ReplaceAltarIcons(str);
std::replace(str.begin(), str.end(), '&', NEWLINE()[0]);
std::replace(str.begin(), str.end(), '^', WAIT_FOR_INPUT()[0]);
std::replace(str.begin(), str.end(), '@', PLAYER_NAME()[0]);
str += MESSAGE_END();
}
void CustomMessage::InsertNumber(uint8_t num){
for (std::string& str : messages) {
size_t firstBar = str.find('|');
if (firstBar != std::string::npos) {
size_t secondBar = str.find('|', firstBar + 1);
if (secondBar != std::string::npos) {
size_t thirdBar = str.find('|', secondBar + 1);
if (thirdBar != std::string::npos) {
if (num == 1) {
str.erase(secondBar, thirdBar - secondBar);
} else {
str.erase(firstBar, secondBar - firstBar);
}
}
}
}
}
//remove the remaining bar
this->Replace("|", "");
Replace("[[d]]", std::to_string(num));
}
void CustomMessage::Capitalize() {
for (std::string* str : { &english, &french, &german }) {
(*str)[0] = std::toupper((*str)[0]);
for (std::string str : messages) {
(str)[0] = std::toupper((str)[0]);
}
}
void CustomMessage::ReplaceSpecialCharacters() {
void CustomMessage::ReplaceSpecialCharacters(std::string& str) const {
// add special characters
for (std::string* str : { &english, &french, &german }) {
for (auto specialCharacterPair : textBoxSpecialCharacters) {
size_t start_pos = 0;
std::string textBoxSpecialCharacterString = ""s;
textBoxSpecialCharacterString += specialCharacterPair.second;
while ((start_pos = str->find(specialCharacterPair.first, start_pos)) != std::string::npos) {
str->replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString);
start_pos += textBoxSpecialCharacterString.length();
}
for (auto specialCharacterPair : textBoxSpecialCharacters) {
size_t start_pos = 0;
std::string textBoxSpecialCharacterString = ""s;
textBoxSpecialCharacterString += specialCharacterPair.second;
while ((start_pos = str.find(specialCharacterPair.first, start_pos)) != std::string::npos) {
str.replace(start_pos, specialCharacterPair.first.length(), textBoxSpecialCharacterString);
start_pos += textBoxSpecialCharacterString.length();
}
}
}
@ -194,31 +452,49 @@ const char* Interface_ReplaceSpecialCharacters(char text[]) {
return textChar;
}
void CustomMessage::ReplaceColors() {
for (std::string* str : { &english, &french, &german }) {
for (const auto& colorPair : colors) {
std::string textToReplace = "%";
textToReplace += colorPair.first;
size_t start_pos = 0;
while ((start_pos = str->find(textToReplace, start_pos)) != std::string::npos) {
str->replace(start_pos, textToReplace.length(), COLOR(colorPair.second));
start_pos += textToReplace.length();
}
void CustomMessage::ReplaceColors(std::string& str) const {
for (const auto& colorPair : percentColors) {
std::string textToReplace = "%";
textToReplace += colorPair.first;
size_t start_pos = 0;
while ((start_pos = str.find(textToReplace, start_pos)) != std::string::npos) {
str.replace(start_pos, textToReplace.length(), COLOR(colorPair.second));
start_pos += textToReplace.length();
}
}
for (auto color: colors) {
if (const size_t firstHashtag = str.find('#'); firstHashtag != std::string::npos) {
str.replace(firstHashtag, 1, COLOR(color));
if (const size_t secondHashtag = str.find('#', firstHashtag + 1); secondHashtag != std::string::npos) {
str.replace(secondHashtag, 1, COLOR(QM_WHITE));
} else {
SPDLOG_DEBUG("non-matching hashtags in string: \"%s\"", str);
}
}
}
// Remove any remaining '#' characters.
std::erase(str, '#');
}
void CustomMessage::ReplaceAltarIcons(std::string& str) const {
for (const auto& iconPair : altarIcons) {
std::string textToReplace = "$";
textToReplace += iconPair.first;
size_t start_pos = 0;
while ((start_pos = str.find(textToReplace, start_pos)) != std::string::npos) {
str.replace(start_pos, textToReplace.length(), ITEM_OBTAINED(iconPair.second));
start_pos += textToReplace.length();
}
}
}
void CustomMessage::ReplaceAltarIcons() {
for (std::string* str : { &english, &french, &german }) {
for (const auto& iconPair : altarIcons) {
std::string textToReplace = "$";
textToReplace += iconPair.first;
size_t start_pos = 0;
while ((start_pos = str->find(textToReplace, start_pos)) != std::string::npos) {
str->replace(start_pos, textToReplace.length(), ITEM_OBTAINED(iconPair.second));
start_pos += textToReplace.length();
}
}
void CustomMessage::InsertNames(std::vector<CustomMessage> toInsert){
for(uint8_t a = 0; a < toInsert.size(); a++){
CustomMessage temp = toInsert[a];
if ((capital.size() > a) && (capital[a] = true)){
temp.Capitalize();
}
Replace("[[" + std::to_string(a+1) + "]]", temp);
}
}
@ -234,8 +510,12 @@ std::string CustomMessage::NEWLINE() {
return "\x01"s;
}
std::string CustomMessage::COLOR(uint8_t x) {
return "\x05"s + char(x);
std::string CustomMessage::COLOR(std::string x) {
return "\x05"s + x;
}
std::string CustomMessage::POINTS(std::string x) {
return "\x1E"s + x;
}
std::string CustomMessage::WAIT_FOR_INPUT() {

View File

@ -1,8 +1,9 @@
#pragma once
#include <string>
#include <unordered_map>
#include <cstdint>
#include <exception>
#include <vector>
#include <string>
#include "../../../include/z64item.h"
#include "../../../include/message_data_textbox_types.h"
@ -10,14 +11,23 @@
#undef MESSAGE_END
#define QM_WHITE 0x00
#define QM_RED 0x41
#define QM_GREEN 0x42
#define QM_BLUE 0x43
#define QM_LBLUE 0x44
#define QM_PINK 0x45
#define QM_YELLOW 0x46
#define QM_BLACK 0x47
#define QM_WHITE "\x00"s
#define QM_RED "\x41"
#define QM_GREEN "\x42"
#define QM_BLUE "\x43"
#define QM_LBLUE "\x44"
#define QM_PINK "\x45"
#define QM_YELLOW "\x46"
#define QM_BLACK "\x47"
#define HS_HORSE_ARCHERY "\x00"s //HS_HBA is an enum already
typedef enum {
MF_FORMATTED,
MF_CLEAN,
MF_RAW,
MF_AUTO_FORMAT
} MessageFormat;
/**
* @brief Encapsulates logic surrounding languages, and formatting strings for OoT's textboxes and
@ -30,25 +40,41 @@ class CustomMessage {
CustomMessage() = default;
CustomMessage(std::string english_, std::string german_, std::string french_,
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(std::string english_, std::string german_, std::string french_, std::vector<std::string> colors_, std::vector<bool> capital_ = {},
TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(std::string english_, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(std::string english_, std::vector<std::string> colors_, std::vector<bool> capital_ = {}, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
CustomMessage(Text text, TextBoxType type_ = TEXTBOX_TYPE_BLACK, TextBoxPosition position_ = TEXTBOX_POS_BOTTOM);
static std::string MESSAGE_END() ;
static std::string ITEM_OBTAINED(uint8_t x) ;
static std::string NEWLINE() ;
static std::string COLOR(uint8_t x) ;
static std::string COLOR(std::string x) ;
static std::string POINTS(std::string x) ;//HIGH_SCORE is also a macro
static std::string WAIT_FOR_INPUT() ;
static std::string PLAYER_NAME() ;
const std::string& GetEnglish() const;
const std::string& GetFrench() const;
const std::string& GetGerman() const;
const std::string GetEnglish(MessageFormat format = MF_FORMATTED) const;
const std::string GetFrench(MessageFormat format = MF_FORMATTED) const;
const std::string GetGerman(MessageFormat format = MF_FORMATTED) const;
const std::string GetForCurrentLanguage(MessageFormat format = MF_FORMATTED) const;
const std::string GetForLanguage(uint8_t language, MessageFormat format = MF_FORMATTED) const;
const std::vector<std::string> GetAllMessages(MessageFormat format = MF_FORMATTED) const;
void ProcessMessageFormat(std::string& str, MessageFormat format) const;
const std::vector<std::string>& GetColors() const;
void SetColors(std::vector<std::string> colors_);
const std::vector<bool>& GetCapital() const;
void SetCapital(std::vector<bool> capital_);
const TextBoxType& GetTextBoxType() const;
void SetTextBoxType(TextBoxType boxType);
const TextBoxPosition& GetTextBoxPosition() const;
CustomMessage operator+(const CustomMessage& right) const;
CustomMessage operator+(const std::string& right) const;
void operator+=(const std::string& right);
bool operator==(const CustomMessage& right) const;
void operator+=(const CustomMessage& right);
bool operator==(const CustomMessage& operand) const;
bool operator==(const std::string& operand) const;
bool operator!=(const CustomMessage& right) const;
/**
@ -63,15 +89,13 @@ class CustomMessage {
/**
* @brief Finds an instance of oldStr in each language of the CustomMessage,
* and replaces it with the corresponding new string provided for each language.
* and replaces it with the corresponding string in the provided CustomMessage.
* Typically used for dynamic variable replacement (i.e. gameplay stats, skulltula count)
*
* @param oldStr the string to be replaced
* @param newEnglish the new string for the English message
* @param newGerman the new string for the German message
* @param newFrench the new string for the French message
* @param newMessage the message containing the new strings.
*/
void Replace(std::string&& oldStr, std::string&& newEnglish, std::string&& newGerman, std::string&& newFrench);
void Replace(std::string&& oldStr, CustomMessage newMessage);
/**
* @brief Capitalizes the first letter of the string for each language.
@ -82,17 +106,22 @@ class CustomMessage {
* @brief Replaces special characters (things like diacritics for non-english langugages)
* with the control codes used to display them in OoT's textboxes.
*/
void ReplaceSpecialCharacters();
void ReplaceSpecialCharacters(std::string& str) const;
/**
* @brief Replaces our color variable strings with the OoT control codes.
*/
void ReplaceColors();
void ReplaceColors(std::string& str) const;
/**
* @brief Replaces `$<char>` variable strings with OoT control codes.
*/
void ReplaceAltarIcons();
void ReplaceAltarIcons(std::string& str) const;
/**
* @brief Replaces [[1]] style variable strings with the provided vector of customMessages
*/
void InsertNames(std::vector<CustomMessage> toInsert);
/**
* @brief Replaces various symbols with the control codes necessary to
@ -103,6 +132,15 @@ class CustomMessage {
*/
void Format(ItemID iid);
/**
* @brief Replaces [[d]] in text with the supplied number, and if plural
* options exist (2 blocks of text surrounded by |) choose the former if it 1,
* and the latter otherwise, deleting the other and the |'s.
*
* @param num the number to insert.
*/
void InsertNumber(uint8_t num);
/**
* @brief Replaces various symbols with the control codes necessary to
* display them in OoT's textboxes. i.e. special characters, colors, newlines,
@ -110,12 +148,44 @@ class CustomMessage {
*/
void Format();
/**
* @brief formats the message specifically to fit in OoT's
* textboxes, and use it's formatting.
*/
void AutoFormat();
/**
* @brief Removes all OoT formatting from the message,
* making it a good form for writing into spoiler logs.
*/
void Clean();
/**
* @brief Replaces various symbols with the control codes necessary to
* display them in OoT's textboxes for a single string
* . i.e. special characters, colors, newlines, wait for input, etc.
*/
void FormatString(std::string& str) const;
/**
* @brief formats the string specifically to fit in OoT's
* textboxes, and use it's formatting.
* RANDOTODO whoever knows exactly what this does check my adaption
*/
void AutoFormatString(std::string& str) const;
/**
* @brief Removes symbols used for control codes from the string,
* leaving raw text
*/
void CleanString(std::string& str) const;
private:
std::string english = "";
std::string french = "";
std::string german = "";
std::vector<std::string> messages = {"","",""};
TextBoxType type = TEXTBOX_TYPE_BLACK;
TextBoxPosition position = TEXTBOX_POS_BOTTOM;
std::vector<std::string> colors = {};
std::vector<bool> capital = {};
};
typedef std::unordered_map<uint16_t, CustomMessage> CustomMessageTable;

View File

@ -100,6 +100,7 @@ typedef enum {
TEXT_MALON_LINK_HAS_TIME_BUT_NO_RECORD = 0x2090,
TEXT_MALON_LINK_HAS_RECORD = 0x2091,
TEXT_MALON_FIRST_BEAT_THIS_RECORD = 0x2092,
TEXT_BIGGORON_I_MAAAADE_THISSSS = 0x3002,
TEXT_MEDIGORON = 0x304C,
TEXT_FIRE_TEMPLE_GORON_OWE_YOU_BIG_TIME = 0x3052,
TEXT_BIGGORON_BETTER_AT_SMITHING = 0x3053,

View File

@ -13,15 +13,15 @@
#define Path _Path
#define PATH_HACK
#include <Utils/StringHelper.h>
#include <utils/StringHelper.h>
#include <Window.h>
#include <Context.h>
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include <ImGui/imgui.h>
#include <ImGui/imgui_internal.h>
#include <imgui.h>
#include <imgui_internal.h>
#undef PATH_HACK
#undef Path
@ -36,12 +36,12 @@ extern PlayState* gPlayState;
#include <libultraship/bridge.h>
#include <libultraship/libultraship.h>
#define CMD_REGISTER LUS::Context::GetInstance()->GetConsole()->AddCommand
#define CMD_REGISTER Ship::Context::GetInstance()->GetConsole()->AddCommand
// TODO: Commands should be using the output passed in.
#define ERROR_MESSAGE std::reinterpret_pointer_cast<LUS::ConsoleWindow>(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendErrorMessage
#define INFO_MESSAGE std::reinterpret_pointer_cast<LUS::ConsoleWindow>(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendInfoMessage
#define ERROR_MESSAGE std::reinterpret_pointer_cast<Ship::ConsoleWindow>(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendErrorMessage
#define INFO_MESSAGE std::reinterpret_pointer_cast<Ship::ConsoleWindow>(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->SendInfoMessage
static bool ActorSpawnHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool ActorSpawnHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if ((args.size() != 9) && (args.size() != 3) && (args.size() != 6)) {
ERROR_MESSAGE("Not enough arguments passed to actorspawn");
return 1;
@ -101,7 +101,7 @@ static bool ActorSpawnHandler(std::shared_ptr<LUS::Console> Console, const std::
return 0;
}
static bool KillPlayerHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>&, std::string* output) {
static bool KillPlayerHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&, std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::SetPlayerHealth();
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = 0;
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
@ -114,7 +114,7 @@ static bool KillPlayerHandler(std::shared_ptr<LUS::Console> Console, const std::
}
}
static bool SetPlayerHealthHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool SetPlayerHealthHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -145,7 +145,7 @@ static bool SetPlayerHealthHandler(std::shared_ptr<LUS::Console> Console, const
}
}
static bool LoadSceneHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>&, std::string* output) {
static bool LoadSceneHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>&, std::string* output) {
gSaveContext.respawnFlag = 0;
gSaveContext.seqId = 0xFF;
gSaveContext.gameMode = 0;
@ -153,7 +153,7 @@ static bool LoadSceneHandler(std::shared_ptr<LUS::Console> Console, const std::v
return 0;
}
static bool RupeeHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool RupeeHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
return 1;
}
@ -178,7 +178,7 @@ static bool RupeeHandler(std::shared_ptr<LUS::Console> Console, const std::vecto
return 0;
}
static bool SetPosHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string> args, std::string* output) {
static bool SetPosHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string> args, std::string* output) {
if (gPlayState == nullptr) {
ERROR_MESSAGE("PlayState == nullptr");
return 1;
@ -205,7 +205,7 @@ static bool SetPosHandler(std::shared_ptr<LUS::Console> Console, const std::vect
return 0;
}
static bool ResetHandler(std::shared_ptr<LUS::Console> Console, std::vector<std::string> args, std::string* output) {
static bool ResetHandler(std::shared_ptr<Ship::Console> Console, std::vector<std::string> args, std::string* output) {
if (gPlayState == nullptr) {
ERROR_MESSAGE("PlayState == nullptr");
return 1;
@ -225,7 +225,7 @@ const static std::map<std::string, uint16_t> ammoItems{
{ "beans", ITEM_BEAN }
};
static bool AddAmmoHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool AddAmmoHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 3) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -264,7 +264,7 @@ static bool AddAmmoHandler(std::shared_ptr<LUS::Console> Console, const std::vec
}
}
static bool TakeAmmoHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool TakeAmmoHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 3) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -311,7 +311,7 @@ const static std::map<std::string, uint16_t> bottleItems{
{ "big_poe", ITEM_BIG_POE }, { "blue_fire", ITEM_BLUE_FIRE }, { "rutos_letter", ITEM_LETTER_RUTO },
};
static bool BottleHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool BottleHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 3) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -343,7 +343,7 @@ static bool BottleHandler(std::shared_ptr<LUS::Console> Console, const std::vect
return 0;
}
static bool BHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool BHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -353,7 +353,7 @@ static bool BHandler(std::shared_ptr<LUS::Console> Console, const std::vector<st
return 0;
}
static bool ItemHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool ItemHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 3) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -364,7 +364,7 @@ static bool ItemHandler(std::shared_ptr<LUS::Console> Console, const std::vector
return 0;
}
static bool GiveItemHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string> args, std::string* output) {
static bool GiveItemHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string> args, std::string* output) {
if (args.size() < 3) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -385,7 +385,7 @@ static bool GiveItemHandler(std::shared_ptr<LUS::Console> Console, const std::ve
return 0;
}
static bool EntranceHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool EntranceHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -406,7 +406,7 @@ static bool EntranceHandler(std::shared_ptr<LUS::Console> Console, const std::ve
gSaveContext.nextTransitionType = TRANS_TYPE_INSTANT;
}
static bool VoidHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool VoidHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (gPlayState != nullptr) {
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempSwchFlags = gPlayState->actorCtx.flags.tempSwch;
gSaveContext.respawn[RESPAWN_MODE_DOWN].tempCollectFlags = gPlayState->actorCtx.flags.tempCollect;
@ -422,7 +422,7 @@ static bool VoidHandler(std::shared_ptr<LUS::Console> Console, const std::vector
return 0;
}
static bool ReloadHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool ReloadHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (gPlayState != nullptr) {
gPlayState->nextEntranceIndex = gSaveContext.entranceIndex;
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
@ -439,7 +439,7 @@ const static std::map<std::string, uint16_t> fw_options {
{ "clear", 0}, {"warp", 1}, {"backup", 2}
};
static bool FWHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool FWHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -471,7 +471,7 @@ static bool FWHandler(std::shared_ptr<LUS::Console> Console, const std::vector<s
return 0;
break;
case 2: //backup
if (CVarGetInteger("gBetterFW", 0)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterFarore"), 0)) {
gSaveContext.fw = gSaveContext.backupFW;
gSaveContext.fw.set = 1;
INFO_MESSAGE("[SOH] Backup FW data copied! Reload scene to take effect.");
@ -491,7 +491,7 @@ static bool FWHandler(std::shared_ptr<LUS::Console> Console, const std::vector<s
return 0;
}
static bool FileSelectHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool FileSelectHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (gPlayState != nullptr) {
SET_NEXT_GAMESTATE(&gPlayState->state, FileChoose_Init, FileChooseContext);
gPlayState->state.running = 0;
@ -502,12 +502,12 @@ static bool FileSelectHandler(std::shared_ptr<LUS::Console> Console, const std::
return 0;
}
static bool QuitHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
LUS::Context::GetInstance()->GetWindow()->Close();
static bool QuitHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
Ship::Context::GetInstance()->GetWindow()->Close();
return 0;
}
static bool SaveStateHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool SaveStateHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot();
const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::SAVE });
@ -521,7 +521,7 @@ static bool SaveStateHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
}
static bool LoadStateHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool LoadStateHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
unsigned int slot = OTRGlobals::Instance->gSaveStateMgr->GetCurrentSlot();
const SaveStateReturn rtn = OTRGlobals::Instance->gSaveStateMgr->AddRequest({ slot, RequestType::LOAD });
@ -542,7 +542,7 @@ static bool LoadStateHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
static bool StateSlotSelectHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool StateSlotSelectHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -567,7 +567,7 @@ static bool StateSlotSelectHandler(std::shared_ptr<LUS::Console> Console, const
return 0;
}
static bool InvisibleHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool InvisibleHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -594,7 +594,7 @@ static bool InvisibleHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
}
static bool GiantLinkHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool GiantLinkHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -622,7 +622,7 @@ static bool GiantLinkHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
}
static bool MinishLinkHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool MinishLinkHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -650,7 +650,7 @@ static bool MinishLinkHandler(std::shared_ptr<LUS::Console> Console, const std::
}
}
static bool AddHeartContainerHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool AddHeartContainerHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -681,7 +681,7 @@ static bool AddHeartContainerHandler(std::shared_ptr<LUS::Console> Console, cons
}
}
static bool RemoveHeartContainerHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool RemoveHeartContainerHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -712,7 +712,7 @@ static bool RemoveHeartContainerHandler(std::shared_ptr<LUS::Console> Console, c
}
}
static bool GravityHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool GravityHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -721,7 +721,7 @@ static bool GravityHandler(std::shared_ptr<LUS::Console> Console, const std::vec
GameInteractionEffectBase* effect = new GameInteractionEffect::ModifyGravity();
try {
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = LUS::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY);
dynamic_cast<ParameterizedGameInteractionEffect*>(effect)->parameters[0] = Ship::Math::clamp(std::stoi(args[1], nullptr, 10), GI_GRAVITY_LEVEL_LIGHT, GI_GRAVITY_LEVEL_HEAVY);
} catch (std::invalid_argument const& ex) {
ERROR_MESSAGE("[SOH] Gravity value must be a number.");
return 1;
@ -737,7 +737,7 @@ static bool GravityHandler(std::shared_ptr<LUS::Console> Console, const std::vec
}
}
static bool NoUIHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool NoUIHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -765,7 +765,7 @@ static bool NoUIHandler(std::shared_ptr<LUS::Console> Console, const std::vector
}
}
static bool FreezeHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool FreezeHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::FreezePlayer();
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
@ -778,7 +778,7 @@ static bool FreezeHandler(std::shared_ptr<LUS::Console> Console, const std::vect
}
}
static bool DefenseModifierHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool DefenseModifierHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -802,7 +802,7 @@ static bool DefenseModifierHandler(std::shared_ptr<LUS::Console> Console, const
}
}
static bool DamageHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool DamageHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -832,7 +832,7 @@ static bool DamageHandler(std::shared_ptr<LUS::Console> Console, const std::vect
}
}
static bool HealHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool HealHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -862,7 +862,7 @@ static bool HealHandler(std::shared_ptr<LUS::Console> Console, const std::vector
}
}
static bool FillMagicHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool FillMagicHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::FillMagic();
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
@ -875,7 +875,7 @@ static bool FillMagicHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
}
static bool EmptyMagicHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool EmptyMagicHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::EmptyMagic();
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
@ -888,7 +888,7 @@ static bool EmptyMagicHandler(std::shared_ptr<LUS::Console> Console, const std::
}
}
static bool NoZHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool NoZHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -916,7 +916,7 @@ static bool NoZHandler(std::shared_ptr<LUS::Console> Console, const std::vector<
}
}
static bool OneHitKOHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool OneHitKOHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -944,7 +944,7 @@ static bool OneHitKOHandler(std::shared_ptr<LUS::Console> Console, const std::ve
}
}
static bool PacifistHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool PacifistHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -972,7 +972,7 @@ static bool PacifistHandler(std::shared_ptr<LUS::Console> Console, const std::ve
}
}
static bool PaperLinkHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool PaperLinkHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1001,7 +1001,7 @@ static bool PaperLinkHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
}
static bool RainstormHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool RainstormHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1029,7 +1029,7 @@ static bool RainstormHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
}
static bool ReverseControlsHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool ReverseControlsHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1058,7 +1058,7 @@ static bool ReverseControlsHandler(std::shared_ptr<LUS::Console> Console, const
}
}
static bool UpdateRupeesHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool UpdateRupeesHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1082,7 +1082,7 @@ static bool UpdateRupeesHandler(std::shared_ptr<LUS::Console> Console, const std
}
}
static bool SpeedModifierHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool SpeedModifierHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1112,7 +1112,7 @@ const static std::map<std::string, uint16_t> boots {
{ "hover", EQUIP_VALUE_BOOTS_HOVER },
};
static bool BootsHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool BootsHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1143,7 +1143,7 @@ const static std::map<std::string, uint16_t> shields {
{ "mirror", ITEM_SHIELD_MIRROR },
};
static bool GiveShieldHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool GiveShieldHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1168,7 +1168,7 @@ static bool GiveShieldHandler(std::shared_ptr<LUS::Console> Console, const std::
}
}
static bool TakeShieldHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool TakeShieldHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1193,7 +1193,7 @@ static bool TakeShieldHandler(std::shared_ptr<LUS::Console> Console, const std::
}
}
static bool KnockbackHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool KnockbackHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
@ -1223,7 +1223,7 @@ static bool KnockbackHandler(std::shared_ptr<LUS::Console> Console, const std::v
}
}
static bool ElectrocuteHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool ElectrocuteHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::ElectrocutePlayer();
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
@ -1236,7 +1236,7 @@ static bool ElectrocuteHandler(std::shared_ptr<LUS::Console> Console, const std:
}
}
static bool BurnHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool BurnHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
GameInteractionEffectBase* effect = new GameInteractionEffect::BurnPlayer();
GameInteractionEffectQueryResult result = GameInteractor::ApplyEffect(effect);
@ -1249,7 +1249,7 @@ static bool BurnHandler(std::shared_ptr<LUS::Console> Console, const std::vector
}
}
static bool CuccoStormHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool CuccoStormHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
GameInteractionEffectQueryResult result = GameInteractor::RawAction::SpawnActor(ACTOR_EN_NIW, 0);
if (result == GameInteractionEffectQueryResult::Possible) {
@ -1261,7 +1261,7 @@ static bool CuccoStormHandler(std::shared_ptr<LUS::Console> Console, const std::
}
}
static bool GenerateRandoHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static bool GenerateRandoHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() == 1) {
if (GenerateRandomizer()) {
return 0;
@ -1289,16 +1289,58 @@ static bool GenerateRandoHandler(std::shared_ptr<LUS::Console> Console, const st
return 1;
}
static bool CosmeticsHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static constexpr std::array<std::pair<const char*, CosmeticGroup>, COSMETICS_GROUP_MAX> cosmetic_groups = {{
{"link", COSMETICS_GROUP_LINK},
{"mirror_shield", COSMETICS_GROUP_MIRRORSHIELD},
{"swords", COSMETICS_GROUP_SWORDS},
{"gloves", COSMETICS_GROUP_GLOVES},
{"equipment", COSMETICS_GROUP_EQUIPMENT},
{"consumable", COSMETICS_GROUP_CONSUMABLE},
{"hud", COSMETICS_GROUP_HUD},
{"kaleido", COSMETICS_GROUP_KALEIDO},
{"title", COSMETICS_GROUP_TITLE},
{"npc", COSMETICS_GROUP_NPC},
{"world", COSMETICS_GROUP_WORLD},
{"magic", COSMETICS_GROUP_MAGIC},
{"arrows", COSMETICS_GROUP_ARROWS},
{"spin_attack", COSMETICS_GROUP_SPIN_ATTACK},
{"trials", COSMETICS_GROUP_TRAILS},
{"navi", COSMETICS_GROUP_NAVI},
{"ivan", COSMETICS_GROUP_IVAN},
}};
static bool CosmeticsHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
if (args[1].compare("reset") == 0) {
CosmeticsEditor_ResetAll();
if (args.size() == 2) {
CosmeticsEditor_ResetAll();
} else {
for (const auto& [key, value] : cosmetic_groups) {
if (args[2].compare(key) == 0) {
CosmeticsEditor_ResetGroup(value);
return 0;
}
}
ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
return 1;
}
} else if (args[1].compare("randomize") == 0) {
CosmeticsEditor_RandomizeAll();
if (args.size() == 2) {
CosmeticsEditor_RandomizeAll();
} else {
for (const auto& [key, value] : cosmetic_groups) {
if (args[2].compare(key) == 0) {
CosmeticsEditor_RandomizeGroup(value);
return 0;
}
}
ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
return 1;
}
} else {
ERROR_MESSAGE("[SOH] Invalid argument passed, must be 'reset' or 'randomize'");
return 1;
@ -1307,16 +1349,50 @@ static bool CosmeticsHandler(std::shared_ptr<LUS::Console> Console, const std::v
return 0;
}
static bool SfxHandler(std::shared_ptr<LUS::Console> Console, const std::vector<std::string>& args, std::string* output) {
static std::map<std::string, SeqType> sfx_groups = {
{"bgm", SEQ_BGM_WORLD},
{"fanfares", SEQ_FANFARE},
{"events", SEQ_BGM_EVENT},
{"battle", SEQ_BGM_BATTLE},
{"ocarina", SEQ_OCARINA},
{"instruments", SEQ_INSTRUMENT},
{"sfx", SEQ_SFX},
{"voices", SEQ_VOICE},
{"custom", SEQ_BGM_CUSTOM},
};
static bool SfxHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
if (args.size() < 2) {
ERROR_MESSAGE("[SOH] Unexpected arguments passed");
return 1;
}
if (args[1].compare("reset") == 0) {
AudioEditor_ResetAll();
if (args.size() == 2) {
AudioEditor_ResetAll();
} else {
for (const auto& [key, value] : sfx_groups) {
if (args[2].compare(key) == 0) {
AudioEditor_ResetGroup(value);
return 0;
}
}
ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
return 1;
}
} else if (args[1].compare("randomize") == 0) {
AudioEditor_RandomizeAll();
if (args.size() == 2) {
AudioEditor_RandomizeAll();
} else {
for (const auto& [key, value] : sfx_groups) {
if (args[2].compare(key) == 0) {
AudioEditor_RandomizeGroup(value);
return 0;
}
}
ERROR_MESSAGE("[SOH] Invalid argument passed, unrecognized group name");
return 1;
}
} else {
ERROR_MESSAGE("[SOH] Invalid argument passed, must be 'reset' or 'randomize'");
return 1;
@ -1335,17 +1411,17 @@ void DebugConsole_Init(void) {
CMD_REGISTER("save_state", {SaveStateHandler, "Save a state."});
CMD_REGISTER("load_state", {LoadStateHandler, "Load a state."});
CMD_REGISTER("set_slot", {StateSlotSelectHandler, "Selects a SaveState slot", {
{"Slot number", LUS::ArgumentType::NUMBER,}
{"Slot number", Ship::ArgumentType::NUMBER,}
}});
// Map & Location
CMD_REGISTER("void", {VoidHandler, "Voids out of the current map."});
CMD_REGISTER("reload", {ReloadHandler, "Reloads the current map."});
CMD_REGISTER("fw", {FWHandler, "Spawns the player where Farore's Wind is set.", {
{"clear|warp|backup", LUS::ArgumentType::TEXT}
{"clear|warp|backup", Ship::ArgumentType::TEXT}
}});
CMD_REGISTER("entrance", {EntranceHandler, "Sends player to the entered entrance (hex)", {
{"entrance", LUS::ArgumentType::NUMBER}
{"entrance", Ship::ArgumentType::NUMBER}
}});
// Gameplay
@ -1354,64 +1430,64 @@ void DebugConsole_Init(void) {
CMD_REGISTER("map", {LoadSceneHandler, "Load up kak?"});
CMD_REGISTER("rupee", {RupeeHandler, "Set your rupee counter.", {
{"amount", LUS::ArgumentType::NUMBER}
{"amount", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("bItem", {BHandler, "Set an item to the B button.", {
{"Item ID", LUS::ArgumentType::NUMBER}
{"Item ID", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor name/id", LUS::ArgumentType::NUMBER }, // TODO there should be an actor_id arg type
{"data", LUS::ArgumentType::NUMBER},
{"x", LUS::ArgumentType::NUMBER, true},
{"y", LUS::ArgumentType::NUMBER, true},
{"z", LUS::ArgumentType::NUMBER, true},
{"rx", LUS::ArgumentType::NUMBER, true},
{"ry", LUS::ArgumentType::NUMBER, true},
{"rz", LUS::ArgumentType::NUMBER, true}
CMD_REGISTER("spawn", { ActorSpawnHandler, "Spawn an actor.", { { "actor name/id", Ship::ArgumentType::NUMBER }, // TODO there should be an actor_id arg type
{"data", Ship::ArgumentType::NUMBER},
{"x", Ship::ArgumentType::NUMBER, true},
{"y", Ship::ArgumentType::NUMBER, true},
{"z", Ship::ArgumentType::NUMBER, true},
{"rx", Ship::ArgumentType::NUMBER, true},
{"ry", Ship::ArgumentType::NUMBER, true},
{"rz", Ship::ArgumentType::NUMBER, true}
}});
CMD_REGISTER("pos", {SetPosHandler, "Sets the position of the player.", {
{"x", LUS::ArgumentType::NUMBER, true},
{"y", LUS::ArgumentType::NUMBER, true},
{"z", LUS::ArgumentType::NUMBER, true}
{"x", Ship::ArgumentType::NUMBER, true},
{"y", Ship::ArgumentType::NUMBER, true},
{"z", Ship::ArgumentType::NUMBER, true}
}});
CMD_REGISTER("addammo", {AddAmmoHandler, "Adds ammo of an item.", {
{"sticks|nuts|bombs|seeds|arrows|bombchus|beans", LUS::ArgumentType::TEXT},
{"count", LUS::ArgumentType::NUMBER}
{"sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT},
{"count", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("takeammo", {TakeAmmoHandler, "Removes ammo of an item.", {
{"sticks|nuts|bombs|seeds|arrows|bombchus|beans", LUS::ArgumentType::TEXT},
{"count", LUS::ArgumentType::NUMBER}
{"sticks|nuts|bombs|seeds|arrows|bombchus|beans", Ship::ArgumentType::TEXT},
{"count", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("bottle", {BottleHandler, "Changes item in a bottle slot.", {
{"item", LUS::ArgumentType::TEXT},
{"slot", LUS::ArgumentType::NUMBER}
{"item", Ship::ArgumentType::TEXT},
{"slot", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("give_item", {GiveItemHandler, "Gives an item to the player as if it was given from an actor", {
{"vanilla|randomizer", LUS::ArgumentType::TEXT},
{"giveItemID", LUS::ArgumentType::NUMBER}
{"vanilla|randomizer", Ship::ArgumentType::TEXT},
{"giveItemID", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("item", {ItemHandler, "Sets item ID in arg 1 into slot arg 2. No boundary checks. Use with caution.", {
{"slot", LUS::ArgumentType::NUMBER},
{"item id", LUS::ArgumentType::NUMBER}
{"slot", Ship::ArgumentType::NUMBER},
{"item id", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("invisible", {InvisibleHandler, "Activate Link's Elvish cloak, making him appear invisible.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("giant_link", {GiantLinkHandler, "Turn Link into a giant Lonky boi.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("minish_link", {MinishLinkHandler, "Turn Link into a minish boi.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("add_heart_container",
@ -1421,25 +1497,25 @@ void DebugConsole_Init(void) {
{RemoveHeartContainerHandler, "Remove a heart from Link. The minimal amount of hearts is 3."});
CMD_REGISTER("gravity", {GravityHandler, "Set gravity level.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("no_ui", {NoUIHandler, "Disables the UI.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("freeze", {FreezeHandler, "Freezes Link in place"});
CMD_REGISTER("defense_modifier", {DefenseModifierHandler, "Sets the defense modifier.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("damage", {DamageHandler, "Deal damage to Link.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("heal", {HealHandler, "Heals Link.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("fill_magic", {FillMagicHandler, "Fills magic."});
@ -1447,50 +1523,50 @@ void DebugConsole_Init(void) {
CMD_REGISTER("empty_magic", {EmptyMagicHandler, "Empties magic."});
CMD_REGISTER("no_z", {NoZHandler, "Disables Z-button presses.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("ohko", {OneHitKOHandler,
"Activates one hit KO. Any damage kills Link and he cannot gain health in this mode.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("pacifist", {PacifistHandler, "Activates pacifist mode. Prevents Link from using his weapon.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("paper_link", {PaperLinkHandler, "Link but made out of paper.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("rainstorm", {RainstormHandler, "Activates rainstorm."});
CMD_REGISTER("reverse_controls", {ReverseControlsHandler, "Reverses the controls.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("update_rupees", {UpdateRupeesHandler, "Adds rupees.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("speed_modifier", {SpeedModifierHandler, "Sets the speed modifier.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("boots", {BootsHandler, "Activates boots.", {
{"kokiri|iron|hover", LUS::ArgumentType::TEXT},
{"kokiri|iron|hover", Ship::ArgumentType::TEXT},
}});
CMD_REGISTER("giveshield", {GiveShieldHandler, "Gives a shield and equips it when Link is the right age for it.", {
{"deku|hylian|mirror", LUS::ArgumentType::TEXT},
{"deku|hylian|mirror", Ship::ArgumentType::TEXT},
}});
CMD_REGISTER("takeshield", {TakeShieldHandler, "Takes a shield and unequips it if Link is wearing it.", {
{"deku|hylian|mirror", LUS::ArgumentType::TEXT},
{"deku|hylian|mirror", Ship::ArgumentType::TEXT},
}});
CMD_REGISTER("knockback", {KnockbackHandler, "Knocks Link back.", {
{"value", LUS::ArgumentType::NUMBER}
{"value", Ship::ArgumentType::NUMBER}
}});
CMD_REGISTER("electrocute", {ElectrocuteHandler, "Electrocutes Link."});
@ -1500,16 +1576,18 @@ void DebugConsole_Init(void) {
CMD_REGISTER("cucco_storm", {CuccoStormHandler, "Cucco Storm"});
CMD_REGISTER("gen_rando", {GenerateRandoHandler, "Generate a randomizer seed", {
{"seed|count", LUS::ArgumentType::NUMBER, true},
{"testing", LUS::ArgumentType::NUMBER, true},
{"seed|count", Ship::ArgumentType::NUMBER, true},
{"testing", Ship::ArgumentType::NUMBER, true},
}});
CMD_REGISTER("cosmetics", {CosmeticsHandler, "Change cosmetics.", {
{"reset|randomize", LUS::ArgumentType::TEXT},
{"reset|randomize", Ship::ArgumentType::TEXT},
{"group name", Ship::ArgumentType::TEXT, true},
}});
CMD_REGISTER("sfx", {SfxHandler, "Change SFX.", {
{"reset|randomize", LUS::ArgumentType::TEXT},
{"reset|randomize", Ship::ArgumentType::TEXT},
{"group_name", Ship::ArgumentType::TEXT, true},
}});
CVarSave();

View File

@ -121,7 +121,7 @@ void FindMessage(PlayState* play, const uint16_t textId, const uint8_t language)
Font* font;
u16 bufferId = textId;
// Use the better owl message if better owl is enabled
if (CVarGetInteger("gBetterOwl", 0) != 0 && (bufferId == 0x2066 || bufferId == 0x607B ||
if (CVarGetInteger(CVAR_ENHANCEMENT("BetterOwl"), 0) != 0 && (bufferId == 0x2066 || bufferId == 0x607B ||
bufferId == 0x10C2 || bufferId == 0x10C6 || bufferId == 0x206A))
{
bufferId = 0x71B3;
@ -204,16 +204,7 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan
const CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(tableId, textId);
font->charTexBuf[0] = (messageEntry.GetTextBoxType() << 4) | messageEntry.GetTextBoxPosition();
switch (language) {
case LANGUAGE_FRA:
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetFrench(), maxBufferSize);
break;
case LANGUAGE_GER:
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetGerman(), maxBufferSize);
break;
case LANGUAGE_ENG:
default:
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetEnglish(), maxBufferSize);
break;
font->msgLength = SohUtils::CopyStringToCharBuffer(buffer, messageEntry.GetForLanguage(language), maxBufferSize);
}
msgCtx->msgLength = static_cast<int32_t>(font->msgLength);
}

View File

@ -26,7 +26,7 @@ void MessageDebug_DisplayCustomMessage(const char* customMessage);
}
class MessageViewer : public LUS::GuiWindow {
class MessageViewer : public Ship::GuiWindow {
public:
static inline const char* TABLE_ID = "MessageViewer";
using GuiWindow::GuiWindow;

View File

@ -12,6 +12,7 @@
#include <string>
#include <libultraship/bridge.h>
#include <libultraship/libultraship.h>
#include "soh/OTRGlobals.h"
extern "C" {
#include <z64.h>
@ -887,7 +888,7 @@ std::vector<u16> GetActorsWithDescriptionContainingString(std::string s) {
}
void ActorViewer_AddTagForActor(Actor* actor) {
int val = CVarGetInteger("gDebugActorViewerNameTags", ACTORVIEWER_NAMETAGS_NONE);
int val = CVarGetInteger(CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), ACTORVIEWER_NAMETAGS_NONE);
auto entry = ActorDB::Instance->RetrieveEntry(actor->id);
std::string tag;
@ -1129,10 +1130,10 @@ void ActorViewerWindow::DrawElement() {
newActor.params = 0;
}
UIWidgets::EnhancementCheckbox("Advanced mode", "gActorViewerAdvancedParams");
UIWidgets::EnhancementCheckbox("Advanced mode", CVAR_DEVELOPER_TOOLS("ActorViewer.AdvancedParams"));
UIWidgets::InsertHelpHoverText("Changes the actor specific param menus with a direct input");
if (CVarGetInteger("gActorViewerAdvancedParams", 0)) {
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ActorViewer.AdvancedParams"), 0)) {
ImGui::InputScalar("params", ImGuiDataType_S16, &newActor.params, &one);
} else if (std::find(noParamsActors.begin(), noParamsActors.end(), newActor.id) == noParamsActors.end()) {
CreateActorSpecificData();
@ -1214,7 +1215,7 @@ void ActorViewerWindow::DrawElement() {
UIWidgets::Spacer(0);
ImGui::Text("Actor Name Tags");
if (UIWidgets::EnhancementCombobox("gDebugActorViewerNameTags", nameTagOptions, ACTORVIEWER_NAMETAGS_NONE)) {
if (UIWidgets::EnhancementCombobox(CVAR_DEVELOPER_TOOLS("ActorViewer.NameTags"), nameTagOptions, ACTORVIEWER_NAMETAGS_NONE)) {
NameTag_RemoveAllByTag(DEBUG_ACTOR_NAMETAG_TAG);
ActorViewer_AddTagForAllActors();
}

View File

@ -2,7 +2,7 @@
#include <libultraship/libultraship.h>
class ActorViewerWindow : public LUS::GuiWindow {
class ActorViewerWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

View File

@ -7,6 +7,7 @@
#include <cmath>
#include <libultraship/bridge.h>
#include <libultraship/libultraship.h>
#include "soh/OTRGlobals.h"
extern "C" {
#include <z64.h>
@ -57,17 +58,17 @@ void ColViewerWindow::DrawElement() {
ImGui::End();
return;
}
UIWidgets::EnhancementCheckbox("Enabled", "gColViewerEnabled");
UIWidgets::EnhancementCheckbox("Enabled", CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"));
UIWidgets::LabeledRightAlignedEnhancementCombobox("Scene", "gColViewerScene", ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::LabeledRightAlignedEnhancementCombobox("Bg Actors", "gColViewerBgActors", ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", "gColViewerColCheck", ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::LabeledRightAlignedEnhancementCombobox("Waterbox", "gColViewerWaterbox", ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::LabeledRightAlignedEnhancementCombobox("Scene", CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::LabeledRightAlignedEnhancementCombobox("Bg Actors", CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::LabeledRightAlignedEnhancementCombobox("Col Check", CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::LabeledRightAlignedEnhancementCombobox("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), ColRenderSettingNames, COLVIEW_DISABLED);
UIWidgets::EnhancementCheckbox("Apply as decal", "gColViewerDecal");
UIWidgets::EnhancementCheckbox("Apply as decal", CVAR_DEVELOPER_TOOLS("ColViewer.Decal"));
UIWidgets::InsertHelpHoverText("Applies the collision as a decal display. This can be useful if there is z-fighting occuring "
"with the scene geometry, but can cause other artifacts.");
UIWidgets::EnhancementCheckbox("Shaded", "gColViewerShaded");
UIWidgets::EnhancementCheckbox("Shaded", CVAR_DEVELOPER_TOOLS("ColViewer.Shaded"));
UIWidgets::InsertHelpHoverText("Applies the scene's shading to the collision display.");
// This has to be duplicated in both code paths due to the nature of ImGui::IsItemHovered()
@ -75,20 +76,20 @@ void ColViewerWindow::DrawElement() {
if (ImGui::TreeNode("Colors")) {
UIWidgets::InsertHelpHoverText(colorHelpText);
UIWidgets::EnhancementColor("Normal", "gColViewerColorNormal", scene_col, ImVec4(255, 255, 255, 255), false);
UIWidgets::EnhancementColor("Hookshot", "gColViewerColorHookshot", hookshot_col, ImVec4(128, 128, 255, 255),
UIWidgets::EnhancementColor("Normal", CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), scene_col, ImVec4(255, 255, 255, 255), false);
UIWidgets::EnhancementColor("Hookshot", CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), hookshot_col, ImVec4(128, 128, 255, 255),
false);
UIWidgets::EnhancementColor("Entrance", "gColViewerColorEntrance", entrance_col, ImVec4(0, 255, 0, 255), false);
UIWidgets::EnhancementColor("Special Surface (Grass/Sand/Etc)", "gColViewerColorSpecialSurface",
UIWidgets::EnhancementColor("Entrance", CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), entrance_col, ImVec4(0, 255, 0, 255), false);
UIWidgets::EnhancementColor("Special Surface (Grass/Sand/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"),
specialSurface_col, ImVec4(192, 255, 192, 255), false);
UIWidgets::EnhancementColor("Interactable (Vines/Crawlspace/Etc)", "gColViewerColorInteractable",
UIWidgets::EnhancementColor("Interactable (Vines/Crawlspace/Etc)", CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"),
interactable_col, ImVec4(192, 0, 192, 255), false);
UIWidgets::EnhancementColor("Slope", "gColViewerColorSlope", slope_col, ImVec4(255, 255, 128, 255), false);
UIWidgets::EnhancementColor("Void", "gColViewerColorVoid", void_col, ImVec4(255, 0, 0, 255), false);
UIWidgets::EnhancementColor("OC", "gColViewerColorOC", oc_col, ImVec4(255, 255, 255, 255), false);
UIWidgets::EnhancementColor("AC", "gColViewerColorAC", ac_col, ImVec4(0, 0, 255, 255), false);
UIWidgets::EnhancementColor("AT", "gColViewerColorAT", at_col, ImVec4(255, 0, 0, 255), false);
UIWidgets::EnhancementColor("Waterbox", "gColViewerColorWaterbox", waterbox_col, ImVec4(0, 0, 255, 255), false);
UIWidgets::EnhancementColor("Slope", CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), slope_col, ImVec4(255, 255, 128, 255), false);
UIWidgets::EnhancementColor("Void", CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), void_col, ImVec4(255, 0, 0, 255), false);
UIWidgets::EnhancementColor("OC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), oc_col, ImVec4(255, 255, 255, 255), false);
UIWidgets::EnhancementColor("AC", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), ac_col, ImVec4(0, 0, 255, 255), false);
UIWidgets::EnhancementColor("AT", CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), at_col, ImVec4(255, 0, 0, 255), false);
UIWidgets::EnhancementColor("Waterbox", CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), waterbox_col, ImVec4(0, 0, 255, 255), false);
ImGui::TreePop();
} else {
@ -308,7 +309,7 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
alpha = 0xFF;
}
if (CVarGetInteger("gColViewerDecal", 0) != 0) {
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), 0) != 0) {
rm |= ZMODE_DEC;
} else if (setting == ColRenderSetting::Transparent) {
rm |= ZMODE_XLU;
@ -320,7 +321,7 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
gfx.push_back(gsDPSetCycleType(G_CYC_1CYCLE));
gfx.push_back(gsDPSetRenderMode(rm | blc1, rm | blc2));
if (CVarGetInteger("gColViewerShaded", 0) != 0) {
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Shaded"), 0) != 0) {
gfx.push_back(gsDPSetCombineMode(G_CC_MODULATERGB_PRIM_ENVA, G_CC_MODULATERGB_PRIM_ENVA));
gfx.push_back(gsSPLoadGeometryMode(G_CULL_BACK | G_ZBUFFER | G_LIGHTING));
} else {
@ -333,16 +334,13 @@ void InitGfx(std::vector<Gfx>& gfx, ColRenderSetting setting) {
// Draws a dynapoly structure (scenes or Bg Actors)
void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
uint32_t colorR = CVarGetInteger("gColViewerColorNormalR", 255);
uint32_t colorG = CVarGetInteger("gColViewerColorNormalG", 255);
uint32_t colorB = CVarGetInteger("gColViewerColorNormalB", 255);
uint32_t colorA = 255;
Color_RGBA8 color = {255, 255, 255, 255};
uint32_t lastColorR = colorR;
uint32_t lastColorG = colorG;
uint32_t lastColorB = colorB;
uint32_t lastColorR = color.r;
uint32_t lastColorG = color.g;
uint32_t lastColorB = color.b;
dl.push_back(gsDPSetPrimColor(0, 0, colorR, colorG, colorB, colorA));
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
// This keeps track of if we have processed a poly, but not drawn it yet so we can batch them.
// This saves several hundred commands in larger scenes
@ -352,49 +350,35 @@ void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
CollisionPoly* poly = &col->polyList[i];
if (SurfaceType_IsHookshotSurface(&gPlayState->colCtx, poly, bgId)) {
colorR = CVarGetInteger("gColViewerColorHookshotR", 128);
colorG = CVarGetInteger("gColViewerColorHookshotG", 128);
colorB = CVarGetInteger("gColViewerColorHookshotB", 255);
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorHookshot"), { 128, 128, 255, 255 });
} else if (func_80041D94(&gPlayState->colCtx, poly, bgId) > 0x01) {
colorR = CVarGetInteger("gColViewerColorInteractableR", 192);
colorG = CVarGetInteger("gColViewerColorInteractableG", 0);
colorB = CVarGetInteger("gColViewerColorInteractableB", 192);
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorInteractable"), {192, 0, 192, 255});
} else if (func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x0C) {
colorR = CVarGetInteger("gColViewerColorVoidR", 255);
colorG = CVarGetInteger("gColViewerColorVoidG", 0);
colorB = CVarGetInteger("gColViewerColorVoidB", 0);
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorVoid"), { 255, 0, 0, 255 });
} else if (SurfaceType_GetSceneExitIndex(&gPlayState->colCtx, poly, bgId) ||
func_80041E80(&gPlayState->colCtx, poly, bgId) == 0x05) {
colorR = CVarGetInteger("gColViewerColorEntranceR", 0);
colorG = CVarGetInteger("gColViewerColorEntranceG", 255);
colorB = CVarGetInteger("gColViewerColorEntranceB", 0);
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorEntrance"), { 0, 255, 0, 255 });
} else if (func_80041D4C(&gPlayState->colCtx, poly, bgId) != 0 ||
SurfaceType_IsWallDamage(&gPlayState->colCtx, poly, bgId)) {
colorR = CVarGetInteger("gColViewerColorSpecialSurfaceR", 192);
colorG = CVarGetInteger("gColViewerColorSpecialSurfaceG", 255);
colorB = CVarGetInteger("gColViewerColorSpecialSurfaceB", 192);
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSpecialSurface"), { 192, 255, 192, 255 });
} else if (SurfaceType_GetSlope(&gPlayState->colCtx, poly, bgId) == 0x01) {
colorR = CVarGetInteger("gColViewerColorSlopeR", 255);
colorG = CVarGetInteger("gColViewerColorSlopeG", 255);
colorB = CVarGetInteger("gColViewerColorSlopeB", 128);
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorSlope"), { 255, 255, 128, 255 });
} else {
colorR = CVarGetInteger("gColViewerColorNormalR", 255);
colorG = CVarGetInteger("gColViewerColorNormalG", 255);
colorB = CVarGetInteger("gColViewerColorNormalB", 255);
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorNormal"), { 255, 255, 255, 255 });
}
if (colorR != lastColorR || colorG != lastColorG || colorB != lastColorB) {
if (color.r != lastColorR || color.g != lastColorG || color.b != lastColorB) {
// Color changed, flush previous poly
if (previousPoly) {
dl.push_back(gsSPVertex((uintptr_t)&vtxDl.at(vtxDl.size() - 3), 3, 0));
dl.push_back(gsSP1Triangle(0, 1, 2, 0));
previousPoly = false;
}
dl.push_back(gsDPSetPrimColor(0, 0, colorR, colorG, colorB, colorA));
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
}
lastColorR = colorR;
lastColorG = colorG;
lastColorB = colorB;
lastColorR = color.r;
lastColorG = color.g;
lastColorB = color.b;
Vec3s* va = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)];
Vec3s* vb = &col->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)];
@ -428,9 +412,9 @@ void DrawDynapoly(std::vector<Gfx>& dl, CollisionHeader* col, int32_t bgId) {
// Draws the scene
void DrawSceneCollision() {
ColRenderSetting showSceneColSetting = (ColRenderSetting)CVarGetInteger("gColViewerScene", COLVIEW_DISABLED);
ColRenderSetting showSceneColSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_DISABLED);
if (showSceneColSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
if (showSceneColSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
return;
}
@ -443,8 +427,8 @@ void DrawSceneCollision() {
// Draws all Bg Actors
void DrawBgActorCollision() {
ColRenderSetting showBgActorSetting = (ColRenderSetting)CVarGetInteger("gColViewerBgActors", COLVIEW_DISABLED);
if (showBgActorSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
ColRenderSetting showBgActorSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_DISABLED);
if (showBgActorSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
return;
}
@ -461,7 +445,7 @@ void DrawBgActorCollision() {
bg.curTransform.scale.z, bg.curTransform.rot.x, bg.curTransform.rot.y,
bg.curTransform.rot.z, bg.curTransform.pos.x, bg.curTransform.pos.y,
bg.curTransform.pos.z);
guMtxF2L(&mf, &m);
guMtxF2L(mf.mf, &m);
mtxDl.push_back(m);
dl.push_back(gsSPMatrix(&mtxDl.back(), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH));
@ -509,7 +493,7 @@ void DrawColCheckList(std::vector<Gfx>& dl, Collider** objects, int32_t count) {
SkinMatrix_SetScale(&ms, radius / 128.0f, radius / 128.0f, radius / 128.0f);
MtxF dest;
SkinMatrix_MtxFMtxFMult(&mf, &ms, &dest);
guMtxF2L(&dest, &m);
guMtxF2L(dest.mf, &m);
mtxDl.push_back(m);
dl.push_back(gsSPMatrix(&mtxDl.back(), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH));
@ -528,7 +512,7 @@ void DrawColCheckList(std::vector<Gfx>& dl, Collider** objects, int32_t count) {
SkinMatrix_SetScale(&ms, radius / 128.0f, cyl->dim.height / 128.0f, radius / 128.0f);
MtxF dest;
SkinMatrix_MtxFMtxFMult(&mt, &ms, &dest);
guMtxF2L(&dest, &m);
guMtxF2L(dest.mf, &m);
mtxDl.push_back(m);
dl.push_back(gsSPMatrix(&mtxDl.back(), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_PUSH));
@ -568,8 +552,8 @@ void DrawColCheckList(std::vector<Gfx>& dl, Collider** objects, int32_t count) {
// Draws all Col Check objects
void DrawColCheckCollision() {
ColRenderSetting showColCheckSetting = (ColRenderSetting)CVarGetInteger("gColViewerColCheck", COLVIEW_DISABLED);
if (showColCheckSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
ColRenderSetting showColCheckSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_DISABLED);
if (showColCheckSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
return;
}
@ -578,15 +562,14 @@ void DrawColCheckCollision() {
dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH));
CollisionCheckContext& col = gPlayState->colChkCtx;
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorOCR", 255), CVarGetInteger("gColViewerColorOCG", 255),
CVarGetInteger("gColViewerColorOCB", 255), 255));
Color_RGBA8 color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorOC"), { 255, 255, 255, 255 });
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
DrawColCheckList(dl, col.colOC, col.colOCCount);
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorACR", 0), CVarGetInteger("gColViewerColorACG", 0),
CVarGetInteger("gColViewerColorACB", 255), 255));
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAC"), { 0, 0, 255, 255 });
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
DrawColCheckList(dl, col.colAC, col.colACCount);
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorATR", 255), CVarGetInteger("gColViewerColorATG", 0),
CVarGetInteger("gColViewerColorATB", 0), 255));
color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorAT"), { 0, 0, 255, 255 });
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
DrawColCheckList(dl, col.colAT, col.colATCount);
}
@ -621,8 +604,8 @@ extern "C" f32 zdWaterBoxMinY;
// Draws all waterboxes
void DrawWaterboxList() {
ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVarGetInteger("gColViewerWaterbox", COLVIEW_DISABLED);
if (showWaterboxSetting == ColRenderSetting::Disabled || !CVarGetInteger("gColViewerEnabled", 0)) {
ColRenderSetting showWaterboxSetting = (ColRenderSetting)CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_DISABLED);
if (showWaterboxSetting == ColRenderSetting::Disabled || !CVarGetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), 0)) {
return;
}
@ -630,9 +613,9 @@ void DrawWaterboxList() {
InitGfx(dl, showWaterboxSetting);
dl.push_back(gsSPMatrix(&gMtxClear, G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH));
dl.push_back(gsDPSetPrimColor(0, 0, CVarGetInteger("gColViewerColorWaterboxR", 0),
CVarGetInteger("gColViewerColorWaterboxG", 0),
CVarGetInteger("gColViewerColorWaterboxB", 255), 255));
Color_RGBA8 color = CVarGetColor(CVAR_DEVELOPER_TOOLS("ColViewer.ColorWaterbox"), { 0, 0, 255, 255 });
dl.push_back(gsDPSetPrimColor(0, 0, color.r, color.g, color.b, 255));
CollisionHeader* col = gPlayState->colCtx.colHeader;
for (int32_t waterboxIndex = 0; waterboxIndex < col->numWaterBoxes; waterboxIndex++) {
@ -693,7 +676,7 @@ extern "C" void DrawColViewer() {
OPEN_DISPS(gPlayState->state.gfxCtx);
uint8_t mirroredWorld = CVarGetInteger("gMirroredWorld", 0);
uint8_t mirroredWorld = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0);
// Col viewer needs inverted culling in mirror mode for both OPA and XLU buffers
if (mirroredWorld) {
gSPSetExtraGeometryMode(POLY_OPA_DISP++, G_EX_INVERT_CULLING);

View File

@ -14,7 +14,7 @@ typedef enum {
} ColViewerRenderSetting;
#ifdef __cplusplus
class ColViewerWindow : public LUS::GuiWindow {
class ColViewerWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

View File

@ -614,7 +614,7 @@ void DrawInfoTab() {
void DrawBGSItemFlag(uint8_t itemID) {
const ItemMapEntry& slotEntry = itemMapping[itemID];
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1));
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1));
ImGui::SameLine();
int tradeIndex = itemID - ITEM_POCKET_EGG;
bool hasItem = (gSaveContext.adultTradeItems & (1 << tradeIndex)) != 0;
@ -656,7 +656,7 @@ void DrawInventoryTab() {
uint8_t item = gSaveContext.inventory.items[index];
if (item != ITEM_NONE) {
const ItemMapEntry& slotEntry = itemMapping.find(item)->second;
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
ImVec2(1, 1), 0)) {
selectedIndex = index;
ImGui::OpenPopup(itemPopupPicker);
@ -704,7 +704,7 @@ void DrawInventoryTab() {
ImGui::SameLine();
}
const ItemMapEntry& slotEntry = possibleItems[pickerIndex];
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f),
ImVec2(0, 0), ImVec2(1, 1), 0)) {
gSaveContext.inventory.items[selectedIndex] = slotEntry.id;
// Set adult trade item flag if you're playing adult trade shuffle in rando
@ -742,7 +742,7 @@ void DrawInventoryTab() {
ImGui::PushItemWidth(32.0f);
ImGui::BeginGroup();
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[item].name), ImVec2(32.0f, 32.0f));
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[item].name), ImVec2(32.0f, 32.0f));
ImGui::InputScalar("##ammoInput", ImGuiDataType_S8, &AMMO(item));
ImGui::EndGroup();
@ -1187,7 +1187,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const
uint8_t item = items[CUR_UPG_VALUE(categoryId)];
if (item != ITEM_NONE) {
const ItemMapEntry& slotEntry = itemMapping[item];
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
ImVec2(1, 1), 0)) {
ImGui::OpenPopup(upgradePopupPicker);
}
@ -1215,7 +1215,7 @@ void DrawUpgradeIcon(const std::string& categoryName, int32_t categoryId, const
UIWidgets::SetLastItemHoverText("None");
} else {
const ItemMapEntry& slotEntry = itemMapping[items[pickerIndex]];
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(slotEntry.name), ImVec2(32.0f, 32.0f), ImVec2(0, 0),
ImVec2(1, 1), 0)) {
Inventory_ChangeUpgrade(categoryId, pickerIndex);
ImGui::CloseCurrentPopup();
@ -1252,7 +1252,7 @@ void DrawEquipmentTab() {
bool hasEquip = (bitMask & gSaveContext.inventory.equipment) != 0;
const ItemMapEntry& entry = itemMapping[equipmentValues[i]];
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasEquip ? entry.name : entry.nameFaded),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasEquip ? entry.name : entry.nameFaded),
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
if (hasEquip) {
gSaveContext.inventory.equipment &= ~bitMask;
@ -1351,7 +1351,7 @@ void DrawQuestItemButton(uint32_t item) {
uint32_t bitMask = 1 << entry.id;
bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0;
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
if (hasQuestItem) {
gSaveContext.inventory.questItems &= ~bitMask;
@ -1369,7 +1369,7 @@ void DrawDungeonItemButton(uint32_t item, uint32_t scene) {
uint32_t bitMask = 1 << (entry.id - ITEM_KEY_BOSS); // Bitset starts at ITEM_KEY_BOSS == 0. the rest are sequential
bool hasItem = (bitMask & gSaveContext.inventory.dungeonItems[scene]) != 0;
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem ? entry.name : entry.nameFaded),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem ? entry.name : entry.nameFaded),
ImVec2(32.0f, 32.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
if (hasItem) {
gSaveContext.inventory.dungeonItems[scene] &= ~bitMask;
@ -1416,7 +1416,7 @@ void DrawQuestStatusTab() {
uint32_t bitMask = 1 << entry.id;
bool hasQuestItem = (bitMask & gSaveContext.inventory.questItems) != 0;
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
if (ImGui::ImageButton(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
if (ImGui::ImageButton(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasQuestItem ? entry.name : entry.nameFaded),
ImVec2(16.0f, 24.0f), ImVec2(0, 0), ImVec2(1, 1), 0)) {
if (hasQuestItem) {
gSaveContext.inventory.questItems &= ~bitMask;
@ -1479,7 +1479,7 @@ void DrawQuestStatusTab() {
if (dungeonItemsScene != SCENE_JABU_JABU_BOSS) {
float lineHeight = ImGui::GetTextLineHeightWithSpacing();
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[ITEM_KEY_SMALL].name), ImVec2(lineHeight, lineHeight));
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(itemMapping[ITEM_KEY_SMALL].name), ImVec2(lineHeight, lineHeight));
ImGui::SameLine();
if (ImGui::InputScalar("##Keys", ImGuiDataType_S8, gSaveContext.inventory.dungeonKeys + dungeonItemsScene)) {
gSaveContext.sohStats.dungeonKeys[dungeonItemsScene] = gSaveContext.inventory.dungeonKeys[dungeonItemsScene];
@ -1735,7 +1735,7 @@ void DrawPlayerTab() {
ImGui::SameLine();
ImGui::InputScalar("C Right", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[3], &one, NULL);
if (CVarGetInteger("gDpadEquips", 0)) {
if (CVarGetInteger(CVAR_SETTING("DpadEquips"), 0)) {
ImGui::NewLine();
ImGui::Text("Current D-pad Equips");
ImGui::InputScalar("D-pad Up ", ImGuiDataType_U8, &gSaveContext.equips.buttonItems[4], &one, NULL); // Two spaces at the end for aligning, not elegant but it's working
@ -1823,34 +1823,34 @@ void SaveEditorWindow::DrawElement() {
void SaveEditorWindow::InitElement() {
// Load item icons into ImGui
for (const auto& entry : itemMapping) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
}
for (const auto& entry : gregMapping) {
ImVec4 gregGreen = ImVec4(42.0f / 255.0f, 169.0f / 255.0f, 40.0f / 255.0f, 1.0f);
ImVec4 gregFadedGreen = gregGreen;
gregFadedGreen.w = 0.3f;
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, gregGreen);
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen);
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, gregGreen);
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen);
}
for (const auto& entry : triforcePieceMapping) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
}
for (const auto& entry : questMapping) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
}
for (const auto& entry : songMapping) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
ImVec4 fadedCol = entry.color;
fadedCol.w = 0.3f;
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
}
for (const auto& entry : vanillaSongMapping) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.name, gSongNoteTex, entry.color);
ImVec4 fadedCol = entry.color;
fadedCol.w = 0.3f;
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.nameFaded, gSongNoteTex, fadedCol);
}
}

View File

@ -349,22 +349,9 @@ const std::vector<FlagTable> flagTables = {
{ 0x30, "Entered the Market" },
} },
{ "Randomizer Inf Flags", RANDOMIZER_INF, 16, {
{ RAND_INF_DUNGEONS_DONE_DEKU_TREE, "DUNGEONS_DONE_DEKU_TREE" },
{ RAND_INF_DUNGEONS_DONE_DODONGOS_CAVERN, "DUNGEONS_DONE_DODONGOS_CAVERN" },
{ RAND_INF_DUNGEONS_DONE_JABU_JABUS_BELLY, "DUNGEONS_DONE_JABU_JABUS_BELLY" },
{ RAND_INF_DUNGEONS_DONE_FOREST_TEMPLE, "DUNGEONS_DONE_FOREST_TEMPLE" },
{ RAND_INF_DUNGEONS_DONE_FIRE_TEMPLE, "DUNGEONS_DONE_FIRE_TEMPLE" },
{ RAND_INF_DUNGEONS_DONE_WATER_TEMPLE, "DUNGEONS_DONE_WATER_TEMPLE" },
{ RAND_INF_DUNGEONS_DONE_SPIRIT_TEMPLE, "DUNGEONS_DONE_SPIRIT_TEMPLE" },
{ RAND_INF_DUNGEONS_DONE_SHADOW_TEMPLE, "DUNGEONS_DONE_SHADOW_TEMPLE" },
{ RAND_INF_TRIALS_DONE_LIGHT_TRIAL, "TRIALS_DONE_LIGHT_TRIAL" },
{ RAND_INF_TRIALS_DONE_FOREST_TRIAL, "TRIALS_DONE_FOREST_TRIAL" },
{ RAND_INF_TRIALS_DONE_FIRE_TRIAL, "TRIALS_DONE_FIRE_TRIAL" },
{ RAND_INF_TRIALS_DONE_WATER_TRIAL, "TRIALS_DONE_WATER_TRIAL" },
{ RAND_INF_TRIALS_DONE_SPIRIT_TRIAL, "TRIALS_DONE_SPIRIT_TRIAL" },
{ RAND_INF_TRIALS_DONE_SHADOW_TRIAL, "TRIALS_DONE_SHADOW_TRIAL" },
{ RAND_INF_COWS_MILKED_KF_LINKS_HOUSE_COW, "COWS_MILKED_KF_LINKS_HOUSE_COW" },
{ RAND_INF_COWS_MILKED_HF_COW_GROTTO_COW, "COWS_MILKED_HF_COW_GROTTO_COW" },
{ RAND_INF_COWS_MILKED_LLR_STABLES_LEFT_COW, "COWS_MILKED_LLR_STABLES_LEFT_COW" },
@ -505,6 +492,7 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" },
{ RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" },
{ RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" },
{ RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" },
{ RAND_INF_GOHMA_SOUL, "RAND_INF_GOHMA_SOUL" },
{ RAND_INF_KING_DODONGO_SOUL, "RAND_INF_KING_DODONGO_SOUL" },
@ -515,7 +503,6 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_BONGO_BONGO_SOUL, "RAND_INF_BONGO_BONGO_SOUL" },
{ RAND_INF_TWINROVA_SOUL, "RAND_INF_TWINROVA_SOUL" },
{ RAND_INF_GANON_SOUL, "RAND_INF_GANON_SOUL" },
{ RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" },
{ RAND_INF_HAS_OCARINA_A, "RAND_INF_HAS_OCARINA_A"},
{ RAND_INF_HAS_OCARINA_C_UP, "RAND_INF_HAS_OCARINA_C_UP" },
@ -607,7 +594,19 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_ZD_FISH_2, "RAND_INF_ZD_FISH_2" },
{ RAND_INF_ZD_FISH_3, "RAND_INF_ZD_FISH_3" },
{ RAND_INF_ZD_FISH_4, "RAND_INF_ZD_FISH_4" },
{ RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" }
{ RAND_INF_ZD_FISH_5, "RAND_INF_ZD_FISH_5" },
{ RAND_INF_LINKS_POCKET, "RAND_INF_LINKS_POCKET" },
{ RAND_INF_LEARNED_EPONA_SONG, "RAND_INF_LEARNED_EPONA_SONG" },
{ RAND_INF_DARUNIAS_JOY, "RAND_INF_DARUNIAS_JOY" },
{ RAND_INF_KING_ZORA_THAWED, "RAND_INF_KING_ZORA_THAWED" },
{ RAND_INF_HC_GREAT_FAIRY_REWARD, "RAND_INF_HC_GREAT_FAIRY_REWARD" },
{ RAND_INF_DMT_GREAT_FAIRY_REWARD, "RAND_INF_DMT_GREAT_FAIRY_REWARD" },
{ RAND_INF_DMC_GREAT_FAIRY_REWARD, "RAND_INF_DMC_GREAT_FAIRY_REWARD" },
{ RAND_INF_ZF_GREAT_FAIRY_REWARD, "RAND_INF_ZF_GREAT_FAIRY_REWARD" },
{ RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD, "RAND_INF_COLOSSUS_GREAT_FAIRY_REWARD" },
{ RAND_INF_OGC_GREAT_FAIRY_REWARD, "RAND_INF_OGC_GREAT_FAIRY_REWARD" },
} },
};
@ -692,7 +691,7 @@ const std::vector<std::string> state3 = {
"Travelling to Hook Target"
};
class SaveEditorWindow : public LUS::GuiWindow {
class SaveEditorWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

View File

@ -65,7 +65,7 @@ std::map<int, std::string> cmdMap = {
};
void PerformDisplayListSearch() {
auto result = LUS::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles("*" + std::string(searchString) + "*DL*");
auto result = Ship::Context::GetInstance()->GetResourceManager()->GetArchiveManager()->ListFiles("*" + std::string(searchString) + "*DL*");
displayListSearchResults.clear();
@ -127,7 +127,7 @@ void DLViewerWindow::DrawElement() {
}
try {
auto res = std::static_pointer_cast<LUS::DisplayList>(LUS::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList));
auto res = std::static_pointer_cast<LUS::DisplayList>(Ship::Context::GetInstance()->GetResourceManager()->LoadResource(activeDisplayList));
if (res->GetInitData()->Type != static_cast<uint32_t>(LUS::ResourceType::DisplayList)) {
ImGui::Text("Resource type is not a Display List. Please choose another.");

View File

@ -2,7 +2,7 @@
#include <libultraship/libultraship.h>
class DLViewerWindow : public LUS::GuiWindow {
class DLViewerWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

View File

@ -1,5 +1,6 @@
#include "valueViewer.h"
#include "../../UIWidgets.hpp"
#include "soh/OTRGlobals.h"
extern "C" {
#include <z64.h>
@ -34,6 +35,8 @@ std::vector<ValueTableElement> valueTable = {
{ "Text ID", "play->msgCtx.textId", "TEXTID:", TYPE_U16, true, []() -> void* { return &gPlayState->msgCtx.textId; }, WHITE },
{ "Analog Stick X", "play->state.input->cur.stick_x", "AX:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_x; }, WHITE },
{ "Analog Stick Y", "play->state.input->cur.stick_y", "AY:", TYPE_S8, true, []() -> void* { return &gPlayState->state.input->cur.stick_y; }, WHITE },
{ "getItemID", "Player->getItemId", "ITEM:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemId; }, WHITE },
{ "getItemEntry", "Player->getItemEntry", "IE:", TYPE_S16, true, []() -> void* { return &GET_PLAYER(gPlayState)->getItemEntry.itemId; }, WHITE },
/* TODO: Find these (from GZ)
"XZ Units Traveled (Camera based speed variable)" f32 0x801C9018
"Movement Angle" x16 0x801DBB1C
@ -107,7 +110,7 @@ void ValueViewerWindow::DrawElement() {
return;
}
UIWidgets::PaddedEnhancementCheckbox("Enable Printing", "gValueViewer.EnablePrinting");
UIWidgets::PaddedEnhancementCheckbox("Enable Printing", CVAR_DEVELOPER_TOOLS("ValueViewerEnablePrinting"));
ImGui::BeginGroup();
static int selectedElement = -1;
@ -187,7 +190,7 @@ void ValueViewerWindow::DrawElement() {
}
ImGui::BeginGroup();
if (CVarGetInteger("gValueViewer.EnablePrinting", 0)) {
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ValueViewerEnablePrinting"), 0)) {
ImGui::Checkbox(("Print##" + std::string(element.name)).c_str(), &element.isPrinted);
if (element.isPrinted) {
char* prefix = (char*)element.prefix.c_str();

View File

@ -33,7 +33,7 @@ typedef struct {
uint32_t y;
} ValueTableElement;
class ValueViewerWindow : public LUS::GuiWindow {
class ValueViewerWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

View File

@ -5,6 +5,7 @@
#include "soh/Enhancements/randomizer/context.h"
#include "soh/Enhancements/enhancementTypes.h"
#include "variables.h"
#include "soh/OTRGlobals.h"
extern "C" {
#include <z64.h>
@ -234,7 +235,7 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *po
}
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) {
if (CVarGetInteger("gRandomizedEnemies", ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed() : gSaveContext.sohStats.fileCreatedAt);
Random_Init(finalSeed);
}

View File

@ -14,6 +14,13 @@ typedef enum {
CSMC_SIZE
} ChestStyleMatchesContentsType;
typedef enum {
SGIA_DISABLED,
SGIA_JUNK,
SGIA_ALL,
SGIA_SIZE
} SkipGetItemAnimationType;
typedef enum {
BUNNY_HOOD_VANILLA,
BUNNY_HOOD_FAST_AND_JUMP,

View File

@ -3,6 +3,7 @@
#ifndef GameInteractor_h
#define GameInteractor_h
#include "libultraship/libultraship.h"
#include "GameInteractionEffect.h"
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include <z64.h>
@ -67,6 +68,328 @@ typedef enum {
/* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_7,
} GITeleportDestinations;
typedef enum {
// Vanilla condition: gSaveContext.showTitleCard
VB_SHOW_TITLE_CARD,
// Opt: *EnWonderTalk2
VB_WONDER_TALK,
// Opt: *ElfMsg
VB_NAVI_TALK,
// Vanilla condition: INFTABLE_GREETED_BY_SARIA
VB_NOT_BE_GREETED_BY_SARIA,
// Opt: *EnMd
// Vanilla condition: EnMd->interactInfo.talkState == NPC_TALK_STATE_ACTION
VB_MOVE_MIDO_IN_KOKIRI_FOREST,
// Opt: *EnMd
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
VB_MIDO_CONSIDER_DEKU_TREE_DEAD,
// Opt: *ObjDekujr
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FOREST)
VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED,
// Opt: *EnKo
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
VB_OPEN_KOKIRI_FOREST,
// Opt: *EnOwl
// Vanilla condition: EnOwl->actor.xzDistToPlayer < targetDist
VB_OWL_INTERACTION,
// Vanilla condition: EVENTCHKINF_TALON_RETURNED_FROM_CASTLE
VB_MALON_RETURN_FROM_CASTLE,
// Vanilla condition: CUR_UPG_VALUE(UPG_STRENGTH) <= 0
VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD,
/* Vanilla condition:
```
LINK_IS_ADULT &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
```
*/
VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS,
// Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SARIA)
VB_BE_ELIGIBLE_FOR_SARIAS_SONG,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_SONG_EPONA)
VB_MALON_ALREADY_TAUGHT_EPONAS_SONG,
// Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)
VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER,
// Vanilla condition: (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT
VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER,
// Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP
VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT,
VB_BE_ELIGIBLE_FOR_RAINBOW_BRIDGE,
/* Vanilla Condition:
```
LINK_IS_ADULT &&
gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) &&
!Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL);
```
*/
VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW,
// Opt: *EnGo2
// Vanilla condition: CUR_CAPACITY(UPG_BOMB_BAG) >= 20 && this->waypoint > 7 && this->waypoint < 12
VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD,
// Vanilla condition: !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON)
VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE,
// Opt: *EnMs
// Vanilla condition: gSaveContext.rupees >= sPrices[BEANS_BOUGHT]
VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE,
// Opt: *EnItem00
// Vanilla condition: Flags_GetCollectible(play, this->collectibleFlag)
VB_ITEM00_DESPAWN,
// Opt: *EnTk
// Vanilla condition: gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD
VB_DAMPE_IN_GRAVEYARD_DESPAWN,
// Opt: *EnTk
// Vanilla condition: this->validDigHere == 1
VB_BE_VALID_GRAVEDIGGING_SPOT,
// Opt: *EnTk
// Vanilla condition: this->currentReward == 3
VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE,
// Opt: *EnTk
// Vanilla condition: !Flags_GetItemGetInf(ITEMGETINF_1C)
VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE,
// Opt: *EnShopnuts
/* Vanilla Condition:
```
((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) ||
((this->actor.params == 0x0009) && (Flags_GetInfTable(INFTABLE_192))) ||
((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193)))
```
*/
VB_BUSINESS_SCRUB_DESPAWN,
// Opt: *EnCow
// Vanilla condition: play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE))
VB_DESPAWN_HORSE_RACE_COW,
// Opt: *EnHs
// Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30)
VB_DESPAWN_GROG,
// Opt: *EnKo
// Vanilla condition: (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false;
VB_SPAWN_LW_FADO,
// Opt: *EnMk
VB_PLAY_EYEDROP_CREATION_ANIM,
// Opt: *EnDs
VB_PLAY_ODD_POTION_ANIM,
// Opt: *EnMk
// Vanilla condition: INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS
VB_USE_EYEDROP_DIALOGUE,
// Opt: *EnMk
// Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30)
VB_OFFER_BLUE_POTION,
// Vanilla condition: Inventory_HasEmptyBottle() == 0
VB_NEED_BOTTLE_FOR_GRANNYS_ITEM,
// Opt: *EnNiwLady
VB_SET_CUCCO_COUNT,
// Opt: *EnKz
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)
VB_KING_ZORA_THANK_CHILD,
// Opt: *EnKz
// Vanilla condition: this->actor.textId == 0x401A
VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER,
// Opt: *EnKz
// Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)
VB_KING_ZORA_BE_MOVED,
// Vanilla condition: gSaveState.bgsFlag
VB_BIGGORON_CONSIDER_TRADE_COMPLETE,
// Vanilla condition: gSaveState.bgsFlag
VB_BIGGORON_CONSIDER_SWORD_COLLECTED,
// Vanilla condition: Environment_GetBgsDayCount() >= 3
VB_BIGGORON_CONSIDER_SWORD_FORGED,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)
VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_GORON_RUBY)
VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED,
// Opt: *uint16_t
// Vanilla condition: false
VB_OVERRIDE_LINK_THE_GORON_DIALOGUE,
// Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)
VB_GORONS_CONSIDER_TUNIC_COLLECTED,
// Opt: *EnSyatekiMan
// Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50)
VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD,
// Opt: *EnOkarinaTag
// Vanilla condition: !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME)
VB_BE_ELIGIBLE_TO_OPEN_DOT,
// Opt: *BgDyYoseizo
// Vanilla condition: see soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c
VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD,
// Vanilla condition: see CheckCarpentersFreed in z_en_ge1 and z_en_ge2
VB_GERUDOS_BE_FRIENDLY,
// Vanilla condition: switch
VB_GTG_GATE_BE_OPEN,
/*** Play Cutscenes ***/
VB_PLAY_TRANSITION_CS,
// Opt: *EventChkInf flag
VB_PLAY_ENTRANCE_CS,
// Opt: *cutsceneId
VB_PLAY_ONEPOINT_CS,
// Opt: *actor
VB_PLAY_ONEPOINT_ACTOR_CS,
// Opt: *BgTreemouth
VB_PLAY_DEKU_TREE_INTRO_CS,
// Vanilla condition: !EventChkInf except for spirit & shadow temple which are !medallion, and Jabu which always is true
VB_PLAY_BLUE_WARP_CS,
VB_PLAY_DARUNIAS_JOY_CS,
VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS,
// Vanilla condition: !EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL
VB_PLAY_PULL_MASTER_SWORD_CS,
VB_PLAY_DROP_FISH_FOR_JABU_CS,
// Vanilla condition: player->getItemId == GI_GAUNTLETS_SILVER
VB_PLAY_NABOORU_CAPTURED_CS,
VB_PLAY_ZELDAS_LULLABY_CS,
// Opt: *EnSa
VB_PLAY_SARIAS_SONG_CS,
VB_PLAY_PRELUDE_OF_LIGHT_CS,
VB_PLAY_MINUET_OF_FOREST_CS,
VB_PLAY_BOLERO_OF_FIRE_CS,
VB_PLAY_SERENADE_OF_WATER_CS,
VB_PLAY_EYEDROPS_CS,
// Opt: *EnOkarinaTag
VB_PLAY_DRAIN_WELL_CS,
// Opt: *EnOkarinaTag
// Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SUN)
VB_PLAY_SUNS_SONG_CS,
// Opt: *EnOkarinaTag
VB_PLAY_ROYAL_FAMILY_TOMB_CS,
VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE,
// Opt: *EnOkarinaTag
VB_PLAY_DOOR_OF_TIME_CS,
VB_PLAY_RAINBOW_BRIDGE_CS,
/*** Give Items ***/
// Opt: *EnBox
VB_GIVE_ITEM_FROM_CHEST,
VB_GIVE_ITEM_FROM_BLUE_WARP,
// Opt: *EnItem00
VB_GIVE_ITEM_FROM_ITEM_00,
// Opt: *EnSi
VB_GIVE_ITEM_SKULL_TOKEN,
// Opt: *EnCow
VB_GIVE_ITEM_FROM_COW,
// Opt: *EnDns
VB_GIVE_ITEM_FROM_BUSINESS_SCRUB,
// Opt: *EnMk
VB_GIVE_ITEM_FROM_LAB_DIVE,
// Opt: *EnDs
VB_GIVE_ITEM_FROM_GRANNYS_SHOP,
// Opt: *EnNiwLady
VB_GIVE_ITEM_FROM_ANJU_AS_CHILD,
// Opt: *EnNiwLady
VB_GIVE_ITEM_FROM_ANJU_AS_ADULT,
// Opt: *EnKz
// Vanilla condition: !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)
VB_GIVE_ITEM_FROM_THAWING_KING_ZORA,
// Opt: *EnGo2
VB_GIVE_ITEM_FROM_GORON,
// Opt: *EnJs
VB_GIVE_ITEM_FROM_CARPET_SALESMAN,
// Opt: *EnGm
VB_GIVE_ITEM_FROM_MEDIGORON,
// Opt: *EnMs
VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN,
// Opt: *EnFr
VB_GIVE_ITEM_FROM_FROGS,
// Opt: *EnSkj
VB_GIVE_ITEM_FROM_OCARINA_MEMORY_GAME,
// Opt: *EnSkj
VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG,
VB_GIVE_ITEM_FROM_MAN_ON_ROOF,
// Opt: *EnSyatekiMan
VB_GIVE_ITEM_FROM_SHOOTING_GALLERY,
// Opt: *EnExItem
VB_GIVE_ITEM_FROM_TARGET_IN_WOODS,
// Opt: *EnTa
VB_GIVE_ITEM_FROM_TALONS_CHICKENS,
// Opt: *EnDivingGame
VB_GIVE_ITEM_FROM_DIVING_MINIGAME,
// Opt: *EnGe1
VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY,
// Opt: *EnSth
VB_GIVE_ITEM_FROM_SKULLTULA_REWARD,
// Opt: *EnHy
VB_GIVE_ITEM_FROM_LOST_DOG,
// Opt: *EnBomBowlPit
VB_GIVE_ITEM_FROM_BOMBCHU_BOWLING,
VB_GIVE_ITEM_GERUDO_MEMBERSHIP_CARD,
VB_GIVE_ITEM_FAIRY_OCARINA,
VB_GIVE_ITEM_WEIRD_EGG,
VB_GIVE_ITEM_LIGHT_ARROW,
VB_GIVE_ITEM_STRENGTH_1,
VB_GIVE_ITEM_ZELDAS_LETTER,
VB_GIVE_ITEM_MASTER_SWORD,
VB_GIVE_ITEM_OCARINA_OF_TIME,
VB_GIVE_ITEM_KOKIRI_EMERALD,
VB_GIVE_ITEM_GORON_RUBY,
VB_GIVE_ITEM_ZORA_SAPPHIRE,
VB_GIVE_ITEM_LIGHT_MEDALLION,
VB_GIVE_ITEM_FOREST_MEDALLION,
VB_GIVE_ITEM_FIRE_MEDALLION,
VB_GIVE_ITEM_WATER_MEDALLION,
VB_GIVE_ITEM_SPIRIT_MEDALLION,
VB_GIVE_ITEM_SHADOW_MEDALLION,
/*** Give Songs ***/
VB_GIVE_ITEM_ZELDAS_LULLABY,
VB_GIVE_ITEM_SARIAS_SONG,
VB_GIVE_ITEM_EPONAS_SONG,
VB_GIVE_ITEM_SUNS_SONG,
VB_GIVE_ITEM_SONG_OF_TIME,
VB_GIVE_ITEM_SONG_OF_STORMS,
VB_GIVE_ITEM_MINUET_OF_FOREST,
VB_GIVE_ITEM_BOLERO_OF_FIRE,
VB_GIVE_ITEM_SERENADE_OF_WATER,
VB_GIVE_ITEM_REQUIEM_OF_SPIRIT,
VB_GIVE_ITEM_NOCTURNE_OF_SHADOW,
VB_GIVE_ITEM_PRELUDE_OF_LIGHT,
/*** Adult Trade ***/
// Opt: *EnNiwLady
VB_TRADE_POCKET_CUCCO,
// Opt: *EnHs
VB_TRADE_COJIRO,
// Opt: *EnDs
VB_TRADE_ODD_MUSHROOM,
// Opt: *EnKo
VB_TRADE_ODD_POTION,
// Opt: *EnToryo
VB_TRADE_SAW,
// Opt: *EnKz,
VB_TRADE_PRESCRIPTION,
// Opt: *EnMk
VB_TRADE_FROG,
VB_TRADE_TIMER_ODD_MUSHROOM,
VB_TRADE_TIMER_EYEDROPS,
VB_TRADE_TIMER_FROG,
// Opt: *EnNiwLady
VB_ANJU_SET_OBTAINED_TRADE_ITEM,
/*** Fixes ***/
// Vanilla condition: false
VB_FIX_SAW_SOFTLOCK,
/*** Cheats? ***/
VB_DEKU_STICK_BE_ON_FIRE,
VB_DEKU_STICK_BREAK,
VB_DEKU_STICK_BURN_DOWN,
VB_DEKU_STICK_BURN_OUT,
VB_DEKU_UPDATE_BURNING_DEKU_STICK,
/*** Quick Boss Deaths ***/
// Vanilla condition: true
VB_PHANTOM_GANON_DEATH_SCENE,
VB_NABOORU_KNUCKLE_DEATH_SCENE,
} GIVanillaBehavior;
#ifdef __cplusplus
extern "C" {
#endif
@ -98,6 +421,7 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state);
#ifdef __cplusplus
#include <thread>
#include <unordered_map>
#include <vector>
#include <functional>
#include <string>
@ -107,11 +431,17 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state);
#include <nlohmann/json.hpp>
#endif
#define DEFINE_HOOK(name, type) \
struct name { \
typedef std::function<type> fn; \
typedef uint32_t HOOK_ID;
#define DEFINE_HOOK(name, args) \
struct name { \
typedef std::function<void args> fn; \
typedef std::function<bool args> filter; \
}
#define REGISTER_VB_SHOULD(flag, body) \
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::ShouldVanillaBehavior>(flag, [](GIVanillaBehavior _, bool* should, void* opt) body)
class GameInteractor {
public:
static GameInteractor* Instance;
@ -163,11 +493,22 @@ public:
static GameInteractionEffectQueryResult RemoveEffect(RemovableGameInteractionEffect* effect);
// Game Hooks
uint32_t nextHookId = 1;
template <typename H> struct RegisteredGameHooks { inline static std::unordered_map<uint32_t, typename H::fn> functions; };
template <typename H> struct HooksToUnregister { inline static std::vector<uint32_t> hooks; };
template <typename H> uint32_t RegisterGameHook(typename H::fn h) {
// Ensure hook id is unique and not 0, which is reserved for invalid hooks
HOOK_ID nextHookId = 1;
template <typename H> struct RegisteredGameHooks {
inline static std::unordered_map<HOOK_ID, typename H::fn> functions;
inline static std::unordered_map<int32_t, std::unordered_map<HOOK_ID, typename H::fn>> functionsForID;
inline static std::unordered_map<uintptr_t, std::unordered_map<HOOK_ID, typename H::fn>> functionsForPtr;
inline static std::unordered_map<HOOK_ID, std::pair<typename H::filter, typename H::fn>> functionsForFilter;
};
template <typename H> struct HooksToUnregister {
inline static std::vector<HOOK_ID> hooks;
inline static std::vector<HOOK_ID> hooksForID;
inline static std::vector<HOOK_ID> hooksForPtr;
inline static std::vector<HOOK_ID> hooksForFilter;
};
// General Hooks
template <typename H> HOOK_ID RegisterGameHook(typename H::fn h) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functions.find(this->nextHookId) != RegisteredGameHooks<H>::functions.end()) {
this->nextHookId++;
@ -176,10 +517,10 @@ public:
RegisteredGameHooks<H>::functions[this->nextHookId] = h;
return this->nextHookId++;
}
template <typename H> void UnregisterGameHook(uint32_t id) {
HooksToUnregister<H>::hooks.push_back(id);
template <typename H> void UnregisterGameHook(HOOK_ID hookId) {
if (hookId == 0) return;
HooksToUnregister<H>::hooks.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooks(Args&&... args) {
for (auto& hookId : HooksToUnregister<H>::hooks) {
RegisteredGameHooks<H>::functions.erase(hookId);
@ -190,57 +531,167 @@ public:
}
}
DEFINE_HOOK(OnLoadGame, void(int32_t fileNum));
DEFINE_HOOK(OnExitGame, void(int32_t fileNum));
DEFINE_HOOK(OnGameFrameUpdate, void());
DEFINE_HOOK(OnItemReceive, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum));
DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum));
DEFINE_HOOK(OnSceneFlagSet, void(int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneFlagUnset, void(int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagSet, void(int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagUnset, void(int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneSpawnActors, void());
DEFINE_HOOK(OnPlayerUpdate, void());
DEFINE_HOOK(OnOcarinaSongAction, void());
DEFINE_HOOK(OnShopSlotChange, void(uint8_t cursorIndex, int16_t price));
DEFINE_HOOK(OnActorInit, void(void* actor));
DEFINE_HOOK(OnActorUpdate, void(void* actor));
DEFINE_HOOK(OnActorKill, void(void* actor));
DEFINE_HOOK(OnEnemyDefeat, void(void* actor));
DEFINE_HOOK(OnPlayerBonk, void());
DEFINE_HOOK(OnPlayDestroy, void());
DEFINE_HOOK(OnPlayDrawEnd, void());
// ID based Hooks
template <typename H> HOOK_ID RegisterGameHookForID(int32_t id, typename H::fn h) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForID[id].find(this->nextHookId) != RegisteredGameHooks<H>::functionsForID[id].end()) {
this->nextHookId++;
}
DEFINE_HOOK(OnSaveFile, void(int32_t fileNum));
DEFINE_HOOK(OnLoadFile, void(int32_t fileNum));
DEFINE_HOOK(OnDeleteFile, void(int32_t fileNum));
DEFINE_HOOK(OnDialogMessage, void());
DEFINE_HOOK(OnPresentTitleCard, void());
DEFINE_HOOK(OnInterfaceUpdate, void());
DEFINE_HOOK(OnKaleidoscopeUpdate, void(int16_t inDungeonScene));
DEFINE_HOOK(OnPresentFileSelect, void());
DEFINE_HOOK(OnUpdateFileSelectSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileSelectConfirmationSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileCopySelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileCopyConfirmationSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileEraseSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileAudioSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileTargetSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileLanguageSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileQuestSelection, void(uint8_t questIndex));
DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, void(uint8_t optionIndex, uint8_t optionValue));
DEFINE_HOOK(OnUpdateFileNameSelection, void(int16_t charCode));
DEFINE_HOOK(OnSetGameLanguage, void());
RegisteredGameHooks<H>::functionsForID[id][this->nextHookId] = h;
return this->nextHookId++;
}
template <typename H> void UnregisterGameHookForID(HOOK_ID hookId) {
if (hookId == 0) return;
HooksToUnregister<H>::hooksForID.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooksForID(int32_t id, Args&&... args) {
for (auto& hookId : HooksToUnregister<H>::hooksForID) {
for (auto it = RegisteredGameHooks<H>::functionsForID[id].begin(); it != RegisteredGameHooks<H>::functionsForID[id].end(); ) {
if (it->first == hookId) {
it = RegisteredGameHooks<H>::functionsForID[id].erase(it);
HooksToUnregister<H>::hooksForID.erase(std::remove(HooksToUnregister<H>::hooksForID.begin(), HooksToUnregister<H>::hooksForID.end(), hookId), HooksToUnregister<H>::hooksForID.end());
} else {
++it;
}
}
}
for (auto& hook : RegisteredGameHooks<H>::functionsForID[id]) {
hook.second(std::forward<Args>(args)...);
}
}
DEFINE_HOOK(OnFileDropped, void(std::string filePath));
DEFINE_HOOK(OnAssetAltChange, void());
DEFINE_HOOK(OnKaleidoUpdate, void());
// PTR based Hooks
template <typename H> HOOK_ID RegisterGameHookForPtr(uintptr_t ptr, typename H::fn h) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForPtr[ptr].find(this->nextHookId) != RegisteredGameHooks<H>::functionsForPtr[ptr].end()) {
this->nextHookId++;
}
RegisteredGameHooks<H>::functionsForPtr[ptr][this->nextHookId] = h;
return this->nextHookId++;
}
template <typename H> void UnregisterGameHookForPtr(HOOK_ID hookId) {
if (hookId == 0) return;
HooksToUnregister<H>::hooksForPtr.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooksForPtr(uintptr_t ptr, Args&&... args) {
for (auto& hookId : HooksToUnregister<H>::hooksForPtr) {
for (auto it = RegisteredGameHooks<H>::functionsForPtr[ptr].begin(); it != RegisteredGameHooks<H>::functionsForPtr[ptr].end(); ) {
if (it->first == hookId) {
it = RegisteredGameHooks<H>::functionsForPtr[ptr].erase(it);
HooksToUnregister<H>::hooksForPtr.erase(std::remove(HooksToUnregister<H>::hooksForPtr.begin(), HooksToUnregister<H>::hooksForPtr.end(), hookId), HooksToUnregister<H>::hooksForPtr.end());
} else {
++it;
}
}
}
for (auto& hook : RegisteredGameHooks<H>::functionsForPtr[ptr]) {
hook.second(std::forward<Args>(args)...);
}
}
// Filter based Hooks
template <typename H> HOOK_ID RegisterGameHookForFilter(typename H::filter f, typename H::fn h) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForFilter.find(this->nextHookId) != RegisteredGameHooks<H>::functionsForFilter.end()) {
this->nextHookId++;
}
RegisteredGameHooks<H>::functionsForFilter[this->nextHookId] = std::make_pair(f, h);
return this->nextHookId++;
}
template <typename H> void UnregisterGameHookForFilter(HOOK_ID hookId) {
if (hookId == 0) return;
HooksToUnregister<H>::hooksForFilter.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooksForFilter(Args&&... args) {
for (auto& hookId : HooksToUnregister<H>::hooksForFilter) {
RegisteredGameHooks<H>::functionsForFilter.erase(hookId);
}
HooksToUnregister<H>::hooksForFilter.clear();
for (auto& hook : RegisteredGameHooks<H>::functionsForFilter) {
if (hook.second.first(std::forward<Args>(args)...)) {
hook.second.second(std::forward<Args>(args)...);
}
}
}
class HookFilter {
public:
static auto ActorNotPlayer(Actor* actor) {
return actor->id != ACTOR_PLAYER;
}
// For use with Should hooks
static auto SActorNotPlayer(Actor* actor, bool* result) {
return actor->id != ACTOR_PLAYER;
}
static auto ActorMatchIdAndParams(int16_t id, int16_t params) {
return [id, params](Actor* actor) {
return actor->id == id && actor->params == params;
};
}
// For use with Should hooks
static auto SActorMatchIdAndParams(int16_t id, int16_t params) {
return [id, params](Actor* actor, bool* result) {
return actor->id == id && actor->params == params;
};
}
};
DEFINE_HOOK(OnLoadGame, (int32_t fileNum));
DEFINE_HOOK(OnExitGame, (int32_t fileNum));
DEFINE_HOOK(OnGameFrameUpdate, ());
DEFINE_HOOK(OnItemReceive, (GetItemEntry itemEntry));
DEFINE_HOOK(OnSaleEnd, (GetItemEntry itemEntry));
DEFINE_HOOK(OnTransitionEnd, (int16_t sceneNum));
DEFINE_HOOK(OnSceneInit, (int16_t sceneNum));
DEFINE_HOOK(OnSceneFlagSet, (int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneFlagUnset, (int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagSet, (int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagUnset, (int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneSpawnActors, ());
DEFINE_HOOK(OnPlayerUpdate, ());
DEFINE_HOOK(OnOcarinaSongAction, ());
DEFINE_HOOK(OnShopSlotChange, (uint8_t cursorIndex, int16_t price));
DEFINE_HOOK(OnActorInit, (void* actor));
DEFINE_HOOK(OnActorUpdate, (void* actor));
DEFINE_HOOK(OnActorKill, (void* actor));
DEFINE_HOOK(OnEnemyDefeat, (void* actor));
DEFINE_HOOK(OnPlayerBonk, ());
DEFINE_HOOK(OnPlayDestroy, ());
DEFINE_HOOK(OnPlayDrawEnd, ());
DEFINE_HOOK(OnVanillaBehavior, (GIVanillaBehavior flag, bool* result, void* opt));
DEFINE_HOOK(OnSaveFile, (int32_t fileNum));
DEFINE_HOOK(OnLoadFile, (int32_t fileNum));
DEFINE_HOOK(OnDeleteFile, (int32_t fileNum));
DEFINE_HOOK(OnDialogMessage, ());
DEFINE_HOOK(OnPresentTitleCard, ());
DEFINE_HOOK(OnInterfaceUpdate, ());
DEFINE_HOOK(OnKaleidoscopeUpdate, (int16_t inDungeonScene));
DEFINE_HOOK(OnPresentFileSelect, ());
DEFINE_HOOK(OnUpdateFileSelectSelection, (uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileSelectConfirmationSelection, (uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileCopySelection, (uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileCopyConfirmationSelection, (uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileEraseSelection, (uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, (uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileAudioSelection, (uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileTargetSelection, (uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileLanguageSelection, (uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileQuestSelection, (uint8_t questIndex));
DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, (uint8_t optionIndex, uint8_t optionValue));
DEFINE_HOOK(OnUpdateFileNameSelection, (int16_t charCode));
DEFINE_HOOK(OnSetGameLanguage, ());
DEFINE_HOOK(OnFileDropped, (std::string filePath));
DEFINE_HOOK(OnAssetAltChange, ());
DEFINE_HOOK(OnKaleidoUpdate, ());
// Helpers
static bool IsSaveLoaded(bool allowDbgSave = false);

View File

@ -16,34 +16,44 @@ void GameInteractor_ExecuteOnGameFrameUpdate() {
void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnItemReceive>(itemEntry);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnItemReceive>(itemEntry);
}
void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaleEnd>(itemEntry);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnSaleEnd>(itemEntry);
}
void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnTransitionEnd>(sceneNum);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnTransitionEnd>(sceneNum, sceneNum);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnTransitionEnd>(sceneNum);
}
void GameInteractor_ExecuteOnSceneInitHooks(int16_t sceneNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneInit>(sceneNum);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnSceneInit>(sceneNum, sceneNum);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnSceneInit>(sceneNum);
}
void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneFlagSet>(sceneNum, flagType, flag);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnSceneFlagSet>(sceneNum, flagType, flag);
}
void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneFlagUnset>(sceneNum, flagType, flag);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnSceneFlagUnset>(sceneNum, flagType, flag);
}
void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnFlagSet>(flagType, flag);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnFlagSet>(flagType, flag);
}
void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnFlagUnset>(flagType, flag);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnFlagUnset>(flagType, flag);
}
void GameInteractor_ExecuteOnSceneSpawnActors() {
@ -64,18 +74,30 @@ void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t pr
void GameInteractor_ExecuteOnActorInit(void* actor) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorInit>(actor);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorInit>(((Actor*)actor)->id, actor);
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnActorInit>((uintptr_t)actor, actor);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorInit>(actor);
}
void GameInteractor_ExecuteOnActorUpdate(void* actor) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorUpdate>(actor);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorUpdate>(((Actor*)actor)->id, actor);
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnActorUpdate>((uintptr_t)actor, actor);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorUpdate>(actor);
}
void GameInteractor_ExecuteOnActorKill(void* actor) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnActorKill>(actor);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnActorKill>(((Actor*)actor)->id, actor);
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnActorKill>((uintptr_t)actor, actor);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnActorKill>(actor);
}
void GameInteractor_ExecuteOnEnemyDefeat(void* actor) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnEnemyDefeat>(actor);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnEnemyDefeat>(((Actor*)actor)->id, actor);
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnEnemyDefeat>((uintptr_t)actor, actor);
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnEnemyDefeat>(actor);
}
void GameInteractor_ExecuteOnPlayerBonk() {
@ -90,6 +112,16 @@ void GameInteractor_ExecuteOnPlayDrawEnd() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnPlayDrawEnd>();
}
bool GameInteractor_Should(GIVanillaBehavior flag, bool result, void* opt) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnVanillaBehavior>(flag, &result, opt);
GameInteractor::Instance->ExecuteHooksForID<GameInteractor::OnVanillaBehavior>(flag, flag, &result, opt);
if (opt != nullptr) {
GameInteractor::Instance->ExecuteHooksForPtr<GameInteractor::OnVanillaBehavior>((uintptr_t)opt, flag, &result, opt);
}
GameInteractor::Instance->ExecuteHooksForFilter<GameInteractor::OnVanillaBehavior>(flag, &result, opt);
return result;
}
// MARK: - Save Files
void GameInteractor_ExecuteOnSaveFile(int32_t fileNum) {

View File

@ -27,6 +27,7 @@ void GameInteractor_ExecuteOnOcarinaSongAction();
void GameInteractor_ExecuteOnShopSlotChangeHooks(uint8_t cursorIndex, int16_t price);
void GameInteractor_ExecuteOnPlayDestroy();
void GameInteractor_ExecuteOnPlayDrawEnd();
bool GameInteractor_Should(GIVanillaBehavior flag, bool result, void* opt);
// MARK: - Save Files
void GameInteractor_ExecuteOnSaveFile(int32_t fileNum);

View File

@ -353,19 +353,19 @@ void GameInteractor::RawAction::SetTimeOfDay(uint32_t time) {
}
void GameInteractor::RawAction::SetCollisionViewer(bool active) {
CVarSetInteger("gColViewerEnabled", active);
CVarSetInteger("gColViewerDecal", active);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Enabled"), active);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Decal"), active);
if (active) {
CVarSetInteger("gColViewerScene", COLVIEW_TRANSPARENT);
CVarSetInteger("gColViewerBgActors", COLVIEW_TRANSPARENT);
CVarSetInteger("gColViewerColCheck", COLVIEW_TRANSPARENT);
CVarSetInteger("gColViewerWaterbox", COLVIEW_TRANSPARENT);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_TRANSPARENT);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_TRANSPARENT);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_TRANSPARENT);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_TRANSPARENT);
} else {
CVarSetInteger("gColViewerScene", COLVIEW_DISABLED);
CVarSetInteger("gColViewerBgActors", COLVIEW_DISABLED);
CVarSetInteger("gColViewerColCheck", COLVIEW_DISABLED);
CVarSetInteger("gColViewerWaterbox", COLVIEW_DISABLED);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Scene"), COLVIEW_DISABLED);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.BGActors"), COLVIEW_DISABLED);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.ColCheck"), COLVIEW_DISABLED);
CVarSetInteger(CVAR_DEVELOPER_TOOLS("ColViewer.Waterbox"), COLVIEW_DISABLED);
}
}
@ -428,55 +428,55 @@ void GameInteractor::RawAction::SetCosmeticsColor(uint8_t cosmeticCategory, uint
switch (cosmeticCategory) {
case GI_COSMETICS_TUNICS:
CVarSetColor("gCosmetics.Link_KokiriTunic.Value", newColor);
CVarSetInteger("gCosmetics.Link_KokiriTunic.Changed", 1);
CVarSetColor("gCosmetics.Link_GoronTunic.Value", newColor);
CVarSetInteger("gCosmetics.Link_GoronTunic.Changed", 1);
CVarSetColor("gCosmetics.Link_ZoraTunic.Value", newColor);
CVarSetInteger("gCosmetics.Link_ZoraTunic.Changed", 1);
CVarSetColor(CVAR_COSMETIC("Link.KokiriTunic.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.KokiriTunic.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Link.GoronTunic.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.GoronTunic.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Link.ZoraTunic.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.ZoraTunic.Changed"), 1);
break;
case GI_COSMETICS_NAVI:
CVarSetColor("gCosmetics.Navi_EnemyPrimary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_EnemyPrimary.Changed", 1);
CVarSetColor("gCosmetics.Navi_EnemySecondary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_EnemySecondary.Changed", 1);
CVarSetColor("gCosmetics.Navi_IdlePrimary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_IdlePrimary.Changed", 1);
CVarSetColor("gCosmetics.Navi_IdleSecondary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_IdleSecondary.Changed", 1);
CVarSetColor("gCosmetics.Navi_NPCPrimary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_NPCPrimary.Changed", 1);
CVarSetColor("gCosmetics.Navi_NPCSecondary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_NPCSecondary.Changed", 1);
CVarSetColor("gCosmetics.Navi_PropsPrimary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_PropsPrimary.Changed", 1);
CVarSetColor("gCosmetics.Navi_PropsSecondary.Value", newColor);
CVarSetInteger("gCosmetics.Navi_PropsSecondary.Changed", 1);
CVarSetColor(CVAR_COSMETIC("Navi.EnemyPrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.EnemyPrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.EnemySecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.EnemySecondary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.IdlePrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.IdlePrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.IdleSecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.IdleSecondary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.NPCPrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.NPCPrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.NPCSecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.NPCSecondary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.PropsPrimary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.PropsPrimary.Changed"), 1);
CVarSetColor(CVAR_COSMETIC("Navi.PropsSecondary.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Navi.PropsSecondary.Changed"), 1);
break;
case GI_COSMETICS_HAIR:
CVarSetColor("gCosmetics.Link_Hair.Value", newColor);
CVarSetInteger("gCosmetics.Link_Hair.Changed", 1);
CVarSetColor(CVAR_COSMETIC("Link.Hair.Value"), newColor);
CVarSetInteger(CVAR_COSMETIC("Link.Hair.Changed"), 1);
break;
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
ApplyOrResetCustomGfxPatches();
}
void GameInteractor::RawAction::RandomizeCosmeticsColors(bool excludeBiddingWarColors) {
const char* cvarsToLock[12] = {
"gCosmetics.Link_KokiriTunic.Locked",
"gCosmetics.Link_GoronTunic.Locked",
"gCosmetics.Link_ZoraTunic.Locked",
"gCosmetics.Navi_EnemyPrimary.Locked",
"gCosmetics.Navi_EnemySecondary.Locked",
"gCosmetics.Navi_IdlePrimary.Locked",
"gCosmetics.Navi_IdleSecondary.Locked",
"gCosmetics.Navi_NPCPrimary.Locked",
"gCosmetics.Navi_NPCSecondary.Locked",
"gCosmetics.Navi_PropsPrimary.Locked",
"gCosmetics.Navi_PropsSecondary.Locked",
"gCosmetics.Link_Hair.Locked"
CVAR_COSMETIC("Link.KokiriTunic.Locked"),
CVAR_COSMETIC("Link.GoronTunic.Locked"),
CVAR_COSMETIC("Link.ZoraTunic.Locked"),
CVAR_COSMETIC("Navi.EnemyPrimary.Locked"),
CVAR_COSMETIC("Navi.EnemySecondary.Locked"),
CVAR_COSMETIC("Navi.IdlePrimary.Locked"),
CVAR_COSMETIC("Navi.IdleSecondary.Locked"),
CVAR_COSMETIC("Navi.NPCPrimary.Locked"),
CVAR_COSMETIC("Navi.NPCSecondary.Locked"),
CVAR_COSMETIC("Navi.PropsPrimary.Locked"),
CVAR_COSMETIC("Navi.PropsSecondary.Locked"),
CVAR_COSMETIC("Link.Hair.Locked")
};
if (excludeBiddingWarColors) {

View File

@ -2,12 +2,13 @@
#include "GameInteractor.h"
#include <spdlog/spdlog.h>
#include <ImGui/imgui.h>
#include <ImGui/imgui_internal.h>
#include <imgui.h>
#include <imgui_internal.h>
#include <unordered_map>
#include <tuple>
#include <type_traits>
#include <libultraship/libultraship.h>
#include "soh/OTRGlobals.h"
// MARK: - Remote
@ -16,7 +17,7 @@ void GameInteractor::EnableRemoteInteractor() {
return;
}
if (SDLNet_ResolveHost(&remoteIP, CVarGetString("gRemote.IP", "127.0.0.1"), CVarGetInteger("gRemote.Port", 43384)) == -1) {
if (SDLNet_ResolveHost(&remoteIP, CVarGetString(CVAR_REMOTE("IP"), "127.0.0.1"), CVarGetInteger(CVAR_REMOTE("Port"), 43384)) == -1) {
SPDLOG_ERROR("[GameInteractor] SDLNet_ResolveHost: {}", SDLNet_GetError());
}

View File

@ -66,7 +66,7 @@ void GameInteractorSail::HandleRemoteJson(nlohmann::json payload) {
}
std::string command = payload["command"].get<std::string>();
std::reinterpret_pointer_cast<LUS::ConsoleWindow>(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch(command);
std::reinterpret_pointer_cast<Ship::ConsoleWindow>(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch(command);
responsePayload["status"] = "success";
GameInteractor::Instance->TransmitJsonToRemote(responsePayload);
return;
@ -88,7 +88,7 @@ void GameInteractorSail::HandleRemoteJson(nlohmann::json payload) {
}
std::string command = payload["effect"]["command"].get<std::string>();
std::reinterpret_pointer_cast<LUS::ConsoleWindow>(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch(command);
std::reinterpret_pointer_cast<Ship::ConsoleWindow>(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch(command);
responsePayload["status"] = "success";
GameInteractor::Instance->TransmitJsonToRemote(responsePayload);
return;

View File

@ -14,6 +14,7 @@ extern "C" {
#include <libultraship/bridge.h>
#include <libultraship/libultraship.h>
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/OTRGlobals.h"
extern "C" {
#include <z64.h>
@ -387,7 +388,7 @@ void GameplayStatsRow(const char* label, const std::string& value, ImVec4 color
}
bool compareTimestampInfoByTime(const TimestampInfo& a, const TimestampInfo& b) {
return CVarGetInteger("gGameplayStats.TimestampsReverse", 0) ? a.time > b.time : a.time < b.time;
return CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ReverseTimestamps"), 0) ? a.time > b.time : a.time < b.time;
}
const char* ResolveSceneID(int sceneID, int roomID){
@ -442,13 +443,13 @@ void DrawGameplayStatsHeader() {
} else {
GameplayStatsRow("Total Game Time:", formatTimestampGameplayStat(GAMEPLAYSTAT_TOTAL_TIME), gSaveContext.sohStats.gameComplete ? COLOR_GREEN : COLOR_WHITE);
}
if (CVarGetInteger("gGameplayStats.ShowAdditionalTimers", 0)) { // !Only display total game time
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ShowAdditionalTimers"), 0)) { // !Only display total game time
GameplayStatsRow("Gameplay Time:", formatTimestampGameplayStat(gSaveContext.sohStats.playTimer / 2), COLOR_GREY);
GameplayStatsRow("Pause Menu Time:", formatTimestampGameplayStat(gSaveContext.sohStats.pauseTimer / 3), COLOR_GREY);
GameplayStatsRow("Time in scene:", formatTimestampGameplayStat(gSaveContext.sohStats.sceneTimer / 2), COLOR_LIGHT_BLUE);
GameplayStatsRow("Time in room:", formatTimestampGameplayStat(gSaveContext.sohStats.roomTimer / 2), COLOR_LIGHT_BLUE);
}
if (gPlayState != NULL && CVarGetInteger("gGameplayStats.ShowDebugInfo", 0)) { // && display debug info
if (gPlayState != NULL && CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.ShowDebugInfo"), 0)) { // && display debug info
GameplayStatsRow("play->sceneNum:", formatHexGameplayStat(gPlayState->sceneNum), COLOR_YELLOW);
GameplayStatsRow("gSaveContext.entranceIndex:", formatHexGameplayStat(gSaveContext.entranceIndex), COLOR_YELLOW);
GameplayStatsRow("gSaveContext.cutsceneIndex:", formatHexOnlyGameplayStat(gSaveContext.cutsceneIndex), COLOR_YELLOW);
@ -538,7 +539,7 @@ void DrawGameplayStatsCountsTab() {
GameplayStatsRow("Sword Swings:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_SWORD_SWINGS]));
GameplayStatsRow("Steps Taken:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_STEPS]));
// If using MM Bunny Hood enhancement, show how long it's been equipped (not counting pause time)
if (CVarGetInteger("gMMBunnyHood", BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) {
if (CVarGetInteger(CVAR_ENHANCEMENT("MMBunnyHood"), BUNNY_HOOD_VANILLA) != BUNNY_HOOD_VANILLA || gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] > 0) {
GameplayStatsRow("Bunny Hood Time:", formatTimestampGameplayStat(gSaveContext.sohStats.count[COUNT_TIME_BUNNY_HOOD] / 2));
}
GameplayStatsRow("Rolls:", formatIntGameplayStat(gSaveContext.sohStats.count[COUNT_ROLLS]));
@ -566,13 +567,13 @@ void DrawGameplayStatsBreakdownTab() {
for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) {
std::string sceneName = ResolveSceneID(gSaveContext.sohStats.sceneTimestamps[i].scene, gSaveContext.sohStats.sceneTimestamps[i].room);
std::string name;
if (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) && gSaveContext.sohStats.sceneTimestamps[i].scene != SCENE_GROTTOS) {
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.sohStats.sceneTimestamps[i].scene != SCENE_GROTTOS) {
name = fmt::format("{:s} Room {:d}", sceneName, gSaveContext.sohStats.sceneTimestamps[i].room);
} else {
name = sceneName;
}
strcpy(sceneTimestampDisplay[i].name, name.c_str());
sceneTimestampDisplay[i].time = CVarGetInteger("gGameplayStats.RoomBreakdown", 0) ?
sceneTimestampDisplay[i].time = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) ?
gSaveContext.sohStats.sceneTimestamps[i].roomTime : gSaveContext.sohStats.sceneTimestamps[i].sceneTime;
sceneTimestampDisplay[i].color = COLOR_GREY;
sceneTimestampDisplay[i].isRoom = gSaveContext.sohStats.sceneTimestamps[i].isRoom;
@ -583,13 +584,13 @@ void DrawGameplayStatsBreakdownTab() {
ImGui::TableSetupColumn("stat", ImGuiTableColumnFlags_WidthStretch);
for (int i = 0; i < gSaveContext.sohStats.tsIdx; i++) {
TimestampInfo tsInfo = sceneTimestampDisplay[i];
bool canShow = !tsInfo.isRoom || CVarGetInteger("gGameplayStats.RoomBreakdown", 0);
bool canShow = !tsInfo.isRoom || CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0);
if (tsInfo.time > 0 && strnlen(tsInfo.name, 40) > 1 && canShow) {
GameplayStatsRow(tsInfo.name, formatTimestampGameplayStat(tsInfo.time), tsInfo.color);
}
}
std::string toPass;
if (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) && gSaveContext.sohStats.sceneNum != SCENE_GROTTOS) {
if (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) && gSaveContext.sohStats.sceneNum != SCENE_GROTTOS) {
toPass = fmt::format("{:s} Room {:d}", ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum), gSaveContext.sohStats.roomNum);
} else {
toPass = ResolveSceneID(gSaveContext.sohStats.sceneNum, gSaveContext.sohStats.roomNum);
@ -600,21 +601,21 @@ void DrawGameplayStatsBreakdownTab() {
}
void DrawGameplayStatsOptionsTab() {
UIWidgets::PaddedEnhancementCheckbox("Show in-game total timer", "gGameplayStats.ShowIngameTimer", true, false);
UIWidgets::PaddedEnhancementCheckbox("Show in-game total timer", CVAR_ENHANCEMENT("GameplayStats.ShowIngameTimer"), true, false);
UIWidgets::InsertHelpHoverText("Keep track of the timer as an in-game HUD element. The position of the timer can be changed in the Cosmetics Editor.");
UIWidgets::PaddedEnhancementCheckbox("Show latest timestamps on top", "gGameplayStats.TimestampsReverse", true, false);
UIWidgets::PaddedEnhancementCheckbox("Room Breakdown", "gGameplayStats.RoomBreakdown", true, false);
UIWidgets::PaddedEnhancementCheckbox("Show latest timestamps on top", CVAR_ENHANCEMENT("GameplayStats.ReverseTimestamps"), true, false);
UIWidgets::PaddedEnhancementCheckbox("Room Breakdown", CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), true, false);
ImGui::SameLine();
UIWidgets::InsertHelpHoverText("Allows a more in-depth perspective of time spent in a certain map.");
UIWidgets::PaddedEnhancementCheckbox("RTA Timing on new files", "gGameplayStats.RTATiming", true, false);
UIWidgets::PaddedEnhancementCheckbox("RTA Timing on new files", CVAR_ENHANCEMENT("GameplayStats.RTATiming"), true, false);
ImGui::SameLine();
UIWidgets::InsertHelpHoverText(
"Timestamps are relative to starting timestamp rather than in game time, usually necessary for races/speedruns.\n\n"
"Starting timestamp is on first non-c-up input after intro cutscene.\n\n"
"NOTE: THIS NEEDS TO BE SET BEFORE CREATING A FILE TO TAKE EFFECT"
);
UIWidgets::PaddedEnhancementCheckbox("Show additional detail timers", "gGameplayStats.ShowAdditionalTimers", true, false);
UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", "gGameplayStats.ShowDebugInfo");
UIWidgets::PaddedEnhancementCheckbox("Show additional detail timers", CVAR_ENHANCEMENT("GameplayStats.ShowAdditionalTimers"), true, false);
UIWidgets::PaddedEnhancementCheckbox("Show Debug Info", CVAR_ENHANCEMENT("GameplayStats.ShowDebugInfo"));
}
void GameplayStatsWindow::DrawElement() {
@ -656,7 +657,7 @@ void InitStats(bool isDebug) {
for (int dungeon = 0; dungeon < ARRAY_COUNT(gSaveContext.sohStats.dungeonKeys); dungeon++) {
gSaveContext.sohStats.dungeonKeys[dungeon] = isDebug ? 8 : 0;
}
gSaveContext.sohStats.rtaTiming = CVarGetInteger("gGameplayStats.RTATiming", 0);
gSaveContext.sohStats.rtaTiming = CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RTATiming"), 0);
gSaveContext.sohStats.fileCreatedAt = 0;
gSaveContext.sohStats.playTimer = 0;
gSaveContext.sohStats.pauseTimer = 0;

View File

@ -12,7 +12,7 @@
(!gSaveContext.sohStats.fileCreatedAt ? 0 : ((GetUnixTimestamp() - gSaveContext.sohStats.fileCreatedAt) / 100)) :\
(gSaveContext.sohStats.itemTimestamp[TIMESTAMP_DEFEAT_GANON])) :\
(gSaveContext.sohStats.playTimer / 2 + gSaveContext.sohStats.pauseTimer / 3))
#define CURRENT_MODE_TIMER (CVarGetInteger("gGameplayStats.RoomBreakdown", 0) ?\
#define CURRENT_MODE_TIMER (CVarGetInteger(CVAR_ENHANCEMENT("GameplayStats.RoomBreakdown"), 0) ?\
gSaveContext.sohStats.roomTimer :\
gSaveContext.sohStats.sceneTimer)

View File

@ -1,7 +1,7 @@
#include <libultraship/libultraship.h>
#include "gameplaystats.h"
class GameplayStatsWindow : public LUS::GuiWindow {
class GameplayStatsWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;

View File

@ -10,6 +10,9 @@
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
#include <soh/Enhancements/item-tables/ItemTableManager.h>
#include "soh/Enhancements/nametag.h"
#include "soh/Enhancements/timesaver_hook_handlers.h"
#include "soh/Enhancements/cheat_hook_handlers.h"
#include "soh/Enhancements/randomizer/hook_handlers.h"
#include "objects/object_gi_compass/object_gi_compass.h"
#include "src/overlays/actors/ovl_En_Bb/z_en_bb.h"
@ -69,7 +72,7 @@ void ReloadSceneTogglingLinkAge() {
void RegisterInfiniteMoney() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gInfiniteMoney", 0) != 0 && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_WALLET))) {
if (CVarGetInteger(CVAR_CHEAT("InfiniteMoney"), 0) != 0 && (!IS_RANDO || Flags_GetRandomizerInf(RAND_INF_HAS_WALLET))) {
if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) {
gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET);
}
@ -80,7 +83,7 @@ void RegisterInfiniteMoney() {
void RegisterInfiniteHealth() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gInfiniteHealth", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("InfiniteHealth"), 0) != 0) {
if (gSaveContext.health < gSaveContext.healthCapacity) {
gSaveContext.health = gSaveContext.healthCapacity;
}
@ -91,7 +94,7 @@ void RegisterInfiniteHealth() {
void RegisterInfiniteAmmo() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gInfiniteAmmo", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("InfiniteAmmo"), 0) != 0) {
// Deku Sticks
if (AMMO(ITEM_STICK) < CUR_CAPACITY(UPG_STICKS)) {
AMMO(ITEM_STICK) = CUR_CAPACITY(UPG_STICKS);
@ -128,7 +131,7 @@ void RegisterInfiniteAmmo() {
void RegisterInfiniteMagic() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gInfiniteMagic", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("InfiniteMagic"), 0) != 0) {
if (gSaveContext.isMagicAcquired && gSaveContext.magic != (gSaveContext.isDoubleMagicAcquired + 1) * 0x30) {
gSaveContext.magic = (gSaveContext.isDoubleMagicAcquired + 1) * 0x30;
}
@ -139,7 +142,7 @@ void RegisterInfiniteMagic() {
void RegisterInfiniteNayrusLove() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gInfiniteNayru", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("InfiniteNayru"), 0) != 0) {
gSaveContext.nayrusLoveTimer = 0x44B;
}
});
@ -149,7 +152,7 @@ void RegisterMoonJumpOnL() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gMoonJumpOnL", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("MoonJumpOnL"), 0) != 0) {
Player* player = GET_PLAYER(gPlayState);
if (CHECK_BTN_ANY(gPlayState->state.input[0].cur.button, BTN_L)) {
@ -164,7 +167,7 @@ void RegisterInfiniteISG() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gEzISG", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("EasyISG"), 0) != 0) {
Player* player = GET_PLAYER(gPlayState);
player->meleeWeaponState = 1;
}
@ -176,7 +179,7 @@ void RegisterEzQPA() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gEzQPA", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("EasyQPA"), 0) != 0) {
Player* player = GET_PLAYER(gPlayState);
player->meleeWeaponQuads[0].info.toucher.dmgFlags = 0x16171617;
player->meleeWeaponQuads[1].info.toucher.dmgFlags = 0x16171617;
@ -188,7 +191,7 @@ void RegisterUnrestrictedItems() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!GameInteractor::IsSaveLoaded(true)) return;
if (CVarGetInteger("gNoRestrictItems", 0) != 0) {
if (CVarGetInteger(CVAR_CHEAT("NoRestrictItems"), 0) != 0) {
u8 sunsBackup = gPlayState->interfaceCtx.restrictions.sunsSong;
memset(&gPlayState->interfaceCtx.restrictions, 0, sizeof(gPlayState->interfaceCtx.restrictions));
gPlayState->interfaceCtx.restrictions.sunsSong = sunsBackup;
@ -198,15 +201,15 @@ void RegisterUnrestrictedItems() {
void RegisterFreezeTime() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (CVarGetInteger("gFreezeTime", 0) != 0) {
if (CVarGetInteger("gPrevTime", -1) == -1) {
CVarSetInteger("gPrevTime", gSaveContext.dayTime);
if (CVarGetInteger(CVAR_CHEAT("FreezeTime"), 0) != 0) {
if (CVarGetInteger(CVAR_GENERAL("PrevTime"), -1) == -1) {
CVarSetInteger(CVAR_GENERAL("PrevTime"), gSaveContext.dayTime);
}
int32_t prevTime = CVarGetInteger("gPrevTime", gSaveContext.dayTime);
int32_t prevTime = CVarGetInteger(CVAR_GENERAL("PrevTime"), gSaveContext.dayTime);
gSaveContext.dayTime = prevTime;
} else {
CVarClear("gPrevTime");
CVarClear(CVAR_GENERAL("PrevTime"));
}
});
}
@ -217,7 +220,7 @@ void RegisterSwitchAge() {
static bool warped = false;
if (!GameInteractor::IsSaveLoaded(true)) {
CVarClear("gSwitchAge");
CVarClear(CVAR_GENERAL("SwitchAge"));
warped = false;
return;
}
@ -227,7 +230,7 @@ void RegisterSwitchAge() {
static RoomContext* roomCtx;
static s32 roomNum;
if (CVarGetInteger("gSwitchAge", 0) && !warped) {
if (CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) && !warped) {
playerPos = GET_PLAYER(gPlayState)->actor.world.pos;
playerYaw = GET_PLAYER(gPlayState)->actor.shape.rot.y;
roomCtx = &gPlayState->roomCtx;
@ -246,7 +249,7 @@ void RegisterSwitchAge() {
func_80097534(gPlayState, roomCtx); // load map for new room (unloading the previous room)
}
warped = false;
CVarClear("gSwitchAge");
CVarClear(CVAR_GENERAL("SwitchAge"));
}
});
}
@ -256,7 +259,7 @@ void RegisterOcarinaTimeTravel() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnOcarinaSongAction>([]() {
if (!GameInteractor::IsSaveLoaded(true)) {
CVarClear("gTimeTravel");
CVarClear(CVAR_ENHANCEMENT("TimeTravel"));
return;
}
@ -270,16 +273,16 @@ void RegisterOcarinaTimeTravel() {
uint8_t hasOcarinaOfTime = (INV_CONTENT(ITEM_OCARINA_TIME) == ITEM_OCARINA_TIME);
// If TimeTravel + Player have the Ocarina of Time + Have Master Sword + is in proper range
// TODO: Once Swordless Adult is fixed: Remove the Master Sword check
if (((CVarGetInteger("gTimeTravel", 0) == 1 && hasOcarinaOfTime) || CVarGetInteger("gTimeTravel", 0) == 2) && hasMasterSword &&
if (((CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 1 && hasOcarinaOfTime) || CVarGetInteger(CVAR_ENHANCEMENT("TimeTravel"), 0) == 2) && hasMasterSword &&
gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock &&
!nearbyOcarinaSpot && !nearbyFrogs) {
if (IS_RANDO) {
CVarSetInteger("gSwitchTimeline", 1);
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1);
} else if (!IS_RANDO && !nearbyDoorOfTime) {
// This check is made for when Link is learning the Song Of Time in a vanilla save file that load a
// Temple of Time scene where the only object present is the Door of Time
CVarSetInteger("gSwitchTimeline", 1);
CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 1);
}
ReloadSceneTogglingLinkAge();
}
@ -292,13 +295,13 @@ void AutoSave(GetItemEntry itemEntry) {
// Don't autosave immediately after buying items from shops to prevent getting them for free!
// Don't autosave in the Chamber of Sages since resuming from that map breaks the game
// Don't autosave during the Ganon fight when picking up the Master Sword
if ((CVarGetInteger("gAutosave", AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) &&
if ((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) != AUTOSAVE_OFF) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) &&
(gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0) && (gPlayState->sceneNum != SCENE_GANON_BOSS) && (gPlayState->sceneNum != SCENE_CHAMBER_OF_THE_SAGES)) {
if (((CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS) || (CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_ALL_ITEMS)) && (item != ITEM_NONE)) {
if (((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS) || (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_ALL_ITEMS)) && (item != ITEM_NONE)) {
// Autosave for all items
performSave = true;
} else if (((CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS) || (CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_MAJOR_ITEMS)) && (item != ITEM_NONE)) {
} else if (((CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS) || (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_MAJOR_ITEMS)) && (item != ITEM_NONE)) {
// Autosave for major items
if (itemEntry.modIndex == 0) {
switch (item) {
@ -338,7 +341,7 @@ void AutoSave(GetItemEntry itemEntry) {
case ITEM_BOMBCHU:
case ITEM_BOMBCHUS_5:
case ITEM_BOMBCHUS_20:
if (!CVarGetInteger("gBombchuDrops", 0)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("BombchuDrops"), 0)) {
performSave = true;
}
break;
@ -349,9 +352,9 @@ void AutoSave(GetItemEntry itemEntry) {
} else if (itemEntry.modIndex == 1 && item != RG_ICE_TRAP) {
performSave = true;
}
} else if (CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS ||
CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS ||
CVarGetInteger("gAutosave", AUTOSAVE_OFF) == AUTOSAVE_LOCATION) {
} else if (CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_MAJOR_ITEMS ||
CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION_AND_ALL_ITEMS ||
CVarGetInteger(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_OFF) == AUTOSAVE_LOCATION) {
performSave = true;
}
if (performSave) {
@ -369,13 +372,13 @@ void RegisterAutoSave() {
void RegisterRupeeDash() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
if (!CVarGetInteger("gRupeeDash", 0)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("RupeeDash"), 0)) {
return;
}
// Initialize Timer
static uint16_t rupeeDashTimer = 0;
uint16_t rdmTime = CVarGetInteger("gDashInterval", 5) * 20;
uint16_t rdmTime = CVarGetInteger(CVAR_ENHANCEMENT("RupeeDashInterval"), 5) * 20;
// Did time change by DashInterval?
if (rupeeDashTimer >= rdmTime) {
@ -397,7 +400,7 @@ void RegisterShadowTag() {
static uint16_t delayTimer = 60;
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
if (!CVarGetInteger("gShadowTag", 0)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("ShadowTag"), 0)) {
return;
}
if (gPlayState->sceneNum == SCENE_FOREST_TEMPLE && // Forest Temple Scene
@ -428,7 +431,7 @@ static bool hasAffectedHealth = false;
void UpdatePermanentHeartLossState() {
if (!GameInteractor::IsSaveLoaded()) return;
if (!CVarGetInteger("gPermanentHeartLoss", 0) && hasAffectedHealth) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) && hasAffectedHealth) {
uint8_t heartContainers = gSaveContext.sohStats.heartContainers; // each worth 16 health
uint8_t heartPieces = gSaveContext.sohStats.heartPieces; // each worth 4 health, but only in groups of 4
uint8_t startingHealth = 16 * (IS_RANDO ? (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_HEARTS) + 1) : 3);
@ -448,7 +451,7 @@ void RegisterPermanentHeartLoss() {
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
if (!CVarGetInteger("gPermanentHeartLoss", 0) || !GameInteractor::IsSaveLoaded()) return;
if (!CVarGetInteger(CVAR_ENHANCEMENT("PermanentHeartLoss"), 0) || !GameInteractor::IsSaveLoaded()) return;
if (gSaveContext.healthCapacity > 16 && gSaveContext.healthCapacity - gSaveContext.health >= 16) {
gSaveContext.healthCapacity -= 16;
@ -460,12 +463,12 @@ void RegisterPermanentHeartLoss() {
void RegisterDeleteFileOnDeath() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
if (!CVarGetInteger("gDeleteFileOnDeath", 0) || !GameInteractor::IsSaveLoaded() || &gPlayState->gameOverCtx == NULL || &gPlayState->pauseCtx == NULL) return;
if (!CVarGetInteger(CVAR_ENHANCEMENT("DeleteFileOnDeath"), 0) || !GameInteractor::IsSaveLoaded() || &gPlayState->gameOverCtx == NULL || &gPlayState->pauseCtx == NULL) return;
if (gPlayState->gameOverCtx.state == GAMEOVER_DEATH_MENU && gPlayState->pauseCtx.state == 9) {
SaveManager::Instance->DeleteZeldaFile(gSaveContext.fileNum);
hasAffectedHealth = false;
std::reinterpret_pointer_cast<LUS::ConsoleWindow>(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch("reset");
std::reinterpret_pointer_cast<Ship::ConsoleWindow>(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->Dispatch("reset");
}
});
}
@ -481,7 +484,7 @@ using DayTimeGoldSkulltulasList = std::vector<DayTimeGoldSkulltulas>;
void RegisterDaytimeGoldSkultullas() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
if (!CVarGetInteger("gNightGSAlwaysSpawn", 0)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("NightGSAlwaysSpawn"), 0)) {
return;
}
@ -527,7 +530,7 @@ void RegisterDaytimeGoldSkultullas() {
}
bool IsHyperBossesActive() {
return CVarGetInteger("gHyperBosses", 0) ||
return CVarGetInteger(CVAR_ENHANCEMENT("HyperBosses"), 0) ||
(IS_BOSS_RUSH && gSaveContext.bossRushOptions[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES);
}
@ -595,7 +598,7 @@ void UpdateHyperEnemiesState() {
actorUpdateHookId = 0;
}
if (CVarGetInteger("gHyperEnemies", 0)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0)) {
actorUpdateHookId = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>([](void* refActor) {
// Run the update function a second time to make enemies and minibosses move and act twice as fast.
@ -607,7 +610,7 @@ void UpdateHyperEnemiesState() {
bool isExcludedEnemy = actor->id == ACTOR_EN_FIRE_ROCK || actor->id == ACTOR_EN_ENCOUNT2;
// Don't apply during cutscenes because it causes weird behaviour and/or crashes on some cutscenes.
if (CVarGetInteger("gHyperEnemies", 0) && isEnemy && !isExcludedEnemy &&
if (CVarGetInteger(CVAR_ENHANCEMENT("HyperEnemies"), 0) && isEnemy && !isExcludedEnemy &&
!Player_InBlockingCsMode(gPlayState, player)) {
GameInteractor::RawAction::UpdateActor(actor);
}
@ -617,7 +620,7 @@ void UpdateHyperEnemiesState() {
void RegisterBonkDamage() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerBonk>([]() {
uint8_t bonkOption = CVarGetInteger("gBonkDamageMul", BONK_DAMAGE_NONE);
uint8_t bonkOption = CVarGetInteger(CVAR_ENHANCEMENT("BonkDamageMult"), BONK_DAMAGE_NONE);
if (bonkOption == BONK_DAMAGE_NONE) {
return;
}
@ -663,10 +666,10 @@ void UpdateDirtPathFixState(int32_t sceneNum) {
case SCENE_HYRULE_FIELD:
case SCENE_KOKIRI_FOREST:
case SCENE_HYRULE_CASTLE:
CVarSetInteger("gZFightingMode", CVarGetInteger("gSceneSpecificDirtPathFix", ZFIGHT_FIX_DISABLED));
CVarSetInteger(CVAR_Z_FIGHTING_MODE, CVarGetInteger(CVAR_ENHANCEMENT("SceneSpecificDirtPathFix"), ZFIGHT_FIX_DISABLED));
return;
default:
CVarClear("gZFightingMode");
CVarClear(CVAR_Z_FIGHTING_MODE);
}
}
@ -680,7 +683,7 @@ void UpdateMirrorModeState(int32_t sceneNum) {
static bool prevMirroredWorld = false;
bool nextMirroredWorld = false;
int16_t mirroredMode = CVarGetInteger("gMirroredWorldMode", MIRRORED_WORLD_OFF);
int16_t mirroredMode = CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorldMode"), MIRRORED_WORLD_OFF);
int16_t inDungeon = (sceneNum >= SCENE_DEKU_TREE && sceneNum <= SCENE_INSIDE_GANONS_CASTLE_COLLAPSE && sceneNum != SCENE_THIEVES_HIDEOUT) ||
(sceneNum >= SCENE_DEKU_TREE_BOSS && sceneNum <= SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR) ||
(sceneNum == SCENE_GANON_BOSS);
@ -703,10 +706,10 @@ void UpdateMirrorModeState(int32_t sceneNum) {
((mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) && randomMirror)))
) {
nextMirroredWorld = true;
CVarSetInteger("gMirroredWorld", 1);
CVarSetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 1);
} else {
nextMirroredWorld = false;
CVarClear("gMirroredWorld");
CVarClear(CVAR_ENHANCEMENT("MirroredWorld"));
}
if (prevMirroredWorld != nextMirroredWorld) {
@ -722,7 +725,7 @@ void RegisterMirrorModeHandler() {
}
void UpdatePatchHand() {
if ((CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) && LINK_IS_CHILD) {
if ((CVarGetInteger(CVAR_ENHANCEMENT("EquimentAlwaysVisible"), 0)) && LINK_IS_CHILD) {
ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer1", 92, gsSPDisplayListOTRFilePath(gLinkChildLeftFistNearDL));
ResourceMgr_PatchGfxByName(gLinkAdultLeftHandHoldingHammerNearDL, "childHammer2", 93, gsSPEndDisplayList());
ResourceMgr_PatchGfxByName(gLinkAdultRightHandHoldingHookshotNearDL, "childHookshot1", 84, gsSPDisplayListOTRFilePath(gLinkChildRightHandClosedNearDL));
@ -750,7 +753,7 @@ void UpdatePatchHand() {
ResourceMgr_UnpatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife1");
ResourceMgr_UnpatchGfxByName(gLinkAdultHandHoldingBrokenGiantsKnifeDL, "childBrokenGiantsKnife2");
}
if ((CVarGetInteger("gEnhancements.EquimentAlwaysVisible", 0)) && LINK_IS_ADULT) {
if ((CVarGetInteger(CVAR_ENHANCEMENT("EquimentAlwaysVisible"), 0)) && LINK_IS_ADULT) {
ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndKokiriSwordNearDL, "adultKokiriSword", 13, gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL));
ResourceMgr_PatchGfxByName(gLinkChildRightHandHoldingSlingshotNearDL, "adultSlingshot", 13, gsSPDisplayListOTRFilePath(gLinkAdultRightHandClosedNearDL));
ResourceMgr_PatchGfxByName(gLinkChildLeftFistAndBoomerangNearDL, "adultBoomerang", 50, gsSPDisplayListOTRFilePath(gLinkAdultLeftHandClosedNearDL));
@ -771,7 +774,7 @@ void RegisterPatchHandHandler() {
void RegisterResetNaviTimer() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int32_t sceneNum) {
if (CVarGetInteger("gEnhancements.ResetNaviTimer", 0)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("ResetNaviTimer"), 0)) {
gSaveContext.naviTimer = 0;
}
});
@ -1025,16 +1028,16 @@ typedef enum {
} AltTrapType;
const char* altTrapTypeCvars[] = {
"gAddTraps.Ice",
"gAddTraps.Burn",
"gAddTraps.Shock",
"gAddTraps.Knock",
"gAddTraps.Speed",
"gAddTraps.Bomb",
"gAddTraps.Void",
"gAddTraps.Ammo",
"gAddTraps.Kill",
"gAddTraps.Tele"
CVAR_ENHANCEMENT("ExtraTraps.Ice"),
CVAR_ENHANCEMENT("ExtraTraps.Burn"),
CVAR_ENHANCEMENT("ExtraTraps.Shock"),
CVAR_ENHANCEMENT("ExtraTraps.Knockback"),
CVAR_ENHANCEMENT("ExtraTraps.Speed"),
CVAR_ENHANCEMENT("ExtraTraps.Bomb"),
CVAR_ENHANCEMENT("ExtraTraps.Void"),
CVAR_ENHANCEMENT("ExtraTraps.Ammo"),
CVAR_ENHANCEMENT("ExtraTraps.Kill"),
CVAR_ENHANCEMENT("ExtraTraps.Teleport")
};
std::vector<AltTrapType> getEnabledAddTraps () {
@ -1056,7 +1059,7 @@ void RegisterAltTrapTypes() {
static int eventTimer = -1;
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry itemEntry) {
if (!CVarGetInteger("gAddTraps.enabled", 0) || itemEntry.modIndex != MOD_RANDOMIZER || itemEntry.getItemId != RG_ICE_TRAP) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) || itemEntry.modIndex != MOD_RANDOMIZER || itemEntry.getItemId != RG_ICE_TRAP) {
return;
}
roll = RandomElement(getEnabledAddTraps());
@ -1161,9 +1164,7 @@ void RegisterAltTrapTypes() {
void RegisterRandomizerSheikSpawn() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneSpawnActors>([]() {
if (!gPlayState) return;
bool canSheik = (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIAL_COUNT) != 0 &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LIGHT_ARROWS_HINT));
if (!IS_RANDO || !LINK_IS_ADULT || !canSheik) return;
if (!IS_RANDO || !LINK_IS_ADULT || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHEIK_LA_HINT)) return;
switch (gPlayState->sceneNum) {
case SCENE_TEMPLE_OF_TIME:
if (gPlayState->roomCtx.curRoom.num == 1) {
@ -1256,7 +1257,7 @@ void UpdateHurtContainerModeState(bool newState) {
void RegisterHurtContainerModeHandler() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
UpdateHurtContainerModeState(CVarGetInteger("gHurtContainer", 0));
UpdateHurtContainerModeState(CVarGetInteger(CVAR_ENHANCEMENT("HurtContainer"), 0));
});
}
@ -1275,7 +1276,7 @@ void RegisterRandomizedEnemySizes() {
actor->id == ACTOR_BOSS_FD2 || actor->id == ACTOR_EN_DH;
// Only apply to enemies and bosses.
if (!CVarGetInteger("gRandomizedEnemySizes", 0) || (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || excludedEnemy) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemySizes"), 0) || (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || excludedEnemy) {
return;
}
@ -1298,7 +1299,7 @@ void RegisterRandomizedEnemySizes() {
Actor_SetScale(actor, actor->scale.z * randomScale);
if (CVarGetInteger("gEnemySizeScalesHealth", 0) && (actor->category == ACTORCAT_ENEMY)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("EnemySizeScalesHealth"), 0) && (actor->category == ACTORCAT_ENEMY)) {
// Scale the health based on a smaller factor than randomScale
float healthScalingFactor = 0.8f; // Adjust this factor as needed
float scaledHealth = actor->colChkInfo.health * (randomScale * healthScalingFactor);
@ -1315,7 +1316,7 @@ void RegisterOpenAllHours() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* refActor) {
Actor* actor = static_cast<Actor*>(refActor);
if (CVarGetInteger("gEnhancements.OpenAllHours", 0) && (actor->id == ACTOR_EN_DOOR)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR)) {
switch (actor->params) {
case 4753: // Night Market Bazaar
case 1678: // Night Potion Shop
@ -1342,7 +1343,7 @@ void RegisterOpenAllHours() {
void PatchToTMedallions() {
// TODO: Refactor the DemoEffect_UpdateJewelAdult and DemoEffect_UpdateJewelChild from z_demo_effect
// effects to take effect in there
if (CVarGetInteger("gToTMedallionsColors", 0)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0)) {
ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007A70, "ToTMedallions_StartGrayscale", 7, gsSPGrayscale(true));
ResourceMgr_PatchGfxByName(tokinoma_room_0DL_007FD0, "ToTMedallions_2_StartGrayscale", 7, gsSPGrayscale(true));
@ -1408,13 +1409,13 @@ void PatchToTMedallions() {
void RegisterToTMedallions() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry _unused) {
if (!CVarGetInteger("gToTMedallionsColors", 0) || !gPlayState || gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || !gPlayState || gPlayState->sceneNum != SCENE_TEMPLE_OF_TIME) {
return;
}
PatchToTMedallions();
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([](int16_t sceneNum) {
if (!CVarGetInteger("gToTMedallionsColors", 0) || sceneNum != SCENE_TEMPLE_OF_TIME) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("ToTMedallionsColors"), 0) || sceneNum != SCENE_TEMPLE_OF_TIME) {
return;
}
PatchToTMedallions();
@ -1425,7 +1426,7 @@ void RegisterToTMedallions() {
void RegisterFloorSwitchesHook() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* refActor) {
Actor* actor = static_cast<Actor*>(refActor);
if (actor->id != ACTOR_OBJ_SWITCH || !CVarGetInteger("gEnhancements.FixFloorSwitches", 0)) {
if (actor->id != ACTOR_OBJ_SWITCH || !CVarGetInteger(CVAR_ENHANCEMENT("FixFloorSwitches"), 0)) {
return;
}
@ -1441,7 +1442,7 @@ void RegisterFloorSwitchesHook() {
void RegisterPauseMenuHooks() {
static bool pauseWarpHooksRegistered = false;
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([&]() {
if (!GameInteractor::IsSaveLoaded() || !CVarGetInteger("gPauseWarp", 0)) {
if (!GameInteractor::IsSaveLoaded() || !CVarGetInteger(CVAR_ENHANCEMENT("PauseWarp"), 0)) {
pauseWarpHooksRegistered = false;
return;
}
@ -1464,40 +1465,44 @@ typedef struct {
//special respawns used when voided out without swim to prevent infinite loops
std::map<s32, SpecialRespawnInfo> swimSpecialRespawnInfo = {
{
0x1D9,//hf to zr in water
ENTR_ZORAS_RIVER_3,//hf to zr in water
{ { -1455.443, -20, 1384.826 }, 28761 }
},
{
0x311,//zr to hf in water
ENTR_HYRULE_FIELD_14,//zr to hf in water
{ { 5830.209, -92.16, 3925.911 }, -20025 }
},
{
0x4DA,//zr to lw
ENTR_LOST_WOODS_7,//zr to lw
{ { 1978.718, -36.908, -855 }, -16384 }
},
{
0x1DD,//lw to zr
ENTR_ZORAS_RIVER_4,//lw to zr
{ { 4082.366, 860.442, -1018.949 }, -32768 }
},
{
0x219,//gv to lh
ENTR_LAKE_HYLIA_1,//gv to lh
{ { -3276.416, -1033, 2908.421 }, 11228 }
},
{
0x10,//lh to water temple
ENTR_WATER_TEMPLE_0,//lh to water temple
{ { -182, 780, 759.5 }, -32768 }
},
{
0x21D,//water temple to lh
ENTR_LAKE_HYLIA_2,//water temple to lh
{ { -955.028, -1306.9, 6768.954 }, -32768 }
},
{
0x328,//lh to zd
ENTR_ZORAS_DOMAIN_4,//lh to zd
{ { -109.86, 11.396, -9.933 }, -29131 }
},
{
0x560,//zd to lh
ENTR_LAKE_HYLIA_7,//zd to lh
{ { -912, -1326.967, 3391 }, 0 }
},
{
ENTR_GERUDO_VALLEY_1,//caught by gerudos as child
{ { -424, -2051, -74 }, 16384 }
}
};
@ -1690,7 +1695,7 @@ extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
void PatchCompasses() {
s8 compassesCanBeOutsideDungeon = IS_RANDO && DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_SHUFFLE_MAPANDCOMPASS);
s8 isColoredCompassesEnabled = compassesCanBeOutsideDungeon && CVarGetInteger("gRandoEnhancement.MatchCompassColors", 1);
s8 isColoredCompassesEnabled = compassesCanBeOutsideDungeon && CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MatchCompassColors"), 1);
if (isColoredCompassesEnabled) {
ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_PrimColor", 5, gsDPNoOp());
ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_EnvColor", 6, gsDPNoOp());
@ -1707,6 +1712,9 @@ void RegisterRandomizerCompasses() {
}
void InitMods() {
RandomizerRegisterHooks();
TimeSaverRegisterHooks();
CheatsRegisterHooks();
RegisterTTS();
RegisterInfiniteMoney();
RegisterInfiniteHealth();

View File

@ -5,6 +5,7 @@
#include "soh/frame_interpolation.h"
#include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h"
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/OTRGlobals.h"
extern "C" {
#include "z64.h"
@ -70,11 +71,11 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) {
Color_RGBA8 textboxColor = { 0, 0, 0, 80};
Color_RGBA8 textColor = { 255, 255, 255, 255 };
if (CVarGetInteger("gCosmetics.Hud_NameTagActorBackground.Changed", 0)) {
textboxColor = CVarGetColor("gCosmetics.Hud_NameTagActorBackground.Value", textboxColor);
if (CVarGetInteger(CVAR_COSMETIC("HUD.NameTagActorBackground.Changed"), 0)) {
textboxColor = CVarGetColor(CVAR_COSMETIC("HUD.NameTagActorBackground.Value"), textboxColor);
}
if (CVarGetInteger("gCosmetics.Hud_NameTagActorText.Changed", 0)) {
textColor = CVarGetColor("gCosmetics.Hud_NameTagActorText.Value", textColor);
if (CVarGetInteger(CVAR_COSMETIC("HUD.NameTagActorText.Changed"), 0)) {
textColor = CVarGetColor(CVAR_COSMETIC("HUD.NameTagActorText.Value"), textColor);
}
FrameInterpolation_RecordOpenChild(nameTag->actor, 10);
@ -90,7 +91,7 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) {
// Set position, billboard effect, scale (with mirror mode), then center nametag
Matrix_Translate(nameTag->actor->world.pos.x, posY, nameTag->actor->world.pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(scale * (CVarGetInteger("gMirroredWorld", 0) ? -1 : 1), -scale, 1.0f, MTXMODE_APPLY);
Matrix_Scale(scale * (CVarGetInteger(CVAR_ENHANCEMENT("MirroredWorld"), 0) ? -1 : 1), -scale, 1.0f, MTXMODE_APPLY);
Matrix_Translate(-(float)nameTag->width / 2, -nameTag->height, 0, MTXMODE_APPLY);
Matrix_ToMtx(nameTag->mtx, (char*)__FILE__, __LINE__);

View File

@ -85,7 +85,8 @@ void PauseWarp_HandleSelection() {
if (gSaveContext.inventory.items[SLOT_OCARINA] != ITEM_NONE) {
int aButtonPressed = CHECK_BTN_ALL(gPlayState->state.input->press.button, BTN_A);
int song = gPlayState->pauseCtx.cursorPoint[PAUSE_QUEST];
if (aButtonPressed && CHECK_QUEST_ITEM(song) && song >= QUEST_SONG_MINUET && song <= QUEST_SONG_PRELUDE) {
if (aButtonPressed && CHECK_QUEST_ITEM(song) && song >= QUEST_SONG_MINUET && song <= QUEST_SONG_PRELUDE &&
gPlayState->pauseCtx.pageIndex == PAUSE_QUEST && gPlayState->pauseCtx.state == 6) {
ActivateWarp(&gPlayState->pauseCtx, song);
}
}

View File

@ -40,7 +40,7 @@ void applyPreset(std::vector<PresetEntry> entries) {
}
void DrawPresetSelector(PresetType presetTypeId) {
const std::string presetTypeCvar = "gPreset" + std::to_string(presetTypeId);
const std::string presetTypeCvar = CVAR_GENERAL("SelectedPresets.") + std::to_string(presetTypeId);
const PresetTypeDefinition presetTypeDef = presetTypes.at(presetTypeId);
const uint16_t selectedPresetId = CVarGetInteger(presetTypeCvar.c_str(), 0);
const PresetDefinition selectedPresetDef = presetTypeDef.presets.at(selectedPresetId);
@ -70,7 +70,7 @@ void DrawPresetSelector(PresetType presetTypeId) {
if (selectedPresetId != 0) {
applyPreset(selectedPresetDef.entries);
}
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
ImGui::PopStyleVar(1);
}

File diff suppressed because it is too large Load Diff

View File

@ -158,7 +158,7 @@ constexpr std::array DungeonColors = {
CreateMessage(textId, unk_04, textBoxType, textBoxPosition, text.GetEnglish(), text.GetFrench(), text.GetSpanish());
}
Text AddColorsAndFormat(Text text, const std::vector<uint8_t>& colors /*= {}*/) {
Text AddColorsAndFormat(Text text, const std::vector<std::string>& colors /*= {}*/) {
//for each language
for (std::string* textStr : {&text.english, &text.french, &text.spanish}) {
@ -280,12 +280,12 @@ constexpr std::array DungeonColors = {
std::string SET_SPEED(uint8_t x) {
return "\x7F\x10"s + char(x);
}
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; }
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; } //RANDOTODO just refernce the versions in CustomMessage
std::string CURRENT_TIME() { return "\x7F\x17"s; }
std::string UNSKIPPABLE() { return "\x7F\x19"s; }
std::string TWO_WAY_CHOICE() { return "\x1B"s; }
std::string NEWLINE() { return "\x7F\x1C"s; }
std::string COLOR(uint8_t x) { return "\x7F\x1D"s + char(x); }
std::string COLOR(std::string x) { return "\x7F\x1D"s + x; }
std::string CENTER_TEXT() { return "\x7F\x1E"s; }
std::string IF_NOT_MQ() { return "\x7F\x29"s; }
std::string MQ_ELSE() { return "\x7F\x2A"s; }

View File

@ -7,15 +7,6 @@
#include "text.hpp"
#define QM_WHITE 0x00
#define QM_RED 0x41
#define QM_GREEN 0x42
#define QM_BLUE 0x43
#define QM_LBLUE 0x44
#define QM_PINK 0x45
#define QM_YELLOW 0x46
#define QM_BLACK 0x47
namespace CustomMessages {
typedef struct {
// In the true file format, offset is the offset into the QM file.
@ -73,7 +64,7 @@ typedef struct {
std::string UNSKIPPABLE();
std::string TWO_WAY_CHOICE();
std::string NEWLINE();
std::string COLOR(uint8_t x);
std::string COLOR(std::string x);
std::string CENTER_TEXT();
std::string IF_NOT_MQ();
std::string MQ_ELSE();

View File

@ -9,7 +9,6 @@
#include "spoiler_log.hpp"
#include "starting_inventory.hpp"
#include "hints.hpp"
#include "hint_list.hpp"
#include "../entrance.h"
#include "shops.hpp"
#include "pool_functions.hpp"
@ -635,7 +634,7 @@ static void AssumedFill(const std::vector<RandomizerGet>& items, const std::vect
bool setLocationsAsHintable = false) {
auto ctx = Rando::Context::GetInstance();
if (items.size() > allowedLocations.size()) {
printf("\x1b[2;2HERROR: MORE ITEMS THAN LOCATIONS IN GIVEN LISTS");
SPDLOG_ERROR("ERROR: MORE ITEMS THAN LOCATIONS IN GIVEN LISTS");
SPDLOG_DEBUG("Items:\n");
// NOLINTNEXTLINE(clang-diagnostic-unused-variable)
for (const RandomizerGet item : items) {
@ -893,7 +892,7 @@ static void RandomizeDungeonItems() {
std::vector<RandomizerGet> overworldItems;
for (auto dungeon : ctx->GetDungeons()->GetDungeonList()) {
if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON)) {
if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_ANY_DUNGEON)) {
auto dungeonKeys = FilterAndEraseFromPool(ItemPool, [dungeon](const RandomizerGet i){return (i == dungeon->GetSmallKey()) || (i == dungeon->GetKeyRing());});
AddElementsToPool(anyDungeonItems, dungeonKeys);
} else if (ctx->GetOption(RSK_KEYSANITY).Is(RO_DUNGEON_ITEM_LOC_OVERWORLD)) {
@ -919,10 +918,10 @@ static void RandomizeDungeonItems() {
}
if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_ANY_DUNGEON)) {
auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY; });
auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; });
AddElementsToPool(anyDungeonItems, gerudoKeys);
} else if (ctx->GetOption(RSK_GERUDO_KEYS).Is(RO_GERUDO_KEYS_OVERWORLD)) {
auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY; });
auto gerudoKeys = FilterAndEraseFromPool(ItemPool, [](const auto i) { return i == RG_GERUDO_FORTRESS_SMALL_KEY || i == RG_GERUDO_FORTRESS_KEY_RING; });
AddElementsToPool(overworldItems, gerudoKeys);
}
@ -984,9 +983,9 @@ void VanillaFill() {
}
//If necessary, handle ER stuff
if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) {
printf("\x1b[7;10HShuffling Entrances...");
SPDLOG_INFO("Shuffling Entrances...");
ctx->GetEntranceShuffler()->ShuffleAllEntrances();
printf("\x1b[7;32HDone");
SPDLOG_INFO("Shuffling Entrances Done");
}
// Populate the playthrough for entrances so they are placed in the spoiler log
GeneratePlaythrough();
@ -997,11 +996,6 @@ void VanillaFill() {
}
void ClearProgress() {
printf("\x1b[7;32H "); // Done
printf("\x1b[8;10H "); // Placing Items...Done
printf("\x1b[9;10H "); // Calculating Playthrough...Done
printf("\x1b[10;10H "); // Creating Hints...Done
printf("\x1b[11;10H "); // Writing Spoiler Log...Done
}
int Fill() {
@ -1024,13 +1018,13 @@ int Fill() {
//can validate the world using deku/hylian shields
AddElementsToPool(ItemPool, GetMinVanillaShopItems(32)); //assume worst case shopsanity 4
if (ctx->GetOption(RSK_SHUFFLE_ENTRANCES)) {
printf("\x1b[7;10HShuffling Entrances");
SPDLOG_INFO("Shuffling Entrances...");
if (ctx->GetEntranceShuffler()->ShuffleAllEntrances() == ENTRANCE_SHUFFLE_FAILURE) {
retries++;
ClearProgress();
continue;
}
printf("\x1b[7;32HDone");
SPDLOG_INFO("Shuffling Entrances Done");
}
SetAreas();
//erase temporary shop items
@ -1127,7 +1121,19 @@ int Fill() {
std::vector<RandomizerGet> remainingPool = FilterAndEraseFromPool(ItemPool, [](const auto i) { return true; });
FastFill(remainingPool, GetAllEmptyLocations(), false);
//Add prices for scrubsanity, this is unique to SoH because we write/read scrub prices to/from the spoilerfile.
//Add default prices to scrubs
for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) {
if (Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_NEAR_BRIDGE || Rando::StaticData::scrubLocations[i] == RC_LW_DEKU_SCRUB_GROTTO_FRONT) {
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(40);
} else if (Rando::StaticData::scrubLocations[i] == RC_HF_DEKU_SCRUB_GROTTO) {
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10);
} else {
auto loc = Rando::StaticData::GetLocation(Rando::StaticData::scrubLocations[i]);
auto item = Rando::StaticData::RetrieveItem(loc->GetVanillaItem());
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(item.GetPrice());
}
}
if (ctx->GetOption(RSK_SHUFFLE_SCRUBS).Is(RO_SCRUBS_AFFORDABLE)) {
for (size_t i = 0; i < Rando::StaticData::scrubLocations.size(); i++) {
ctx->GetItemLocation(Rando::StaticData::scrubLocations[i])->SetCustomPrice(10);
@ -1142,27 +1148,21 @@ int Fill() {
GeneratePlaythrough();
//Successful placement, produced beatable result
if(ctx->playthroughBeatable && !placementFailure) {
printf("Done");
printf("\x1b[9;10HCalculating Playthrough...");
SPDLOG_INFO("Calculating Playthrough...");
PareDownPlaythrough();
CalculateWotH();
CalculateBarren();
printf("Done");
SPDLOG_INFO("Calculating Playthrough Done");
ctx->CreateItemOverrides();
ctx->GetEntranceShuffler()->CreateEntranceOverrides();
//funny ganon line
Text ganonText = RandomElement(GetHintCategory(HintCategory::GanonLine)).GetText();
CreateMessageFromTextObject(0x70CB, 0, 2, 3, AddColorsAndFormat(ganonText));
SetGanonText(ganonText);
CreateAllHints();
CreateWarpSongTexts();
return 1;
}
//Unsuccessful placement
if(retries < 4) {
SPDLOG_DEBUG("\nGOT STUCK. RETRYING...\n");
SPDLOG_DEBUG("Failed to generate a beatable seed. Retrying...");
Areas::ResetAllLocations();
logic->Reset();
ClearProgress();

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
#pragma once
#include "hints.hpp"
#include <vector>
extern std::array<HintText, RHT_MAX> hintTable;
void HintTable_Init();
const HintText& Hint(const RandomizerHintTextKey hintKey);
const HintText& Hint(const RandomizerArea area);
std::vector<HintText> GetHintCategory(HintCategory category);
void HintTable_Init_Item();
void HintTable_Init_Exclude_Overworld();
void HintTable_Init_Exclude_Dungeon();

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,15 @@
#pragma once
#include <array>
#include <string>
#include <vector>
#include <variant>
#include "text.hpp"
#include "random.hpp"
#include <functional>
#include "../randomizerTypes.h"
#include "../../custom-message/CustomMessageManager.h"
struct HintDistributionSetting {
std::string name;
HintType type;
@ -16,21 +19,8 @@ struct HintDistributionSetting {
std::function<bool(RandomizerCheck)> filter;
uint8_t dungeonLimit;
HintDistributionSetting(std::string _name,
HintType _type,
uint32_t _weight,
uint8_t _fixed,
uint8_t _copies,
std::function<bool(RandomizerCheck)> _filter,
uint8_t _dungeonLimit = 40){
name = _name;
type = _type;
weight = _weight;
fixed = _fixed;
copies = _copies;
filter = _filter;
dungeonLimit = _dungeonLimit;
}
HintDistributionSetting(std::string _name, HintType _type, uint32_t _weight, uint8_t _fixed, uint8_t _copies,
std::function<bool(RandomizerCheck)> _filter, uint8_t _dungeonLimit = 40);
};
struct HintSetting {
@ -40,185 +30,45 @@ struct HintSetting {
std::vector<HintDistributionSetting> distTable;
};
enum class HintCategory {
Item,
Always,
Sometimes,
Exclude,
Entrance,
Region,
Junk,
DungeonName,
Boss,
Bridge,
GanonsBossKey,
LACS,
Altar,
Validation,
OtherHint,
MasterSword,
GanonLine,
SheikLine,
MerchantsDialogs,
};
class HintText {
public:
HintText() = default;
HintText(std::vector<Text> obscureText_, std::vector<Text> ambiguousText_, Text clearText_, HintCategory type_)
: obscureText(std::move(obscureText_)),
ambiguousText(std::move(ambiguousText_)),
clearText(std::move(clearText_)),
type(type_) {
}
static auto Item(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Item};
}
static auto Always(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Always};
}
static auto Sometimes(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Sometimes};
}
static auto Exclude(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Exclude};
}
static auto Entrance(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Entrance};
}
static auto Region(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Region};
}
static auto Junk(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Junk};
}
static auto DungeonName(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::DungeonName};
}
static auto Boss(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Boss};
}
static auto Bridge(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Bridge};
}
static auto GanonsBossKey(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonsBossKey};
}
static auto LACS(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::LACS};
}
static auto Altar(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Altar};
}
static auto Validation(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::Validation};
}
static auto OtherHint(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::OtherHint};
}
static auto MasterSword(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::MasterSword};
}
static auto GanonLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::GanonLine};
}
static auto SheikLine(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::SheikLine};
}
static auto MerchantsDialogs(std::vector<Text>&& obscureText, std::vector<Text>&& ambiguousText = {}, Text&& clearText = {}) {
return HintText{std::move(obscureText), std::move(ambiguousText), std::move(clearText), HintCategory::MerchantsDialogs};
}
Text& GetObscure() {
return RandomElement(obscureText);
}
const Text& GetObscure() const {
return RandomElement(obscureText);
}
Text& GetAmbiguous() {
if (ambiguousText.size() > 0) {
return RandomElement(ambiguousText);
}
return RandomElement(obscureText);
}
const Text& GetAmbiguous() const {
if (ambiguousText.size() > 0) {
return RandomElement(ambiguousText);
}
return RandomElement(obscureText);
}
const Text& GetClear() const {
if (clearText.GetEnglish().empty()) {
return GetObscure();
}
return clearText;
}
const Text& GetText() const;
const Text GetTextCopy() const;
HintCategory GetType() const {
return type;
}
bool operator==(const HintText& right) const {
return obscureText == right.obscureText &&
ambiguousText == right.ambiguousText &&
clearText == right.clearText;
}
bool operator!=(const HintText& right) const {
return !operator==(right);
}
HintText(CustomMessage clearText_, std::vector<CustomMessage> ambiguousText_ = {}, std::vector<CustomMessage> obscureText_ = {});
const CustomMessage& GetClear() const;
const CustomMessage& GetObscure() const;
const CustomMessage& GetObscure(uint8_t selection) const;
const CustomMessage& GetAmbiguous() const;
const CustomMessage& GetAmbiguous(uint8_t selection) const;
uint8_t GetAmbiguousSize() const;
uint8_t GetObscureSize() const;
const CustomMessage& GetHintMessage(uint8_t selection = 0) const;
const CustomMessage GetMessageCopy() const;
bool operator==(const HintText& right) const;
bool operator!=(const HintText& right) const;
private:
std::vector<Text> obscureText = {};
std::vector<Text> ambiguousText = {};
Text clearText;
HintCategory type;
CustomMessage clearText;
std::vector<CustomMessage> ambiguousText = {};
std::vector<CustomMessage> obscureText = {};
};
using ConditionalAlwaysHint = std::pair<RandomizerCheck, std::function<bool()>>;
struct StaticHintInfo{
HintType type;
std::vector<RandomizerHintTextKey> hintKeys;
RandomizerSettingKey setting;
std::variant<bool, uint8_t> condition;
std::vector<RandomizerCheck> targetChecks;
std::vector<RandomizerGet> targetItems;
std::vector<RandomizerCheck> hintChecks;
bool yourPocket;
int num;
typedef enum {
DUNGEON_NEITHER,
DUNGEON_BARREN,
DUNGEON_WOTH,
} DungeonHintInfo;
//10 dungeons as GTG and GC are excluded
extern std::array<DungeonHintInfo, 10> dungeonInfoData;
extern std::array<ConditionalAlwaysHint, 12> conditionalAlwaysHints;
StaticHintInfo() = default;
StaticHintInfo(HintType _type, std::vector<RandomizerHintTextKey> _hintKeys, RandomizerSettingKey _setting, std::variant<bool, uint8_t> _condition,
std::vector<RandomizerCheck> _targetChecks, std::vector<RandomizerGet> _targetItems = {},
std::vector<RandomizerCheck> _hintChecks = {}, bool _yourPocket = false, int _num = 0);
};
extern void CreateAllHints();
extern void CreateWarpSongTexts();
void SetGanonText(Text text);
std::string GetMasterSwordHintLoc();
std::string GetLightArrowHintLoc();
void CreateStaticHints();

View File

@ -468,7 +468,7 @@ void PlaceJunkInExcludedLocation(const RandomizerCheck il) {
return;
}
}
printf("ERROR: No Junk to Place!!!\n");
SPDLOG_ERROR("ERROR: No Junk to Place!!!");
}
static void PlaceVanillaDekuScrubItems() {
@ -904,11 +904,16 @@ void GenerateItemPool() {
} else if (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK)) {
AddItemToMainPool(RG_TREASURE_GAME_SMALL_KEY); // 1 key which will behave as a pack of 6
} else {
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, RG_GREEN_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, RG_GREEN_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, RG_BLUE_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, RG_BLUE_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, RG_RED_RUPEE, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, RG_TREASURE_GAME_SMALL_KEY, false, true);
ctx->PlaceItemInLocation(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, RG_TREASURE_GAME_SMALL_KEY, false, true);
};
if (ctx->GetOption(RSK_SHUFFLE_TOKENS).Is(RO_TOKENSANITY_OFF)) {

View File

@ -4,7 +4,6 @@
#include <vector>
#include <list>
#include "hint_list.hpp"
#include "fill.hpp"
#include "../randomizerTypes.h"
#include "../context.h"

View File

@ -38,10 +38,10 @@ void AreaTable_Init_CastleTown() {
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}),
}, {
//Locations
LocationAccess(RC_TOT_LEFT_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_TOT_LEFTMOST_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_TOT_LEFT_CENTER_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_TOT_RIGHT_CENTER_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_TOT_RIGHT_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_TOT_RIGHTMOST_GOSSIP_STONE, {[]{return true;}}),
}, {
//Exits
Entrance(RR_THE_MARKET, {[]{return true;}}),
@ -65,6 +65,7 @@ void AreaTable_Init_CastleTown() {
}, {
//Locations
LocationAccess(RC_TOT_MASTER_SWORD, {[]{return logic->IsAdult;}}),
LocationAccess(RC_GIFT_FROM_SAGES, {[]{return logic->IsAdult;}}),
LocationAccess(RC_SHEIK_AT_TEMPLE, {[]{return logic->ForestMedallion && logic->IsAdult;}}),
}, {
//Exits
@ -234,10 +235,15 @@ void AreaTable_Init_CastleTown() {
//Locations
LocationAccess(RC_GREG_HINT, {[]{return true;}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_REWARD, {[]{return logic->ChildsWallet && ((logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 6)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 2)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_3, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 3)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_4, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 4)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_KEY_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
LocationAccess(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, {[]{return logic->ChildsWallet && ((randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !randoCtx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)));}}),
}, {
//Exits

View File

@ -32,12 +32,12 @@ void AreaTable_Init_GanonsCastle() {
Entrance(RR_GANONS_CASTLE_SHADOW_TRIAL, {[]{return true;}}),
Entrance(RR_GANONS_CASTLE_SPIRIT_TRIAL, {[]{return true;}}),
Entrance(RR_GANONS_CASTLE_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}),
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(Rando::FOREST_TRIAL)->IsSkipped()) &&
(logic->FireTrialClear || randoCtx->GetTrial(Rando::FIRE_TRIAL)->IsSkipped()) &&
(logic->WaterTrialClear || randoCtx->GetTrial(Rando::WATER_TRIAL)->IsSkipped()) &&
(logic->ShadowTrialClear || randoCtx->GetTrial(Rando::SHADOW_TRIAL)->IsSkipped()) &&
(logic->SpiritTrialClear || randoCtx->GetTrial(Rando::SPIRIT_TRIAL)->IsSkipped()) &&
(logic->LightTrialClear || randoCtx->GetTrial(Rando::LIGHT_TRIAL)->IsSkipped());}}),
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
(logic->FireTrialClear || randoCtx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
(logic->WaterTrialClear || randoCtx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
(logic->ShadowTrialClear || randoCtx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
(logic->SpiritTrialClear || randoCtx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) &&
(logic->LightTrialClear || randoCtx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}),
Entrance(RR_GANONS_CASTLE_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
});
@ -134,12 +134,12 @@ void AreaTable_Init_GanonsCastle() {
Entrance(RR_GANONS_CASTLE_MQ_SHADOW_TRIAL, {[]{return true;}}),
Entrance(RR_GANONS_CASTLE_MQ_SPIRIT_TRIAL, {[]{return true;}}),
Entrance(RR_GANONS_CASTLE_MQ_LIGHT_TRIAL, {[]{return logic->CanUse(RG_GOLDEN_GAUNTLETS);}}),
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(Rando::FOREST_TRIAL)->IsSkipped()) &&
(logic->FireTrialClear || randoCtx->GetTrial(Rando::FIRE_TRIAL)->IsSkipped()) &&
(logic->WaterTrialClear || randoCtx->GetTrial(Rando::WATER_TRIAL)->IsSkipped()) &&
(logic->ShadowTrialClear || randoCtx->GetTrial(Rando::SHADOW_TRIAL)->IsSkipped()) &&
(logic->SpiritTrialClear || randoCtx->GetTrial(Rando::SPIRIT_TRIAL)->IsSkipped()) &&
(logic->LightTrialClear || randoCtx->GetTrial(Rando::LIGHT_TRIAL)->IsSkipped());}}),
Entrance(RR_GANONS_CASTLE_TOWER, {[]{return (logic->ForestTrialClear || randoCtx->GetTrial(TK_FOREST_TRIAL)->IsSkipped()) &&
(logic->FireTrialClear || randoCtx->GetTrial(TK_FIRE_TRIAL)->IsSkipped()) &&
(logic->WaterTrialClear || randoCtx->GetTrial(TK_WATER_TRIAL)->IsSkipped()) &&
(logic->ShadowTrialClear || randoCtx->GetTrial(TK_SHADOW_TRIAL)->IsSkipped()) &&
(logic->SpiritTrialClear || randoCtx->GetTrial(TK_SPIRIT_TRIAL)->IsSkipped()) &&
(logic->LightTrialClear || randoCtx->GetTrial(TK_LIGHT_TRIAL)->IsSkipped());}}),
Entrance(RR_GANONS_CASTLE_MQ_DEKU_SCRUBS, {[]{return randoCtx->GetTrickOption(RT_LENS_GANON_MQ) || logic->CanUse(RG_LENS_OF_TRUTH);}}),
});

View File

@ -34,7 +34,7 @@ void AreaTable_Init_HyruleField() {
//Locations
LocationAccess(RC_HF_SOUTHEAST_GROTTO_CHEST, {[]{return true;}}),
LocationAccess(RC_HF_SOUTHEAST_GROTTO_FISH, {[]{return logic->HasBottle;}}),
LocationAccess(RC_HF_SOUTHEAST_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_HF_SOUTHEAST_GROTTO_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
LocationAccess(RC_HF_SOUTHEAST_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
}, {
@ -77,7 +77,7 @@ void AreaTable_Init_HyruleField() {
//Locations
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_CHEST, {[]{return true;}}),
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_FISH, {[]{return logic->HasBottle;}}),
LocationAccess(RC_HF_NEAR_MARKET_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
LocationAccess(RC_HF_NEAR_MARKET_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
}, {

View File

@ -281,7 +281,7 @@ void AreaTable_Init_Kakariko() {
EventAccess(&logic->GossipStoneFairy, {[]{return logic->GossipStoneFairy || logic->CanSummonGossipFairyWithoutSuns;}}),
}, {
//Locations
LocationAccess(RC_GY_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_GRAVEYARD_GOSSIP_STONE, {[]{return true;}}),
}, {
//Exits
Entrance(RR_THE_GRAVEYARD, {[]{return true;}}),

View File

@ -98,7 +98,7 @@ void AreaTable_Init_LostWoods() {
//Locations
LocationAccess(RC_KF_STORMS_GROTTO_CHEST, {[]{return true;}}),
LocationAccess(RC_KF_STORMS_GROTTO_FISH, {[]{return logic->HasBottle;}}),
LocationAccess(RC_KF_STORMS_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_KF_STORMS_GROTTO_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
LocationAccess(RC_KF_STORMS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
}, {
@ -168,7 +168,7 @@ void AreaTable_Init_LostWoods() {
//Locations
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, {[]{return true;}}),
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_FISH, {[]{return logic->HasBottle;}}),
LocationAccess(RC_LW_NEAR_SHORTCUTS_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_LEFT, {[]{return logic->CanBreakLowerBeehives;}}),
LocationAccess(RC_LW_NEAR_SHORTCUTS_GROTTO_BEEHIVE_RIGHT, {[]{return logic->CanBreakLowerBeehives;}}),
}, {

View File

@ -158,8 +158,8 @@ void AreaTable_Init_ZorasDomain() {
LocationAccess(RC_ZF_GS_TREE, {[]{return logic->IsChild;}}),
LocationAccess(RC_ZF_GS_ABOVE_THE_LOG, {[]{return logic->IsChild && logic->HookshotOrBoomerang && logic->AtNight && logic->CanGetNightTimeGS;}}),
LocationAccess(RC_ZF_GS_HIDDEN_CAVE, {[]{return logic->CanUse(RG_SILVER_GAUNTLETS) && logic->CanBlastOrSmash && logic->HookshotOrBoomerang && logic->IsAdult && logic->AtNight && logic->CanGetNightTimeGS;}}),
LocationAccess(RC_FAIRY_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_JABU_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_ZF_FAIRY_GOSSIP_STONE, {[]{return true;}}),
LocationAccess(RC_ZF_JABU_GOSSIP_STONE, {[]{return true;}}),
}, {
//Exits
Entrance(RR_ZD_BEHIND_KING_ZORA, {[]{return true;}}),

View File

@ -50,12 +50,10 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
int ret = Playthrough::Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks);
if (ret < 0) {
if (ret == -1) { // Failed to generate after 5 tries
printf("\n\nFailed to generate after 5 tries.\nPress B to go back to the menu.\nA different seed might be "
"successful.");
SPDLOG_DEBUG("\nRANDOMIZATION FAILED COMPLETELY. PLZ FIX\n");//RANDOTODO print seed for reproduction purposes
SPDLOG_ERROR("Failed to generate after 5 tries.");
return false;
} else {
printf("\n\nError %d with fill.\nPress Select to exit or B to go back to the menu.\n", ret);
SPDLOG_ERROR("Error {} with fill.", ret);
return false;
}
}

View File

@ -8,7 +8,8 @@
#include "random.hpp"
#include "spoiler_log.hpp"
#include "soh/Enhancements/randomizer/randomizerTypes.h"
#include <variables.h>
#include "variables.h"
#include "soh/OTRGlobals.h"
#include "../option.h"
namespace Playthrough {
@ -44,7 +45,7 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
}
}
if (CVarGetInteger("gRandomizerDontGenerateSpoiler", 0)) {
if (CVarGetInteger(CVAR_RANDOMIZER_SETTING("DontGenerateSpoiler"), 0)) {
settingsStr += (char*)gBuildVersion;
}
@ -69,18 +70,18 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
if (true) {
//TODO: Handle different types of file output (i.e. Spoiler Log, Plando Template, Patch Files, Race Files, etc.)
// write logs
printf("\x1b[11;10HWriting Spoiler Log...");
SPDLOG_INFO("Writing Spoiler Log...");
if (SpoilerLog_Write()) {
printf("Done");
SPDLOG_INFO("Writing Spoiler Log Done");
} else {
printf("Failed");
SPDLOG_ERROR("Writing Spoiler Log Failed");
}
#ifdef ENABLE_DEBUG
printf("\x1b[11;10HWriting Placement Log...");
SPDLOG_INFO("Writing Placement Log...");
if (PlacementLog_Write()) {
printf("Done\n");
SPDLOG_INFO("Writing Placement Log Done");
} else {
printf("Failed\n");
SPDLOG_ERROR("Writing Placement Log Failed");
}
#endif
}
@ -93,7 +94,7 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
// used for generating a lot of seeds at once
int Playthrough_Repeat(std::set<RandomizerCheck> excludedLocations, std::set<RandomizerTrick> enabledTricks, int count /*= 1*/) {
printf("\x1b[0;0HGENERATING %d SEEDS", count);
SPDLOG_INFO("GENERATING {} SEEDS", count);
auto ctx = Rando::Context::GetInstance();
uint32_t repeatedSeed = 0;
for (int i = 0; i < count; i++) {
@ -103,7 +104,7 @@ int Playthrough_Repeat(std::set<RandomizerCheck> excludedLocations, std::set<Ran
//CitraPrint("testing seed: " + std::to_string(Settings::seed));
ClearProgress();
Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks);
printf("\x1b[15;15HSeeds Generated: %d\n", i + 1);
SPDLOG_INFO("Seeds Generated: {}", i + 1);
}
return 1;

Some files were not shown because too many files have changed in this diff Show More