Merge branch 'develop-rando' into check_tracker_show_logic
This commit is contained in:
commit
91e0420697
|
@ -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
|
||||
|
|
|
@ -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' }}
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -448,5 +448,5 @@ _packages
|
|||
*/extract_assets_cmake*
|
||||
/build*
|
||||
|
||||
soh/build.c
|
||||
soh/src/boot/build.c
|
||||
soh/properties.h
|
||||
|
|
|
@ -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")
|
|
@ -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}"
|
||||
)
|
|
@ -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
2
ZAPDTR
|
@ -1 +1 @@
|
|||
Subproject commit eff29036118349e142ee8efca80fd975a2a2b6ff
|
||||
Subproject commit f38a9c92eb99368c0607acf356d5651ebdc96f51
|
|
@ -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
|
|
@ -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>"
|
||||
|
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
Binary file not shown.
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(?);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
extern PlayState* gPlayState;
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
|
||||
void SkipIntro_Register() {
|
||||
REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Intro"), IS_RANDO)) {
|
||||
if (gSaveContext.entranceIndex == ENTR_LINKS_HOUSE_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "macros.h"
|
||||
#include "src/overlays/actors/ovl_En_Ko/z_en_ko.h"
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
#include "variables.h"
|
||||
}
|
||||
|
||||
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetSelectedOptionIndex()
|
||||
|
||||
/**
|
||||
* This will override the transitions into the blue warp cutscenes, set any appropriate flags, and
|
||||
* set the entrance index to where you would normally end up after the blue warp cutscene. This
|
||||
* should also account for the difference between your first and following visits to the blue warp.
|
||||
*/
|
||||
void SkipBlueWarp_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, void* opt) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
uint8_t isBlueWarp = 0;
|
||||
// Deku Tree Blue warp
|
||||
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_11;
|
||||
isBlueWarp = 1;
|
||||
// Dodongo's Cavern Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_DEATH_MOUNTAIN_TRAIL_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_TRAIL_5;
|
||||
isBlueWarp = 1;
|
||||
// Jabu Jabu's Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_ZORAS_FOUNTAIN_0 && gSaveContext.cutsceneIndex == 0xFFF0) {
|
||||
gSaveContext.entranceIndex = ENTR_ZORAS_FOUNTAIN_0;
|
||||
isBlueWarp = 1;
|
||||
// Forest Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_FOREST) {
|
||||
// Normally set in the blue warp cutscene
|
||||
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_DEKU_TREE_SPROUT);
|
||||
|
||||
if (IS_RANDO) {
|
||||
gSaveContext.entranceIndex = ENTR_SACRED_FOREST_MEADOW_3;
|
||||
} else {
|
||||
gSaveContext.entranceIndex = ENTR_KOKIRI_FOREST_12;
|
||||
}
|
||||
|
||||
isBlueWarp = 1;
|
||||
// Fire Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 && gSaveContext.cutsceneIndex == 0xFFF3) {
|
||||
gSaveContext.entranceIndex = ENTR_DEATH_MOUNTAIN_CRATER_5;
|
||||
isBlueWarp = 1;
|
||||
// Water Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_WATER) {
|
||||
// Normally set in the blue warp cutscene
|
||||
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4800;
|
||||
|
||||
gSaveContext.entranceIndex = ENTR_LAKE_HYLIA_9;
|
||||
isBlueWarp = 1;
|
||||
// Spirit Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SPIRIT) {
|
||||
gSaveContext.entranceIndex = ENTR_DESERT_COLOSSUS_8;
|
||||
isBlueWarp = 1;
|
||||
// Shadow Temple Blue warp
|
||||
} else if (gSaveContext.entranceIndex == ENTR_CHAMBER_OF_THE_SAGES_0 && gSaveContext.cutsceneIndex == 0x0 && gSaveContext.chamberCutsceneNum == CHAMBER_CS_SHADOW) {
|
||||
gSaveContext.entranceIndex = ENTR_GRAVEYARD_8;
|
||||
isBlueWarp = 1;
|
||||
}
|
||||
|
||||
if (isBlueWarp) {
|
||||
if (gSaveContext.entranceIndex != ENTR_LAKE_HYLIA_9) {
|
||||
// Normally set in the blue warp cutscene
|
||||
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x8000;
|
||||
}
|
||||
|
||||
*should = false;
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
|
||||
if (IS_RANDO && (RAND_GET_OPTION(RSK_SHUFFLE_DUNGEON_ENTRANCES) != RO_DUNGEON_ENTRANCE_SHUFFLE_OFF || RAND_GET_OPTION(RSK_SHUFFLE_BOSS_ENTRANCES) != RO_BOSS_ROOM_ENTRANCE_SHUFFLE_OFF)) {
|
||||
Entrance_OverrideBlueWarp();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* While we could rely on the Item_Give that's normally called, it's not very clear to the player that they
|
||||
* received the item when skipping the blue warp cutscene, so we'll prevent that and queue it up to be given
|
||||
* to the player instead.
|
||||
*/
|
||||
void SkipBlueWarp_ShouldGiveItem(GIVanillaBehavior _, bool* should, void* opt) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: Move item queueing here
|
||||
|
||||
/**
|
||||
* This ensures the Kokiri blocking the forest exit checks if you are eligible to leave the forest
|
||||
* every frame, instead of only at init. The reason we need to do this is when we skip the blue warp cutscene
|
||||
* you end up getting the Kokiri Emerald after the actor has init'd, so the actor doesn't know you have it
|
||||
*/
|
||||
void EnKo_MoveWhenReady(EnKo* enKo, PlayState* play) {
|
||||
func_80A995CC(enKo, play);
|
||||
|
||||
if ((enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3) {
|
||||
if (GameInteractor_Should(VB_OPEN_KOKIRI_FOREST, CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD), NULL)) {
|
||||
enKo->collider.dim.height -= 200;
|
||||
Path_CopyLastPoint(enKo->path, &enKo->actor.world.pos);
|
||||
enKo->actionFunc = func_80A99384;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkipBlueWarp_OnActorUpdate(void* actorPtr) {
|
||||
EnKo* enKo = static_cast<EnKo*>(actorPtr);
|
||||
|
||||
if (
|
||||
(enKo->actor.params & 0xFF) == ENKO_TYPE_CHILD_3 &&
|
||||
enKo->actionFunc == func_80A995CC &&
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)
|
||||
) {
|
||||
enKo->actionFunc = EnKo_MoveWhenReady;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will ensure that the Deku Tree Sprout considers the Forest Temple finished when you skip the blue warp cutscene.
|
||||
* Typically this checks for if you have the medallion, and when skipping the cutscene at this point you don't have it yet.
|
||||
*/
|
||||
void SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished(GIVanillaBehavior _, bool* should, void* opt) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
if (gSaveContext.entranceIndex == ENTR_KOKIRI_FOREST_11 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||
*should = Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkipBlueWarp_Register() {
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorUpdate>(ACTOR_EN_KO, SkipBlueWarp_OnActorUpdate);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_TRANSITION_CS, SkipBlueWarp_ShouldPlayTransitionCS);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_DEKU_JR_CONSIDER_FOREST_TEMPLE_FINISHED, SkipBlueWarp_ShouldDekuJrConsiderForestTempleFinished);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_GIVE_ITEM_FROM_BLUE_WARP, SkipBlueWarp_ShouldGiveItem);
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "src/overlays/actors/ovl_Bg_Treemouth/z_bg_treemouth.h"
|
||||
}
|
||||
|
||||
/**
|
||||
* This will skip the Deku Tree intro, and simply open the mouth as you approach it.
|
||||
*/
|
||||
void SkipDekuTreeIntro_Register() {
|
||||
REGISTER_VB_SHOULD(VB_PLAY_DEKU_TREE_INTRO_CS, {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
BgTreemouth* treeMouth = static_cast<BgTreemouth*>(opt);
|
||||
Flags_SetEventChkInf(EVENTCHKINF_DEKU_TREE_OPENED_MOUTH);
|
||||
Audio_PlaySoundGeneral(NA_SE_EV_WOODDOOR_OPEN, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||
BgTreemouth_SetupAction(treeMouth, func_808BC6F8);
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
extern PlayState* gPlayState;
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
|
||||
void SkipLostWoodsBridge_Register() {
|
||||
/**
|
||||
* This skips the cutscene where you speak to Saria on the bridge in Lost Woods, where she gives you the Fairy Ocarina.
|
||||
*/
|
||||
REGISTER_VB_SHOULD(VB_PLAY_TRANSITION_CS, {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
if ((gSaveContext.entranceIndex == ENTR_LOST_WOODS_9) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE);
|
||||
if (GameInteractor_Should(VB_GIVE_ITEM_FAIRY_OCARINA, true, NULL)) {
|
||||
Item_Give(gPlayState, ITEM_OCARINA_FAIRY);
|
||||
}
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* While we could rely on the Item_Give that's normally called (and that we have above), it's not very clear to the player
|
||||
* that they received the item when skipping the cutscene, so we'll prevent it, and queue it up to be given instead.
|
||||
*/
|
||||
REGISTER_VB_SHOULD(VB_GIVE_ITEM_FAIRY_OCARINA, {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Todo: Move item queueing here
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "src/overlays/actors/ovl_En_Zl4/z_en_zl4.h"
|
||||
}
|
||||
|
||||
/**
|
||||
* This overrides Zelda's update function to effectively skip the dialog and cutscenes played when
|
||||
* you meet with her in Hyrule Castle Courtyard. As you approach her she will turn around, and talking
|
||||
* with her will place you at the very last dialog option where she gives you the letter.
|
||||
*/
|
||||
|
||||
u16 EnZl4_GiveItemTextId(PlayState* play, Actor* actor) {
|
||||
return 0x207D;
|
||||
}
|
||||
|
||||
void EnZl4_SkipToGivingZeldasLetter(EnZl4* enZl4, PlayState* play) {
|
||||
if (enZl4->csState == 0 && enZl4->actor.xzDistToPlayer < 700.0f && EnZl4_SetNextAnim(enZl4, 3)) {
|
||||
Audio_PlayFanfare(NA_BGM_APPEAR);
|
||||
enZl4->csState = 8; // ZL4_CS_PLAN
|
||||
} else {
|
||||
Npc_UpdateTalking(play, &enZl4->actor, &enZl4->interactInfo.talkState, enZl4->collider.dim.radius + 60.0f, EnZl4_GiveItemTextId, func_80B5B9B0);
|
||||
func_80B5BB78(enZl4, play);
|
||||
|
||||
if (enZl4->interactInfo.talkState != NPC_TALK_STATE_IDLE) {
|
||||
enZl4->talkState = 6;
|
||||
enZl4->actionFunc = EnZl4_Cutscene;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SkipToGivingZeldasLetter_OnActorInit(void* actorPtr) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
EnZl4* enZl4 = static_cast<EnZl4*>(actorPtr);
|
||||
if (enZl4->actionFunc != EnZl4_Cutscene || enZl4->csState != 0) return;
|
||||
|
||||
enZl4->actionFunc = EnZl4_SkipToGivingZeldasLetter;
|
||||
}
|
||||
}
|
||||
|
||||
void SkipToGivingZeldasLetter_Register() {
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(ACTOR_EN_ZL4, SkipToGivingZeldasLetter_OnActorInit);
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "z64save.h"
|
||||
#include "functions.h"
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
|
||||
void SkipZeldaFleeingCastle_ShouldPlayTransitionCS(GIVanillaBehavior _, bool* should, void* opt) {
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
|
||||
if (gSaveContext.entranceIndex == ENTR_HYRULE_FIELD_0 && gSaveContext.cutsceneIndex == 0xFFF1) {
|
||||
// Normally set in the cutscene
|
||||
gSaveContext.dayTime = gSaveContext.skyboxTime = 0x4AAA;
|
||||
|
||||
gSaveContext.cutsceneIndex = 0;
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When this cutscene is skipped, walking up to the bridge to castle town triggers a quick fade in/out
|
||||
* which can be confusing to beginners, because they need to then fetch the Ocarina of Time from the water.
|
||||
* To make it more obvious what happened, we'll play the sound of the Ocarina dropping into the water.
|
||||
*/
|
||||
static int framesSinceSpawn = 0;
|
||||
static HOOK_ID itemOcarinaUpdateHook = 0;
|
||||
static HOOK_ID sceneInitHook = 0;
|
||||
|
||||
void SkipZeldaFleeingCastle_OnActorUpdate(void* actorPtr) {
|
||||
Actor* actor = static_cast<Actor*>(actorPtr);
|
||||
|
||||
framesSinceSpawn++;
|
||||
if (framesSinceSpawn > 20) {
|
||||
Audio_PlayActorSound2(actor, NA_SE_EV_BOMB_DROP_WATER);
|
||||
|
||||
GameInteractor::Instance->UnregisterGameHookForPtr<GameInteractor::OnActorUpdate>(itemOcarinaUpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(sceneInitHook);
|
||||
itemOcarinaUpdateHook = 0;
|
||||
sceneInitHook = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SkipZeldaFleeingCastle_OnActorInit(void* actorPtr) {
|
||||
Actor* actor = static_cast<Actor*>(actorPtr);
|
||||
|
||||
if (
|
||||
actor->params == 3 &&
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)
|
||||
) {
|
||||
framesSinceSpawn = 0;
|
||||
itemOcarinaUpdateHook = GameInteractor::Instance->RegisterGameHookForPtr<GameInteractor::OnActorUpdate>((uintptr_t)actorPtr, SkipZeldaFleeingCastle_OnActorUpdate);
|
||||
sceneInitHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>([] (int16_t sceneNum) {
|
||||
GameInteractor::Instance->UnregisterGameHookForPtr<GameInteractor::OnActorUpdate>(itemOcarinaUpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(sceneInitHook);
|
||||
itemOcarinaUpdateHook = 0;
|
||||
sceneInitHook = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void SkipZeldaFleeingCastle_Register() {
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnActorInit>(ACTOR_ITEM_OCARINA, SkipZeldaFleeingCastle_OnActorInit);
|
||||
GameInteractor::Instance->RegisterGameHookForID<GameInteractor::OnVanillaBehavior>(VB_PLAY_TRANSITION_CS, SkipZeldaFleeingCastle_ShouldPlayTransitionCS);
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
|
||||
extern "C" {
|
||||
#include "z64save.h"
|
||||
#include "macros.h"
|
||||
#include "variables.h"
|
||||
#include "functions.h"
|
||||
extern PlayState* gPlayState;
|
||||
extern SaveContext gSaveContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* This simply skips the Mido interaction in Kokiri Forest, once you equip the Kokiri
|
||||
* Sword and Deku Shield he will move out of the way without you needing to talk to him.
|
||||
*/
|
||||
void MoveMidoInKokiriForest_Register() {
|
||||
REGISTER_VB_SHOULD(VB_MOVE_MIDO_IN_KOKIRI_FOREST, {
|
||||
if (
|
||||
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipMiscInteractions"), IS_RANDO) &&
|
||||
!Flags_GetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD) &&
|
||||
(CUR_EQUIP_VALUE(EQUIP_TYPE_SHIELD) == EQUIP_VALUE_SHIELD_DEKU) &&
|
||||
(CUR_EQUIP_VALUE(EQUIP_TYPE_SWORD) == EQUIP_VALUE_SWORD_KOKIRI)
|
||||
) {
|
||||
Flags_SetEventChkInf(EVENTCHKINF_SHOWED_MIDO_SWORD_SHIELD);
|
||||
*should = true;
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#include "TimeSavers.h"
|
||||
|
||||
void TimeSavers_Register() {
|
||||
// SkipCutscene
|
||||
// Story
|
||||
SkipBlueWarp_Register();
|
||||
SkipDekuTreeIntro_Register();
|
||||
SkipLostWoodsBridge_Register();
|
||||
SkipToGivingZeldasLetter_Register();
|
||||
SkipZeldaFleeingCastle_Register();
|
||||
SkipIntro_Register();
|
||||
// SkipMiscInteractions
|
||||
MoveMidoInKokiriForest_Register();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef TIME_SAVERS_H
|
||||
#define TIME_SAVERS_H
|
||||
|
||||
void TimeSavers_Register();
|
||||
|
||||
// SkipCutscene
|
||||
// Story
|
||||
void SkipBlueWarp_Register();
|
||||
void SkipDekuTreeIntro_Register();
|
||||
void SkipLostWoodsBridge_Register();
|
||||
void SkipToGivingZeldasLetter_Register();
|
||||
void SkipZeldaFleeingCastle_Register();
|
||||
void SkipIntro_Register();
|
||||
// SkipMiscInteractions
|
||||
void MoveMidoInKokiriForest_Register();
|
||||
|
||||
#endif // TIME_SAVERS_H
|
|
@ -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 {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#ifdef __cplusplus
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
});
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef CHEAT_HOOK_HANDLERS_H
|
||||
#define CHEAT_HOOK_HANDLERS_H
|
||||
|
||||
void CheatsRegisterHooks();
|
||||
|
||||
#endif // CHEAT_HOOK_HANDLERS_H
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
class ActorViewerWindow : public LUS::GuiWindow {
|
||||
class ActorViewerWindow : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -14,7 +14,7 @@ typedef enum {
|
|||
} ColViewerRenderSetting;
|
||||
|
||||
#ifdef __cplusplus
|
||||
class ColViewerWindow : public LUS::GuiWindow {
|
||||
class ColViewerWindow : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.");
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
class DLViewerWindow : public LUS::GuiWindow {
|
||||
class DLViewerWindow : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -33,7 +33,7 @@ typedef struct {
|
|||
uint32_t y;
|
||||
} ValueTableElement;
|
||||
|
||||
class ValueViewerWindow : public LUS::GuiWindow {
|
||||
class ValueViewerWindow : public Ship::GuiWindow {
|
||||
public:
|
||||
using GuiWindow::GuiWindow;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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::OnVanillaBehavior>(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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#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/TimeSavers/TimeSavers.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 +73,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 +84,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 +95,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 +132,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 +143,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 +153,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 +168,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 +180,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 +192,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 +202,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 +221,7 @@ void RegisterSwitchAge() {
|
|||
static bool warped = false;
|
||||
|
||||
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||
CVarClear("gSwitchAge");
|
||||
CVarClear(CVAR_GENERAL("SwitchAge"));
|
||||
warped = false;
|
||||
return;
|
||||
}
|
||||
|
@ -227,7 +231,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 +250,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 +260,7 @@ void RegisterOcarinaTimeTravel() {
|
|||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnOcarinaSongAction>([]() {
|
||||
if (!GameInteractor::IsSaveLoaded(true)) {
|
||||
CVarClear("gTimeTravel");
|
||||
CVarClear(CVAR_ENHANCEMENT("TimeTravel"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -270,16 +274,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 +296,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 +342,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 +353,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 +373,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 +401,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,10 +432,10 @@ 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 * 3;
|
||||
uint8_t startingHealth = 16 * (IS_RANDO ? (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_HEARTS) + 1) : 3);
|
||||
|
||||
|
||||
uint8_t newCapacity = startingHealth + (heartContainers * 16) + ((heartPieces - (heartPieces % 4)) * 4);
|
||||
|
@ -448,7 +452,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 +464,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 +485,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 +531,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 +599,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 +611,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 +621,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 +667,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 +684,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 +707,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 +726,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 +754,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 +775,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 +1029,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 +1060,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 +1165,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 +1258,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 +1277,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 +1300,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 +1317,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 +1344,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 +1410,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 +1427,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 +1443,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 +1466,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 +1696,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 +1713,10 @@ void RegisterRandomizerCompasses() {
|
|||
}
|
||||
|
||||
void InitMods() {
|
||||
RandomizerRegisterHooks();
|
||||
TimeSaverRegisterHooks();
|
||||
CheatsRegisterHooks();
|
||||
TimeSavers_Register();
|
||||
RegisterTTS();
|
||||
RegisterInfiniteMoney();
|
||||
RegisterInfiniteHealth();
|
||||
|
|
|
@ -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__);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
@ -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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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();
|
|
@ -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)) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue