Merge branch 'develop' into Custom-DLists

This commit is contained in:
Patrick12115 2025-01-28 18:13:04 -05:00
commit f3410ae3ec
133 changed files with 4008 additions and 3404 deletions

5
.gitignore vendored
View File

@ -4,7 +4,9 @@ __pycache__/
.DS_Store
# Text editor remnants
.vscode/
.vscode/*
!.vscode/tasks.json
.vs/
.idea/
cmake-build-**
@ -400,7 +402,6 @@ ASALocalRun/
lib/libgfxd/libgfxd.a
ExporterTest/ExporterTest.a
ZAPDUtils/ZAPDUtils.a
.vscode/
build/
external/
ZAPDUtils/build/

61
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,61 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Setup CMake Project",
"type": "shell",
"command": "cmake",
"args": [
"-S",
".",
"-B",
"build/x64",
"-G",
"Visual Studio 17 2022",
"-T",
"v143",
"-A",
"x64"
],
"group": "build",
"problemMatcher": []
},
{
"label": "Generate SOH OTR",
"type": "shell",
"command": "cmake",
"args": [
"--build",
"./build/x64",
"--target",
"GenerateSohOtr"
],
"group": "build",
"problemMatcher": []
},
{
"label": "Build Project",
"type": "shell",
"command": "cmake",
"args": [
"--build",
"./build/x64"
],
"group": {
"kind": "build",
"isDefault": true
},
"dependsOn": ["Generate SOH OTR"],
"problemMatcher": []
},
{
"label": "Build All",
"dependsOrder": "sequence",
"dependsOn": [
"Setup CMake Project",
"Generate SOH OTR",
"Build Project"
]
}
]
}

View File

@ -58,7 +58,7 @@ To develop using Visual Studio you only need to use cmake to generate the soluti
To develop using Visual Studio Code or another editor you only need to open the repository in it.
To build you'll need to follow the instructions from the building section.
_Note: If you're using Visual Studio Code, the [cpack plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
_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._
_Experimental: You can also use another build system entirely rather than MSVC like [Ninja](https://ninja-build.org/) for possibly better performance._
@ -177,7 +177,7 @@ Requires Xcode (or xcode-tools) && `sdl2, libpng, glew, ninja, cmake, tinyxml2,
**Important: For maximum performance make sure you have ninja build tools installed!**
_Note: If you're using Visual Studio Code, the [cpack plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) makes it very easy to just press run and debug._
_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

@ -1 +1 @@
Subproject commit 9a974e002f84cd1fe834ee9d2fa4ccf16d899e0f
Subproject commit 5341b017254a186da3ffe6d681d4e293769f23f4

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,10 @@
<Vertex Version="0">
<Vtx X="-28" Y="-23" Z="-21" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-28" Y="-23" Z="21" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-28" Y="34" Z="21" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-28" Y="34" Z="-21" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="28" Y="-23" Z="-21" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="28" Y="-23" Z="21" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="28" Y="34" Z="21" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="28" Y="34" Z="-21" S="0" T="0" R="0" G="0" B="0" A="0"/>
</Vertex>

Binary file not shown.

View File

@ -0,0 +1,11 @@
<DisplayList Version="0">
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_SHADING_SMOOTH="1" />
<PipeSync/>
<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_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"/>
<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_TT_NONE="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="65535" T="65535" Level="0" Tile="0" On="1"/>
<SetPrimColor M="0" L="0" R="0" G="0" B="0" A="255"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,16 @@
<DisplayList Version="0">
<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" />
<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"/>
<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_TT_NONE="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"/>
<SetPrimColor M="0" L="0" R="255" G="192" B="113" A="255"/>
<SetTextureImage Path="objects/object_boss_soul/BarkOrHorns" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b_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="0" ShiftS="0" MaskT="0" ShiftT="0"/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="1023" Dxt="128"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b" Line="8" 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"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,16 @@
<DisplayList Version="0">
<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" />
<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"/>
<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_TT_NONE="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="960" T="960" Level="0" Tile="0" On="1"/>
<SetPrimColor M="0" L="0" R="255" G="255" B="255" A="255"/>
<SetTextureImage Path="objects/object_boss_soul/heart1" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b_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="0" ShiftS="0" MaskT="0" ShiftT="0"/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="255" Dxt="256"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b" 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="4" ShiftS="0" MaskT="4" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="60" Lrt="60"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,15 @@
<DisplayList Version="0">
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_SHADING_SMOOTH="1" />
<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_TEXEL0" A1="G_CCMUX_ENVIRONMENT" B1="G_CCMUX_0" C1="G_CCMUX_COMBINED" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
<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_TT_NONE="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="65535" T="65535" Level="0" Tile="0" On="1"/>
<SetTextureImage Path="objects/object_boss_soul/LightNoise" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b_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="0" ShiftS="0" MaskT="0" ShiftT="0"/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="1023" Dxt="128"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_32b" Line="8" 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"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,12 @@
<DisplayList Version="0">
<PipeSync/>
<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_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_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="65535" T="65535" Level="0" Tile="0" On="1"/>
<SetPrimColor M="0" L="0" R="255" G="255" B="255" A="255"/>
<EndDisplayList/>
</DisplayList>

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,15 @@
<DisplayList Version="0">
<CallDisplayList Path="objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeyringmetal"/>
<CallDisplayList Path="objects/object_housekey/gHouseKeyDL_tri_0"/>
<CallDisplayList Path="objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeytag"/>
<CallDisplayList Path="objects/object_housekey/gHouseKeyDL_tri_1"/>
<CallDisplayList Path="objects/object_housekey/mat_gHouseKeyDL_f3dlite_housekeymetal"/>
<CallDisplayList Path="objects/object_housekey/gHouseKeyDL_tri_2"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,54 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="3" V01="2" V02="4"/>
<Triangle1 V00="3" V01="4" V02="5"/>
<Triangle1 V00="5" V01="4" V02="6"/>
<Triangle1 V00="5" V01="6" V02="7"/>
<Triangle1 V00="7" V01="6" V02="8"/>
<Triangle1 V00="7" V01="8" V02="9"/>
<Triangle1 V00="9" V01="8" V02="10"/>
<Triangle1 V00="9" V01="10" V02="11"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="14" V01="15" V02="12"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_0" VertexBufferIndex="0" VertexOffset="16" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="4" V02="5"/>
<Triangle1 V00="5" V01="6" V02="3"/>
<Triangle1 V00="5" V01="7" V02="6"/>
<Triangle1 V00="8" V01="9" V02="10"/>
<Triangle1 V00="8" V01="10" V02="11"/>
<Triangle1 V00="11" V01="10" V02="12"/>
<Triangle1 V00="11" V01="12" V02="13"/>
<Triangle1 V00="13" V01="12" V02="14"/>
<Triangle1 V00="13" V01="14" V02="15"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_0" VertexBufferIndex="0" VertexOffset="32" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="4" V01="0" V02="3"/>
<Triangle1 V00="4" V01="3" V02="5"/>
<Triangle1 V00="6" V01="4" V02="5"/>
<Triangle1 V00="6" V01="5" V02="7"/>
<Triangle1 V00="8" V01="6" V02="7"/>
<Triangle1 V00="8" V01="7" V02="9"/>
<Triangle1 V00="10" V01="6" V02="8"/>
<Triangle1 V00="10" V01="11" V02="6"/>
<Triangle1 V00="12" V01="11" V02="10"/>
<Triangle1 V00="12" V01="13" V02="11"/>
<Triangle1 V00="13" V01="14" V02="11"/>
<Triangle1 V00="13" V01="15" V02="14"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_0" VertexBufferIndex="0" VertexOffset="48" Count="11"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="3" V01="4" V02="1"/>
<Triangle1 V00="3" V01="5" V02="4"/>
<Triangle1 V00="1" V01="4" V02="6"/>
<Triangle1 V00="1" V01="6" V02="7"/>
<Triangle1 V00="2" V01="1" V02="7"/>
<Triangle1 V00="2" V01="7" V02="8"/>
<Triangle1 V00="9" V01="2" V02="8"/>
<Triangle1 V00="9" V01="8" V02="10"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,43 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="4" V01="3" V02="0"/>
<Triangle1 V00="5" V01="4" V02="0"/>
<Triangle1 V00="5" V01="0" V02="6"/>
<Triangle1 V00="7" V01="5" V02="6"/>
<Triangle1 V00="7" V01="6" V02="8"/>
<Triangle1 V00="9" V01="7" V02="8"/>
<Triangle1 V00="9" V01="8" V02="3"/>
<Triangle1 V00="4" V01="9" V02="3"/>
<Triangle1 V00="9" V01="4" V02="10"/>
<Triangle1 V00="4" V01="11" V02="10"/>
<Triangle1 V00="4" V01="12" V02="11"/>
<Triangle1 V00="5" V01="12" V02="4"/>
<Triangle1 V00="5" V01="13" V02="12"/>
<Triangle1 V00="14" V01="13" V02="5"/>
<Triangle1 V00="14" V01="5" V02="7"/>
<Triangle1 V00="14" V01="7" V02="9"/>
<Triangle1 V00="14" V01="9" V02="15"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_1" VertexBufferIndex="0" VertexOffset="16" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="1" V01="3" V02="2"/>
<Triangle1 V00="2" V01="3" V02="4"/>
<Triangle1 V00="2" V01="4" V02="5"/>
<Triangle1 V00="5" V01="4" V02="6"/>
<Triangle1 V00="5" V01="6" V02="0"/>
<Triangle1 V00="0" V01="6" V02="7"/>
<Triangle1 V00="0" V01="7" V02="8"/>
<Triangle1 V00="0" V01="2" V02="5"/>
<Triangle1 V00="9" V01="10" V02="11"/>
<Triangle1 V00="9" V01="11" V02="12"/>
<Triangle1 V00="13" V01="12" V02="11"/>
<Triangle1 V00="13" V01="11" V02="14"/>
<Triangle1 V00="15" V01="13" V02="14"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_1" VertexBufferIndex="0" VertexOffset="32" Count="5"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="1" V01="3" V02="2"/>
<Triangle1 V00="1" V01="4" V02="3"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,82 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_2" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="3" V01="2" V02="4"/>
<Triangle1 V00="3" V01="4" V02="5"/>
<Triangle1 V00="5" V01="4" V02="6"/>
<Triangle1 V00="5" V01="6" V02="7"/>
<Triangle1 V00="8" V01="5" V02="7"/>
<Triangle1 V00="8" V01="7" V02="9"/>
<Triangle1 V00="10" V01="8" V02="9"/>
<Triangle1 V00="10" V01="9" V02="11"/>
<Triangle1 V00="12" V01="10" V02="11"/>
<Triangle1 V00="12" V01="11" V02="13"/>
<Triangle1 V00="14" V01="10" V02="12"/>
<Triangle1 V00="14" V01="15" V02="10"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_2" VertexBufferIndex="0" VertexOffset="16" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="3" V01="4" V02="1"/>
<Triangle1 V00="3" V01="5" V02="4"/>
<Triangle1 V00="5" V01="6" V02="4"/>
<Triangle1 V00="5" V01="7" V02="6"/>
<Triangle1 V00="4" V01="6" V02="8"/>
<Triangle1 V00="4" V01="8" V02="9"/>
<Triangle1 V00="1" V01="4" V02="9"/>
<Triangle1 V00="1" V01="9" V02="10"/>
<Triangle1 V00="11" V01="12" V02="13"/>
<Triangle1 V00="11" V01="13" V02="14"/>
<Triangle1 V00="14" V01="13" V02="15"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_2" VertexBufferIndex="0" VertexOffset="32" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="2" V01="1" V02="3"/>
<Triangle1 V00="1" V01="4" V02="3"/>
<Triangle1 V00="1" V01="5" V02="4"/>
<Triangle1 V00="2" V01="3" V02="6"/>
<Triangle1 V00="6" V01="3" V02="7"/>
<Triangle1 V00="6" V01="7" V02="8"/>
<Triangle1 V00="9" V01="2" V02="6"/>
<Triangle1 V00="9" V01="6" V02="10"/>
<Triangle1 V00="11" V01="12" V02="13"/>
<Triangle1 V00="11" V01="13" V02="14"/>
<Triangle1 V00="14" V01="13" V02="15"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_2" VertexBufferIndex="0" VertexOffset="48" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="2" V01="1" V02="3"/>
<Triangle1 V00="1" V01="4" V02="3"/>
<Triangle1 V00="1" V01="5" V02="4"/>
<Triangle1 V00="2" V01="3" V02="6"/>
<Triangle1 V00="6" V01="3" V02="7"/>
<Triangle1 V00="6" V01="7" V02="8"/>
<Triangle1 V00="9" V01="2" V02="6"/>
<Triangle1 V00="9" V01="6" V02="10"/>
<Triangle1 V00="11" V01="12" V02="13"/>
<Triangle1 V00="11" V01="13" V02="14"/>
<Triangle1 V00="14" V01="13" V02="15"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_2" VertexBufferIndex="0" VertexOffset="64" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="2" V01="1" V02="3"/>
<Triangle1 V00="1" V01="4" V02="3"/>
<Triangle1 V00="1" V01="5" V02="4"/>
<Triangle1 V00="2" V01="3" V02="6"/>
<Triangle1 V00="6" V01="3" V02="7"/>
<Triangle1 V00="6" V01="7" V02="8"/>
<Triangle1 V00="9" V01="2" V02="6"/>
<Triangle1 V00="9" V01="6" V02="10"/>
<Triangle1 V00="11" V01="12" V02="13"/>
<Triangle1 V00="11" V01="13" V02="14"/>
<Triangle1 V00="14" V01="13" V02="15"/>
<LoadVertices Path="objects/object_housekey/gHouseKeyDL_vtx_2" VertexBufferIndex="0" VertexOffset="80" Count="11"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="2" V01="1" V02="3"/>
<Triangle1 V00="1" V01="4" V02="3"/>
<Triangle1 V00="1" V01="5" V02="4"/>
<Triangle1 V00="2" V01="3" V02="6"/>
<Triangle1 V00="6" V01="3" V02="7"/>
<Triangle1 V00="6" V01="7" V02="8"/>
<Triangle1 V00="9" V01="2" V02="6"/>
<Triangle1 V00="9" V01="6" V02="10"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,61 @@
<Vertex Version="0">
<Vtx X="5" Y="3" Z="3" S="-580" T="-836" R="45" G="180" B="91" A="255"/>
<Vtx X="8" Y="4" Z="-5" S="-580" T="-1092" R="96" G="190" B="205" A="255"/>
<Vtx X="9" Y="9" Z="-5" S="-683" T="-1092" R="110" G="52" B="218" A="255"/>
<Vtx X="6" Y="8" Z="3" S="-683" T="-836" R="59" G="42" B="105" A="255"/>
<Vtx X="4" Y="11" Z="-6" S="-785" T="-1092" R="6" G="105" B="185" A="255"/>
<Vtx X="2" Y="11" Z="2" S="-785" T="-836" R="212" G="95" B="72" A="255"/>
<Vtx X="1" Y="8" Z="-7" S="-887" T="-1092" R="186" G="19" B="152" A="255"/>
<Vtx X="-2" Y="7" Z="1" S="-887" T="-836" R="135" G="9" B="38" A="255"/>
<Vtx X="3" Y="3" Z="-7" S="-990" T="-1092" R="241" G="170" B="164" A="255"/>
<Vtx X="1" Y="3" Z="1" S="-990" T="-836" R="190" G="159" B="50" A="255"/>
<Vtx X="8" Y="4" Z="-5" S="-1092" T="-1092" R="96" G="190" B="205" A="255"/>
<Vtx X="5" Y="3" Z="3" S="-1092" T="-836" R="45" G="180" B="91" A="255"/>
<Vtx X="4" Y="11" Z="-6" S="-892" T="-609" R="6" G="105" B="185" A="255"/>
<Vtx X="9" Y="9" Z="-5" S="-847" T="-746" R="110" G="52" B="218" A="255"/>
<Vtx X="8" Y="4" Z="-5" S="-964" T="-831" R="96" G="190" B="205" A="255"/>
<Vtx X="1" Y="8" Z="-7" S="-1036" T="-609" R="186" G="19" B="152" A="255"/>
<Vtx X="8" Y="4" Z="-5" S="-964" T="-831" R="96" G="190" B="205" A="255"/>
<Vtx X="3" Y="3" Z="-7" S="-1081" T="-746" R="241" G="170" B="164" A="255"/>
<Vtx X="1" Y="8" Z="-7" S="-1036" T="-609" R="186" G="19" B="152" A="255"/>
<Vtx X="1" Y="3" Z="1" S="-825" T="-746" R="190" G="159" B="50" A="255"/>
<Vtx X="5" Y="3" Z="3" S="-708" T="-831" R="45" G="180" B="91" A="255"/>
<Vtx X="6" Y="8" Z="3" S="-591" T="-746" R="59" G="42" B="105" A="255"/>
<Vtx X="-2" Y="7" Z="1" S="-780" T="-609" R="135" G="9" B="38" A="255"/>
<Vtx X="2" Y="11" Z="2" S="-636" T="-609" R="212" G="95" B="72" A="255"/>
<Vtx X="-3" Y="30" Z="-4" S="-683" T="-580" R="33" G="246" B="134" A="255"/>
<Vtx X="4" Y="17" Z="-3" S="-580" T="-580" R="22" G="11" B="131" A="255"/>
<Vtx X="3" Y="17" Z="0" S="-580" T="-751" R="195" G="251" B="111" A="255"/>
<Vtx X="-4" Y="30" Z="-1" S="-683" T="-751" R="206" G="230" B="114" A="255"/>
<Vtx X="6" Y="17" Z="0" S="-580" T="-922" R="119" G="238" B="41" A="255"/>
<Vtx X="-2" Y="33" Z="-2" S="-683" T="-922" R="50" G="114" B="26" A="255"/>
<Vtx X="4" Y="17" Z="-3" S="-580" T="-1092" R="22" G="11" B="131" A="255"/>
<Vtx X="-3" Y="30" Z="-4" S="-683" T="-1092" R="33" G="246" B="134" A="255"/>
<Vtx X="-19" Y="30" Z="-9" S="-785" T="-922" R="168" G="89" B="231" A="255"/>
<Vtx X="-2" Y="33" Z="-2" S="-683" T="-922" R="50" G="114" B="26" A="255"/>
<Vtx X="-3" Y="30" Z="-4" S="-683" T="-1092" R="33" G="246" B="134" A="255"/>
<Vtx X="-17" Y="28" Z="-10" S="-785" T="-1092" R="56" G="250" B="142" A="255"/>
<Vtx X="-21" Y="12" Z="-11" S="-887" T="-922" R="151" G="197" B="215" A="255"/>
<Vtx X="-18" Y="13" Z="-11" S="-887" T="-1092" R="59" G="18" B="145" A="255"/>
<Vtx X="-6" Y="4" Z="-6" S="-990" T="-922" R="23" G="131" B="0" A="255"/>
<Vtx X="-6" Y="7" Z="-7" S="-990" T="-1092" R="38" G="28" B="138" A="255"/>
<Vtx X="6" Y="17" Z="0" S="-1092" T="-922" R="119" G="238" B="41" A="255"/>
<Vtx X="4" Y="17" Z="-3" S="-1092" T="-1092" R="22" G="11" B="131" A="255"/>
<Vtx X="3" Y="17" Z="0" S="-1092" T="-751" R="195" G="251" B="111" A="255"/>
<Vtx X="-7" Y="6" Z="-4" S="-990" T="-751" R="211" G="12" B="118" A="255"/>
<Vtx X="4" Y="17" Z="-3" S="-1092" T="-580" R="22" G="11" B="131" A="255"/>
<Vtx X="-6" Y="7" Z="-7" S="-990" T="-580" R="38" G="28" B="138" A="255"/>
<Vtx X="-19" Y="13" Z="-8" S="-887" T="-751" R="231" G="1" B="125" A="255"/>
<Vtx X="-18" Y="13" Z="-11" S="-887" T="-580" R="59" G="18" B="145" A="255"/>
<Vtx X="-18" Y="13" Z="-11" S="-887" T="-580" R="59" G="18" B="145" A="255"/>
<Vtx X="-18" Y="28" Z="-6" S="-785" T="-751" R="229" G="234" B="122" A="255"/>
<Vtx X="-19" Y="13" Z="-8" S="-887" T="-751" R="231" G="1" B="125" A="255"/>
<Vtx X="-17" Y="28" Z="-10" S="-785" T="-580" R="56" G="250" B="142" A="255"/>
<Vtx X="-4" Y="30" Z="-1" S="-683" T="-751" R="206" G="230" B="114" A="255"/>
<Vtx X="-3" Y="30" Z="-4" S="-683" T="-580" R="33" G="246" B="134" A="255"/>
<Vtx X="-2" Y="33" Z="-2" S="-683" T="-922" R="50" G="114" B="26" A="255"/>
<Vtx X="-19" Y="30" Z="-9" S="-785" T="-922" R="168" G="89" B="231" A="255"/>
<Vtx X="-21" Y="12" Z="-11" S="-887" T="-922" R="151" G="197" B="215" A="255"/>
<Vtx X="-7" Y="6" Z="-4" S="-990" T="-751" R="211" G="12" B="118" A="255"/>
<Vtx X="-6" Y="4" Z="-6" S="-990" T="-922" R="23" G="131" B="0" A="255"/>
</Vertex>

View File

@ -0,0 +1,39 @@
<Vertex Version="0">
<Vtx X="3" Y="-11" Z="-3" S="1" T="1998" R="197" G="224" B="148" A="255"/>
<Vtx X="47" Y="-19" Z="11" S="2015" T="1042" R="122" G="6" B="222" A="255"/>
<Vtx X="30" Y="-38" Z="4" S="2015" T="1998" R="28" G="157" B="181" A="255"/>
<Vtx X="20" Y="8" Z="4" S="1" T="1042" R="57" G="98" B="199" A="255"/>
<Vtx X="3" Y="-2" Z="-3" S="211" T="1772" R="214" G="174" B="169" A="255"/>
<Vtx X="2" Y="-2" Z="0" S="211" T="1772" R="157" G="221" B="72" A="255"/>
<Vtx X="2" Y="-11" Z="-1" S="1" T="1998" R="144" G="214" B="42" A="255"/>
<Vtx X="11" Y="7" Z="4" S="211" T="1268" R="245" G="63" B="110" A="255"/>
<Vtx X="19" Y="8" Z="6" S="1" T="1042" R="4" G="87" B="93" A="255"/>
<Vtx X="12" Y="8" Z="1" S="211" T="1268" R="99" G="75" B="230" A="255"/>
<Vtx X="4" Y="-2" Z="-5" S="211" T="1772" R="28" G="157" B="181" A="255"/>
<Vtx X="-6" Y="9" Z="-8" S="778" T="1772" R="198" G="245" B="143" A="255"/>
<Vtx X="-8" Y="9" Z="-6" S="853" T="1772" R="136" G="12" B="215" A="255"/>
<Vtx X="-8" Y="8" Z="-3" S="778" T="1772" R="140" G="234" B="48" A="255"/>
<Vtx X="1" Y="18" Z="0" S="778" T="1268" R="239" G="87" B="91" A="255"/>
<Vtx X="1" Y="19" Z="-2" S="853" T="1268" R="239" G="126" B="2" A="255"/>
<Vtx X="1" Y="19" Z="-2" S="853" T="1268" R="239" G="126" B="2" A="255"/>
<Vtx X="12" Y="8" Z="1" S="211" T="1268" R="99" G="75" B="230" A="255"/>
<Vtx X="13" Y="8" Z="-2" S="211" T="1268" R="122" G="6" B="222" A="255"/>
<Vtx X="4" Y="-2" Z="-5" S="211" T="1772" R="28" G="157" B="181" A="255"/>
<Vtx X="-6" Y="9" Z="-8" S="778" T="1772" R="198" G="245" B="143" A="255"/>
<Vtx X="2" Y="19" Z="-5" S="778" T="1268" R="40" G="98" B="186" A="255"/>
<Vtx X="-8" Y="9" Z="-6" S="853" T="1772" R="136" G="12" B="215" A="255"/>
<Vtx X="-8" Y="8" Z="-3" S="778" T="1772" R="140" G="234" B="48" A="255"/>
<Vtx X="1" Y="18" Z="0" S="778" T="1268" R="239" G="87" B="91" A="255"/>
<Vtx X="2" Y="-11" Z="-1" S="-16" T="1008" R="144" G="214" B="42" A="255"/>
<Vtx X="3" Y="-11" Z="-3" S="-16" T="1008" R="197" G="224" B="148" A="255"/>
<Vtx X="30" Y="-38" Z="4" S="2032" T="1008" R="28" G="157" B="181" A="255"/>
<Vtx X="29" Y="-38" Z="7" S="2032" T="1008" R="235" G="148" B="63" A="255"/>
<Vtx X="46" Y="-19" Z="14" S="2032" T="-16" R="73" G="253" B="104" A="255"/>
<Vtx X="47" Y="-19" Z="11" S="2032" T="-16" R="122" G="6" B="222" A="255"/>
<Vtx X="20" Y="8" Z="4" S="-16" T="-16" R="57" G="98" B="199" A="255"/>
<Vtx X="20" Y="8" Z="4" S="-16" T="-16" R="57" G="98" B="199" A="255"/>
<Vtx X="19" Y="8" Z="6" S="-16" T="-16" R="4" G="87" B="93" A="255"/>
<Vtx X="46" Y="-19" Z="14" S="2032" T="-16" R="73" G="253" B="104" A="255"/>
<Vtx X="29" Y="-38" Z="7" S="2032" T="1008" R="235" G="148" B="63" A="255"/>
<Vtx X="2" Y="-11" Z="-1" S="-16" T="1008" R="144" G="214" B="42" A="255"/>
</Vertex>

View File

@ -0,0 +1,93 @@
<Vertex Version="0">
<Vtx X="-11" Y="19" Z="-12" S="-708" T="-580" R="193" G="214" B="154" A="255"/>
<Vtx X="-20" Y="19" Z="-7" S="-580" T="-580" R="204" G="214" B="148" A="255"/>
<Vtx X="-17" Y="21" Z="-2" S="-580" T="-751" R="60" G="53" B="99" A="255"/>
<Vtx X="-8" Y="21" Z="-7" S="-708" T="-751" R="50" G="53" B="104" A="255"/>
<Vtx X="-21" Y="16" Z="-1" S="-580" T="-922" R="197" G="170" B="72" A="255"/>
<Vtx X="-5" Y="16" Z="-10" S="-708" T="-922" R="97" G="176" B="240" A="255"/>
<Vtx X="-20" Y="19" Z="-7" S="-580" T="-1092" R="204" G="214" B="148" A="255"/>
<Vtx X="-11" Y="19" Z="-12" S="-708" T="-1092" R="193" G="214" B="154" A="255"/>
<Vtx X="-9" Y="33" Z="-16" S="-836" T="-922" R="59" G="86" B="184" A="255"/>
<Vtx X="-13" Y="28" Z="-15" S="-836" T="-1092" R="196" G="203" B="157" A="255"/>
<Vtx X="-25" Y="33" Z="-7" S="-964" T="-922" R="159" G="80" B="16" A="255"/>
<Vtx X="-22" Y="28" Z="-10" S="-964" T="-1092" R="206" G="203" B="152" A="255"/>
<Vtx X="-21" Y="16" Z="-1" S="-1092" T="-922" R="197" G="170" B="72" A="255"/>
<Vtx X="-20" Y="19" Z="-7" S="-1092" T="-1092" R="204" G="214" B="148" A="255"/>
<Vtx X="-17" Y="21" Z="-2" S="-1092" T="-751" R="60" G="53" B="99" A="255"/>
<Vtx X="-19" Y="30" Z="-5" S="-964" T="-751" R="63" G="42" B="102" A="255"/>
<Vtx X="-20" Y="19" Z="-7" S="-1092" T="-580" R="204" G="214" B="148" A="255"/>
<Vtx X="-19" Y="30" Z="-5" S="-964" T="-751" R="63" G="42" B="102" A="255"/>
<Vtx X="-17" Y="21" Z="-2" S="-1092" T="-751" R="60" G="53" B="99" A="255"/>
<Vtx X="-22" Y="28" Z="-10" S="-964" T="-580" R="206" G="203" B="152" A="255"/>
<Vtx X="-10" Y="31" Z="-10" S="-836" T="-751" R="52" G="42" B="108" A="255"/>
<Vtx X="-13" Y="28" Z="-15" S="-836" T="-580" R="196" G="203" B="157" A="255"/>
<Vtx X="-8" Y="21" Z="-7" S="-708" T="-751" R="50" G="53" B="104" A="255"/>
<Vtx X="-11" Y="19" Z="-12" S="-708" T="-580" R="193" G="214" B="154" A="255"/>
<Vtx X="-5" Y="16" Z="-10" S="-708" T="-922" R="97" G="176" B="240" A="255"/>
<Vtx X="-9" Y="33" Z="-16" S="-836" T="-922" R="59" G="86" B="184" A="255"/>
<Vtx X="-25" Y="33" Z="-7" S="-964" T="-922" R="159" G="80" B="16" A="255"/>
<Vtx X="-21" Y="22" Z="-4" S="-900" T="-580" R="211" G="116" B="228" A="255"/>
<Vtx X="-20" Y="19" Z="-7" S="-772" T="-580" R="245" G="10" B="130" A="255"/>
<Vtx X="-35" Y="-3" Z="11" S="-772" T="-708" R="176" G="167" B="213" A="255"/>
<Vtx X="-36" Y="0" Z="14" S="-900" T="-708" R="142" G="15" B="55" A="255"/>
<Vtx X="-31" Y="-4" Z="13" S="-772" T="-836" R="45" G="140" B="28" A="255"/>
<Vtx X="-36" Y="0" Z="14" S="-900" T="-708" R="142" G="15" B="55" A="255"/>
<Vtx X="-31" Y="-4" Z="13" S="-772" T="-836" R="45" G="140" B="28" A="255"/>
<Vtx X="-32" Y="0" Z="17" S="-900" T="-836" R="11" G="246" B="126" A="255"/>
<Vtx X="-16" Y="18" Z="-5" S="-772" T="-964" R="114" G="241" B="201" A="255"/>
<Vtx X="-20" Y="19" Z="-7" S="-644" T="-964" R="245" G="10" B="130" A="255"/>
<Vtx X="-35" Y="-3" Z="11" S="-644" T="-836" R="176" G="167" B="213" A="255"/>
<Vtx X="-17" Y="21" Z="-2" S="-900" T="-964" R="80" G="89" B="43" A="255"/>
<Vtx X="-20" Y="19" Z="-7" S="-772" T="-1092" R="245" G="10" B="130" A="255"/>
<Vtx X="-21" Y="22" Z="-4" S="-900" T="-1092" R="211" G="116" B="228" A="255"/>
<Vtx X="-36" Y="0" Z="14" S="-1028" T="-836" R="142" G="15" B="55" A="255"/>
<Vtx X="-21" Y="22" Z="-4" S="-1028" T="-964" R="211" G="116" B="228" A="255"/>
<Vtx X="-30" Y="3" Z="10" S="-900" T="-580" R="105" G="24" B="188" A="255"/>
<Vtx X="-33" Y="0" Z="9" S="-772" T="-580" R="10" G="171" B="162" A="255"/>
<Vtx X="-40" Y="5" Z="10" S="-772" T="-708" R="154" G="7" B="181" A="255"/>
<Vtx X="-37" Y="9" Z="11" S="-900" T="-708" R="249" G="117" B="206" A="255"/>
<Vtx X="-40" Y="5" Z="14" S="-772" T="-836" R="151" G="232" B="68" A="255"/>
<Vtx X="-37" Y="9" Z="11" S="-900" T="-708" R="249" G="117" B="206" A="255"/>
<Vtx X="-40" Y="5" Z="14" S="-772" T="-836" R="151" G="232" B="68" A="255"/>
<Vtx X="-37" Y="8" Z="15" S="-900" T="-836" R="246" G="85" B="94" A="255"/>
<Vtx X="-33" Y="-1" Z="13" S="-772" T="-964" R="7" G="139" B="50" A="255"/>
<Vtx X="-33" Y="0" Z="9" S="-644" T="-964" R="10" G="171" B="162" A="255"/>
<Vtx X="-40" Y="5" Z="10" S="-644" T="-836" R="154" G="7" B="181" A="255"/>
<Vtx X="-30" Y="2" Z="14" S="-900" T="-964" R="102" G="249" B="75" A="255"/>
<Vtx X="-33" Y="0" Z="9" S="-772" T="-1092" R="10" G="171" B="162" A="255"/>
<Vtx X="-30" Y="3" Z="10" S="-900" T="-1092" R="105" G="24" B="188" A="255"/>
<Vtx X="-37" Y="9" Z="11" S="-1028" T="-836" R="249" G="117" B="206" A="255"/>
<Vtx X="-30" Y="3" Z="10" S="-1028" T="-964" R="105" G="24" B="188" A="255"/>
<Vtx X="-28" Y="7" Z="7" S="-900" T="-580" R="105" G="24" B="188" A="255"/>
<Vtx X="-30" Y="4" Z="6" S="-772" T="-580" R="10" G="171" B="162" A="255"/>
<Vtx X="-35" Y="9" Z="7" S="-772" T="-708" R="154" G="7" B="181" A="255"/>
<Vtx X="-33" Y="11" Z="8" S="-900" T="-708" R="249" G="117" B="206" A="255"/>
<Vtx X="-35" Y="8" Z="10" S="-772" T="-836" R="151" G="232" B="68" A="255"/>
<Vtx X="-33" Y="11" Z="8" S="-900" T="-708" R="249" G="117" B="206" A="255"/>
<Vtx X="-35" Y="8" Z="10" S="-772" T="-836" R="151" G="232" B="68" A="255"/>
<Vtx X="-33" Y="11" Z="11" S="-900" T="-836" R="246" G="85" B="94" A="255"/>
<Vtx X="-30" Y="4" Z="9" S="-772" T="-964" R="7" G="139" B="50" A="255"/>
<Vtx X="-30" Y="4" Z="6" S="-644" T="-964" R="10" G="171" B="162" A="255"/>
<Vtx X="-35" Y="9" Z="7" S="-644" T="-836" R="154" G="7" B="181" A="255"/>
<Vtx X="-28" Y="6" Z="10" S="-900" T="-964" R="102" G="249" B="75" A="255"/>
<Vtx X="-30" Y="4" Z="6" S="-772" T="-1092" R="10" G="171" B="162" A="255"/>
<Vtx X="-28" Y="7" Z="7" S="-900" T="-1092" R="105" G="24" B="188" A="255"/>
<Vtx X="-33" Y="11" Z="8" S="-1028" T="-836" R="249" G="117" B="206" A="255"/>
<Vtx X="-28" Y="7" Z="7" S="-1028" T="-964" R="105" G="24" B="188" A="255"/>
<Vtx X="-24" Y="12" Z="2" S="-900" T="-580" R="105" G="24" B="188" A="255"/>
<Vtx X="-27" Y="9" Z="1" S="-772" T="-580" R="10" G="171" B="162" A="255"/>
<Vtx X="-35" Y="15" Z="2" S="-772" T="-708" R="154" G="7" B="181" A="255"/>
<Vtx X="-32" Y="19" Z="3" S="-900" T="-708" R="249" G="117" B="206" A="255"/>
<Vtx X="-35" Y="14" Z="7" S="-772" T="-836" R="151" G="232" B="68" A="255"/>
<Vtx X="-32" Y="19" Z="3" S="-900" T="-708" R="249" G="117" B="206" A="255"/>
<Vtx X="-35" Y="14" Z="7" S="-772" T="-836" R="151" G="232" B="68" A="255"/>
<Vtx X="-32" Y="18" Z="8" S="-900" T="-836" R="246" G="85" B="94" A="255"/>
<Vtx X="-27" Y="8" Z="6" S="-772" T="-964" R="7" G="139" B="50" A="255"/>
<Vtx X="-27" Y="9" Z="1" S="-644" T="-964" R="10" G="171" B="162" A="255"/>
<Vtx X="-35" Y="15" Z="2" S="-644" T="-836" R="154" G="7" B="181" A="255"/>
<Vtx X="-24" Y="11" Z="7" S="-900" T="-964" R="102" G="249" B="75" A="255"/>
<Vtx X="-27" Y="9" Z="1" S="-772" T="-1092" R="10" G="171" B="162" A="255"/>
<Vtx X="-24" Y="12" Z="2" S="-900" T="-1092" R="105" G="24" B="188" A="255"/>
<Vtx X="-32" Y="19" Z="3" S="-1028" T="-836" R="249" G="117" B="206" A="255"/>
<Vtx X="-24" Y="12" Z="2" S="-1028" T="-964" R="105" G="24" B="188" A="255"/>
</Vertex>

View File

@ -0,0 +1,20 @@
<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_ENVIRONMENT" 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" />
<ClearGeometryMode G_CULL_FRONT="1" G_TEXTURE_GEN_LINEAR="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="960" T="960" Level="0" Tile="0" On="1"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_housekey/Hilite_new" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_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="4" ShiftS="0" MaskT="4" ShiftT="0"/>
<LoadSync/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="255" Dxt="512"/>
<PipeSync/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b" 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="4" ShiftS="0" MaskT="4" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="60" Lrt="60"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,21 @@
<DisplayList Version="0">
<PipeSync/>
<SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_SHADE" D0="G_CCMUX_0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_TEXTURE_GEN="1" G_SHADING_SMOOTH="1" />
<ClearGeometryMode G_CULL_FRONT="1" G_TEXTURE_GEN_LINEAR="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="960" T="960" Level="0" Tile="0" On="1"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_housekey/Hilite_new" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_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="4" ShiftS="0" MaskT="4" ShiftT="0"/>
<LoadSync/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="255" Dxt="512"/>
<PipeSync/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b" 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="4" ShiftS="0" MaskT="4" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="60" Lrt="60"/>
<SetPrimColor M="0" L="0" R="255" G="255" B="218" A="255"/>
<EndDisplayList/>
</DisplayList>

View File

@ -0,0 +1,21 @@
<DisplayList Version="0">
<PipeSync/>
<SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_SHADE" D0="G_CCMUX_0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_SHADING_SMOOTH="1" />
<ClearGeometryMode G_CULL_FRONT="1" G_TEXTURE_GEN="1" G_TEXTURE_GEN_LINEAR="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="65535" T="65535" Level="0" Tile="0" On="1"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_housekey/HouseKey_Tag" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_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="6" ShiftS="0" MaskT="6" ShiftT="0"/>
<LoadSync/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="4095" Dxt="128"/>
<PipeSync/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b" Line="16" TMem="0" Tile="0" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="6" ShiftS="0" MaskT="6" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="252" Lrt="252"/>
<SetPrimColor M="0" L="0" R="255" G="255" B="255" A="255"/>
<EndDisplayList/>
</DisplayList>

View File

@ -237,6 +237,9 @@ static const ALIGN_ASSET(2) char gKeyringKeysShadowTempleMQDL[] = dgKeyringKeysS
#define dgKeyringKeysGanonsCastleMQDL "__OTR__objects/object_keyring/gKeyringKeysGanonsCastleMQDL"
static const ALIGN_ASSET(2) char gKeyringKeysGanonsCastleMQDL[] = dgKeyringKeysGanonsCastleMQDL;
#define dgHouseKeyDL "__OTR__objects/object_housekey/gHouseKeyDL"
static const ALIGN_ASSET(2) char gHouseKeyDL[] = dgHouseKeyDL;
// overlays
#define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx"
static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx;
@ -335,3 +338,10 @@ static const ALIGN_ASSET(2) char gLinkAdultGoronTunicSkel[] = dgLinkAdultGoronTu
#define dgLinkAdultZoraTunicSkel "__OTR__objects/object_link_boy_zora/gLinkAdultZoraTunicSkel"
static const ALIGN_ASSET(2) char gLinkAdultZoraTunicSkel[] = dgLinkAdultZoraTunicSkel;
// LUS Logo
#define dgShipLogoDL "__OTR__textures/nintendo_rogo_static/gShipLogoDL"
static const ALIGN_ASSET(2) char gShipLogoDL[] = dgShipLogoDL;
#define dnintendo_rogo_static_Tex_LUS_000000 "__OTR__textures/nintendo_rogo_static/nintendo_rogo_static_Tex_LUS_000000"
static const ALIGN_ASSET(2) char nintendo_rogo_static_Tex_LUS_000000[] = dnintendo_rogo_static_Tex_LUS_000000;

View File

@ -275,7 +275,12 @@ extern GraphicsContext* __gfxCtx;
: (((a2) >= (a3)) ? (a2) : (((a3) >= (a1)) ? (a1) : (a3))))
#define MATRIX_TOMTX(dest) Matrix_ToMtx(dest, __FILE__, __LINE__)
#ifdef __cplusplus
#define MATRIX_NEWMTX(gfxCtx) Matrix_NewMtx(gfxCtx, const_cast<char*>(__FILE__), __LINE__)
#else
#define MATRIX_NEWMTX(gfxCtx) Matrix_NewMtx(gfxCtx, __FILE__, __LINE__)
#endif
#define MATRIX_CHECKFLOATS(mf) Matrix_CheckFloats(mf, __FILE__, __LINE__)
#define ZELDA_ARENA_MALLOC_DEBUG(size) ZeldaArena_MallocDebug(size, __FILE__, __LINE__)

103
soh/soh/AboutWindow.cpp Normal file
View File

@ -0,0 +1,103 @@
#include "AboutWindow.h"
#include <imgui.h>
#include <soh/GameVersions.h>
#include "soh/ResourceManagerHelpers.h"
extern "C" {
#include "variables.h"
}
AboutWindow::~AboutWindow() {
SPDLOG_TRACE("destruct about window");
}
void AboutWindow::InitElement() {
mIsTaggedVersion = gGitCommitTag[0] != 0;
strncpy(mGitCommitHashTruncated, (char*)gGitCommitHash, 7);
mGitCommitHashTruncated[7] = 0;
}
void AboutWindow::Draw() {
if (!IsVisible()) {
return;
}
ImGuiWindowFlags windowFlags = ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoDocking |
ImGuiWindowFlags_NoScrollWithMouse |
ImGuiWindowFlags_NoScrollbar;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(16 * ImGui::GetIO().FontGlobalScale, 8 * ImGui::GetIO().FontGlobalScale));
if (!ImGui::Begin(GetName().c_str(), &mIsVisible, windowFlags)) {
ImGui::End();
} else {
DrawElement();
ImGui::End();
}
ImGui::PopStyleVar();
// Sync up the IsVisible flag if it was changed by ImGui
SyncVisibilityConsoleVariable();
}
const char* AboutWindow::GetGameVersionString(uint32_t index) {
uint32_t gameVersion = ResourceMgr_GetGameVersion(index);
switch (gameVersion) {
case OOT_NTSC_US_10:
return "NTSC-U 1.0";
case OOT_NTSC_US_11:
return "NTSC-U 1.1";
case OOT_NTSC_US_12:
return "NTSC-U 1.2";
case OOT_PAL_10:
return "PAL 1.0";
case OOT_PAL_11:
return "PAL 1.1";
case OOT_PAL_GC:
return "PAL GC";
case OOT_PAL_MQ:
return "PAL MQ";
case OOT_PAL_GC_DBG1:
case OOT_PAL_GC_DBG2:
return "PAL GC-D";
case OOT_PAL_GC_MQ_DBG:
return "PAL MQ-D";
case OOT_IQUE_CN:
return "IQUE CN";
case OOT_IQUE_TW:
return "IQUE TW";
default:
return "UNKNOWN";
}
}
void AboutWindow::DrawElement() {
// The icon is already padded - adjust for that
ImVec2 cursorPos = ImGui::GetCursorScreenPos();
cursorPos.x -= 16 * ImGui::GetIO().FontGlobalScale;
ImGui::SetCursorScreenPos(cursorPos);
ImGui::Image(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("Game_Icon"), ImVec2(64.0f * ImGui::GetIO().FontGlobalScale, 64.0f * ImGui::GetIO().FontGlobalScale));
ImGui::SameLine();
ImGui::BeginGroup();
ImGui::Text("Ship of Harkinian");
if (mIsTaggedVersion) {
ImGui::Text("%s", gBuildVersion);
} else {
ImGui::Text("%s", gGitBranch);
ImGui::Text("%s", mGitCommitHashTruncated);
}
ImGui::EndGroup();
ImGui::Dummy(ImVec2(0, 2 * ImGui::GetIO().FontGlobalScale));
ImGui::Text("Game Archives:");
for (uint32_t i = 0; i < ResourceMgr_GetNumGameVersions(); i++) {
ImGui::BulletText(GetGameVersionString(i));
}
}

20
soh/soh/AboutWindow.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <libultraship/libultraship.h>
class AboutWindow : public Ship::GuiWindow {
public:
using GuiWindow::GuiWindow;
~AboutWindow();
private:
void InitElement() override;
void Draw() override;
void DrawElement() override;
void UpdateElement() override {};
const char* GetGameVersionString(uint32_t index);
bool mIsTaggedVersion;
char mGitCommitHashTruncated[8];
};

View File

@ -0,0 +1,40 @@
#include <libultraship/libultraship.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "variables.h"
#include "overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h"
}
#define CVAR_FRAME_ADVANCE_NAME CVAR_CHEAT("EasyFrameAdvance")
#define CVAR_FRAME_ADVANCE_DEFAULT 0
#define CVAR_FRAME_ADVANCE_VALUE CVarGetInteger(CVAR_FRAME_ADVANCE_NAME, CVAR_FRAME_ADVANCE_DEFAULT)
static int frameAdvanceTimer = 0;
#define PAUSE_STATE_OFF 0
#define PAUSE_STATE_UNPAUSE_CLOSE 19
void RegisterEasyFrameAdvance() {
COND_HOOK(OnGameStateMainStart, CVAR_FRAME_ADVANCE_VALUE, []() {
if (gPlayState == NULL) {
return;
}
Input* input = &gPlayState->state.input[0];
PauseContext* pauseCtx = &gPlayState->pauseCtx;
if (frameAdvanceTimer > 0 && pauseCtx->state == PAUSE_STATE_OFF) {
frameAdvanceTimer--;
if (frameAdvanceTimer == 0 && CHECK_BTN_ALL(input->cur.button, BTN_START)) {
input->press.button |= BTN_START;
}
}
if (pauseCtx->state == PAUSE_STATE_UNPAUSE_CLOSE) {
frameAdvanceTimer = 2;
}
});
}
static RegisterShipInitFunc initFunc(RegisterEasyFrameAdvance, { CVAR_FRAME_ADVANCE_NAME });

View File

@ -0,0 +1,203 @@
#include "libultraship/bridge.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "soh/Enhancements/randomizer/3drando/random.hpp"
#include "soh/Notification/Notification.h"
#include "soh/OTRGlobals.h"
extern "C" {
#include "variables.h"
#include "functions.h"
#include "macros.h"
extern PlayState* gPlayState;
GetItemEntry ItemTable_RetrieveEntry(s16 modIndex, s16 getItemID);
}
#define CVAR_EXTRA_TRAPS_NAME CVAR_ENHANCEMENT("ExtraTraps.Enabled")
#define CVAR_EXTRA_TRAPS_DEFAULT 0
#define CVAR_EXTRA_TRAPS_VALUE CVarGetInteger(CVAR_EXTRA_TRAPS_NAME, CVAR_EXTRA_TRAPS_DEFAULT)
typedef enum {
ADD_ICE_TRAP,
ADD_BURN_TRAP,
ADD_SHOCK_TRAP,
ADD_KNOCK_TRAP,
ADD_SPEED_TRAP,
ADD_BOMB_TRAP,
ADD_VOID_TRAP,
ADD_AMMO_TRAP,
ADD_KILL_TRAP,
ADD_TELEPORT_TRAP,
ADD_TRAP_MAX
} AltTrapType;
static AltTrapType roll = ADD_TRAP_MAX;
static int statusTimer = -1;
static int eventTimer = -1;
const char* altTrapTypeCvars[] = {
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 () {
std::vector<AltTrapType> enabledAddTraps;
for (int i = 0; i < ADD_TRAP_MAX; i++) {
if (CVarGetInteger(altTrapTypeCvars[i], 0)) {
if (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && (i == ADD_VOID_TRAP || i == ADD_TELEPORT_TRAP)) {
continue; // don't add void or teleport if you're holding the fishing pole, as this causes issues
}
enabledAddTraps.push_back(static_cast<AltTrapType>(i));
}
}
if (enabledAddTraps.size() == 0) {
enabledAddTraps.push_back(ADD_ICE_TRAP);
}
return enabledAddTraps;
};
static void RollRandomTrap(uint32_t seed) {
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
Random_Init(finalSeed);
roll = RandomElement(getEnabledAddTraps());
switch (roll) {
case ADD_ICE_TRAP:
GameInteractor::RawAction::FreezePlayer();
break;
case ADD_BURN_TRAP:
GameInteractor::RawAction::BurnPlayer();
break;
case ADD_SHOCK_TRAP:
GameInteractor::RawAction::ElectrocutePlayer();
break;
case ADD_KNOCK_TRAP:
eventTimer = 3;
break;
case ADD_SPEED_TRAP:
Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
GameInteractor::State::RunSpeedModifier = -2;
statusTimer = 200;
Notification::Emit({ .message = "Speed Decreased!" });
break;
case ADD_BOMB_TRAP:
eventTimer = 3;
break;
case ADD_VOID_TRAP:
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
eventTimer = 3;
break;
case ADD_AMMO_TRAP:
eventTimer = 3;
Notification::Emit({ .message = "Ammo Halved!" });
break;
case ADD_KILL_TRAP:
GameInteractor::RawAction::SetPlayerHealth(0);
break;
case ADD_TELEPORT_TRAP:
eventTimer = 3;
break;
default:
break;
}
}
static void OnPlayerUpdate() {
Player* player = GET_PLAYER(gPlayState);
if (statusTimer == 0) {
GameInteractor::State::RunSpeedModifier = 0;
}
if (eventTimer == 0) {
switch (roll) {
case ADD_KNOCK_TRAP:
GameInteractor::RawAction::KnockbackPlayer(1);
break;
case ADD_BOMB_TRAP:
GameInteractor::RawAction::SpawnActor(ACTOR_EN_BOM, 1);
break;
case ADD_VOID_TRAP:
Play_TriggerRespawn(gPlayState);
break;
case ADD_AMMO_TRAP:
AMMO(ITEM_STICK) = AMMO(ITEM_STICK) * 0.5;
AMMO(ITEM_NUT) = AMMO(ITEM_NUT) * 0.5;
AMMO(ITEM_SLINGSHOT) = AMMO(ITEM_SLINGSHOT) * 0.5;
AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5;
AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5;
AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5;
Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
break;
case ADD_TELEPORT_TRAP: {
int entrance;
int index = Random(0, 7);
switch (index) {
case 0:
entrance = GI_TP_DEST_SERENADE;
break;
case 1:
entrance = GI_TP_DEST_REQUIEM;
break;
case 2:
entrance = GI_TP_DEST_BOLERO;
break;
case 3:
entrance = GI_TP_DEST_MINUET;
break;
case 4:
entrance = GI_TP_DEST_NOCTURNE;
break;
case 5:
entrance = GI_TP_DEST_PRELUDE;
break;
default:
entrance = GI_TP_DEST_LINKSHOUSE;
break;
}
GameInteractor::RawAction::TeleportPlayer(entrance);
break;
}
default:
break;
}
}
if (statusTimer >= 0) {
statusTimer--;
}
if (eventTimer >= 0) {
eventTimer--;
}
}
void RegisterExtraTraps() {
COND_HOOK(OnPlayerUpdate, CVAR_EXTRA_TRAPS_VALUE, OnPlayerUpdate);
COND_VB_SHOULD(VB_SHORT_CIRCUIT_GIVE_ITEM_PROCESS, true, {
if (!gSaveContext.ship.pendingIceTrapCount) {
return;
}
Player* player = GET_PLAYER(gPlayState);
*should = true;
gSaveContext.ship.pendingIceTrapCount--;
gSaveContext.ship.stats.count[COUNT_ICE_TRAPS]++;
GameInteractor_ExecuteOnItemReceiveHooks(ItemTable_RetrieveEntry(MOD_RANDOMIZER, RG_ICE_TRAP));
if (CVAR_EXTRA_TRAPS_VALUE) {
RollRandomTrap(gPlayState->sceneNum + player->getItemEntry.drawItemId);
} else {
GameInteractor::RawAction::FreezePlayer();
}
});
}
static RegisterShipInitFunc initFunc(RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME });

View File

@ -13,7 +13,7 @@ std::array<std::string, LANGUAGE_MAX> RandomizerSettingsMenuText[RSM_MAX] = {
// German
"Start Randomizer",
// French
"Start Randomizer",
"Commencer le Randomizer",
},
{
// English
@ -21,7 +21,7 @@ std::array<std::string, LANGUAGE_MAX> RandomizerSettingsMenuText[RSM_MAX] = {
// German
"Generate New Randomizer Seed",
// French
"Generate New Randomizer Seed",
"Générer une nouvelle seed pour le Randomizer",
},
{
// English
@ -29,7 +29,7 @@ std::array<std::string, LANGUAGE_MAX> RandomizerSettingsMenuText[RSM_MAX] = {
// German
"Open Randomizer Settings",
// French
"Open Randomizer Settings",
"Ouvrir les paramètres du Randomizer",
},
{
// English
@ -37,7 +37,7 @@ std::array<std::string, LANGUAGE_MAX> RandomizerSettingsMenuText[RSM_MAX] = {
// German
"Generating...",
// French
"Generating...",
"Génération en cours...",
},
{
// English

View File

@ -0,0 +1,83 @@
#include <libultraship/libultraship.h>
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
#include "variables.h"
#include "overlays/misc/ovl_kaleido_scope/z_kaleido_scope.h"
}
#define CVAR_BUFFER_NAME CVAR_ENHANCEMENT("PauseBufferWindow")
#define CVAR_BUFFER_DEFAULT 0
#define CVAR_BUFFER_VALUE CVarGetInteger(CVAR_BUFFER_NAME, CVAR_BUFFER_DEFAULT)
#define CVAR_INCLUDE_NAME CVAR_ENHANCEMENT("IncludeHeldInputsBufferWindow")
#define CVAR_INCLUDE_DEFAULT 0
#define CVAR_INCLUDE_VALUE CVarGetInteger(CVAR_INCLUDE_NAME, CVAR_INCLUDE_DEFAULT)
#define CVAR_FRAME_ADVANCE_NAME CVAR_CHEAT("EasyFrameAdvance")
#define CVAR_FRAME_ADVANCE_DEFAULT 0
#define CVAR_FRAME_ADVANCE_VALUE CVarGetInteger(CVAR_FRAME_ADVANCE_NAME, CVAR_FRAME_ADVANCE_DEFAULT)
static u16 inputBufferTimer = 0;
static u16 prePauseInputs = 0;
static u16 pauseInputs = 0;
#define PAUSE_STATE_OFF 0
#define PAUSE_STATE_OPENING_1 2
#define PAUSE_STATE_UNPAUSE_SETUP 18
void RegisterPauseBufferInputs() {
COND_VB_SHOULD(VB_KALEIDO_UNPAUSE_CLOSE, CVAR_BUFFER_VALUE || CVAR_INCLUDE_VALUE, {
Input* input = &gPlayState->state.input[0];
// Store all inputs that were pressed during the buffer window
pauseInputs |= input->press.button;
// If the user opts to include held inputs in the buffer window, store the held inputs, minus the held inputs when the pause menu was opened
if (CVAR_INCLUDE_VALUE && inputBufferTimer == 0) {
pauseInputs |= input->cur.button & ~prePauseInputs;
prePauseInputs = 0;
}
// Wait a specified number of frames before continuing the unpause
inputBufferTimer++;
if (inputBufferTimer < CVAR_BUFFER_VALUE) {
*should = false;
}
});
COND_HOOK(OnGameStateMainStart, CVAR_BUFFER_VALUE || CVAR_INCLUDE_VALUE, []() {
if (gPlayState == NULL) {
return;
}
Input* input = &gPlayState->state.input[0];
PauseContext* pauseCtx = &gPlayState->pauseCtx;
// if the input buffer timer is not 0 and the pause state is off, then the player just unpaused
if (inputBufferTimer != 0 && pauseCtx->state == PAUSE_STATE_OFF) {
inputBufferTimer = 0;
// If the user opts into easy frame advance, remove START input
if (CVAR_FRAME_ADVANCE_VALUE) {
pauseInputs &= ~BTN_START;
}
// So we need to re-apply the inputs that were pressed during the buffer window
input->press.button |= pauseInputs;
}
// Reset the timer and stored inputs at the beginning of the unpause process
if (pauseCtx->state == PAUSE_STATE_UNPAUSE_SETUP && pauseCtx->unk_1F4 != 160.0f) {
inputBufferTimer = 0;
pauseInputs = 0;
}
// If the user opts to include held inputs in the buffer window, store the held inputs at the beginning of the pause process, minus the START input
if (pauseCtx->state == PAUSE_STATE_OPENING_1 && CVAR_INCLUDE_VALUE) {
prePauseInputs = input->cur.button & ~BTN_START;
}
});
}
static RegisterShipInitFunc initFunc(RegisterPauseBufferInputs, { CVAR_BUFFER_NAME, CVAR_INCLUDE_NAME });

View File

@ -196,7 +196,6 @@ void TimeDisplayWindow::Draw() {
uint16_t textureIndex = 0;
for (size_t i = 0; i < textLength; i++) {
ImVec2 originalCursorPos = ImGui::GetCursorPos();
if (textToDecode[i] == ':' || textToDecode[i] == '.') {
textureIndex = 10;
} else {

View File

@ -10,7 +10,7 @@ extern "C" {
#include "variables.h"
}
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex()
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
static bool sEnteredBlueWarp = false;

View File

@ -12,14 +12,6 @@
#include "soh/OTRGlobals.h"
#include "soh/cvar_prefixes.h"
uint8_t gLoadFileSelect = 0, gSkipLogoTest = 0;
extern BootCommandFunc BootCommands_Command_SkipLogo(char** argv, s32 argc);
extern BootCommandFunc BootCommands_Command_LoadFileSelect(char** argv, s32 argc);
static BootCommand sCommands[] = { { "--skiplogo", BootCommands_Command_SkipLogo },
{ "--loadfileselect", BootCommands_Command_LoadFileSelect } };
void BootCommands_Init()
{
// Clears vars to prevent randomizer menu from being disabled
@ -28,48 +20,7 @@ void BootCommands_Init()
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(CVAR_IMGUI_CONTROLLER_NAV, 1); // always enable controller nav on switch/wii u
#endif
}
//void BootCommands_ParseBootArgs(char* str)
void BootCommands_ParseBootArgs(s32 argc, char** argv)
{
s32 i;
// Parse the commands
for (i = 0; i < argc; i++) {
s32 j;
for (j = 0; j < ARRAY_COUNT(sCommands); j++) {
if (!strcmp(argv[i], sCommands[j].name)) {
s32 numArgsProcessed = sCommands[j].func(&argv[i], argc - i);
i += numArgsProcessed;
break;
}
}
}
}
/*
* Command Name: --skiplogo
* Description: Skips the N64 Logo Screen
* Arguments: None
*/
BootCommandFunc BootCommands_Command_SkipLogo(char** argv, s32 argc) {
gSkipLogoTest = 1;
return 0;
}
/*
* Command Name: --loadfileselect
* Description: Loads the file select screen on bootup.
* Arguments: None
*/
BootCommandFunc BootCommands_Command_LoadFileSelect(char** argv, s32 argc) {
gLoadFileSelect = 1;
return 0;
}

View File

@ -3,19 +3,6 @@
#include <libultraship/libultra.h>
#include <z64.h>
typedef s32 (*BootCommandFunc)(char** argv, s32 argc); // Returns the number of arguments it read
typedef struct BootCommand
{
char* name;
BootCommandFunc func;
} BootCommand;
extern uint8_t gLoadFileSelect;
extern uint8_t gSkipLogoTest;
void BootCommands_Init();
//void BootCommands_ParseBootArgs(char* str);
void BootCommands_ParseBootArgs(s32 argc, char** argv);
#endif

View File

@ -46,13 +46,6 @@ void SohInputEditorWindow::InitElement() {
addButtonName(BTN_DLEFT, "D-pad left");
addButtonName(BTN_DRIGHT, "D-pad right");
addButtonName(0, "None");
mDeviceIndexVisiblity.clear();
mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Keyboard] = true;
mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Blue] = true;
for (auto index = 1; index < Ship::ShipDeviceIndex::Max; index++) {
mDeviceIndexVisiblity[static_cast<Ship::ShipDeviceIndex>(index)] = false;
}
}
#define INPUT_EDITOR_WINDOW_GAME_INPUT_BLOCK_ID 95237929
@ -176,6 +169,9 @@ void SohInputEditorWindow::DrawAnalogPreview(const char* label, ImVec2 stick, fl
#define BUTTON_COLOR_KEYBOARD_BEIGE ImVec4(0.651f, 0.482f, 0.357f, 0.5f)
#define BUTTON_COLOR_KEYBOARD_BEIGE_HOVERED ImVec4(0.651f, 0.482f, 0.357f, 1.0f)
#define BUTTON_COLOR_MOUSE_BEIGE ImVec4(0.5f, 0.5f, 0.5f, 0.5f)
#define BUTTON_COLOR_MOUSE_BEIGE_HOVERED ImVec4(0.5f, 0.5f, 0.5f, 1.0f)
#define BUTTON_COLOR_GAMEPAD_BLUE ImVec4(0.0f, 0.255f, 0.976f, 0.5f)
#define BUTTON_COLOR_GAMEPAD_BLUE_HOVERED ImVec4(0.0f, 0.255f, 0.976f, 1.0f)
@ -191,29 +187,21 @@ void SohInputEditorWindow::DrawAnalogPreview(const char* label, ImVec2 stick, fl
#define BUTTON_COLOR_GAMEPAD_PURPLE ImVec4(0.431f, 0.369f, 0.706f, 0.5f)
#define BUTTON_COLOR_GAMEPAD_PURPLE_HOVERED ImVec4(0.431f, 0.369f, 0.706f, 1.0f)
void SohInputEditorWindow::GetButtonColorsForLUSDeviceIndex(Ship::ShipDeviceIndex lusIndex, ImVec4& buttonColor,
void SohInputEditorWindow::GetButtonColorsForDeviceType(Ship::PhysicalDeviceType lusIndex, ImVec4& buttonColor,
ImVec4& buttonHoveredColor) {
switch (lusIndex) {
case Ship::ShipDeviceIndex::Keyboard:
case Ship::PhysicalDeviceType::Keyboard:
buttonColor = BUTTON_COLOR_KEYBOARD_BEIGE;
buttonHoveredColor = BUTTON_COLOR_KEYBOARD_BEIGE_HOVERED;
break;
case Ship::ShipDeviceIndex::Blue:
case Ship::PhysicalDeviceType::Mouse:
buttonColor = BUTTON_COLOR_MOUSE_BEIGE;
buttonHoveredColor = BUTTON_COLOR_MOUSE_BEIGE_HOVERED;
break;
case Ship::PhysicalDeviceType::SDLGamepad:
buttonColor = BUTTON_COLOR_GAMEPAD_BLUE;
buttonHoveredColor = BUTTON_COLOR_GAMEPAD_BLUE_HOVERED;
break;
case Ship::ShipDeviceIndex::Red:
buttonColor = BUTTON_COLOR_GAMEPAD_RED;
buttonHoveredColor = BUTTON_COLOR_GAMEPAD_RED_HOVERED;
break;
case Ship::ShipDeviceIndex::Orange:
buttonColor = BUTTON_COLOR_GAMEPAD_ORANGE;
buttonHoveredColor = BUTTON_COLOR_GAMEPAD_ORANGE_HOVERED;
break;
case Ship::ShipDeviceIndex::Green:
buttonColor = BUTTON_COLOR_GAMEPAD_GREEN;
buttonHoveredColor = BUTTON_COLOR_GAMEPAD_GREEN_HOVERED;
break;
default:
buttonColor = BUTTON_COLOR_GAMEPAD_PURPLE;
buttonHoveredColor = BUTTON_COLOR_GAMEPAD_PURPLE_HOVERED;
@ -266,9 +254,6 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
if (mapping == nullptr) {
return;
}
if (!mDeviceIndexVisiblity[mapping->GetShipDeviceIndex()]) {
return;
}
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
std::string icon = "";
@ -287,7 +272,7 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
auto physicalInputDisplayName =
StringHelper::Sprintf("%s %s", icon.c_str(), mapping->GetPhysicalInputName().c_str());
GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor);
GetButtonColorsForDeviceType(mapping->GetPhysicalDeviceType(), buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
auto popupId = StringHelper::Sprintf("editButtonMappingPopup##%s", id.c_str());
@ -324,19 +309,12 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
ImGui::PopStyleVar();
ImGui::SameLine(0, 0);
#ifndef __WIIU__
auto sdlAxisDirectionToButtonMapping = std::dynamic_pointer_cast<Ship::SDLAxisDirectionToButtonMapping>(mapping);
auto indexMapping = Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetDeviceIndexMappingFromShipDeviceIndex(mapping->GetShipDeviceIndex());
auto sdlIndexMapping = std::dynamic_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(indexMapping);
if (sdlIndexMapping != nullptr && sdlAxisDirectionToButtonMapping != nullptr) {
if (sdlAxisDirectionToButtonMapping != nullptr) {
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor);
GetButtonColorsForDeviceType(mapping->GetPhysicalDeviceType(), buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(1.0f, 0.5f));
@ -357,17 +335,19 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
ImGui::Text("Axis Threshold\n\nThe extent to which the joystick\nmust be moved or the trigger\npressed to "
"initiate the assigned\nbutton action.\n\n");
auto globalSettings = Ship::Context::GetInstance()->GetControlDeck()->GetGlobalSDLDeviceSettings();
if (sdlAxisDirectionToButtonMapping->AxisIsStick()) {
ImGui::Text("Stick axis threshold:");
int32_t stickAxisThreshold = sdlIndexMapping->GetStickAxisThresholdPercentage();
int32_t stickAxisThreshold = globalSettings->GetStickAxisThresholdPercentage();
if (stickAxisThreshold == 0) {
ImGui::BeginDisabled();
}
ImGui::PushButtonRepeat(true);
if (ImGui::Button(StringHelper::Sprintf("-##Stick Axis Threshold%s", id.c_str()).c_str())) {
sdlIndexMapping->SetStickAxisThresholdPercentage(stickAxisThreshold - 1);
sdlIndexMapping->SaveToConfig();
globalSettings->SetStickAxisThresholdPercentage(stickAxisThreshold - 1);
globalSettings->SaveToConfig();
}
ImGui::PopButtonRepeat();
if (stickAxisThreshold == 0) {
@ -377,8 +357,8 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f));
if (ImGui::SliderInt(StringHelper::Sprintf("##Stick Axis Threshold%s", id.c_str()).c_str(),
&stickAxisThreshold, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp)) {
sdlIndexMapping->SetStickAxisThresholdPercentage(stickAxisThreshold);
sdlIndexMapping->SaveToConfig();
globalSettings->SetStickAxisThresholdPercentage(stickAxisThreshold);
globalSettings->SaveToConfig();
}
ImGui::SameLine(0.0f, 0.0f);
if (stickAxisThreshold == 100) {
@ -386,8 +366,8 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
}
ImGui::PushButtonRepeat(true);
if (ImGui::Button(StringHelper::Sprintf("+##Stick Axis Threshold%s", id.c_str()).c_str())) {
sdlIndexMapping->SetStickAxisThresholdPercentage(stickAxisThreshold + 1);
sdlIndexMapping->SaveToConfig();
globalSettings->SetStickAxisThresholdPercentage(stickAxisThreshold + 1);
globalSettings->SaveToConfig();
}
ImGui::PopButtonRepeat();
if (stickAxisThreshold == 100) {
@ -398,14 +378,14 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
if (sdlAxisDirectionToButtonMapping->AxisIsTrigger()) {
ImGui::Text("Trigger axis threshold:");
int32_t triggerAxisThreshold = sdlIndexMapping->GetTriggerAxisThresholdPercentage();
int32_t triggerAxisThreshold = globalSettings->GetTriggerAxisThresholdPercentage();
if (triggerAxisThreshold == 0) {
ImGui::BeginDisabled();
}
ImGui::PushButtonRepeat(true);
if (ImGui::Button(StringHelper::Sprintf("-##Trigger Axis Threshold%s", id.c_str()).c_str())) {
sdlIndexMapping->SetTriggerAxisThresholdPercentage(triggerAxisThreshold - 1);
sdlIndexMapping->SaveToConfig();
globalSettings->SetTriggerAxisThresholdPercentage(triggerAxisThreshold - 1);
globalSettings->SaveToConfig();
}
ImGui::PopButtonRepeat();
if (triggerAxisThreshold == 0) {
@ -415,8 +395,8 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
ImGui::SetNextItemWidth(SCALE_IMGUI_SIZE(160.0f));
if (ImGui::SliderInt(StringHelper::Sprintf("##Trigger Axis Threshold%s", id.c_str()).c_str(),
&triggerAxisThreshold, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp)) {
sdlIndexMapping->SetTriggerAxisThresholdPercentage(triggerAxisThreshold);
sdlIndexMapping->SaveToConfig();
globalSettings->SetTriggerAxisThresholdPercentage(triggerAxisThreshold);
globalSettings->SaveToConfig();
}
ImGui::SameLine(0.0f, 0.0f);
if (triggerAxisThreshold == 100) {
@ -424,8 +404,8 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
}
ImGui::PushButtonRepeat(true);
if (ImGui::Button(StringHelper::Sprintf("+##Trigger Axis Threshold%s", id.c_str()).c_str())) {
sdlIndexMapping->SetTriggerAxisThresholdPercentage(triggerAxisThreshold + 1);
sdlIndexMapping->SaveToConfig();
globalSettings->SetTriggerAxisThresholdPercentage(triggerAxisThreshold + 1);
globalSettings->SaveToConfig();
}
ImGui::PopButtonRepeat();
if (triggerAxisThreshold == 100) {
@ -444,7 +424,6 @@ void SohInputEditorWindow::DrawButtonLineEditMappingButton(uint8_t port, N64Butt
ImGui::PopStyleVar();
ImGui::SameLine(0, 0);
}
#endif
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
@ -539,9 +518,6 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port,
if (mapping == nullptr) {
return;
}
if (!mDeviceIndexVisiblity[mapping->GetShipDeviceIndex()]) {
return;
}
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
std::string icon = "";
@ -560,7 +536,7 @@ void SohInputEditorWindow::DrawStickDirectionLineEditMappingButton(uint8_t port,
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
auto physicalInputDisplayName =
StringHelper::Sprintf("%s %s", icon.c_str(), mapping->GetPhysicalInputName().c_str());
GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor);
GetButtonColorsForDeviceType(mapping->GetPhysicalDeviceType(), buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
auto popupId = StringHelper::Sprintf("editStickDirectionMappingPopup##%s", id.c_str());
@ -885,7 +861,7 @@ void SohInputEditorWindow::DrawRumbleSection(uint8_t port) {
ImGui::SetNextItemOpen(true, ImGuiCond_Once);
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor);
GetButtonColorsForDeviceType(mapping->GetPhysicalDeviceType(), buttonColor, buttonHoveredColor);
// begin hackaround https://github.com/ocornut/imgui/issues/282#issuecomment-123763192
// spaces to have background color for text in a tree node
std::string spaces = "";
@ -1256,209 +1232,6 @@ void SohInputEditorWindow::DrawGyroSection(uint8_t port) {
}
}
void SohInputEditorWindow::DrawButtonDeviceIcons(uint8_t portIndex, std::set<N64ButtonMask> bitmasks) {
std::set<Ship::ShipDeviceIndex> allLusDeviceIndices;
allLusDeviceIndices.insert(Ship::ShipDeviceIndex::Keyboard);
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
allLusDeviceIndices.insert(lusIndex);
}
std::vector<std::pair<Ship::ShipDeviceIndex, bool>> lusDeviceIndiciesWithMappings;
for (auto lusIndex : allLusDeviceIndices) {
for (auto [bitmask, button] :
Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetAllButtons()) {
if (!bitmasks.contains(bitmask)) {
continue;
}
if (button->HasMappingsForShipDeviceIndex(lusIndex)) {
for (auto [id, mapping] : button->GetAllButtonMappings()) {
if (mapping->GetShipDeviceIndex() == lusIndex) {
lusDeviceIndiciesWithMappings.push_back(
std::pair<Ship::ShipDeviceIndex, bool>(lusIndex, mapping->PhysicalDeviceIsConnected()));
break;
}
}
break;
}
}
}
for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) {
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
ImGui::SameLine();
if (lusIndex == Ship::ShipDeviceIndex::Keyboard) {
ImGui::SmallButton(ICON_FA_KEYBOARD_O);
} else {
ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN);
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
}
void SohInputEditorWindow::DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::StickIndex stickIndex) {
std::set<Ship::ShipDeviceIndex> allLusDeviceIndices;
allLusDeviceIndices.insert(Ship::ShipDeviceIndex::Keyboard);
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
allLusDeviceIndices.insert(lusIndex);
}
std::vector<std::pair<Ship::ShipDeviceIndex, bool>> lusDeviceIndiciesWithMappings;
for (auto lusIndex : allLusDeviceIndices) {
auto controllerStick =
stickIndex == Ship::StickIndex::LEFT_STICK
? Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetLeftStick()
: Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetRightStick();
if (controllerStick->HasMappingsForShipDeviceIndex(lusIndex)) {
for (auto [direction, mappings] : controllerStick->GetAllAxisDirectionMappings()) {
bool foundMapping = false;
for (auto [id, mapping] : mappings) {
if (mapping->GetShipDeviceIndex() == lusIndex) {
foundMapping = true;
lusDeviceIndiciesWithMappings.push_back(
std::pair<Ship::ShipDeviceIndex, bool>(lusIndex, mapping->PhysicalDeviceIsConnected()));
break;
}
}
if (foundMapping) {
break;
}
}
}
}
for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) {
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
ImGui::SameLine();
if (lusIndex == Ship::ShipDeviceIndex::Keyboard) {
ImGui::SmallButton(ICON_FA_KEYBOARD_O);
} else {
ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN);
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
}
void SohInputEditorWindow::DrawRumbleDeviceIcons(uint8_t portIndex) {
std::set<Ship::ShipDeviceIndex> allLusDeviceIndices;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
allLusDeviceIndices.insert(lusIndex);
}
std::vector<std::pair<Ship::ShipDeviceIndex, bool>> lusDeviceIndiciesWithMappings;
for (auto lusIndex : allLusDeviceIndices) {
if (Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->GetRumble()
->HasMappingsForShipDeviceIndex(lusIndex)) {
for (auto [id, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->GetRumble()
->GetAllRumbleMappings()) {
if (mapping->GetShipDeviceIndex() == lusIndex) {
lusDeviceIndiciesWithMappings.push_back(
std::pair<Ship::ShipDeviceIndex, bool>(lusIndex, mapping->PhysicalDeviceIsConnected()));
break;
}
}
}
}
for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) {
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
ImGui::SameLine();
ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN);
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
}
void SohInputEditorWindow::DrawGyroDeviceIcons(uint8_t portIndex) {
auto mapping =
Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->GetGyro()->GetGyroMapping();
if (mapping == nullptr) {
return;
}
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(mapping->GetShipDeviceIndex(), buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
ImGui::SameLine();
ImGui::SmallButton(mapping->PhysicalDeviceIsConnected() ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN);
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
void SohInputEditorWindow::DrawLEDDeviceIcons(uint8_t portIndex) {
std::set<Ship::ShipDeviceIndex> allLusDeviceIndices;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
allLusDeviceIndices.insert(lusIndex);
}
std::vector<std::pair<Ship::ShipDeviceIndex, bool>> lusDeviceIndiciesWithMappings;
for (auto lusIndex : allLusDeviceIndices) {
if (Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->GetRumble()
->HasMappingsForShipDeviceIndex(lusIndex)) {
for (auto [id, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->GetLED()
->GetAllLEDMappings()) {
if (mapping->GetShipDeviceIndex() == lusIndex) {
lusDeviceIndiciesWithMappings.push_back(
std::pair<Ship::ShipDeviceIndex, bool>(lusIndex, mapping->PhysicalDeviceIsConnected()));
break;
}
}
}
}
for (auto [lusIndex, connected] : lusDeviceIndiciesWithMappings) {
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
ImGui::SameLine();
ImGui::SmallButton(connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN);
ImGui::PopStyleColor();
ImGui::PopStyleColor();
}
}
const ImGuiTableFlags PANEL_TABLE_FLAGS =
ImGuiTableFlags_BordersH |
ImGuiTableFlags_BordersV;
@ -1651,66 +1424,52 @@ void SohInputEditorWindow::DrawDpadControlPanel() {
Ship::GuiWindow::EndGroupPanel(0);
}
void SohInputEditorWindow::DrawDeviceVisibilityButtons() {
std::map<Ship::ShipDeviceIndex, std::pair<std::string, int32_t>> indexMappings;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappingsFromConfig()) {
auto sdlIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(mapping);
if (sdlIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), -1 };
}
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappings()) {
auto sdlIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(mapping);
if (sdlIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), sdlIndexMapping->GetSDLDeviceIndex() };
}
void SohInputEditorWindow::DrawDeviceToggles(uint8_t portIndex) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
auto keyboardButtonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto keyboardButtonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(Ship::ShipDeviceIndex::Keyboard, keyboardButtonColor, keyboardButtonHoveredColor);
GetButtonColorsForDeviceType(Ship::PhysicalDeviceType::Keyboard, keyboardButtonColor, keyboardButtonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, keyboardButtonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, keyboardButtonHoveredColor);
bool keyboardVisible = mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Keyboard];
if(ImGui::Button(
StringHelper::Sprintf("%s %s Keyboard", keyboardVisible ? ICON_FA_EYE : ICON_FA_EYE_SLASH, ICON_FA_KEYBOARD_O)
.c_str())) {
mDeviceIndexVisiblity[Ship::ShipDeviceIndex::Keyboard] = !keyboardVisible;
}
ImGui::Button(StringHelper::Sprintf("%s Keyboard", ICON_FA_KEYBOARD_O).c_str());
ImGui::PopStyleColor();
ImGui::PopStyleColor();
auto mouseButtonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto mouseButtonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForDeviceType(Ship::PhysicalDeviceType::Mouse, mouseButtonColor, mouseButtonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, mouseButtonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, mouseButtonHoveredColor);
ImGui::Button(StringHelper::Sprintf("%s Mouse", ICON_FA_KEYBOARD_O).c_str());
ImGui::PopStyleColor();
ImGui::PopStyleColor();
for (auto [lusIndex, info] : indexMappings) {
auto [name, sdlIndex] = info;
bool connected = sdlIndex != -1;
ImGui::PopItemFlag();
auto connectedDeviceManager = Ship::Context::GetInstance()->GetControlDeck()->GetConnectedPhysicalDeviceManager();
for (const auto& [instanceId, name] : connectedDeviceManager->GetConnectedSDLGamepadNames()) {
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
GetButtonColorsForDeviceType(Ship::PhysicalDeviceType::SDLGamepad, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
bool visible = mDeviceIndexVisiblity[lusIndex];
if(ImGui::Button(
StringHelper::Sprintf("%s %s %s (%s)", visible ? ICON_FA_EYE : ICON_FA_EYE_SLASH, connected ? ICON_FA_GAMEPAD : ICON_FA_CHAIN_BROKEN, name.c_str(),
connected ? StringHelper::Sprintf("SDL %d", sdlIndex).c_str() : "Disconnected")
.c_str())) {
mDeviceIndexVisiblity[lusIndex] = !visible;
auto notIgnored = !connectedDeviceManager->PortIsIgnoringInstanceId(portIndex, instanceId);
ImGui::PopItemFlag();
if(ImGui::Checkbox(StringHelper::Sprintf("###instanceId_%d", instanceId).c_str(), &notIgnored)) {
if (notIgnored) {
connectedDeviceManager->UnignoreInstanceIdForPort(portIndex, instanceId);
} else {
connectedDeviceManager->IgnoreInstanceIdForPort(portIndex, instanceId);
}
};
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true);
ImGui::SameLine();
ImGui::Button(StringHelper::Sprintf("%s %s (SDL)", ICON_FA_GAMEPAD, name.c_str()).c_str());
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::PopItemFlag();
}
}
@ -1719,7 +1478,7 @@ void SohInputEditorWindow::DrawLinkTab() {
if (ImGui::BeginTabItem(StringHelper::Sprintf("Link (P1)###port%d", portIndex).c_str())) {
DrawClearAllButton(portIndex);
DrawSetDefaultsButton(portIndex);
DrawDeviceVisibilityButtons();
DrawDeviceToggles(portIndex);
UpdateBitmaskToMappingIds(portIndex);
UpdateStickDirectionToMappingIds(portIndex);
@ -1729,7 +1488,6 @@ void SohInputEditorWindow::DrawLinkTab() {
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawButtonDeviceIcons(portIndex, mButtonsBitmasks);
DrawButtonLine("A", portIndex, BTN_A, CHIP_COLOR_N64_BLUE);
DrawButtonLine("B", portIndex, BTN_B, CHIP_COLOR_N64_GREEN);
DrawButtonLine("Start", portIndex, BTN_START, CHIP_COLOR_N64_RED);
@ -1744,57 +1502,36 @@ void SohInputEditorWindow::DrawLinkTab() {
CHIP_COLOR_N64_YELLOW);
DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT,
CHIP_COLOR_N64_YELLOW);
} else {
DrawButtonDeviceIcons(portIndex, mButtonsBitmasks);
}
if (ImGui::CollapsingHeader("D-Pad", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawButtonDeviceIcons(portIndex, mDpadBitmasks);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_DUP);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_DDOWN);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_DLEFT);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_DRIGHT);
} else {
DrawButtonDeviceIcons(portIndex, mDpadBitmasks);
}
if (ImGui::CollapsingHeader("Analog Stick", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK);
DrawStickSection(portIndex, Ship::LEFT, 0);
} else {
DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK);
}
if (ImGui::CollapsingHeader("Additional (\"Right\") Stick")) {
DrawAnalogStickDeviceIcons(portIndex, Ship::RIGHT_STICK);
DrawStickSection(portIndex, Ship::RIGHT, 1, CHIP_COLOR_N64_YELLOW);
} else {
DrawAnalogStickDeviceIcons(portIndex, Ship::RIGHT_STICK);
}
if (ImGui::CollapsingHeader("Rumble")) {
DrawRumbleDeviceIcons(portIndex);
DrawRumbleSection(portIndex);
} else {
DrawRumbleDeviceIcons(portIndex);
}
if (ImGui::CollapsingHeader("Gyro")) {
DrawGyroDeviceIcons(portIndex);
DrawGyroSection(portIndex);
} else {
DrawGyroDeviceIcons(portIndex);
}
if (ImGui::CollapsingHeader("LEDs")) {
DrawLEDDeviceIcons(portIndex);
DrawLEDSection(portIndex);
} else {
DrawLEDDeviceIcons(portIndex);
}
if (ImGui::CollapsingHeader("Modifier Buttons")) {
DrawButtonDeviceIcons(portIndex, mModifierButtonsBitmasks);
DrawButtonLine("M1", portIndex, BTN_CUSTOM_MODIFIER1);
DrawButtonLine("M2", portIndex, BTN_CUSTOM_MODIFIER2);
@ -1827,15 +1564,10 @@ void SohInputEditorWindow::DrawLinkTab() {
Ship::GuiWindow::EndGroupPanel(0);
}
ImGui::EndDisabled();
} else {
DrawButtonDeviceIcons(portIndex, mModifierButtonsBitmasks);
}
if (ImGui::CollapsingHeader("Ocarina Controls")) {
DrawButtonDeviceIcons(portIndex, mCustomOcarinaButtonsBitmasks);
DrawOcarinaControlPanel();
} else {
DrawButtonDeviceIcons(portIndex, mCustomOcarinaButtonsBitmasks);
}
if (ImGui::CollapsingHeader("Camera Controls")) {
@ -1875,7 +1607,7 @@ void SohInputEditorWindow::DrawIvanTab() {
if (ImGui::BeginTabItem(StringHelper::Sprintf("Ivan (P2)###port%d", portIndex).c_str())) {
DrawClearAllButton(portIndex);
DrawSetDefaultsButton(portIndex);
DrawDeviceVisibilityButtons();
DrawDeviceToggles(portIndex);
UpdateBitmaskToMappingIds(portIndex);
UpdateStickDirectionToMappingIds(portIndex);
@ -1885,7 +1617,6 @@ void SohInputEditorWindow::DrawIvanTab() {
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawButtonDeviceIcons(portIndex, mButtonsBitmasks);
DrawButtonLine("A", portIndex, BTN_A, CHIP_COLOR_N64_BLUE);
DrawButtonLine("B", portIndex, BTN_B, CHIP_COLOR_N64_GREEN);
DrawButtonLine("Z", portIndex, BTN_Z);
@ -1897,25 +1628,17 @@ void SohInputEditorWindow::DrawIvanTab() {
CHIP_COLOR_N64_YELLOW);
DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT,
CHIP_COLOR_N64_YELLOW);
} else {
DrawButtonDeviceIcons(portIndex, mButtonsBitmasks);
}
if (ImGui::CollapsingHeader("D-Pad", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawButtonDeviceIcons(portIndex, mDpadBitmasks);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_DUP);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_DDOWN);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_DLEFT);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_DRIGHT);
} else {
DrawButtonDeviceIcons(portIndex, mDpadBitmasks);
}
if (ImGui::CollapsingHeader("Analog Stick", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK);
DrawStickSection(portIndex, Ship::LEFT, 0);
} else {
DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK);
}
ImGui::PopStyleColor();
@ -1931,7 +1654,7 @@ void SohInputEditorWindow::DrawDebugPortTab(uint8_t portIndex, std::string custo
: customName.c_str())) {
DrawClearAllButton(portIndex);
DrawSetDefaultsButton(portIndex);
DrawDeviceVisibilityButtons();
DrawDeviceToggles(portIndex);
UpdateBitmaskToMappingIds(portIndex);
UpdateStickDirectionToMappingIds(portIndex);
@ -1941,7 +1664,6 @@ void SohInputEditorWindow::DrawDebugPortTab(uint8_t portIndex, std::string custo
ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
if (ImGui::CollapsingHeader("Buttons", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawButtonDeviceIcons(portIndex, mButtonsBitmasks);
DrawButtonLine("A", portIndex, BTN_A, CHIP_COLOR_N64_BLUE);
DrawButtonLine("B", portIndex, BTN_B, CHIP_COLOR_N64_GREEN);
DrawButtonLine("Start", portIndex, BTN_START, CHIP_COLOR_N64_RED);
@ -1956,25 +1678,16 @@ void SohInputEditorWindow::DrawDebugPortTab(uint8_t portIndex, std::string custo
CHIP_COLOR_N64_YELLOW);
DrawButtonLine(StringHelper::Sprintf("C %s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_CRIGHT,
CHIP_COLOR_N64_YELLOW);
} else {
DrawButtonDeviceIcons(portIndex, mButtonsBitmasks);
}
if (ImGui::CollapsingHeader("D-Pad", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawButtonDeviceIcons(portIndex, mDpadBitmasks);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_UP).c_str(), portIndex, BTN_DUP);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_DOWN).c_str(), portIndex, BTN_DDOWN);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_LEFT).c_str(), portIndex, BTN_DLEFT);
DrawButtonLine(StringHelper::Sprintf("%s", ICON_FA_ARROW_RIGHT).c_str(), portIndex, BTN_DRIGHT);
} else {
DrawButtonDeviceIcons(portIndex, mDpadBitmasks);
}
if (ImGui::CollapsingHeader("Analog Stick", NULL, ImGuiTreeNodeFlags_DefaultOpen)) {
DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK);
DrawStickSection(portIndex, Ship::LEFT, 0);
} else {
DrawAnalogStickDeviceIcons(portIndex, Ship::LEFT_STICK);
}
ImGui::PopStyleColor();
@ -2010,19 +1723,6 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) {
}
if (ImGui::BeginPopup(popupId.c_str())) {
std::map<Ship::ShipDeviceIndex, std::pair<std::string, int32_t>> indexMappings;
for (auto [lusIndex, mapping] : Ship::Context::GetInstance()
->GetControlDeck()
->GetDeviceIndexMappingManager()
->GetAllDeviceIndexMappings()) {
auto sdlIndexMapping = std::static_pointer_cast<Ship::ShipDeviceIndexToSDLDeviceIndexMapping>(mapping);
if (sdlIndexMapping == nullptr) {
continue;
}
indexMappings[lusIndex] = { sdlIndexMapping->GetSDLControllerName(), sdlIndexMapping->GetSDLDeviceIndex() };
}
bool shouldClose = false;
ImGui::PushStyleColor(ImGuiCol_Button, BUTTON_COLOR_KEYBOARD_BEIGE);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, BUTTON_COLOR_KEYBOARD_BEIGE_HOVERED);
@ -2041,33 +1741,27 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) {
Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->ClearAllMappingsForDevice(Ship::ShipDeviceIndex::Keyboard);
->ClearAllMappingsForDeviceType(Ship::PhysicalDeviceType::Keyboard);
Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings(
Ship::ShipDeviceIndex::Keyboard);
Ship::PhysicalDeviceType::Keyboard);
shouldClose = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
for (auto [lusIndex, info] : indexMappings) {
auto [name, sdlIndex] = info;
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForLUSDeviceIndex(lusIndex, buttonColor, buttonHoveredColor);
GetButtonColorsForDeviceType(Ship::PhysicalDeviceType::SDLGamepad, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
if (ImGui::Button(StringHelper::Sprintf("%s %s (%s)", ICON_FA_GAMEPAD, name.c_str(),
StringHelper::Sprintf("SDL %d", sdlIndex).c_str())
.c_str())) {
ImGui::OpenPopup(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str());
if (ImGui::Button(StringHelper::Sprintf("%s %s", ICON_FA_GAMEPAD, "Gamepad (SDL)").c_str())) {
ImGui::OpenPopup("Set Defaults for Gamepad (SDL)");
}
ImGui::PopStyleColor();
ImGui::PopStyleColor();
if (ImGui::BeginPopupModal(StringHelper::Sprintf("Set Defaults for %s", name.c_str()).c_str(), NULL,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("This will clear all existing mappings for\n%s (SDL %d) on port %d.\n\nContinue?",
name.c_str(), sdlIndex, portIndex + 1);
if (ImGui::BeginPopupModal("Set Defaults for Gamepad (SDL)", NULL, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("This will clear all existing mappings for\nGamepad (SDL) on port %d.\n\nContinue?", portIndex + 1);
if (ImGui::Button("Cancel")) {
shouldClose = true;
ImGui::CloseCurrentPopup();
@ -2076,15 +1770,14 @@ void SohInputEditorWindow::DrawSetDefaultsButton(uint8_t portIndex) {
Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->ClearAllMappingsForDevice(lusIndex);
->ClearAllMappingsForDeviceType(Ship::PhysicalDeviceType::SDLGamepad);
Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings(
lusIndex);
Ship::PhysicalDeviceType::SDLGamepad);
shouldClose = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
if (ImGui::Button("Cancel") || shouldClose) {
ImGui::CloseCurrentPopup();

View File

@ -83,7 +83,7 @@ class SohInputEditorWindow : public Ship::GuiWindow {
void UpdateBitmaskToMappingIds(uint8_t port);
void UpdateStickDirectionToMappingIds(uint8_t port);
void GetButtonColorsForLUSDeviceIndex(Ship::ShipDeviceIndex lusIndex, ImVec4& buttonColor,
void GetButtonColorsForDeviceType(Ship::PhysicalDeviceType lusIndex, ImVec4& buttonColor,
ImVec4& buttonHoveredColor);
void DrawLinkTab();
void DrawIvanTab();
@ -92,15 +92,9 @@ class SohInputEditorWindow : public Ship::GuiWindow {
std::set<N64ButtonMask> mDpadBitmasks;
std::set<N64ButtonMask> mModifierButtonsBitmasks;
std::set<N64ButtonMask> mCustomOcarinaButtonsBitmasks;
void DrawButtonDeviceIcons(uint8_t portIndex, std::set<N64ButtonMask> bitmasks);
void DrawAnalogStickDeviceIcons(uint8_t portIndex, Ship::StickIndex stickIndex);
void DrawRumbleDeviceIcons(uint8_t portIndex);
void DrawGyroDeviceIcons(uint8_t portIndex);
void DrawLEDDeviceIcons(uint8_t portIndex);
bool mInputEditorPopupOpen;
void DrawSetDefaultsButton(uint8_t portIndex);
void DrawClearAllButton(uint8_t portIndex);
std::map<Ship::ShipDeviceIndex, bool> mDeviceIndexVisiblity;
void DrawDeviceVisibilityButtons();
void DrawDeviceToggles(uint8_t portIndex);
};

View File

@ -32,7 +32,6 @@ extern "C" {
#include "objects/object_st/object_st.h"
#include "objects/object_gi_boomerang/object_gi_boomerang.h"
#include "objects/object_gi_liquid/object_gi_liquid.h"
#include "objects/object_gi_bow/object_gi_bow.h"
#include "objects/object_gi_hearts/object_gi_hearts.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_gi_sword_1/object_gi_sword_1.h"
@ -47,9 +46,8 @@ extern "C" {
#include "objects/object_gjyo_objects/object_gjyo_objects.h"
#include "textures/nintendo_rogo_static/nintendo_rogo_static.h"
#include "objects/object_gi_rabit_mask/object_gi_rabit_mask.h"
#include "overlays/ovl_Boss_Ganon2/ovl_Boss_Ganon2.h"
#include "overlays/ovl_Magic_Wind/ovl_Magic_Wind.h"
#include "textures/nintendo_rogo_static/nintendo_rogo_static.h"
extern PlayState* gPlayState;
void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, int sourceIndex);
@ -74,7 +72,9 @@ std::map<CosmeticGroup, const char*> groupLabels = {
{ COSMETICS_GROUP_SWORDS, "Swords" },
{ COSMETICS_GROUP_GLOVES, "Gloves" },
{ COSMETICS_GROUP_EQUIPMENT, "Equipment" },
{ COSMETICS_GROUP_KEY, "Keys" },
{ COSMETICS_GROUP_KEYRING, "Keyring" },
{ COSMETICS_GROUP_SMALL_KEYS, "Small Keys" },
{ COSMETICS_GROUP_BOSS_KEYS, "Boss Keys" },
{ COSMETICS_GROUP_CONSUMABLE, "Consumables" },
{ COSMETICS_GROUP_HUD, "HUD" },
{ COSMETICS_GROUP_KALEIDO, "Pause Menu" },
@ -253,34 +253,41 @@ static std::map<std::string, CosmeticOption> cosmeticOptions = {
COSMETIC_OPTION("Consumable.GoldRupee", "Gold Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 190, 55, 255), false, true, true),
COSMETIC_OPTION("Consumable.SilverRupee", "Silver Rupee", COSMETICS_GROUP_CONSUMABLE, ColorRGBA8(255, 255, 255, 255), false, true, true),
COSMETIC_OPTION("Key.KeyringRing", "Key Ring Ring", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.ForestSmallBase", "Forest Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.ForestEmblem", "Forest Key Gem/Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.ForestBossBase", "Forest Boss Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.FireSmallBase", "Fire Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.FireEmblem", "Fire Key Gem/Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.FireBossBase", "Fire Boss Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.WaterSmallBase", "Water Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.WaterEmblem", "Water Key Gem/Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.WaterBossBase", "Water Boss Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.SpiritSmallBase", "Spirit Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.SpiritEmblem", "Spirit Key Gem/Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.SpiritBossBase", "Spirit Boss Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.ShadowSmallBase", "Shadow Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.ShadowEmblem", "Shadow Key Gem/Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.ShadowBossBase", "Shadow Boss Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.WellSmallBase", "Well Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.WellEmblem", "Well Key Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.FortSmallBase", "Fortress Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.FortEmblem", "Fortress Key Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.GTGSmallBase", "GTG Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.GTGEmblem", "GTG Key Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.GanonsSmallBase", "Ganon's Small Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.GanonsEmblem", "Ganon's Key Gem/Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.GanonsBossBase", "Ganon's Boss Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 0, 255), false, true, false),
//COSMETIC_OPTION("Key.ChestGameSmallBase", "Chest Game Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 255, 255), false, true, false),
//COSMETIC_OPTION("Key.ChestGameEmblem", "Chest Game Key Emblem", COSMETICS_GROUP_KEY, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.Skeleton", "Skeleton Key", COSMETICS_GROUP_KEY, ColorRGBA8(255, 255, 170, 255), false, true, false),
COSMETIC_OPTION("Key.KeyringRing", "Key Ring Ring", COSMETICS_GROUP_KEYRING, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.ForestSmallBody", "Forest Small Key Body", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.ForestSmallEmblem", "Forest Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(4, 195, 46, 255), false, true, false),
COSMETIC_OPTION("Key.ForestBossBody", "Forest Boss Key Body", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.ForestBossGem", "Forest Boss Key Gem", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("Key.FireSmallBody", "Fire Small Key Body", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.FireSmallEmblem", "Fire Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(237, 95, 95, 255), false, true, false),
COSMETIC_OPTION("Key.FireBossBody", "Fire Boss Key Body", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.FireBossGem", "Fire Boss Key Gem", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("Key.WaterSmallBody", "Water Small Key Body", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.WaterSmallEmblem", "Water Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(85, 180, 223, 255), false, true, false),
COSMETIC_OPTION("Key.WaterBossBody", "Water Boss Key Body", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.WaterBossGem", "Water Boss Key Gem", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("Key.SpiritSmallBody", "Spirit Small Key Body", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.SpiritSmallEmblem", "Spirit Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(222, 158, 47, 255), false, true, false),
COSMETIC_OPTION("Key.SpiritBossBody", "Spirit Boss Key Body", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.SpiritBossGem", "Spirit Boss Key Gem", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("Key.ShadowSmallBody", "Shadow Small Key Body", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.ShadowSmallEmblem", "Shadow Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(126, 16, 177, 255), false, true, false),
COSMETIC_OPTION("Key.ShadowBossBody", "Shadow Boss Key Body", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.ShadowBossGem", "Shadow Boss Key Gem", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("Key.GanonsSmallBody", "Ganons Small Key Body", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.GanonsSmallEmblem", "Ganons Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(80, 80, 80, 255), false, true, false),
COSMETIC_OPTION("Key.GanonsBossBody", "Ganons Boss Key Body", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 255, 0, 255), false, true, false),
COSMETIC_OPTION("Key.GanonsBossGem", "Ganons Boss Key Gem", COSMETICS_GROUP_BOSS_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("Key.WellSmallBody", "Well Small Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.WellSmallEmblem", "Well Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(227, 110, 255, 255), false, true, true),
COSMETIC_OPTION("Key.FortSmallBody", "Fortress Small Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.FortSmallEmblem", "Fortress Small Key Emblem",COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, true),
COSMETIC_OPTION("Key.GTGSmallBody", "GTG Small Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Key.GTGSmallEmblem", "GTG Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(221, 212, 60, 255), false, true, true),
//COSMETIC_OPTION("Key.ChestGameSmallBody", "Chest Game Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
//COSMETIC_OPTION("Key.ChestGameEmblem", "Chest Game Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, true),
COSMETIC_OPTION("Key.Skeleton", "Skeleton Key", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 170, 255), false, true, false),
COSMETIC_OPTION("HUD.AButton", "A Button", COSMETICS_GROUP_HUD, ColorRGBA8( 90, 90, 255, 255), false, true, false),
COSMETIC_OPTION("HUD.BButton", "B Button", COSMETICS_GROUP_HUD, ColorRGBA8( 0, 150, 0, 255), false, true, false),
@ -1475,10 +1482,16 @@ void Reset_Option_Double(const char* Button_Title, const char* name) {
void DrawSillyTab() {
ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
if (UIWidgets::EnhancementCheckbox("Let It Snow", CVAR_GENERAL("LetItSnow"))) {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
UIWidgets::Tooltip("Makes snow fall, changes chest texture colors to red and green, etc, for December holidays.\nWill reset on restart outside of December 23-25.");
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
if (UIWidgets::EnhancementSliderFloat("Link Body Scale: %.3fx", "##Link_BodyScale", CVAR_COSMETIC("Link.BodyScale.Value"), 0.001f, 0.025f, "", 0.01f, true)) {
CVarSetInteger(CVAR_COSMETIC("Link.BodyScale.Changed"), 1);
}
@ -1494,31 +1507,64 @@ void DrawSillyTab() {
player->actor.scale.z = 0.01f;
}
}
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
if (UIWidgets::EnhancementSliderFloat("Link Head Scale: %.2fx", "##Link_HeadScale", CVAR_COSMETIC("Link.HeadScale.Value"), 0.4f, 4.0f, "", 1.0f, false)) {
CVarSetInteger(CVAR_COSMETIC("Link.HeadScale.Changed"), 1);
}
Reset_Option_Double("Reset##Link_HeadScale", CVAR_COSMETIC("Link.HeadScale"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
if (UIWidgets::EnhancementSliderFloat("Link Sword Scale: %f", "##Link_SwordScale", CVAR_COSMETIC("Link.SwordScale.Value"), 1.0f, 2.5f, "", 1.0f, false)) {
CVarSetInteger(CVAR_COSMETIC("Link.SwordScale.Changed"), 1);
}
Reset_Option_Double("Reset##Link_SwordScale", CVAR_COSMETIC("Link.SwordScale"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
UIWidgets::EnhancementSliderFloat("Bunny Hood Length: %f", "##BunnyHood_EarLength", CVAR_COSMETIC("BunnyHood.EarLength"), -300.0f, 1000.0f, "", 0.0f, false);
Reset_Option_Single("Reset##BunnyHood_EarLength", CVAR_COSMETIC("BunnyHood.EarLength"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
UIWidgets::EnhancementSliderFloat("Bunny Hood Spread: %f", "##BunnyHood_EarSpread", CVAR_COSMETIC("BunnyHood.EarSpread"), -300.0f, 500.0f, "", 0.0f, false);
Reset_Option_Single("Reset##BunnyHood_EarSpread", CVAR_COSMETIC("BunnyHood.EarSpread"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
UIWidgets::EnhancementSliderFloat("Goron Neck Length: %f", "##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength"), 0.0f, 5000.0f, "", 0.0f, false);
Reset_Option_Single("Reset##Goron_NeckLength", CVAR_COSMETIC("Goron.NeckLength"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
UIWidgets::EnhancementCheckbox("Unfix Goron Spin", CVAR_COSMETIC("UnfixGoronSpin"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
UIWidgets::EnhancementSliderFloat("Fairies Size: %f", "##Fairies_Size", CVAR_COSMETIC("Fairies.Size"), 0.25f, 5.0f, "", 1.0f, false);
Reset_Option_Single("Reset##Fairies_Size", CVAR_COSMETIC("Fairies.Size"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
UIWidgets::EnhancementSliderFloat("N64 Logo Spin Speed: %f", "##N64Logo_SpinSpeed", CVAR_COSMETIC("N64Logo.SpinSpeed"), 0.25f, 5.0f, "", 1.0f, false);
Reset_Option_Single("Reset##N64Logo_SpinSpeed", CVAR_COSMETIC("N64Logo.SpinSpeed"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
UIWidgets::EnhancementSliderFloat("Moon Size: %f", "##Moon_Size", CVAR_COSMETIC("Moon.Size"), 0.5f, 2.0f, "", 1.0f, false);
Reset_Option_Single("Reset##Moon_Size", CVAR_COSMETIC("Moon.Size"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
if (UIWidgets::EnhancementSliderFloat("Kak Windmill Speed: %f", "##Kak_Windmill_Speed", CVAR_COSMETIC("Kak.Windmill_Speed.Value"), 100.0f, 6000.0f, "", 100.0f, false)) {
CVarSetInteger(CVAR_COSMETIC("Kak.Windmill_Speed.Changed"), 1);
}
Reset_Option_Double("Reset##Kak_Windmill_Speed", CVAR_COSMETIC("Kak.Windmill_Speed"));
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
ImGui::EndDisabled();
}
@ -1748,6 +1794,7 @@ void DrawCosmeticGroup(CosmeticGroup cosmeticGroup) {
DrawCosmeticRow(cosmeticOption);
}
}
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
}
static const char* colorSchemes[2] = {
@ -1755,92 +1802,95 @@ static const char* colorSchemes[2] = {
"Gamecube",
};
void CosmeticsEditorWindow::ApplyDungeonEmblemColors(){
CVarSetColor(cosmeticOptions["Key.ForestEmblem"].cvar, {0, 255, 0, 255});
CVarSetInteger(cosmeticOptions["Key.ForestEmblem"].changedCvar, 1);
cosmeticOptions["Key.ForestEmblem"].currentColor = {0, 255/255.0f, 0, 255/255.0f};
void CosmeticsEditorWindow::ApplyDungeonKeyColors() {
// Keyring
ResetColor(cosmeticOptions.at("Key.KeyringRing"));
CVarSetColor(cosmeticOptions["Key.FireEmblem"].cvar, {255, 30, 0, 255});
CVarSetInteger(cosmeticOptions["Key.FireEmblem"].changedCvar, 1);
cosmeticOptions["Key.FireEmblem"].currentColor = {255/255.0f, 30/255.0f, 0, 255/255.0f};
// Forest Temple
CVarSetColor(cosmeticOptions["Key.ForestSmallBody"].cvar, { 4, 195, 46, 255 });
CVarSetInteger(cosmeticOptions["Key.ForestSmallBody"].changedCvar, 1);
cosmeticOptions["Key.ForestSmallBody"].currentColor = { 4 / 255.0f, 195 / 255.0f, 46 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.ForestSmallEmblem"));
CVarSetColor(cosmeticOptions["Key.WaterEmblem"].cvar, {0, 137, 255, 255});
CVarSetInteger(cosmeticOptions["Key.WaterEmblem"].changedCvar, 1);
cosmeticOptions["Key.WaterEmblem"].currentColor = {0, 137/255.0f, 255/255.0f, 255/255.0f};
ResetColor(cosmeticOptions.at("Key.ForestBossBody"));
CVarSetColor(cosmeticOptions["Key.ForestBossGem"].cvar, { 0, 255, 0, 255 });
CVarSetInteger(cosmeticOptions["Key.ForestBossGem"].changedCvar, 1);
cosmeticOptions["Key.ForestBossGem"].currentColor = { 0, 255 / 255.0f, 0, 255 / 255.0f };
CVarSetColor(cosmeticOptions["Key.SpiritEmblem"].cvar, {255, 85, 0, 255});
CVarSetInteger(cosmeticOptions["Key.SpiritEmblem"].changedCvar, 1);
cosmeticOptions["Key.SpiritEmblem"].currentColor = {255/255.0f, 85/255.0f, 0, 255/255.0f};
// Fire Temple
CVarSetColor(cosmeticOptions["Key.FireSmallBody"].cvar, { 237, 95, 95, 255 });
CVarSetInteger(cosmeticOptions["Key.FireSmallBody"].changedCvar, 1);
cosmeticOptions["Key.FireSmallBody"].currentColor = { 237 / 255.0f, 95 / 255.0f, 95 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.FireSmallEmblem"));
CVarSetColor(cosmeticOptions["Key.ShadowEmblem"].cvar, {153, 0, 255, 255});
CVarSetInteger(cosmeticOptions["Key.ShadowEmblem"].changedCvar, 1);
cosmeticOptions["Key.ShadowEmblem"].currentColor = {153/255.0f, 0, 255/255.0f, 255/255.0f};
ResetColor(cosmeticOptions.at("Key.FireBossBody"));
CVarSetColor(cosmeticOptions["Key.FireBossGem"].cvar, { 255, 30, 0, 255 });
CVarSetInteger(cosmeticOptions["Key.FireBossGem"].changedCvar, 1);
cosmeticOptions["Key.FireBossGem"].currentColor = { 255 / 255.0f, 30 / 255.0f, 0, 255 / 255.0f };
CVarSetColor(cosmeticOptions["Key.WellEmblem"].cvar, { 255, 0, 188, 255});
CVarSetInteger(cosmeticOptions["Key.WellEmblem"].changedCvar, 1);
cosmeticOptions["Key.WellEmblem"].currentColor = {255/255.0f, 0, 188/255.0f, 255/255.0f};
// Water Temple
CVarSetColor(cosmeticOptions["Key.WaterSmallBody"].cvar, { 85, 180, 223, 255 });
CVarSetInteger(cosmeticOptions["Key.WaterSmallBody"].changedCvar, 1);
cosmeticOptions["Key.WaterSmallBody"].currentColor = { 85 / 255.0f, 180 / 255.0f, 223 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.WaterSmallEmblem"));
CVarSetColor(cosmeticOptions["Key.GTGEmblem"].cvar, {255, 255, 0, 255});
CVarSetInteger(cosmeticOptions["Key.GTGEmblem"].changedCvar, 1);
cosmeticOptions["Key.GTGEmblem"].currentColor = {255/255.0f, 255/255.0f, 0, 255/255.0f};
ResetColor(cosmeticOptions.at("Key.WaterBossBody"));
CVarSetColor(cosmeticOptions["Key.WaterBossGem"].cvar, { 0, 137, 255, 255 });
CVarSetInteger(cosmeticOptions["Key.WaterBossGem"].changedCvar, 1);
cosmeticOptions["Key.WaterBossGem"].currentColor = { 0, 137 / 255.0f, 255 / 255.0f, 255 / 255.0f };
CVarSetColor(cosmeticOptions["Key.FortEmblem"].cvar, {255, 255, 203, 255});
CVarSetInteger(cosmeticOptions["Key.FortEmblem"].changedCvar, 1);
cosmeticOptions["Key.FortEmblem"].currentColor = { 255/255.0f, 255/255.0f, 203/255.0f, 255/255.0f};
// Spirit Temple
CVarSetColor(cosmeticOptions["Key.SpiritSmallBody"].cvar, { 222, 158, 47, 255 });
CVarSetInteger(cosmeticOptions["Key.SpiritSmallBody"].changedCvar, 1);
cosmeticOptions["Key.SpiritSmallBody"].currentColor = { 222 / 255.0f, 158 / 255.0f, 47 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.SpiritSmallEmblem"));
CVarSetColor(cosmeticOptions["Key.GanonsEmblem"].cvar, {255, 0, 0, 255});
CVarSetInteger(cosmeticOptions["Key.GanonsEmblem"].changedCvar, 1);
cosmeticOptions["Key.GanonsEmblem"].currentColor = {255/255.0f, 0, 0, 255/255.0f};
ResetColor(cosmeticOptions.at("Key.SpiritBossBody"));
CVarSetColor(cosmeticOptions["Key.SpiritBossGem"].cvar, { 255, 85, 0, 255 });
CVarSetInteger(cosmeticOptions["Key.SpiritBossGem"].changedCvar, 1);
cosmeticOptions["Key.SpiritBossGem"].currentColor = { 255 / 255.0f, 85 / 255.0f, 0, 255 / 255.0f };
//CVarSetColor(cosmeticOptions["Key.ChestGameEmblem"].cvar, {255, 255, 0, 255});
//CVarSetInteger(cosmeticOptions["Key.ChestGameEmblem"].changedCvar, 1);
//cosmeticOptions["Key.ChestGameEmblem"].currentColor = {255/255.0f, 255/255.0f, 0, 255/255.0f};
}
// Shadow Temple
CVarSetColor(cosmeticOptions["Key.ShadowSmallBody"].cvar, { 126, 16, 177, 255 });
CVarSetInteger(cosmeticOptions["Key.ShadowSmallBody"].changedCvar, 1);
cosmeticOptions["Key.ShadowSmallBody"].currentColor = { 126 / 255.0f, 16 / 255.0f, 177 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.ShadowSmallEmblem"));
void CosmeticsEditorWindow::ApplyDungeonBaseColors(){
CVarSetColor(cosmeticOptions["Key.ForestSmallBase"].cvar, {4, 195, 46, 255});
CVarSetInteger(cosmeticOptions["Key.ForestSmallBase"].changedCvar, 1);
cosmeticOptions["Key.ForestSmallBase"].currentColor = {4/255.0f, 195/255.0f, 46/255.0f, 255/255.0f};
ResetColor(cosmeticOptions.at("Key.ShadowBossBody"));
CVarSetColor(cosmeticOptions["Key.ShadowBossGem"].cvar, { 153, 0, 255, 255 });
CVarSetInteger(cosmeticOptions["Key.ShadowBossGem"].changedCvar, 1);
cosmeticOptions["Key.ShadowBossGem"].currentColor = { 153 / 255.0f, 0, 255 / 255.0f, 255 / 255.0f };
CVarSetColor(cosmeticOptions["Key.FireSmallBase"].cvar, {237, 95, 95, 255});
CVarSetInteger(cosmeticOptions["Key.FireSmallBase"].changedCvar, 1);
cosmeticOptions["Key.FireSmallBase"].currentColor = {237/255.0f, 95/255.0f, 95/255.0f, 255/255.0f};
// Ganon's Tower
CVarSetColor(cosmeticOptions["Key.GanonsSmallBody"].cvar, { 80, 80, 80, 255 });
CVarSetInteger(cosmeticOptions["Key.GanonsSmallBody"].changedCvar, 1);
cosmeticOptions["Key.GanonsSmallBody"].currentColor = { 80 / 255.0f, 80 / 255.0f, 80 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.GanonsSmallEmblem"));
CVarSetColor(cosmeticOptions["Key.WaterSmallBase"].cvar, {85, 180, 223, 255});
CVarSetInteger(cosmeticOptions["Key.WaterSmallBase"].changedCvar, 1);
cosmeticOptions["Key.WaterSmallBase"].currentColor = {85/255.0f, 180/255.0f, 223/255.0f, 255/255.0f};
CVarSetColor(cosmeticOptions["Key.GanonsBossBody"].cvar, { 80, 80, 80, 255 });
CVarSetInteger(cosmeticOptions["Key.GanonsBossBody"].changedCvar, 1);
cosmeticOptions["Key.GanonsBossBody"].currentColor = { 80 / 255.0f, 80 / 255.0f, 80 / 255.0f, 255 / 255.0f };
CVarSetColor(cosmeticOptions["Key.GanonsBossGem"].cvar, { 255, 0, 0, 255 });
CVarSetInteger(cosmeticOptions["Key.GanonsBossGem"].changedCvar, 1);
cosmeticOptions["Key.GanonsBossGem"].currentColor = { 255 / 255.0f, 0, 0, 255 / 255.0f };
CVarSetColor(cosmeticOptions["Key.SpiritSmallBase"].cvar, {222, 158, 47, 255});
CVarSetInteger(cosmeticOptions["Key.SpiritSmallBase"].changedCvar, 1);
cosmeticOptions["Key.SpiritSmallBase"].currentColor = {222/255.0f, 158/255.0f, 47/255.0f, 255/255.0f};
// Bottom of the Well
CVarSetColor(cosmeticOptions["Key.WellSmallBody"].cvar, { 227, 110, 255, 255 });
CVarSetInteger(cosmeticOptions["Key.WellSmallBody"].changedCvar, 1);
cosmeticOptions["Key.WellSmallBody"].currentColor = { 227 / 255.0f, 110 / 255.0f, 255 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.WellSmallEmblem"));
CVarSetColor(cosmeticOptions["Key.ShadowSmallBase"].cvar, {126, 16, 177, 255});
CVarSetInteger(cosmeticOptions["Key.ShadowSmallBase"].changedCvar, 1);
cosmeticOptions["Key.ShadowSmallBase"].currentColor = {126/255.0f, 16/255.0f, 177/255.0f, 255/255.0f};
// Gerudo Training Ground
CVarSetColor(cosmeticOptions["Key.GTGSmallBody"].cvar, { 221, 212, 60, 255 });
CVarSetInteger(cosmeticOptions["Key.GTGSmallBody"].changedCvar, 1);
cosmeticOptions["Key.GTGSmallBody"].currentColor = { 221 / 255.0f, 212 / 255.0f, 60 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.GTGSmallEmblem"));
CVarSetColor(cosmeticOptions["Key.WellSmallBase"].cvar, {227, 110, 255, 255});
CVarSetInteger(cosmeticOptions["Key.WellSmallBase"].changedCvar, 1);
cosmeticOptions["Key.WellSmallBase"].currentColor = {227/255.0f, 110/255.0f, 255/255.0f, 255/255.0f};
CVarSetColor(cosmeticOptions["Key.GTGSmallBase"].cvar, {221, 212, 60, 255});
CVarSetInteger(cosmeticOptions["Key.GTGSmallBase"].changedCvar, 1);
cosmeticOptions["Key.GTGSmallBase"].currentColor = {221/255.0f, 212/255.0f, 60/255.0f, 255/255.0f};
CVarSetColor(cosmeticOptions["Key.FortSmallBase"].cvar, {255, 255, 255, 255});
CVarSetInteger(cosmeticOptions["Key.FortSmallBase"].changedCvar, 1);
cosmeticOptions["Key.FortSmallBase"].currentColor = {255/255.0f, 255/255.0f, 255/255.0f, 255/255.0f};
CVarSetColor(cosmeticOptions["Key.GanonsSmallBase"].cvar, {80, 80, 80, 255});
CVarSetInteger(cosmeticOptions["Key.GanonsSmallBase"].changedCvar, 1);
cosmeticOptions["Key.GanonsSmallBase"].currentColor = {80/255.0f, 80/255.0f, 80/255.0f, 255/255.0f};
CVarSetColor(cosmeticOptions["Key.GanonsBossBase"].cvar, {80, 80, 80, 255});
CVarSetInteger(cosmeticOptions["Key.GanonsBossBase"].changedCvar, 1);
cosmeticOptions["Key.GanonsBossBase"].currentColor = {80/255.0f, 80/255.0f, 80/255.0f, 255/255.0f};
//CVarSetColor(cosmeticOptions["Key.ChestGameSmallBase"].cvar, {255, 255, 0, 255});
//CVarSetInteger(cosmeticOptions["Key.ChestGameSmallBase"].changedCvar, 1);
//cosmeticOptions["Key.ChestGameSmallBase"].currentColor = {255/255.0f, 255/255.0f, 0, 255/255.0f};
// Gerudo Fortress
CVarSetColor(cosmeticOptions["Key.FortSmallBody"].cvar, { 255, 255, 255, 255 });
CVarSetInteger(cosmeticOptions["Key.FortSmallBody"].changedCvar, 1);
cosmeticOptions["Key.FortSmallBody"].currentColor = { 255 / 255.0f, 255 / 255.0f, 255 / 255.0f, 255 / 255.0f };
ResetColor(cosmeticOptions.at("Key.FortSmallEmblem"));
}
void CosmeticsEditorWindow::DrawElement() {
@ -1853,15 +1903,6 @@ void CosmeticsEditorWindow::DrawElement() {
"For example, if you have custom Link model, then the Link's Hair color option will most likely not apply."
);
if (ImGui::Button("Apply Dungeon Gem/Emblem Colors", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) {
ApplyDungeonEmblemColors();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
ImGui::SameLine();
if (ImGui::Button("Apply Dungeon Base Colors", ImVec2(ImGui::GetContentRegionAvail().x, 30.0f))) {
ApplyDungeonBaseColors();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
if (CVarGetInteger(CVAR_COSMETIC("AdvancedMode"), 0)) {
if (ImGui::Button("Lock All Advanced", ImVec2(ImGui::GetContentRegionAvail().x / 2, 30.0f))) {
for (auto& [id, cosmeticOption] : cosmeticOptions) {
@ -1950,16 +1991,40 @@ void CosmeticsEditorWindow::DrawElement() {
if (ImGui::BeginTabBar("CosmeticsContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
if (ImGui::BeginTabItem("Link & Items")) {
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
DrawCosmeticGroup(COSMETICS_GROUP_LINK);
DrawCosmeticGroup(COSMETICS_GROUP_GLOVES);
DrawCosmeticGroup(COSMETICS_GROUP_MIRRORSHIELD);
DrawCosmeticGroup(COSMETICS_GROUP_EQUIPMENT);
DrawCosmeticGroup(COSMETICS_GROUP_SWORDS);
DrawCosmeticGroup(COSMETICS_GROUP_KEY);
DrawCosmeticGroup(COSMETICS_GROUP_CONSUMABLE);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Keys")) {
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
if (ImGui::Button("Give all keys dungeon-specific colors", ImVec2(300.0f, 30.0f))) {
ApplyDungeonKeyColors();
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
DrawCosmeticGroup(COSMETICS_GROUP_KEYRING);
DrawCosmeticGroup(COSMETICS_GROUP_SMALL_KEYS);
DrawCosmeticGroup(COSMETICS_GROUP_BOSS_KEYS);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Effects")) {
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
DrawCosmeticGroup(COSMETICS_GROUP_MAGIC);
DrawCosmeticGroup(COSMETICS_GROUP_ARROWS);
DrawCosmeticGroup(COSMETICS_GROUP_SPIN_ATTACK);
@ -1973,9 +2038,15 @@ void CosmeticsEditorWindow::DrawElement() {
CVarClear(CVAR_COSMETIC("Trails.Duration.Changed"));
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("World & NPCs")) {
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
DrawCosmeticGroup(COSMETICS_GROUP_WORLD);
DrawCosmeticGroup(COSMETICS_GROUP_NAVI);
DrawCosmeticGroup(COSMETICS_GROUP_IVAN);
@ -1987,6 +2058,9 @@ void CosmeticsEditorWindow::DrawElement() {
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("HUD")) {
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
DrawCosmeticGroup(COSMETICS_GROUP_HUD);
DrawCosmeticGroup(COSMETICS_GROUP_TITLE);
ImGui::EndTabItem();

View File

@ -9,7 +9,9 @@ typedef enum {
COSMETICS_GROUP_SWORDS,
COSMETICS_GROUP_GLOVES,
COSMETICS_GROUP_EQUIPMENT,
COSMETICS_GROUP_KEY,
COSMETICS_GROUP_KEYRING,
COSMETICS_GROUP_SMALL_KEYS,
COSMETICS_GROUP_BOSS_KEYS,
COSMETICS_GROUP_CONSUMABLE,
COSMETICS_GROUP_HUD,
COSMETICS_GROUP_KALEIDO,
@ -63,8 +65,7 @@ class CosmeticsEditorWindow : public Ship::GuiWindow {
void InitElement() override;
void DrawElement() override;
void ApplyDungeonEmblemColors();
void ApplyDungeonBaseColors();
void ApplyDungeonKeyColors();
void UpdateElement() override {};
};
#endif //__cplusplus

View File

@ -0,0 +1,232 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
#include "textures/nintendo_rogo_static/nintendo_rogo_static.h"
#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "soh_assets.h"
extern "C" {
#include "macros.h"
#include "z64.h"
#include "functions.h"
#include "variables.h"
#include "soh/Enhancements/enhancementTypes.h"
}
extern "C" {
extern void Title_Calc(TitleContext*);
extern void Title_SetupView(TitleContext*, f32, f32, f32);
}
#define LOGO_TO_DRAW_LUS 0
#define LOGO_TO_DRAW_N64 1
static bool shouldDrawIceOnSpinningLogo = false;
extern "C" void CustomLogoTitle_Draw(TitleContext* titleContext, uint8_t logoToDraw) {
static s16 sTitleRotY = 0;
static Lights1 sTitleLights = gdSPDefLights1(0x64, 0x64, 0x64, 0xFF, 0xFF, 0xFF, 0x45, 0x45, 0x45);
u16 y;
u16 idx;
s32 pad1;
Vec3f v3;
Vec3f v1;
Vec3f v2;
s32 pad2[2];
OPEN_DISPS(titleContext->state.gfxCtx);
v3.x = 69;
v3.y = 69;
v3.z = 69;
v2.x = -4949.148;
v2.y = 4002.5417;
v1.x = 0;
v1.y = 0;
v1.z = 0;
v2.z = 1119.0837;
func_8002EABC(&v1, &v2, &v3, titleContext->state.gfxCtx);
gSPSetLights1(POLY_OPA_DISP++, sTitleLights);
Title_SetupView(titleContext, 0, 150.0, 300.0);
Gfx_SetupDL_25Opa(titleContext->state.gfxCtx);
Matrix_Translate(-53.0, -5.0, 0, MTXMODE_NEW);
Matrix_Scale(1.0, 1.0, 1.0, MTXMODE_APPLY);
Matrix_RotateZYX(0, sTitleRotY, 0, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(titleContext->state.gfxCtx), G_MTX_LOAD);
if (logoToDraw == LOGO_TO_DRAW_LUS) {
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gShipLogoDL);
} else {
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gNintendo64LogoDL);
}
Gfx_SetupDL_39Opa(titleContext->state.gfxCtx);
gDPPipeSync(POLY_OPA_DISP++);
gDPSetCycleType(POLY_OPA_DISP++, G_CYC_2CYCLE);
gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF2, G_RM_OPA_CI | CVG_DST_WRAP);
gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, PRIMITIVE, ENV_ALPHA, TEXEL0, 0, 0, 0, TEXEL0, PRIMITIVE, ENVIRONMENT,
COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0);
if (CVarGetInteger(CVAR_COSMETIC("Title.NintendoLogo.Changed"), 0)) {
Color_RGB8 nintendoLogoColor = CVarGetColor24(CVAR_COSMETIC("Title.NintendoLogo.Value"), Color_RGB8{0, 0, 255});
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
gDPSetEnvColor(POLY_OPA_DISP++, nintendoLogoColor.r, nintendoLogoColor.g, nintendoLogoColor.b, 128);
} else {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 170, 255, 255, 255);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 255, 128);
}
gDPLoadMultiBlock(POLY_OPA_DISP++, nintendo_rogo_static_Tex_001800, 0x100, 1, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, 2, 11);
for (idx = 0, y = 94; idx < 16; idx++, y += 2)
{
gDPLoadMultiTile(POLY_OPA_DISP++, (logoToDraw == LOGO_TO_DRAW_N64) ? nintendo_rogo_static_Tex_000000 : nintendo_rogo_static_Tex_LUS_000000, 0, G_TX_RENDERTILE, G_IM_FMT_I, G_IM_SIZ_8b, 192, 32,
0, idx * 2, 192 - 1, (idx + 1) * 2 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK,
G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
gDPSetTileSize(POLY_OPA_DISP++, 0, 0, 0, (192 - 1) << G_TEXTURE_IMAGE_FRAC,
(2 - 1) << G_TEXTURE_IMAGE_FRAC);
gDPSetTileSize(POLY_OPA_DISP++, 1, titleContext->uls, (titleContext->ult & 0x7F) - idx * 4, 0, 0);
gSPTextureRectangle(POLY_OPA_DISP++, 388, y << 2, 1156, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
}
// Draw ice block around spinning N or ship.
if (shouldDrawIceOnSpinningLogo) {
f32 scale = 0.4f;
gSPSegment(POLY_OPA_DISP++, 0x08,
(uintptr_t)Gfx_TwoTexScroll(titleContext->state.gfxCtx, 0, 0, (0 - 1) % 128, 32, 32, 1,
0, (1 * -2) % 128, 32, 32));
Matrix_Translate(0.0f, -10.0f, 0.0f, MTXMODE_APPLY);
Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(titleContext->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 50, 100, 255);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gEffIceFragment3DL);
}
Environment_FillScreen(titleContext->state.gfxCtx, 0, 0, 0, (s16)titleContext->coverAlpha, FILL_SCREEN_XLU);
sTitleRotY += (300 * CVarGetFloat(CVAR_COSMETIC("N64Logo.SpinSpeed"), 1.0f));
CLOSE_DISPS(titleContext->state.gfxCtx);
}
#define CVAR_BOOTSEQUENCE_NAME CVAR_ENHANCEMENT("BootSequence")
#define CVAR_BOOTSEQUENCE_DEFAULT BOOTSEQUENCE_DEFAULT
#define CVAR_BOOTSEQUENCE_VALUE CVarGetInteger(CVAR_BOOTSEQUENCE_NAME, CVAR_BOOTSEQUENCE_DEFAULT)
extern "C" void CustomLogoTitle_Main(TitleContext* titleContext) {
static uint8_t logosSeen = 0;
uint8_t logoToDraw;
if (CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_DEFAULT) {
if (logosSeen == 0) {
logoToDraw = LOGO_TO_DRAW_LUS;
} else {
logoToDraw = LOGO_TO_DRAW_N64;
}
}
if (CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_AUTHENTIC) {
logoToDraw = LOGO_TO_DRAW_N64;
}
OPEN_DISPS(titleContext->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0, (uintptr_t)NULL);
gSPSegment(POLY_OPA_DISP++, 1, (uintptr_t)titleContext->staticSegment);
Gfx_SetupFrame(titleContext->state.gfxCtx, 0, 0, 0);
Title_Calc(titleContext);
CustomLogoTitle_Draw(titleContext, logoToDraw);
if (titleContext->exit) {
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = 0xFF;
gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN;
titleContext->state.running = false;
logosSeen++;
if (CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_DEFAULT && logosSeen == 1) {
SET_NEXT_GAMESTATE(&titleContext->state, Title_Init, TitleContext);
}
if ((CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_DEFAULT && logosSeen == 2) ||
(CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_AUTHENTIC)) {
SET_NEXT_GAMESTATE(&titleContext->state, Opening_Init, OpeningContext);
logosSeen = 0;
}
}
GameInteractor_ExecuteOnZTitleUpdate(titleContext);
CLOSE_DISPS(titleContext->state.gfxCtx);
}
// // // //
// Always
//
void OnZTitleInitReplaceTitleMainWithCustom(void* gameState) {
TitleContext* titleContext = (TitleContext*)gameState;
titleContext->state.main = (GameStateFunc)CustomLogoTitle_Main;
}
// Allows pressing A to skip the boot logo and go to the next state (opening or file select)
void OnZTitleUpdatePressButtonToSkip(void* gameState) {
TitleContext* titleContext = (TitleContext*)gameState;
if (CHECK_BTN_ANY(titleContext->state.input->press.button, BTN_A | BTN_B | BTN_START)) {
// Force the title state to start fading to black and to last roughly 5 frames based on current fade in/out
titleContext->visibleDuration = 0;
titleContext->addAlpha = std::max<int16_t>((255 - titleContext->coverAlpha) / 5, 1);
}
}
void RegisterCustomLogoTitle() {
COND_HOOK(OnZTitleInit, true, OnZTitleInitReplaceTitleMainWithCustom);
COND_HOOK(OnZTitleUpdate, true, OnZTitleUpdatePressButtonToSkip);
}
static RegisterShipInitFunc initFuncAlways(RegisterCustomLogoTitle);
// // // // // //
// Bootsequence
//
void OnZTitleUpdateSkipToFileSelect(void* gameState) {
TitleContext* titleContext = (TitleContext*)gameState;
gSaveContext.seqId = (u8)NA_BGM_DISABLED;
gSaveContext.natureAmbienceId = 0xFF;
gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN;
titleContext->state.running = false;
SET_NEXT_GAMESTATE(&titleContext->state, FileChoose_Init, FileChooseContext);
}
void RegisterCustomLogoTitleBootsequence() {
COND_HOOK(OnZTitleUpdate, CVAR_BOOTSEQUENCE_VALUE == BOOTSEQUENCE_FILESELECT, OnZTitleUpdateSkipToFileSelect);
}
static RegisterShipInitFunc initFuncBootsequence(RegisterCustomLogoTitleBootsequence, { CVAR_BOOTSEQUENCE_NAME });
// // // // // //
// Let it Snow
//
#define CVAR_LETITSNOW_NAME CVAR_GENERAL("LetItSnow")
#define CVAR_LETITSNOW_DEFAULT 0
#define CVAR_LETITSNOW_VALUE CVarGetInteger(CVAR_LETITSNOW_NAME, CVAR_LETITSNOW_DEFAULT)
void RegisterCustomLogoTitleLetItSnow() {
shouldDrawIceOnSpinningLogo = CVAR_LETITSNOW_VALUE != CVAR_LETITSNOW_DEFAULT;
}
static RegisterShipInitFunc initFuncLetItSnow(RegisterCustomLogoTitleLetItSnow, { CVAR_LETITSNOW_NAME });

View File

@ -402,6 +402,7 @@ static bool EntranceHandler(std::shared_ptr<Ship::Console> Console, const std::v
gPlayState->transitionTrigger = TRANS_TRIGGER_START;
gPlayState->transitionType = TRANS_TYPE_INSTANT;
gSaveContext.nextTransitionType = TRANS_TYPE_INSTANT;
return 0;
}
static bool VoidHandler(std::shared_ptr<Ship::Console> Console, const std::vector<std::string>& args, std::string* output) {
@ -1297,7 +1298,9 @@ static constexpr std::array<std::pair<const char*, CosmeticGroup>, COSMETICS_GRO
{"swords", COSMETICS_GROUP_SWORDS},
{"gloves", COSMETICS_GROUP_GLOVES},
{"equipment", COSMETICS_GROUP_EQUIPMENT},
{"key", COSMETICS_GROUP_KEY},
{"keyring", COSMETICS_GROUP_KEYRING},
{"small_keys", COSMETICS_GROUP_SMALL_KEYS },
{"boss_keys", COSMETICS_GROUP_BOSS_KEYS },
{"consumable", COSMETICS_GROUP_CONSUMABLE},
{"hud", COSMETICS_GROUP_HUD},
{"kaleido", COSMETICS_GROUP_KALEIDO},

View File

@ -180,10 +180,8 @@ void MessageDebug_StartTextBox(const char* tableId, uint16_t textId, uint8_t lan
Font* font = &msgCtx->font;
sMessageHasSetSfx = 0;
for (u32 i = 0; i < FONT_CHAR_TEX_SIZE * 120; i += FONT_CHAR_TEX_SIZE) {
if (&font->charTexBuf[i] != nullptr) {
gSPInvalidateTexCache(play->state.gfxCtx->polyOpa.p++, reinterpret_cast<uintptr_t>(&font->charTexBuf[i]));
}
}
R_TEXT_CHAR_SCALE = 75;
R_TEXT_LINE_SPACING = 12;
R_TEXT_INIT_XPOS = 65;

View File

@ -1551,6 +1551,55 @@ const std::vector<FlagTable> flagTables = {
{ RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY, "RAND_INF_SHADOW_TEMPLE_MQ_WIND_HINT_SUN_FAIRY" },
{ RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_CELL_SUN_FAIRY" },
{ RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY, "RAND_INF_BOTTOM_OF_THE_WELL_MQ_BASEMENT_SUN_FAIRY" },
{ RAND_INF_GUARD_HOUSE_UNLOCKED, "RAND_INF_GUARD_HOUSE_UNLOCKED" },
{ RAND_INF_GUARD_HOUSE_KEY_OBTAINED, "RAND_INF_GUARD_HOUSE_KEY_OBTAINED" },
{ RAND_INF_MARKET_BAZAAR_UNLOCKED, "RAND_INF_MARKET_BAZAAR_UNLOCKED" },
{ RAND_INF_MARKET_BAZAAR_KEY_OBTAINED, "RAND_INF_MARKET_BAZAAR_KEY_OBTAINED" },
{ RAND_INF_MARKET_POTION_SHOP_UNLOCKED, "RAND_INF_MARKET_POTION_SHOP_UNLOCKED" },
{ RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED, "RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED" },
{ RAND_INF_MASK_SHOP_UNLOCKED, "RAND_INF_MASK_SHOP_UNLOCKED" },
{ RAND_INF_MASK_SHOP_KEY_OBTAINED, "RAND_INF_MASK_SHOP_KEY_OBTAINED" },
{ RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED" },
{ RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED" },
{ RAND_INF_BOMBCHU_BOWLING_UNLOCKED, "RAND_INF_BOMBCHU_BOWLING_UNLOCKED" },
{ RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED, "RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED" },
{ RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED" },
{ RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED, "RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED" },
{ RAND_INF_BOMBCHU_SHOP_UNLOCKED, "RAND_INF_BOMBCHU_SHOP_UNLOCKED" },
{ RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED, "RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED" },
{ RAND_INF_RICHARDS_HOUSE_UNLOCKED, "RAND_INF_RICHARDS_HOUSE_UNLOCKED" },
{ RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED, "RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED" },
{ RAND_INF_ALLEY_HOUSE_UNLOCKED, "RAND_INF_ALLEY_HOUSE_UNLOCKED" },
{ RAND_INF_ALLEY_HOUSE_KEY_OBTAINED, "RAND_INF_ALLEY_HOUSE_KEY_OBTAINED" },
{ RAND_INF_KAK_BAZAAR_UNLOCKED, "RAND_INF_KAK_BAZAAR_UNLOCKED" },
{ RAND_INF_KAK_BAZAAR_KEY_OBTAINED, "RAND_INF_KAK_BAZAAR_KEY_OBTAINED" },
{ RAND_INF_KAK_POTION_SHOP_UNLOCKED, "RAND_INF_KAK_POTION_SHOP_UNLOCKED" },
{ RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED, "RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED" },
{ RAND_INF_BOSS_HOUSE_UNLOCKED, "RAND_INF_BOSS_HOUSE_UNLOCKED" },
{ RAND_INF_BOSS_HOUSE_KEY_OBTAINED, "RAND_INF_BOSS_HOUSE_KEY_OBTAINED" },
{ RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED, "RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED" },
{ RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED, "RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED" },
{ RAND_INF_SKULLTULA_HOUSE_UNLOCKED, "RAND_INF_SKULLTULA_HOUSE_UNLOCKED" },
{ RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED, "RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED" },
{ RAND_INF_IMPAS_HOUSE_UNLOCKED, "RAND_INF_IMPAS_HOUSE_UNLOCKED" },
{ RAND_INF_IMPAS_HOUSE_KEY_OBTAINED, "RAND_INF_IMPAS_HOUSE_KEY_OBTAINED" },
{ RAND_INF_WINDMILL_UNLOCKED, "RAND_INF_WINDMILL_UNLOCKED" },
{ RAND_INF_WINDMILL_KEY_OBTAINED, "RAND_INF_WINDMILL_KEY_OBTAINED" },
{ RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED, "RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED" },
{ RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED, "RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED" },
{ RAND_INF_DAMPES_HUT_UNLOCKED, "RAND_INF_DAMPES_HUT_UNLOCKED" },
{ RAND_INF_DAMPES_HUT_KEY_OBTAINED, "RAND_INF_DAMPES_HUT_KEY_OBTAINED" },
{ RAND_INF_TALONS_HOUSE_UNLOCKED, "RAND_INF_TALONS_HOUSE_UNLOCKED" },
{ RAND_INF_TALONS_HOUSE_KEY_OBTAINED, "RAND_INF_TALONS_HOUSE_KEY_OBTAINED" },
{ RAND_INF_STABLES_UNLOCKED, "RAND_INF_STABLES_UNLOCKED" },
{ RAND_INF_STABLES_KEY_OBTAINED, "RAND_INF_STABLES_KEY_OBTAINED" },
{ RAND_INF_BACK_TOWER_UNLOCKED, "RAND_INF_BACK_TOWER_UNLOCKED" },
{ RAND_INF_BACK_TOWER_KEY_OBTAINED, "RAND_INF_BACK_TOWER_KEY_OBTAINED" },
{ RAND_INF_HYLIA_LAB_UNLOCKED, "RAND_INF_HYLIA_LAB_UNLOCKED" },
{ RAND_INF_HYLIA_LAB_KEY_OBTAINED, "RAND_INF_HYLIA_LAB_KEY_OBTAINED" },
{ RAND_INF_FISHING_HOLE_UNLOCKED, "RAND_INF_FISHING_HOLE_UNLOCKED" },
{ RAND_INF_FISHING_HOLE_KEY_OBTAINED, "RAND_INF_FISHING_HOLE_KEY_OBTAINED" },
} },
};

View File

@ -1,5 +1,3 @@
#pragma once
#include "performanceTimer.h"
void StartPerformanceTimer(TimerID timer){

View File

@ -305,7 +305,7 @@ EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) {
GetSelectedEnemies();
}
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemies"), ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed() : gSaveContext.ship.stats.fileCreatedAt);
Random_Init(finalSeed);
uint32_t randomNumber = Random(0, RANDOMIZED_ENEMY_SPAWN_TABLE_SIZE);
return selectedEnemyList[randomNumber];

View File

@ -52,14 +52,6 @@ typedef enum {
ENEMY_RANDOMIZER_RANDOM_SEEDED,
} EnemyRandomizerMode;
typedef enum {
FASTFILE_1,
FASTFILE_2,
FASTFILE_3,
FASTFILE_MAP_SELECT,
FASTFILE_FILE_SELECT
} FastFileSelectTarget;
typedef enum {
AUTOSAVE_OFF,
AUTOSAVE_LOCATION_AND_MAJOR_ITEMS,
@ -69,6 +61,12 @@ typedef enum {
AUTOSAVE_ALL_ITEMS
} AutosaveType;
typedef enum {
BOOTSEQUENCE_DEFAULT,
BOOTSEQUENCE_AUTHENTIC,
BOOTSEQUENCE_FILESELECT
} BootSequenceType;
typedef enum {
ZFIGHT_FIX_DISABLED,
ZFIGHT_FIX_CONSISTENT_VANISH,

View File

@ -286,6 +286,7 @@ typedef enum {
VB_RENDER_YES_ON_CONTINUE_PROMPT,
// Vanilla condition: CHECK_BTN_ALL(input->press.button, BTN_START)
VB_CLOSE_PAUSE_MENU,
VB_KALEIDO_UNPAUSE_CLOSE,
// Vanilla condition: true
VB_SPAWN_BLUE_WARP,
// Vanilla condition: this->warpTimer > sWarpTimerTarget && gSaveContext.nextCutsceneIndex == 0xFFEF
@ -304,6 +305,13 @@ typedef enum {
VB_FROGS_GO_TO_IDLE,
// Vanilla condition: var >= gSaveContext.health) && (gSaveContext.health > 0
VB_HEALTH_METER_BE_CRITICAL,
VB_CONSUME_SMALL_KEY,
// Vanilla condition: gSaveContext.inventory.dungeonKeys[gSaveContext.mapIndex] <= 0
VB_NOT_HAVE_SMALL_KEY,
// Vanilla condition: !Flags_GetSwitch(play, this->actor.params & 0x3F)
VB_DOOR_BE_LOCKED,
// Vanilla condition: ((doorActor->params >> 7) & 7) == 3
VB_DOOR_PLAY_SCENE_TRANSITION,
/*** Play Cutscenes ***/
@ -381,6 +389,7 @@ typedef enum {
/*** Give Items ***/
VB_SHORT_CIRCUIT_GIVE_ITEM_PROCESS,
VB_FREEZE_ON_SKULL_TOKEN,
// Opt: *EnBox
VB_GIVE_ITEM_FROM_CHEST,

View File

@ -5,8 +5,11 @@
* - Argument 1: Name of the hook
* - Argument 2: Function type that the hook uses
*/
DEFINE_HOOK(OnZTitleInit, (void* gameState));
DEFINE_HOOK(OnZTitleUpdate, (void* gameState));
DEFINE_HOOK(OnLoadGame, (int32_t fileNum));
DEFINE_HOOK(OnExitGame, (int32_t fileNum));
DEFINE_HOOK(OnGameStateMainStart, ());
DEFINE_HOOK(OnGameFrameUpdate, ());
DEFINE_HOOK(OnItemReceive, (GetItemEntry itemEntry));
DEFINE_HOOK(OnSaleEnd, (GetItemEntry itemEntry));

View File

@ -2,6 +2,14 @@
// MARK: - Gameplay
void GameInteractor_ExecuteOnZTitleInit(void* gameState) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnZTitleInit>(gameState);
}
void GameInteractor_ExecuteOnZTitleUpdate(void* gameState) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnZTitleUpdate>(gameState);
}
void GameInteractor_ExecuteOnLoadGame(int32_t fileNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnLoadGame>(fileNum);
}
@ -10,6 +18,10 @@ void GameInteractor_ExecuteOnExitGame(int32_t fileNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnExitGame>(fileNum);
}
void GameInteractor_ExecuteOnGameStateMainStart() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnGameStateMainStart>();
}
void GameInteractor_ExecuteOnGameFrameUpdate() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnGameFrameUpdate>();
}

View File

@ -7,8 +7,11 @@
extern "C" {
#endif
// MARK: - Gameplay
void GameInteractor_ExecuteOnZTitleInit(void* gameState);
void GameInteractor_ExecuteOnZTitleUpdate(void* gameState);
void GameInteractor_ExecuteOnLoadGame(int32_t fileNum);
void GameInteractor_ExecuteOnExitGame(int32_t fileNum);
void GameInteractor_ExecuteOnGameStateMainStart();
void GameInteractor_ExecuteOnGameFrameUpdate();
void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry);

View File

@ -125,8 +125,8 @@ namespace Rando {
std::make_shared<KaleidoEntryIconCountRequired>(
gTriforcePieceTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 32, 32, Color_RGBA8{ 255,255,255,255 }, 0,
yOffset, reinterpret_cast<int*>(&gSaveContext.ship.quest.data.randomizer.triforcePiecesCollected),
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetContextOptionIndex() + 1,
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).GetContextOptionIndex() + 1));
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1,
ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1));
yOffset += 18;
}
if (ctx->GetOption(RSK_SHUFFLE_OCARINA_BUTTONS)) {

View File

@ -536,7 +536,7 @@ void UpdateMirrorModeState(int32_t sceneNum) {
(sceneNum == SCENE_GANON_BOSS);
if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) {
uint32_t seed = sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSettings()->GetSeed()
uint32_t seed = sceneNum + (IS_RANDO ? Rando::Context::GetInstance()->GetSeed()
: gSaveContext.ship.stats.fileCreatedAt);
Random_Init(seed);
}
@ -1128,162 +1128,6 @@ void RegisterBossDefeatTimestamps() {
});
}
typedef enum {
ADD_ICE_TRAP,
ADD_BURN_TRAP,
ADD_SHOCK_TRAP,
ADD_KNOCK_TRAP,
ADD_SPEED_TRAP,
ADD_BOMB_TRAP,
ADD_VOID_TRAP,
ADD_AMMO_TRAP,
ADD_KILL_TRAP,
ADD_TELEPORT_TRAP,
ADD_TRAP_MAX
} AltTrapType;
const char* altTrapTypeCvars[] = {
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 () {
std::vector<AltTrapType> enabledAddTraps;
for (int i = 0; i < ADD_TRAP_MAX; i++) {
if (CVarGetInteger(altTrapTypeCvars[i], 0)) {
if (gSaveContext.equips.buttonItems[0] == ITEM_FISHING_POLE && (i == ADD_VOID_TRAP || i == ADD_TELEPORT_TRAP)) {
continue; // don't add void or teleport if you're holding the fishing pole, as this causes issues
}
enabledAddTraps.push_back(static_cast<AltTrapType>(i));
}
}
if (enabledAddTraps.size() == 0) {
enabledAddTraps.push_back(ADD_ICE_TRAP);
}
return enabledAddTraps;
};
void RegisterAltTrapTypes() {
static AltTrapType roll = ADD_TRAP_MAX;
static int statusTimer = -1;
static int eventTimer = -1;
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry itemEntry) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("ExtraTraps.Enabled"), 0) || itemEntry.modIndex != MOD_RANDOMIZER || itemEntry.getItemId != RG_ICE_TRAP) {
return;
}
roll = RandomElement(getEnabledAddTraps());
switch (roll) {
case ADD_ICE_TRAP:
GameInteractor::RawAction::FreezePlayer();
break;
case ADD_BURN_TRAP:
GameInteractor::RawAction::BurnPlayer();
break;
case ADD_SHOCK_TRAP:
GameInteractor::RawAction::ElectrocutePlayer();
break;
case ADD_KNOCK_TRAP:
eventTimer = 3;
break;
case ADD_SPEED_TRAP:
Audio_PlaySoundGeneral(NA_SE_VO_KZ_MOVE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
GameInteractor::State::RunSpeedModifier = -2;
statusTimer = 200;
Overlay_DisplayText(10, "Speed Decreased!");
break;
case ADD_BOMB_TRAP:
eventTimer = 3;
break;
case ADD_VOID_TRAP:
Audio_PlaySoundGeneral(NA_SE_EN_GANON_LAUGH, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
eventTimer = 3;
break;
case ADD_AMMO_TRAP:
eventTimer = 3;
Overlay_DisplayText(5, "Ammo Halved!");
break;
case ADD_KILL_TRAP:
GameInteractor::RawAction::SetPlayerHealth(0);
break;
case ADD_TELEPORT_TRAP:
eventTimer = 3;
break;
default:
break;
}
});
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
Player* player = GET_PLAYER(gPlayState);
if (statusTimer == 0) {
GameInteractor::State::RunSpeedModifier = 0;
}
if (eventTimer == 0) {
switch (roll) {
case ADD_KNOCK_TRAP:
GameInteractor::RawAction::KnockbackPlayer(1);
break;
case ADD_BOMB_TRAP:
GameInteractor::RawAction::SpawnActor(ACTOR_EN_BOM, 1);
break;
case ADD_VOID_TRAP:
Play_TriggerRespawn(gPlayState);
break;
case ADD_AMMO_TRAP:
AMMO(ITEM_STICK) = AMMO(ITEM_STICK) * 0.5;
AMMO(ITEM_NUT) = AMMO(ITEM_NUT) * 0.5;
AMMO(ITEM_SLINGSHOT) = AMMO(ITEM_SLINGSHOT) * 0.5;
AMMO(ITEM_BOW) = AMMO(ITEM_BOW) * 0.5;
AMMO(ITEM_BOMB) = AMMO(ITEM_BOMB) * 0.5;
AMMO(ITEM_BOMBCHU) = AMMO(ITEM_BOMBCHU) * 0.5;
Audio_PlaySoundGeneral(NA_SE_VO_FR_SMILE_0, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
break;
case ADD_TELEPORT_TRAP: {
int entrance;
int index = 1 + rand() % 10;
switch (index) {
case 1:
entrance = GI_TP_DEST_SERENADE;
break;
case 2:
entrance = GI_TP_DEST_REQUIEM;
break;
case 3:
entrance = GI_TP_DEST_BOLERO;
break;
case 4:
entrance = GI_TP_DEST_MINUET;
break;
case 5:
entrance = GI_TP_DEST_NOCTURNE;
break;
case 6:
entrance = GI_TP_DEST_PRELUDE;
break;
default:
entrance = GI_TP_DEST_LINKSHOUSE;
break;
}
GameInteractor::RawAction::TeleportPlayer(entrance);
break;
}
default:
break;
}
}
statusTimer--;
eventTimer--;
});
}
void UpdateHurtContainerModeState(bool newState) {
static bool hurtEnabled = false;
if (hurtEnabled == newState) {
@ -1362,7 +1206,7 @@ void RegisterOpenAllHours() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>([](void* refActor) {
Actor* actor = static_cast<Actor*>(refActor);
if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR)) {
if (CVarGetInteger(CVAR_ENHANCEMENT("OpenAllHours"), 0) && (actor->id == ACTOR_EN_DOOR) && (!IS_RANDO || !OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOCK_OVERWORLD_DOORS))) {
switch (actor->params) {
case 4753: // Night Market Bazaar
case 1678: // Night Potion Shop
@ -1592,7 +1436,6 @@ void InitMods() {
RegisterBrokenGiantsKnifeFix();
RegisterEnemyDefeatCounts();
RegisterBossDefeatTimestamps();
RegisterAltTrapTypes();
RegisterRandomizedEnemySizes();
RegisterOpenAllHours();
RegisterToTMedallions();

View File

@ -2,6 +2,7 @@
#include "global.h"
#include "z64.h"
#include "game-interactor/GameInteractor.h"
#include "soh/OTRGlobals.h"
static const int songMessageMap[] = {
TEXT_WARP_MINUET_OF_FOREST,
@ -87,6 +88,47 @@ void PauseWarp_HandleSelection() {
int song = gPlayState->pauseCtx.cursorPoint[PAUSE_QUEST];
if (aButtonPressed && CHECK_QUEST_ITEM(song) && song >= QUEST_SONG_MINUET && song <= QUEST_SONG_PRELUDE &&
gPlayState->pauseCtx.pageIndex == PAUSE_QUEST && gPlayState->pauseCtx.state == 6) {
if (gSaveContext.ship.quest.id == QUEST_RANDOMIZER && Randomizer_GetSettingValue(RSK_SHUFFLE_OCARINA_BUTTONS)) {
bool canplay = false;
switch (song) {
case QUEST_SONG_MINUET:
canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP);
break;
case QUEST_SONG_BOLERO:
canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN);
break;
case QUEST_SONG_SERENADE:
canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN);
break;
case QUEST_SONG_REQUIEM:
canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN);
break;
case QUEST_SONG_NOCTURNE:
canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_A) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_DOWN);
break;
case QUEST_SONG_PRELUDE:
canplay = Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_LEFT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_RIGHT) &&
Flags_GetRandomizerInf(RAND_INF_HAS_OCARINA_C_UP);
break;
}
if (!canplay) {
return;
}
}
ActivateWarp(&gPlayState->pauseCtx, song);
}
}

View File

@ -75,7 +75,7 @@ void DrawPresetSelector(PresetType presetTypeId) {
}
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
if (presetTypeId == PRESET_TYPE_RANDOMIZER){
Rando::Context::GetInstance()->GetSettings()->ReloadOptions();
Rando::Settings::GetInstance()->ReloadOptions();
}
}
ImGui::PopStyleVar(1);

View File

@ -342,8 +342,6 @@ const std::vector<const char*> cheatCvars = {
CVAR_CHEAT("EasyISG"),
CVAR_CHEAT("EasyQPA"),
CVAR_CHEAT("TimelessEquipment"),
CVAR_CHEAT("EasyPauseBuffer"),
CVAR_CHEAT("EasyInputBuffer"),
CVAR_CHEAT("NoRestrictItems"),
CVAR_CHEAT("FreezeTime"),
CVAR_GENERAL("PrevTime"),
@ -408,7 +406,6 @@ const std::vector<const char*> randomizerCvars = {
CVAR_RANDOMIZER_SETTING("DoorOfTime"),
CVAR_RANDOMIZER_SETTING("DungeonCount"),
CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"),
CVAR_RANDOMIZER_SETTING("EnableGlitchCutscenes"),
CVAR_RANDOMIZER_SETTING("FishingPoleHint"),
CVAR_RANDOMIZER_SETTING("Fishsanity"),
CVAR_RANDOMIZER_SETTING("FishsanityAgeSplit"),
@ -1010,7 +1007,6 @@ const std::vector<PresetEntry> spockRacePresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 3),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("GoronPot"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ForgeTime"), 0),
PRESET_ENTRY_S32(CVAR_CHEAT("EasyPauseBuffer"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeAllNight"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("10GSHint"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("20GSHint"), 1),
@ -1062,7 +1058,6 @@ const std::vector<PresetEntry> spockRaceNoLogicPresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AdultMasks"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightAdult"), 6),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AssignableTunicsAndBoots"), 1),
PRESET_ENTRY_S32(CVAR_CHEAT("EasyPauseBuffer"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("MinimumFishWeightChild"), 3),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("ClimbSpeed"), 4),
PRESET_ENTRY_S32(CVAR_COSMETIC("Goron.NeckLength"), 1000),
@ -1200,7 +1195,6 @@ const std::vector<PresetEntry> hellModePresetEntries = {
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("CuccosToReturn"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("DoorOfTime"), RO_DOOROFTIME_OPEN),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableBombchuDrops"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("EnableGlitchCutscenes"), 1),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("ClosedForest"), RO_CLOSED_FOREST_OFF),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrial"), RO_GANONS_TRIALS_SET_NUMBER),
PRESET_ENTRY_S32(CVAR_RANDOMIZER_SETTING("GanonTrialCount"), 6),

View File

@ -238,10 +238,10 @@ static int GetMaxGSCount() {
int maxBridge = 0;
int maxLACS = 0;
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) {
maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex();
maxBridge = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get();
}
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) {
maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex();
maxLACS = ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get();
}
maxBridge = std::max(maxBridge, maxLACS);
//Get the max amount of GS which could be useful from token reward locations
@ -266,7 +266,7 @@ static int GetMaxGSCount() {
maxUseful = 10;
}
//Return max of the two possible reasons tokens could be important, minus the tokens in the starting inventory
return std::max(maxUseful, maxBridge) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).GetContextOptionIndex();
return std::max(maxUseful, maxBridge) - ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get();
}
std::string GetShopItemBaseName(std::string itemName) {

View File

@ -1455,913 +1455,298 @@ void StaticData::HintTable_Init() {
| JUNK HINT TEXT |
---------------------------*/
hintTextTable[RHT_JUNK02] = HintText(CustomMessage("They say you must read the names of \"Special Deal\" shop items carefully.",
hintTextTable[RHT_JUNK01] = HintText(CustomMessage("They say you must read the names of \"Special Deal\" shop items carefully.",
/*german*/ "",
/*french*/ "Selon moi, les \"Offres spéciales\" sont parfois trompeuses... Lisez les attentivement!"));
// /*spanish*/"Según dicen, se debería prestar atención a los nombres de las ofertas especiales."
hintTextTable[RHT_JUNK03] = HintText(CustomMessage("They say that Zelda is a poor leader.",
hintTextTable[RHT_JUNK02] = HintText(CustomMessage("They say that Zelda is a poor leader.",
/*german*/ "",
/*french*/ "Selon moi, Zelda ne ferait pas un bon monarque."));
// /*spanish*/Según dicen, Zelda es mala líder.
hintTextTable[RHT_JUNK04] = HintText(CustomMessage("These hints can be quite useful. This is an exception.",
hintTextTable[RHT_JUNK03] = HintText(CustomMessage("These hints can be quite useful. This is an exception.",
/*german*/ "",
/*french*/ "Ces indices sont très utiles, à l'exception de celui-ci."));
// /*spanish*/Las pistas suelen servir de ayuda. En cambio, esta no.
hintTextTable[RHT_JUNK05] = HintText(CustomMessage("They say that the Lizalfos in Dodongo's Cavern like to play in lava.",
hintTextTable[RHT_JUNK04] = HintText(CustomMessage("They say that the Lizalfos in Dodongo's Cavern like to play in lava.",
/*german*/ "",
/*french*/ "Selon moi, les Lézalfos de la Caverne Dodongo aiment patauger dans la lave."));
// /*spanish*/Según dicen, a los Lizalfos de la Cueva de los Dodongos les gusta jugar en la lava.
hintTextTable[RHT_JUNK06] = HintText(CustomMessage("They say that all the Zora drowned in Wind Waker.",
hintTextTable[RHT_JUNK05] = HintText(CustomMessage("They say that all the Zora drowned in Wind Waker.",
/*german*/ "",
/*french*/ "Selon moi, les Zoras se sont noyés dans Wind Waker."));
// /*spanish*/Según dicen, en Wind Waker todos los zora se ahogaron.
hintTextTable[RHT_JUNK07] = HintText(CustomMessage("If Gorons eat rocks, does that mean I'm in danger?",
hintTextTable[RHT_JUNK06] = HintText(CustomMessage("If Gorons eat rocks, does that mean I'm in danger?",
/*german*/ "",
/*french*/ "Ne dis pas au Gorons que je suis ici. Ils mangent des roches, tu sais!"));
// /*spanish*/Si los Goron se tragan las piedras, ¿no me hace ser una especia vulnarable o algo así
hintTextTable[RHT_JUNK08] = HintText(CustomMessage("'Member when Ganon was a blue pig?^I 'member.",
hintTextTable[RHT_JUNK07] = HintText(CustomMessage("'Member when Ganon was a blue pig?^I 'member.",
/*german*/ "",
/*french*/ "Dans mon temps, Ganon était un cochon bleu...^Pff! Les jeunes de nos jours, et leur Ganondorf!"));
// /*spanish*/¿T'acuerdas cuando Ganon era un cerdo azul?^Qué tiempos, chico.
hintTextTable[RHT_JUNK09] = HintText(CustomMessage("One who does not have Triforce can't go in.",
hintTextTable[RHT_JUNK08] = HintText(CustomMessage("One who does not have Triforce can't go in.",
/*german*/ "",
/*french*/ "Ceux sans Triforce doivent rebrousser chemin."));
// /*spanish*/Aquel que no porte la Trifuerza no podrá pasar.
hintTextTable[RHT_JUNK10] = HintText(CustomMessage("Save your future, end the Happy Mask Salesman.",
hintTextTable[RHT_JUNK09] = HintText(CustomMessage("Save your future, end the Happy Mask Salesman.",
/*german*/ "",
/*french*/ "Selon moi, tu t'éviteras des jours de malheur si tu vaincs le vendeur de masques..."));
// /*spanish*/Salva tu futuro, acaba con el dueño de La Máscara Feliz.
hintTextTable[RHT_JUNK11] = HintText(CustomMessage("Glitches are a pathway to many abilities some consider to be... Unnatural.",
hintTextTable[RHT_JUNK10] = HintText(CustomMessage("Glitches are a pathway to many abilities some consider to be... Unnatural.",
/*german*/ "",
/*french*/ "Les glitchs sont un moyen d'acquérir de nombreuses facultés considérées par certains comme... contraire "));
// /*spanish*/ Los glitches son el camino a muchas habilidades que varios consideran... nada natural.
hintTextTable[RHT_JUNK12] = HintText(CustomMessage("I'm stoned. Get it?",
hintTextTable[RHT_JUNK11] = HintText(CustomMessage("I'm stoned. Get it?",
/*german*/ "",
/*french*/ "Allez, roche, papier, ciseau...&Roche."));
// /*spanish*/Me he quedado de piedra. ¿Lo pillas?
hintTextTable[RHT_JUNK13] = HintText(CustomMessage("Hoot! Hoot! Would you like me to repeat that?",
hintTextTable[RHT_JUNK12] = HintText(CustomMessage("Hoot! Hoot! Would you like me to repeat that?",
/*german*/ "",
/*french*/ "Hou hou! Veux-tu que je répète tout ça?"));
// /*spanish*/¡Buuu, buuu! ¿Te lo vuelvo a repetir?
hintTextTable[RHT_JUNK14] = HintText(CustomMessage("Gorons are stupid. They eat rocks.",
hintTextTable[RHT_JUNK13] = HintText(CustomMessage("Gorons are stupid. They eat rocks.",
/*german*/ "",
/*french*/ "Les Gorons sont des vraies têtes dures."));
// /*spanish*/Los Goron son tontos. Se comen las piedras.
hintTextTable[RHT_JUNK15] = HintText(CustomMessage("They say that Lon Lon Ranch prospered under Ingo.",
hintTextTable[RHT_JUNK14] = HintText(CustomMessage("They say that Lon Lon Ranch prospered under Ingo.",
/*german*/ "",
/*french*/ "Selon moi, le Ranch Lon Lon était plus prospère sous Ingo."));
// /*spanish*/Según dicen, el Rancho Lon Lon prosperó gracias a Ingo.
hintTextTable[RHT_JUNK16] = HintText(CustomMessage("The single rupee is a unique item.",
/*german*/ "",
/*french*/ "Nul objet n'est plus unique que le rubis vert."));
// /*spanish*/La rupia de uno es un objeto singular.
hintTextTable[RHT_JUNK17] = HintText(CustomMessage("Without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!",
hintTextTable[RHT_JUNK15] = HintText(CustomMessage("They say without the Lens of Truth, the Treasure Chest Mini-Game is a 1 out of 32 chance.^Good luck!",
/*german*/ "",
/*french*/ "Gagner la Chasse-aux-Trésors est 1 chance sur 32.^Bonne chance!"));
// /*spanish*/Sin la Lupa de la Verdad, ganarías 1/32 veces en el Cofre del Tesoro.^¡Buena suerte con ello!
hintTextTable[RHT_JUNK18] = HintText(CustomMessage("Use bombs wisely.",
hintTextTable[RHT_JUNK16] = HintText(CustomMessage("Use bombs wisely.",
/*german*/ "",
/*french*/ "Utilise les bombes avec précaution."));
// /*spanish*/No desperdicies las bombas.
hintTextTable[RHT_JUNK19] = HintText(CustomMessage("They say that Volvagia hates splinters",
/*german*/ "",
/*french*/ "Selon moi, Volvagia déteste les échardes."));
// /*spanish*/Según dicen, Volvagia le teme a las astillas.
hintTextTable[RHT_JUNK20] = HintText(CustomMessage("They say that funky monkeys can be spotted on Friday.",
/*german*/ "",
/*french*/ "Selon moi, des capucins coquins sortent le vendredi."));
// /*spanish*/Según dicen, en los viernes puedes hallar monos marchosos.
hintTextTable[RHT_JUNK21] = HintText(CustomMessage("I found you, faker!",
/*german*/ "",
/*french*/ "Ah-ha! Je t'ai trouvé!"));
// /*spanish*/¡Ahí estás, impostor!
hintTextTable[RHT_JUNK22] = HintText(CustomMessage("They say the Groose is loose.",
/*german*/ "",
/*french*/ "Selon moi, Hergo est le vrai héros."));
// /*spanish*/Según dicen, Malton es un espanto.
hintTextTable[RHT_JUNK23] = HintText(CustomMessage("They say that players who select the \"ON\" option for \"MOTION CONTROL\" are the real \"Zelda players!\"",
hintTextTable[RHT_JUNK17] = HintText(CustomMessage("They say that players who select the \"ON\" option for \"MOTION CONTROL\" are the real \"Zelda players!\"",
/*german*/ "",
/*french*/ "Selon moi, ceux qui utilisent les contrôles gyroscopiques sont les VRAIS joueurs."));
// /*spanish*/ "Según dicen, aquellos que juegan usando el control por movimiento son los verdaderos jugadores de Zelda."
hintTextTable[RHT_JUNK24] = HintText(CustomMessage("What happened to Sheik?",
/*german*/ "",
/*french*/ "Donc... Qu'est-ce qui arrive avec Sheik?"));
// /*spanish*/¿Qué la habrá pasado a Sheik?
hintTextTable[RHT_JUNK25] = HintText(CustomMessage("L2P @.",
hintTextTable[RHT_JUNK18] = HintText(CustomMessage("L2P @.",
/*german*/ "",
/*french*/ "Arrête de lire les indices et joue comme un grand, @."));
// /*spanish*/Mira que eres novato, @.
hintTextTable[RHT_JUNK26] = HintText(CustomMessage("I've heard you can cheat at Sploosh Kaboom.",
/*german*/ "",
/*french*/ "Selon moi, il y a une carte aux trésors à Mercantîle... Duh!"));
// /*spanish*/He oído por ahí que puedes hacer trampa en el Sploosh Kaboom.
hintTextTable[RHT_JUNK27] = HintText(CustomMessage("I'm Lonk from Pennsylvania.",
/*german*/ "",
/*french*/ "Je suis Lonk, le héros de Pennsylvanie!"));
// /*spanish*/Soy Lonk, de Pensilvania.
hintTextTable[RHT_JUNK28] = HintText(CustomMessage("I bet you'd like to have more bombs.",
hintTextTable[RHT_JUNK19] = HintText(CustomMessage("I bet you'd like to have more bombs.",
/*german*/ "",
/*french*/ "Je parie que tu veux plus de bombes."));
// /*spanish*/Me apuesto a que quisieras tener más bombas.
hintTextTable[RHT_JUNK29] = HintText(CustomMessage("When all else fails, use Fire.",
hintTextTable[RHT_JUNK20] = HintText(CustomMessage("When all else fails, use Fire.",
/*german*/ "",
/*french*/ "Quand rien ne marche, utilise le feu."));
// /*spanish*/Cuando nada funcione, usa el fuego.
hintTextTable[RHT_JUNK30] = HintText(CustomMessage("Here's a hint, @. Don't be bad.",
hintTextTable[RHT_JUNK21] = HintText(CustomMessage("Here's a hint, @. Don't be bad.",
/*german*/ "",
/*french*/ "Selon moi, la #Triforce# n'est pas dans le jeu... Duh!"));
// /*spanish*/Aquí tienes una pista, @: deja de ser manco.
hintTextTable[RHT_JUNK31] = HintText(CustomMessage("Game Over. Return of Ganon.",
hintTextTable[RHT_JUNK22] = HintText(CustomMessage("Game Over. Return of Ganon.",
/*german*/ "",
/*french*/ "Partie terminée. RETour de Ganon."));
// /*spanish*/Fin de la partida. El regreso de Ganon.
hintTextTable[RHT_JUNK32] = HintText(CustomMessage("May the way of the Hero lead to the Triforce.",
hintTextTable[RHT_JUNK23] = HintText(CustomMessage("May the way of the Hero lead to the Triforce.",
/*german*/ "",
/*french*/ "Que le chemin du héros te mène à la Triforce."));
// /*spanish*/Puede que la senda del héroe te lleve hacia la Trifuerza.
hintTextTable[RHT_JUNK33] = HintText(CustomMessage("Can't find an item? Scan an Amiibo.",
hintTextTable[RHT_JUNK24] = HintText(CustomMessage("Can't find an item? Scan an Amiibo.",
/*german*/ "",
/*french*/ "Tu cherches de quoi? Utilise un Amiibo!"));
// /*spanish*/¿No encuentras algo? Escanea un amiibo.
hintTextTable[RHT_JUNK34] = HintText(CustomMessage("They say this game has just a few glitches.",
hintTextTable[RHT_JUNK25] = HintText(CustomMessage("They say this game has just a few glitches.",
/*german*/ "",
/*french*/ "Selon moi, ce jeu est complètement exempt de glitchs."));
// /*spanish*/Dicen que este juego apenas tiene glitches.
hintTextTable[RHT_JUNK35] = HintText(CustomMessage("BRRING BRRING This is Ulrira. Wrong number?",
hintTextTable[RHT_JUNK26] = HintText(CustomMessage("BRRING BRRING This is Ulrira. Wrong number?",
/*german*/ "",
/*french*/ "DRING DRING!! Pépé le Ramollo à l'appareil... Quoi? Faux numéro?"));
// /*spanish*/¡Ring! ¡Ring! Al habla Ulrira. ¿Me he equivocado de número?
hintTextTable[RHT_JUNK36] = HintText(CustomMessage("Tingle Tingle Kooloo Limpah!",
hintTextTable[RHT_JUNK27] = HintText(CustomMessage("Tingle Tingle Kooloo Limpah!",
/*german*/ "",
/*french*/ "Tingle! Tingle! Kooloolin... Pah!"));
// /*spanish*/Tingle, Tingle, Kurulín... ¡PA!
hintTextTable[RHT_JUNK37] = HintText(CustomMessage("L is real 2401",
hintTextTable[RHT_JUNK28] = HintText(CustomMessage("L is real 2401",
/*german*/ "",
/*french*/ "L is real 2401"));
// /*spanish*/L es real 2401.
hintTextTable[RHT_JUNK38] = HintText(CustomMessage("They say that Ganondorf will appear in the next Mario Tennis.",
hintTextTable[RHT_JUNK29] = HintText(CustomMessage("They say that Ganondorf will appear in the next Mario Tennis.",
/*german*/ "",
/*french*/ "Selon moi, Ganondorf sera la nouvelle recrue dans Mario Tennis."));
// /*spanish*/Según dicen, Ganondorf estará en el próximo Mario Tennis.
hintTextTable[RHT_JUNK39] = HintText(CustomMessage("Medigoron sells the earliest Breath of the Wild demo.",
hintTextTable[RHT_JUNK30] = HintText(CustomMessage("They say Medigoron sells the earliest Breath of the Wild demo.",
/*german*/ "",
/*french*/ "Selon moi, Medigoron vend une démo de #Breath of the Wild#."));
// /*spanish*/Medigoron vende la primera demo del Breath of the Wild.
hintTextTable[RHT_JUNK40] = HintText(CustomMessage("Can you move me? I don't get great service here.",
hintTextTable[RHT_JUNK31] = HintText(CustomMessage("Can you move me? I don't get great service here.",
/*german*/ "",
/*french*/ "Peux-tu me déplacer? J'ai pas une bonne réception ici."));
// /*spanish*/¿Puedes llevarme a otro lado? Aquí nadie me presta atención.
hintTextTable[RHT_JUNK41] = HintText(CustomMessage("They say if you use Strength on the truck, you can find Mew.",
hintTextTable[RHT_JUNK32] = HintText(CustomMessage("They say if you use Strength on the truck, you can find Mew.",
/*german*/ "",
/*french*/ "Selon moi, #Mew# se trouve dessous le camion... Duh!"));
// /*spanish*/Según dicen, puedes hallar un Mew usando Fuerza contra el camión de Ciudad Carmín.
hintTextTable[RHT_JUNK42] = HintText(CustomMessage("I'm a helpful hint Gossip Stone!^See, I'm helping.",
hintTextTable[RHT_JUNK33] = HintText(CustomMessage("I'm a helpful hint Gossip Stone!^See, I'm helping.",
/*german*/ "",
/*french*/ "Salut! Je suis une pierre de bons conseils!^Tiens, tu vois? J'aide bien, hein?"));
// /*spanish*/Soy una Piedra Sheikah muy útil.^¡Mira cómo te ayudo!
hintTextTable[RHT_JUNK43] = HintText(CustomMessage("Dear @, please come to the castle. I've baked a cake for you.&Yours truly, Princess Zelda.",
hintTextTable[RHT_JUNK34] = HintText(CustomMessage("Dear @, please come to the castle. I've baked a cake for you.&Yours truly, Princess Zelda.",
/*german*/ "",
/*french*/ "Mon très cher @:&Viens vite au château, je t'ai préparé&un délicieux gâteau...^À bientôt, Princesse Zelda"));
// /*spanish*/Querido @: Por favor, ven al castillo. He hecho una tarta para ti.&Sinceramente tuya: Princesa Zelda.
hintTextTable[RHT_JUNK44] = HintText(CustomMessage("They say all toasters toast toast.",
hintTextTable[RHT_JUNK35] = HintText(CustomMessage("They say all toasters toast toast.",
/*german*/ "",
/*french*/ "Selon moi, les grille-pains grillent du pain."));
// /*spanish*/Según dicen, todas las tostadoras tostan tostadas tostadas.
hintTextTable[RHT_JUNK45] = HintText(CustomMessage("You thought it would be a useful hint, but it was me, junk hint!",
hintTextTable[RHT_JUNK36] = HintText(CustomMessage("You thought it would be a useful hint, but it was me, junk hint!",
/*german*/ "",
/*french*/ "Tu t'attendais à un bon indice... Mais c'était moi, un mauvais indice!"));
// /*spanish*/Je... Creeías que iba a ser una piedra de utilidad, ¡pero no, era yo, la piedra de la agonía!
hintTextTable[RHT_JUNK46] = HintText(CustomMessage("They say that quest guidance can be found at a talking rock.",
hintTextTable[RHT_JUNK37] = HintText(CustomMessage("They say that quest guidance can be found at a talking rock.",
/*german*/ "",
/*french*/ "Selon moi, des #indices# se trouvent auprès d'une pierre parlante... Duh!"));
// /*spanish*/Según dicen, puedes consultarle ayuda a rocas parlanchinas.
hintTextTable[RHT_JUNK47] = HintText(CustomMessage("They say that the final item you're looking for can be found somewhere in Hyrule.",
hintTextTable[RHT_JUNK38] = HintText(CustomMessage("They say that the final item you're looking for can be found somewhere in Hyrule.",
/*german*/ "",
/*french*/ "Selon moi, le #dernier objet# se trouve quelque part dans Hyrule... Duh!"));
// /*spanish*/Según dicen, el último objeto que te falte puede estar en cualquier rincón de Hyrule.
hintTextTable[RHT_JUNK48] = HintText(CustomMessage("Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.",
hintTextTable[RHT_JUNK39] = HintText(CustomMessage("Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.",
/*german*/ "",
/*french*/ "Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip.^Mwip."));
// /*spanish*/Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.^Mweep.
hintTextTable[RHT_JUNK49] = HintText(CustomMessage("They say that Barinade fears Deku Nuts.",
hintTextTable[RHT_JUNK40] = HintText(CustomMessage("They say that Barinade fears Deku Nuts.",
/*german*/ "",
/*french*/ "Selon moi, Barinade a la frousse des noix Mojo."));
// /*spanish*/Según dicen, lo que más teme a Barinade son las nueces deku.
hintTextTable[RHT_JUNK50] = HintText(CustomMessage("They say that Flare Dancers do not fear Goron-crafted blades.",
hintTextTable[RHT_JUNK41] = HintText(CustomMessage("They say that Flare Dancers do not fear Goron-crafted blades.",
/*german*/ "",
/*french*/ "Selon moi, le danse-flamme n'a pas peur des armes de Goron."));
// /*spanish*/Según dicen, los Bailafuegos no le temen a las armas forjadas por Gorons.
hintTextTable[RHT_JUNK51] = HintText(CustomMessage("They say that Morpha is easily trapped in a corner.",
hintTextTable[RHT_JUNK42] = HintText(CustomMessage("They say that Morpha is easily trapped in a corner.",
/*german*/ "",
/*french*/ "Selon moi, Morpha est facilement coincé."));
// /*spanish*/Según dicen, puedes atrapar a Morpha con facilidad en una esquina.
hintTextTable[RHT_JUNK52] = HintText(CustomMessage("They say that Bongo Bongo really hates the cold.",
hintTextTable[RHT_JUNK43] = HintText(CustomMessage("They say that Bongo Bongo really hates the cold.",
/*german*/ "",
/*french*/ "Selon moi, Bongo Bongo a facilement froid aux doigts."));
// /*spanish*/Según dicen, Bongo Bongo odia a muerte el frío.
hintTextTable[RHT_JUNK53] = HintText(CustomMessage("They say that your sword is most powerful when you put it away.",
hintTextTable[RHT_JUNK44] = HintText(CustomMessage("They say that your sword is most powerful when you put it away.",
/*german*/ "",
/*french*/ "Selon moi, ton épée est à pleine puissance quand tu la rengaines."));
// /*spanish*/Según dicen, tu espada se vuelve más poderosa si la guardas.
hintTextTable[RHT_JUNK54] = HintText(CustomMessage("They say that bombing the hole Volvagia last flew into can be rewarding.",
hintTextTable[RHT_JUNK45] = HintText(CustomMessage("They say that bombing the hole Volvagia last flew into can be rewarding.",
/*german*/ "",
/*french*/ "Selon moi, le trou où se creuse Volvagia est vulnérable aux bombes."));
// /*spanish*/Según dicen, trae buena suerte colocar una bomba en el último agujero de donde salió Volvagia.
hintTextTable[RHT_JUNK55] = HintText(CustomMessage("They say that invisible ghosts can be exposed with Deku Nuts.",
hintTextTable[RHT_JUNK46] = HintText(CustomMessage("They say that invisible ghosts can be exposed with Deku Nuts.",
/*german*/ "",
/*french*/ "Selon moi, des fantômes invisibles apparaissent avec des noix Mojo."));
// /*spanish*/Según dicen, puedes exponer a los espectros invisibles con nueces deku.
hintTextTable[RHT_JUNK56] = HintText(CustomMessage("They say that the real Phantom Ganon is bright and loud.",
hintTextTable[RHT_JUNK47] = HintText(CustomMessage("They say that the real Phantom Ganon is bright and loud.",
/*german*/ "",
/*french*/ "Selon moi, le vrai spectre de Ganon est clair et bruyant."));
// /*spanish*/Según dicen, el verdadero Ganon Fantasma es brillante y ruidoso.
hintTextTable[RHT_JUNK57] = HintText(CustomMessage("They say that walking backwards is very fast.",
hintTextTable[RHT_JUNK48] = HintText(CustomMessage("They say that walking backwards is very fast.",
/*german*/ "",
/*french*/ "Selon moi, tu fais marche arrière très rapidement pour un héros."));
// /*spanish*/Según dicen, es más rápido caminar hacia atrás.
hintTextTable[RHT_JUNK58] = HintText(CustomMessage("They say that leaping above the Market entrance enriches most children.",
/*german*/ "",
/*french*/ "Selon moi, les enfants riches se pavanent en haut du pont-levis."));
// /*spanish*/Según dicen, saltar por las cadenas a la entrada de la plaza enriquece a muchos chiquillos.
hintTextTable[RHT_JUNK59] = HintText(CustomMessage("They say Ingo is not very good at planning ahead.",
hintTextTable[RHT_JUNK49] = HintText(CustomMessage("They say Ingo is not very good at planning ahead.",
/*german*/ "",
/*french*/ "Selon moi, Ingo ne fait pas un très bon geôlier."));
// /*spanish*/Según dicen, a Ingo no se le da especialmente bien planificar con antelación.
hintTextTable[RHT_JUNK60] = HintText(CustomMessage("You found a spiritual Stone! By which I mean, I worship Nayru.",
hintTextTable[RHT_JUNK50] = HintText(CustomMessage("You found a spiritual Stone! By which I mean, I worship Nayru.",
/*german*/ "",
/*french*/ "Vous avez trouvé une Pierre Ancestrale! En effet, je vénère la déesse Hylia."));
// /*spanish*/¡Has encontrado una piedra espiritual! Es que le rindo culto a Nayru...
hintTextTable[RHT_JUNK61] = HintText(CustomMessage("They say that a flying strike with a Deku Stick is no stronger than a grounded one.",
/*german*/ "",
/*french*/ "Selon moi, un coup de bâton sauté n'est pas meilleur qu'au sol."));
// /*spanish*/Según dicen, los golpes aéreos con palos deku son tan fuertes como los normales.
hintTextTable[RHT_JUNK62] = HintText(CustomMessage("Open your eyes.^Open your eyes.^Wake up, @.",
hintTextTable[RHT_JUNK51] = HintText(CustomMessage("Open your eyes.^Open your eyes.^Wake up, @.",
/*german*/ "",
/*french*/ "Réveille-toi...^Réveille-toi.^Ouvre les yeux, @."));
// /*spanish*/Abre los ojos...^Abre los ojos...^Despierta, @...
hintTextTable[RHT_JUNK63] = HintText(CustomMessage("They say that the Nocturne of Shadow can bring you very close to Ganon.",
hintTextTable[RHT_JUNK52] = HintText(CustomMessage("They say that the Nocturne of Shadow can bring you very close to Ganon.",
/*german*/ "",
/*french*/ "Selon moi, le nocturne de l'ombre peut t'amener très près de Ganon."));
// /*spanish*/Según dicen, el Nocturno de la sombra te puede acercar mucho a Ganon.
hintTextTable[RHT_JUNK64] = HintText(CustomMessage("They say that Twinrova always casts the same spell the first three times.",
hintTextTable[RHT_JUNK53] = HintText(CustomMessage("They say that Twinrova always casts the same spell the first three times.",
/*german*/ "",
/*french*/ "Selon moi, Twinrova lance toujours les mêmes trois premiers sorts."));
// /*spanish*/Según dicen, Birova siempre lanza el mismo hechizo las tres primeras veces.
hintTextTable[RHT_JUNK65] = HintText(CustomMessage("They say that the nightly builds may be unstable.",
hintTextTable[RHT_JUNK54] = HintText(CustomMessage("They say that the nightly builds may be unstable.",
/*german*/ "",
/*french*/ "Selon moi, les \"nightly builds\" peuvent être instables."));
// /*spanish*/Según dicen, las últimas nightlies pueden llegar a ser algo inestables.
hintTextTable[RHT_JUNK66] = HintText(CustomMessage("You're playing a Randomizer. I'm randomized!^Here's a random number: #4#.&Enjoy your Randomizer!",
hintTextTable[RHT_JUNK55] = HintText(CustomMessage("You're playing a Randomizer. I'm randomized!^Here's a random number: #4#.&Enjoy your Randomizer!",
/*german*/ "",
/*french*/ "Tu joues à un randomizer. Je suis aléatoire!^Voici un nombre aléatoire: #4#.&Bonne partie!"));
// /*spanish*/¡Estás jugando un Randomizer! ¡Yo también estoy aleatorizada!^Aquí tienes un número aleatorio: #8#.&¡Diviértete!
hintTextTable[RHT_JUNK67] = HintText(CustomMessage("They say Ganondorf's bolts can be reflected with glass or steel.",
hintTextTable[RHT_JUNK56] = HintText(CustomMessage("They say Ganondorf's bolts can be reflected with glass or steel.",
/*german*/ "",
/*french*/ "Selon moi, les éclairs de Ganon se reflètent sur l'acier et le verre."));
// /*spanish*/Según dicen, puedes reflejar las esferas de energía de Ganondorf con cristal y acero.
hintTextTable[RHT_JUNK68] = HintText(CustomMessage("They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, "
hintTextTable[RHT_JUNK57] = HintText(CustomMessage("They say Ganon's tail is vulnerable to nuts, arrows, swords, explosives, hammers...^...sticks, seeds, "
"boomerangs...^...rods, shovels, iron balls, angry bees...",
/*german*/ "",
/*french*/ "Selon moi, la queue de Ganon est vulnérable aux noix, flèches, épées, bombes, marteaux...^...bâtons, "
"graines, boomerangs...^...baguettes, pelles, boulets de fer, abeilles enragées..."));
// /*spanish*/Según dicen, la cola de Ganon es vulnerable a nueces, flechas, espadas, explosivos,
// martillos...^...palos, semillas, bumeráns...^...cetros, palas, bolas de hierro, abejas...
hintTextTable[RHT_JUNK69] = HintText(CustomMessage("They say that you're wasting time reading this hint, but I disagree. Talk to me again!",
hintTextTable[RHT_JUNK58] = HintText(CustomMessage("They say that you're wasting time reading this hint, but I disagree. Talk to me again!",
/*german*/ "",
/*french*/ "Selon moi... tu sais quoi? Parle-moi encore, et je te le dirai!"));
// /*spanish*/Según dicen, pierdes el tiempo en leer esta pista, pero no pienso igual. ¡Vuelve a hablarme, ya verás!
hintTextTable[RHT_JUNK70] = HintText(CustomMessage("They say Ganondorf knows where to find the instrument of his doom.",
hintTextTable[RHT_JUNK59] = HintText(CustomMessage("They say Ganondorf knows where to find the instrument of his doom.",
/*german*/ "",
/*french*/ "Selon moi, Ganondorf sait où il a caché son point faible."));
// /*spanish*/Según dicen, Ganondorf sabe dónde hallar el instrumento de su perdición.
hintTextTable[RHT_JUNK71] = HintText(CustomMessage("I heard @ is pretty good at Zelda.",
hintTextTable[RHT_JUNK60] = HintText(CustomMessage("I heard @ is pretty good at Zelda.",
/*german*/ "",
/*french*/ "Apparemment, @ est super bon à Zelda."));
// /*spanish*/He oído que a @ se le dan muy bien los Zelda.
hintTextTable[RHT_JUNK72] = HintText(CustomMessage("Hi @, we've been trying to reach you about your car's extended warranty. ",
hintTextTable[RHT_JUNK61] = HintText(CustomMessage("Hi @, we've been trying to reach you about your car's extended warranty. ",
/*german*/ "",
/*french*/ "Bonjour, @. Vous avez une voiture? Vous savez, nous offrons des assurances abordables..."));
// /*spanish*/Buenas, @. Le llamamos para ofrecerle un nuevo seguro de hogar que puede pagar en cómodos plazos, sin
// intereses ni comisiones.
hintTextTable[RHT_JUNK73] = HintText(CustomMessage("They say that the best weapon against Iron Knuckles is item 176.",
/*german*/ "",
/*french*/ "Selon moi, les hache-viandes sont vulnérables contre l'objet 176."));
// /*spanish*/Según dicen, la mejor arma para enfrentarse a los Nudillos de hierro es el objeto 176.
hintTextTable[RHT_JUNK74] = HintText(CustomMessage("They say that it's actually possible to beat the running man.",
hintTextTable[RHT_JUNK62] = HintText(CustomMessage("They say that it's actually possible to beat the running man.",
/*german*/ "",
/*french*/ "Selon moi, il est possible de battre le coureur.&Donc, tu prends ton arc, et..."));
// /*spanish*/Según dicen, con mucha perseverancia puedes ganarle al corredor con la capucha de conejo.
hintTextTable[RHT_JUNK75] = HintText(CustomMessage("They say that the stone-cold guardian of the Well is only present during work hours.",
/*german*/ "",
/*french*/ "Selon moi, le gardien de pierre du Puits quitte le soir pour aller se coucher."));
// /*spanish*/Según dicen, la inmensa roca que bloquea el pozo solo trabaja en horas laborales.
hintTextTable[RHT_JUNK76] = HintText(CustomMessage("They say this hint makes more sense in other languages.",
hintTextTable[RHT_JUNK63] = HintText(CustomMessage("They say this hint makes more sense in other languages.",
/*german*/ "",
/*french*/ "Selon moi, ces indices auraient pu être mieux traduits... Duh!"));
// /*spanish*/Según dicen, esta pista revela algo de vital importancia si cambias el idioma del juego...
hintTextTable[RHT_JUNK77] = HintText(CustomMessage("BOK? No way.",
/*german*/ "",
/*french*/ "BD'accord? Hors de question."));
// /*spanish*/¿BVale? Ni hablar.
// ^ Junk hints above are from 3drando
// v Junk hints below are new to soh rando
// ^ junk hints above are from 3drando
// v junk hints below are new to soh rando
// Please keep hints to stuff related to ship directly, or to Nintendo/Zelda related stuff.
// And nothing that's super obscure that no one's going to understand.
#define HINT_TEXT_NEEDS_TRANSLATION_FR \
"Erreur 0x69a504:&Traduction manquante^C'est de la faute à Purple Hato!&J'vous jure!"
hintTextTable[RHT_JUNK78] = HintText(CustomMessage("They say blarg...^...or at least briaguya does.",
hintTextTable[RHT_JUNK64] = HintText(CustomMessage("They say Greg is special.",
/*german*/ "",
/*french*/ "Tout ce que j'ai à dire, c'est blarg...^... 'fin c'est plutôt ce que briaguya dirait."));
// /*spanish*/blarg
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK79] = HintText(CustomMessage("They say this peace is what all true warriors strive for.",
hintTextTable[RHT_JUNK65] = HintText(CustomMessage("They say the longer the Goron's neck, the wiser they are.",
/*german*/ "",
/*french*/ "Selon moi, cette paix est ce pour quoi luttent tous les vrais guerriers."));
// /*spanish*/blarg
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK80] = HintText(CustomMessage("They say this ship is what all true gamers strive for.",
hintTextTable[RHT_JUNK66] = HintText(CustomMessage("They say this ship is what all true gamers strive for.",
/*german*/ "",
/*french*/ "Selon moi, cette version du port est ce pour quoi luttent tous les vrais gamers."));
// /*spanish*/blarg
hintTextTable[RHT_JUNK81] = HintText(CustomMessage("They say that Glowsticks can be found in the Raveyard.",
hintTextTable[RHT_JUNK67] = HintText(CustomMessage("They say that Glowsticks can be found in the Raveyard.",
/*german*/ "",
/*french*/ "On peut trouver des Bâtons Lumineux sur le dancefloor du cimetière."));
// /*spanish*/blarg
hintTextTable[RHT_JUNK_WTC_1] = HintText(CustomMessage("They say %rthere are no more than 18&people on this island.",
hintTextTable[RHT_JUNK68] = HintText(CustomMessage("They say @'s uncle works for Nintendo.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_2] = HintText(CustomMessage("They say I am one yet many",
hintTextTable[RHT_JUNK69] = HintText(CustomMessage("They say pulling all gravestones in the graveyard leads to something magical.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_3] = HintText(CustomMessage("They say its all in the name of guiding&humanity down the right path.",
hintTextTable[RHT_JUNK70] = HintText(CustomMessage("They say holding L while pausing makes you win the game.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_4] = HintText(CustomMessage("They say \"Repetition requested\"",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_5] = HintText(CustomMessage("They say %rThe red tells only the truth!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_6] = HintText(CustomMessage("They say good tidings to you^my traitorous @",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_7] = HintText(CustomMessage("They say when the seagulls cried,&none were left alive.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_8] = HintText(CustomMessage("They say she is lying with the red letters!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_9] = HintText(CustomMessage("They say we'll meet again,&when something else cries.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_10] = HintText(CustomMessage("They say \"Forgive me, but-^Your script will not be used.&....After all...^The one writing the rest of "
"the script...&will be me.\"",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_11] = HintText(CustomMessage("They say tea is best enjoyed...^\"\"With your fellow monsters.\"\"",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_WTC_12] = HintText(CustomMessage("They say I shall make you some black tea. With my own hands, not magic.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_1] = HintText(CustomMessage("They say you know I've kiboshed before...^and I will kibosh again.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_2] = HintText(CustomMessage("They say if relationship @ walks through that door,^they will KILL independent @.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_3] = HintText(CustomMessage("They say you gotta have the BIG Salad.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_4] = HintText(CustomMessage("They say it's a festivus miracle",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_5] = HintText(CustomMessage("They say there are no houses in Tuscany to rent.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_6] = HintText(CustomMessage("They say my last boyfriend had a real&Kroner comprehension problem.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_7] = HintText(CustomMessage("They say it's a festivus miracle.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_8] = HintText(CustomMessage("They say Louis quit the importing&to focus on the exporting.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_9] = HintText(CustomMessage("They say no thanks, I can't drink coffee&late at night, it keeps me up.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_10] = HintText(CustomMessage("They say it's not a lie if you believe it.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_11] = HintText(CustomMessage("They say there was a second spitter.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_12] = HintText(CustomMessage("They say there was a second spitter.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_13] = HintText(CustomMessage("They say the jerk store called,^they're running out of YOU.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_14] = HintText(CustomMessage("They say when you look annoyed all the time,&people thing you are busy.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_15] = HintText(CustomMessage("They say when you look annoyed all the time,&people think you are busy.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_16] = HintText(CustomMessage("They say he fires people like its a bodily function.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_17] = HintText(CustomMessage("They say he threatened to move the ship to New Jersey&just to upset people.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_18] = HintText(CustomMessage("They say there was significant shrinkage.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_19] = HintText(CustomMessage("They say if it wasn't for the toilet there'd be no books.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_20] = HintText(CustomMessage("They say if it wasn't for the toilet there'd be no books.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_21] = HintText(CustomMessage("They say don't trust men in capes.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_22] = HintText(CustomMessage("They say @'s uncle works for Nintendo.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_23] = HintText(CustomMessage("They say @'s stole the marble rye.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_24] = HintText(CustomMessage("They say there is no better harmony&than the black and white cookie.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_25] = HintText(CustomMessage("They say @ hasn't vomited since 1983.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_26] = HintText(CustomMessage("They say you gotta have the early bird special.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_27] = HintText(CustomMessage("They say a donation has been made in your name&to the human fund.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_28] = HintText(CustomMessage("They say you want to be my latex salesman.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SEI_29] = HintText(CustomMessage("They say if every instinct you have is wrong...^... then the opposite would have to be right.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_1] = HintText(CustomMessage("They say OTR stands for&Over the Rainbow",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_2] = HintText(CustomMessage("They say that OTR stands for&Onions, Tomatoes, and Radishes",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_3] = HintText(CustomMessage("They say that OTR stands for&Ocarina of Time Resources",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_4] = HintText(CustomMessage("They say that OTR stands for&Over the Road",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_5] = HintText(CustomMessage("They say that OTR stands for&Off the Record",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_6] = HintText(CustomMessage("They say that OTR stands for&Office of Tax and Revenue",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_7] = HintText(CustomMessage("They say OTR stands for&Over the Rainbow",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_8] = HintText(CustomMessage("They say that OTR stands for&Office of Trade Relations",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_9] = HintText(CustomMessage("They say that OTR stands for&Original Theatrical Release",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_10] = HintText(CustomMessage("They say that OTR stands for&Operational Test Requirement",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_11] = HintText(CustomMessage("They say that OTR stands for&Operational Trouble Report",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_12] = HintText(CustomMessage("They say that OTR stands for&Oxygen Transmission Rate",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_13] = HintText(CustomMessage("They say that OTR stands for&One Touch Recording",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_14] = HintText(CustomMessage("They say that OTR stands for&Olympic Torch Relay",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_15] = HintText(CustomMessage("They say that OTR stands for&Off the Rack",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_16] = HintText(CustomMessage("They say that OTR stands for&Overhead Transfer Rate",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_17] = HintText(CustomMessage("They say that OTR stands for&Operational TurnaRound",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_18] = HintText(CustomMessage("They say that OTR stands for&Opportunity to Recall",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_19] = HintText(CustomMessage("They say that OTR stands for&Operability Test Report",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_20] = HintText(CustomMessage("They say that OTR stands for&Overall Tuning Range",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_21] = HintText(CustomMessage("They say that OTR stands for&One Time Requisition",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_22] = HintText(CustomMessage("They say that OTR stands for&Oblivious to Reality",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_23] = HintText(CustomMessage("They say that OTR stands for&On the Run",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_24] = HintText(CustomMessage("They say that OTR stands for&On Time Reporting",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_25] = HintText(CustomMessage("They say that OTR stands for&Order to Receipt",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_26] = HintText(CustomMessage("They say that OTR stands for&Other Terrestrial Radio",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_27] = HintText(CustomMessage("They say that OTR stands for&On Target Reports",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_28] = HintText(CustomMessage("They say that OTR stands for&One Time Repair",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_29] = HintText(CustomMessage("They say that OTR stands for&Own the Room",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_OTR_MEANS_30] = HintText(CustomMessage("They say that OTR stands for&Online Text Repository",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_1] = HintText(CustomMessage("They say #Kenix# isn't a developer...^...Just a PR guy",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR,
{QM_GREEN}));
hintTextTable[RHT_JUNK_MISC_2] = HintText(CustomMessage("They say... No",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_3] = HintText(CustomMessage("They say BIG RIGS: OTR",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_4] = HintText(CustomMessage("They say you wanted to see me #Mr. Kenix#?",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR,
{QM_PINK}));
hintTextTable[RHT_JUNK_MISC_5] = HintText(CustomMessage("They say Louis once saw an&equals not get set equals",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_6] = HintText(CustomMessage("They say only you can find your rom.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_7] = HintText(CustomMessage("They say ZAPD is good software.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_8] = HintText(CustomMessage("They say you can encounter&a parascode in tall grass.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_9] = HintText(CustomMessage("They say the ship sails on March 32nd.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_10] = HintText(CustomMessage("They say bombing dodongos is fun.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_11] = HintText(CustomMessage("They say shopkeepers don't give credits.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_12] = HintText(CustomMessage("They say shopkeepers don't give credits.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_13] = HintText(CustomMessage("They say Malon is glitched.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_14] = HintText(CustomMessage("They say do I look like I know&what a DList is?",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_15] = HintText(CustomMessage("They say do I look like I know&what an AList is?",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_16] = HintText(CustomMessage("They say the king drinks enthusiastically",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_MISC_17] = HintText(CustomMessage("They say Rubies are on the path to&Lamp Oil, Rope, and Bombs",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_1] = HintText(CustomMessage("They say %rError. Human is dead, mismatch.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_2] = HintText(CustomMessage("They say this is the choice of the&steins gate.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_3] = HintText(CustomMessage("They say el psy kongroo.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_4] = HintText(CustomMessage("They say tutturu~.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_5] = HintText(CustomMessage("They say im not Christina!.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_6] = HintText(CustomMessage("They say you know where to find an IBN5100.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_7] = HintText(CustomMessage("They say when you're on a chicken bender&grab a box of chicken tenders.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_SG_8] = HintText(CustomMessage("Juicy Chicken #1! Wow!.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_1] = HintText(CustomMessage("They say that %gGanondorf's Mom%w is going out with %ySqueak%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_2] = HintText(CustomMessage("They say that %gProxySaw%w is still fixing %yCaladius's Bugs%w...",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_3] = HintText(CustomMessage("They say that %gItsHeckinPat%w is still just %yEyeballing it%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_4] = HintText(CustomMessage("They say that %gCaladius%w is working on %yV2%w of something.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_5] = HintText(CustomMessage("They say that %gdice%w is a funny name for a %ytaco%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_6] = HintText(CustomMessage("They say %g2Ship Rando%w is still blocked by %yV3%w...",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_7] = HintText(CustomMessage("They say if you click your heels and say %gframebuffer%w 3 times, %yArchez%w appears!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_8] = HintText(CustomMessage("They say %gVB%w stands for %yVirtual Bananas%w... Probably.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_9] = HintText(CustomMessage("They say %gZeru%w is still routing his %yHundo%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_10] = HintText(CustomMessage("They say %gRaccoonCloud%w is still looking for his %yHover Boots%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_11] = HintText(CustomMessage("They say %gItsHeckinPat%w foreclosed on his %yHut%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_12] = HintText(CustomMessage("They say %gRaccoonCloud%w is part of the %yInner Circle%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_13] = HintText(CustomMessage("They say %gMoonlitxShadows%w is the %rleader%w of the %yDork Army%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_14] = HintText(CustomMessage("They say %gGanondorf%w hates the %yInternet%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_15] = HintText(CustomMessage("They say %gMido's House%w hoards %yTrash%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_16] = HintText(CustomMessage("They say %gSweettalking Ganondorf%w rewards %yHis Heart%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_17] = HintText(CustomMessage("They say %gaMannus%w said %yGo To Bed%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_18] = HintText(CustomMessage("They say %gCaladius%w is a %yPinhead%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_19] = HintText(CustomMessage("They say %gRaccoonCloud%w loves the %yIce Cavern%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_20] = HintText(CustomMessage("They say %gNo One%w should forget %yHover Scrub%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_21] = HintText(CustomMessage("They say %gMoonlitxShadows%w likes to %ySlide%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_23] = HintText(CustomMessage("They say that %gBackwalking%w should be %rBanned%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_24] = HintText(CustomMessage("They say that %gGorons%w should always have %yLong Necks%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_25] = HintText(CustomMessage("They say that %gCaladius%w has a %ytendency to lose his shirt%w!",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_26] = HintText(CustomMessage("They say that if your %rSkip keeps Failing%w, you're probably an %yESS Off%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_27] = HintText(CustomMessage("They say that %gLogic%w is just a %ySuggestion%w.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_28] = HintText(CustomMessage("They say there's %gAlways Logic%w in %yNo Logic%w...",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));
hintTextTable[RHT_JUNK_CREW_29] = HintText(CustomMessage("They said that %rFredomato%w has just %yone more push up%w to do!",
hintTextTable[RHT_JUNK71] = HintText(CustomMessage("They say @'s body is ready.",
/*german*/ "",
/*french*/ HINT_TEXT_NEEDS_TRANSLATION_FR));

View File

@ -882,11 +882,11 @@ hintTextTable[RHT_FIRE_TEMPLE_NEAR_BOSS_CHEST] = HintText(CustomMessage("They sa
/*german*/ "",
/*french*/ "Selon moi, un #coeur dans le Temple du Feu# cache #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RAND_INF_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a hot arena# reveals #[[1]]#.",
hintTextTable[RHT_FIRE_TEMPLE_MQ_LOOP_STALFOS_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a hot arena# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "Selon moi, #appeler le soleil dans une arène chaude# révèle #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RAND_INF_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun behind a knight's throne in a volcano# reveals #[[1]]#.",
hintTextTable[RHT_FIRE_TEMPLE_MQ_LOOP_KNUCKLE_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun behind a knight's throne in a volcano# reveals #[[1]]#.",
/*german*/ "!!!",
/*french*/ "Selon moi, #appeler le soleil derrière le trône dun chevalier dans un volcan# révèle #[[1]]#.", {QM_RED, QM_GREEN}));

View File

@ -1936,5 +1936,23 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
/*german*/ "!!!",
/*french*/ "Selon moi, jouer une mélodie orageuse pour une pierre étrange dans le côté d'un cratère révèle [[1]].", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LH_ISLAND_SUN_FAIRY] = HintText(CustomMessage("They say that #summoning the sun on the lake's island# calls #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_POND_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling rain to the field's pond# summons #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_HF_FENCE_GROTTO_STORMS_FAIRY] = HintText(CustomMessage("They say that #making it rain in a scrub's cave# wakes #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMT_FLAG_SUN_FAIRY] = HintText(CustomMessage("They say that #changing the time in front of the trail's flag# reveals #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_DMT_COW_GROTTO_STORMS_FAIRY] = HintText(CustomMessage("They say that #calling a storm for a lonely cow# reveals #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_SHORTCUT_STORMS_FAIRY] = HintText(CustomMessage("They say that #making it rain in the Lost Woods# reveals #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_GF_KITCHEN_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a guarded kitchen# exposes #[[1]]#.", {QM_RED, QM_GREEN}));
hintTextTable[RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun for scrubs in the Lost Woods# reveals #[[1]]#.", { QM_RED, QM_GREEN }));
hintTextTable[RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = HintText(CustomMessage("They say that #calling the sun in a royal tomb# reveals #[[1]]#.", { QM_RED, QM_GREEN }));
}
}

View File

@ -1361,7 +1361,18 @@ void StaticData::HintTable_Init_Item() {
// /*spanish*/un destructor de cerraduras final
CustomMessage("a final lockpick", /*german*/"ein finaler Dietrich", /*french*/"un crochet à porte final")});
// /*spanish*/una apertura portentosa final
hintTextTable[RHT_OVERWORLD_KEY] = HintText(CustomMessage("an Overworld Key", /*german*/"ein Überwelt-Schlüssel", /*french*/"une clé de l'Overworld"),
// /*spanish*/una llave del mundo exterior
{
CustomMessage("a small key", /*german*/"ein kleiner Schlüssel", /*french*/"une petite clé")
// /*spanish*/una llave
}, {
CustomMessage("a key to the world", /*german*/"ein Schlüssel zur Welt", /*french*/"une clé du monde"),
// /*spanish*/una llave al mundo
CustomMessage("a key to the kingdom", /*german*/"ein Schlüssel zum Königreich", /*french*/"une clé du royaume"),
// /*spanish*/una llave al reino
CustomMessage("a key to the universe", /*german*/"ein Schlüssel zum Universum", /*french*/"une clé de l'univers")});
// /*spanish*/una llave al universo
hintTextTable[RHT_FOREST_TEMPLE_KEY_RING] = HintText(CustomMessage("a Forest Temple Key Ring", /*german*/"ein Schlüsselbund des Waldtempels", /*french*/"un trousseau de clés du Temple de la Forêt"),
// /*spanish*/un llavero del Templo del Bosque
{

View File

@ -112,10 +112,10 @@ StaticHintInfo::StaticHintInfo(HintType _type, std::vector<RandomizerHintTextKey
targetItems(_targetItems), hintChecks(_hintChecks), yourPocket(_yourPocket), num(_num){}
RandomizerHintTextKey GetRandomJunkHint(){
//temp code to handle random junk hints now I work in keys instead of a vector of HintText
//Will be replaced with a better system once more customisable hint pools are added
uint32_t range = RHT_JUNK_CREW_29 - RHT_JUNK02;
return (RandomizerHintTextKey)(Random(0, range) + RHT_JUNK02);
// Temp code to handle random junk hints now I work in keys instead of a vector of HintText
// Will be replaced with a better system once more customisable hint pools are added
uint32_t range = RHT_JUNK71 - RHT_JUNK01;
return (RandomizerHintTextKey)(Random(0, range) + RHT_JUNK01);
}
RandomizerHintTextKey GetRandomGanonJoke(){
@ -222,18 +222,18 @@ uint8_t StonesRequiredBySettings() {
auto ctx = Rando::Context::GetInstance();
uint8_t stones = 0;
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) {
stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).GetContextOptionIndex();
stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get();
} else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) {
stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex() - 6;
stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - 6;
} else if ((ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) && (ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON))) {
stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex() - 6;
stones = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - 6;
}
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) {
stones = std::max<uint8_t>({ stones, ctx->GetOption(RSK_LACS_STONE_COUNT).GetContextOptionIndex() });
stones = std::max<uint8_t>({ stones, ctx->GetOption(RSK_LACS_STONE_COUNT).Get() });
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) {
stones = std::max<uint8_t>({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex() - 6 )});
stones = std::max<uint8_t>({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 6 )});
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) {
stones = std::max<uint8_t>({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex() - 6 )});
stones = std::max<uint8_t>({ stones, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 6 )});
}
return stones;
}
@ -242,18 +242,18 @@ uint8_t MedallionsRequiredBySettings() {
auto ctx = Rando::Context::GetInstance();
uint8_t medallions = 0;
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) {
medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).GetContextOptionIndex();
medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get();
} else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) {
medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex() - 3;
medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get() - 3;
} else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) {
medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex() - 3;
medallions = ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get() - 3;
}
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) {
medallions = std::max({ medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).GetContextOptionIndex() });
medallions = std::max({ medallions, ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get() });
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) {
medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex() - 3 )});
medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get() - 3 )});
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS) && ctx->GetOption(RSK_SHUFFLE_DUNGEON_REWARDS).Is(RO_DUNGEON_REWARDS_END_OF_DUNGEON)) {
medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex() - 3 )});
medallions = std::max({ medallions, (uint8_t)(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get() - 3 )});
}
return medallions;
}
@ -262,10 +262,10 @@ uint8_t TokensRequiredBySettings() {
auto ctx = Rando::Context::GetInstance();
uint8_t tokens = 0;
if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) {
tokens = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex();
tokens = ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get();
}
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) {
tokens = std::max<uint8_t>({ tokens, ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex() });
tokens = std::max<uint8_t>({ tokens, ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get() });
}
return tokens;
}
@ -273,7 +273,7 @@ uint8_t TokensRequiredBySettings() {
std::vector<std::pair<RandomizerCheck, std::function<bool()>>> conditionalAlwaysHints = {
std::make_pair(RC_MARKET_10_BIG_POES, []() {
auto ctx = Rando::Context::GetInstance();
return ctx->GetOption(RSK_BIG_POE_COUNT).GetContextOptionIndex() >= 3 && !ctx->GetOption(RSK_BIG_POES_HINT);
return ctx->GetOption(RSK_BIG_POE_COUNT).Get() >= 3 && !ctx->GetOption(RSK_BIG_POES_HINT);
}), // Remember, the option's value being 3 means 4 are required
std::make_pair(RC_DEKU_THEATER_MASK_OF_TRUTH, []() {
auto ctx = Rando::Context::GetInstance();
@ -483,7 +483,7 @@ static void CreateTrialHints(uint8_t copies) {
AddGossipStoneHintCopies(copies, HINT_TYPE_HINT_KEY, "Trial", {RHT_ZERO_TRIALS});
} else {
std::vector<TrialInfo*> trials = ctx->GetTrials()->GetTrialList(); //there's probably a way to remove this assignment
if (ctx->GetOption(RSK_TRIAL_COUNT).GetContextOptionIndex() >= 4) {//4 or 5 required trials, get skipped trials
if (ctx->GetOption(RSK_TRIAL_COUNT).Get() >= 4) {//4 or 5 required trials, get skipped trials
trials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsSkipped();});
} else {//1 to 3 trials, get requried trials
auto requiredTrials = FilterFromPool(trials, [](TrialInfo* trial){return trial->IsRequired();});
@ -611,7 +611,7 @@ uint8_t PlaceHints(std::vector<uint8_t>& selectedHints, std::vector<HintDistribu
void CreateStoneHints() {
auto ctx = Rando::Context::GetInstance();
SPDLOG_DEBUG("\nNOW CREATING HINTS\n");
const HintSetting& hintSetting = hintSettingTable[ctx->GetOption(RSK_HINT_DISTRIBUTION).GetContextOptionIndex()];
const HintSetting& hintSetting = hintSettingTable[ctx->GetOption(RSK_HINT_DISTRIBUTION).Get()];
std::vector<HintDistributionSetting> distTable = hintSetting.distTable;
// Apply impa's song exclusions when zelda is skipped
@ -738,7 +738,7 @@ void CreateAdultAltarHint() {
void CreateStaticHintFromData(RandomizerHint hint, StaticHintInfo staticData){
auto ctx = Rando::Context::GetInstance();
if (!ctx->GetHint(hint)->IsEnabled()){
Option option = ctx->GetOption(staticData.setting);
OptionValue& option = ctx->GetOption(staticData.setting);
if ((std::holds_alternative<bool>(staticData.condition) && option.Is(std::get<bool>(staticData.condition))) ||
(std::holds_alternative<uint8_t>(staticData.condition) && option.Is(std::get<uint8_t>(staticData.condition)))){

View File

@ -761,7 +761,7 @@ static void SetMinimalItemPool() {
ReplaceMaxItem(RG_PROGRESSIVE_BOMB_BAG, 1);
ReplaceMaxItem(RG_PIECE_OF_HEART, 0);
// Need an extra heart container when starting with 1 heart to be able to reach 3 hearts
ReplaceMaxItem(RG_HEART_CONTAINER, (ctx->GetOption(RSK_STARTING_HEARTS).GetContextOptionIndex() == 18)? 1 : 0);
ReplaceMaxItem(RG_HEART_CONTAINER, (ctx->GetOption(RSK_STARTING_HEARTS).Get() == 18)? 1 : 0);
}
void GenerateItemPool() {
@ -827,7 +827,7 @@ void GenerateItemPool() {
if (ctx->GetOption(RSK_TRIFORCE_HUNT)) {
ctx->possibleIceTrapModels.push_back(RG_TRIFORCE_PIECE);
AddItemToMainPool(RG_TRIFORCE_PIECE, (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).GetContextOptionIndex() + 1));
AddItemToMainPool(RG_TRIFORCE_PIECE, (ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_TOTAL).Get() + 1));
ctx->PlaceItemInLocation(RC_TRIFORCE_COMPLETED, RG_TRIFORCE); // Win condition
ctx->PlaceItemInLocation(RC_GANON, GetJunkItem(), false, true);
} else {
@ -935,7 +935,7 @@ void GenerateItemPool() {
if (fsMode.IsNot(RO_FISHSANITY_OFF)) {
if (fsMode.Is(RO_FISHSANITY_POND) || fsMode.Is(RO_FISHSANITY_BOTH)) {
// 17 max child pond fish
uint8_t pondCt = ctx->GetOption(RSK_FISHSANITY_POND_COUNT).GetContextOptionIndex();
uint8_t pondCt = ctx->GetOption(RSK_FISHSANITY_POND_COUNT).Get();
for (uint8_t i = 0; i < pondCt; i++) {
AddItemToMainPool(GetJunkItem());
}
@ -1276,6 +1276,33 @@ void GenerateItemPool() {
}
}
if (ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) {
AddItemToPool(ItemPool, RG_GUARD_HOUSE_KEY);
AddItemToPool(ItemPool, RG_MARKET_BAZAAR_KEY);
AddItemToPool(ItemPool, RG_MARKET_POTION_SHOP_KEY);
AddItemToPool(ItemPool, RG_MASK_SHOP_KEY);
AddItemToPool(ItemPool, RG_MARKET_SHOOTING_GALLERY_KEY);
AddItemToPool(ItemPool, RG_BOMBCHU_BOWLING_KEY);
AddItemToPool(ItemPool, RG_TREASURE_CHEST_GAME_BUILDING_KEY);
AddItemToPool(ItemPool, RG_BOMBCHU_SHOP_KEY);
AddItemToPool(ItemPool, RG_RICHARDS_HOUSE_KEY);
AddItemToPool(ItemPool, RG_ALLEY_HOUSE_KEY);
AddItemToPool(ItemPool, RG_KAK_BAZAAR_KEY);
AddItemToPool(ItemPool, RG_KAK_POTION_SHOP_KEY);
AddItemToPool(ItemPool, RG_BOSS_HOUSE_KEY);
AddItemToPool(ItemPool, RG_GRANNYS_POTION_SHOP_KEY);
AddItemToPool(ItemPool, RG_SKULLTULA_HOUSE_KEY);
AddItemToPool(ItemPool, RG_IMPAS_HOUSE_KEY);
AddItemToPool(ItemPool, RG_WINDMILL_KEY);
AddItemToPool(ItemPool, RG_KAK_SHOOTING_GALLERY_KEY);
AddItemToPool(ItemPool, RG_DAMPES_HUT_KEY);
AddItemToPool(ItemPool, RG_TALONS_HOUSE_KEY);
AddItemToPool(ItemPool, RG_STABLES_KEY);
AddItemToPool(ItemPool, RG_BACK_TOWER_KEY);
AddItemToPool(ItemPool, RG_HYLIA_LAB_KEY);
AddItemToPool(ItemPool, RG_FISHING_HOLE_KEY);
}
//Shopsanity
if (
ctx->GetOption(RSK_SHOPSANITY).Is(RO_SHOPSANITY_OFF) ||
@ -1491,7 +1518,7 @@ void GenerateItemPool() {
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) {
ctx->PlaceItemInLocation(RC_KAK_100_GOLD_SKULLTULA_REWARD, RG_GANONS_CASTLE_BOSS_KEY);
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).GetContextOptionIndex() >= RO_GANON_BOSS_KEY_LACS_VANILLA && ctx->GetOption(RSK_GANONS_BOSS_KEY).IsNot(RO_GANON_BOSS_KEY_TRIFORCE_HUNT)) {
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Get() >= RO_GANON_BOSS_KEY_LACS_VANILLA && ctx->GetOption(RSK_GANONS_BOSS_KEY).IsNot(RO_GANON_BOSS_KEY_TRIFORCE_HUNT)) {
ctx->PlaceItemInLocation(RC_TOT_LIGHT_ARROWS_CUTSCENE, RG_GANONS_CASTLE_BOSS_KEY);
} else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_VANILLA)) {
ctx->PlaceItemInLocation(RC_GANONS_TOWER_BOSS_KEY_CHEST, RG_GANONS_CASTLE_BOSS_KEY);

View File

@ -44,12 +44,12 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
return false; // TODO: Not sure if this is correct but I don't think we support this functionality yet anyway.
}
ctx->GetSettings()->SetSeedString(seedInput);
uint32_t seedHash = boost::hash_32<std::string>{}(ctx->GetSettings()->GetSeedString());
ctx->GetSettings()->SetSeed(seedHash & 0xFFFFFFFF);
ctx->SetSeedString(seedInput);
uint32_t seedHash = boost::hash_32<std::string>{}(ctx->GetSeedString());
ctx->SetSeed(seedHash & 0xFFFFFFFF);
ctx->ClearItemLocations();
int ret = Playthrough::Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks);
int ret = Playthrough::Playthrough_Init(ctx->GetSeed(), excludedLocations, enabledTricks);
if (ret < 0) {
if (ret == -1) { // Failed to generate after 5 tries
SPDLOG_ERROR("Failed to generate after 5 tries.");
@ -60,14 +60,6 @@ bool GenerateRandomizer(std::set<RandomizerCheck> excludedLocations, std::set<Ra
}
}
// Restore settings that were set to a specific value for vanilla logic
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
for (Rando::Option* setting : ctx->GetSettings()->VanillaLogicDefaults) {
setting->RestoreDelayedOption();
}
ctx->GetOption(RSK_KEYSANITY).RestoreDelayedOption();
}
StopPerformanceTimer(PT_WHOLE_SEED);
SPDLOG_DEBUG("Full Seed Genration Time: {}ms", GetPerformanceTimer(PT_WHOLE_SEED).count());
SPDLOG_DEBUG("LogicReset time: {}ms", GetPerformanceTimer(PT_LOGIC_RESET).count());

View File

@ -31,10 +31,12 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
Regions::AccessReset();
StopPerformanceTimer(PT_REGION_RESET);
ctx->GetSettings()->FinalizeSettings(excludedLocations, enabledTricks);
ctx->FinalizeSettings(excludedLocations, enabledTricks);
// once the settings have been finalized turn them into a string for hashing
std::string settingsStr;
for (const Rando::OptionGroup& optionGroup : ctx->GetSettings()->GetOptionGroups()) {
auto& optionGroups = Rando::Settings::GetInstance()->GetOptionGroups();
for (size_t i = 0; i < RSG_MAX; i++) {
auto& optionGroup = optionGroups[i];
// don't go through non-menus
if (optionGroup.GetContainsType() == Rando::OptionGroupType::SUBGROUP) {
continue;
@ -43,7 +45,15 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
for (Rando::Option* option : optionGroup.GetOptions()) {
if (option->IsCategory(Rando::OptionCategory::Setting)) {
if (option->GetOptionCount() > 0) {
settingsStr += option->GetSelectedOptionText();
if (i >= RSG_EXCLUDES_KOKIRI_FOREST && i <= RSG_EXCLUDES_GANONS_CASTLE) {
auto locationOption = static_cast<Rando::LocationOption*>(option);
settingsStr += option->GetOptionText(ctx->GetLocationOption(locationOption->GetKey()).Get());
} else if (i == RSG_TRICKS) {
auto trickOption = static_cast<Rando::TrickOption*>(option);
settingsStr += option->GetOptionText(ctx->GetTrickOption(trickOption->GetKey()).Get());
} else {
settingsStr += option->GetOptionText(ctx->GetOption(option->GetKey()).Get());
}
}
}
}
@ -53,9 +63,9 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
settingsStr += (char*)gBuildVersion;
}
uint32_t finalHash = boost::hash_32<std::string>{}(std::to_string(ctx->GetSettings()->GetSeed()) + settingsStr);
uint32_t finalHash = boost::hash_32<std::string>{}(std::to_string(ctx->GetSeed()) + settingsStr);
Random_Init(finalHash);
ctx->GetSettings()->SetHash(std::to_string(finalHash));
ctx->SetHash(std::to_string(finalHash));
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
@ -94,12 +104,12 @@ int Playthrough_Repeat(std::set<RandomizerCheck> excludedLocations, std::set<Ran
auto ctx = Rando::Context::GetInstance();
uint32_t repeatedSeed = 0;
for (int i = 0; i < count; i++) {
ctx->GetSettings()->SetSeedString(std::to_string(rand() % 0xFFFFFFFF));
repeatedSeed = boost::hash_32<std::string>{}(ctx->GetSettings()->GetSeedString());
ctx->GetSettings()->SetSeed(repeatedSeed % 0xFFFFFFFF);
ctx->SetSeedString(std::to_string(rand() % 0xFFFFFFFF));
repeatedSeed = boost::hash_32<std::string>{}(ctx->GetSeedString());
ctx->SetSeed(repeatedSeed % 0xFFFFFFFF);
SPDLOG_DEBUG("testing seed: %d", repeatedSeed);
ClearProgress();
Playthrough_Init(ctx->GetSettings()->GetSeed(), excludedLocations, enabledTricks);
Playthrough_Init(ctx->GetSeed(), excludedLocations, enabledTricks);
SPDLOG_INFO("Seeds Generated: {}", i + 1);
}

View File

@ -156,7 +156,7 @@ int GetPriceFromMax(int max) {
uint16_t GetPriceFromSettings(Rando::Location *loc, PriceSettingsStruct priceSettings) {
auto ctx = Rando::Context::GetInstance();
switch (ctx->GetOption(priceSettings.main).GetContextOptionIndex()){
switch (ctx->GetOption(priceSettings.main).Get()){
case RO_PRICE_VANILLA:
return loc->GetVanillaPrice();
case RO_PRICE_CHEAP_BALANCED:
@ -172,19 +172,19 @@ uint16_t GetPriceFromSettings(Rando::Location *loc, PriceSettingsStruct priceSet
return 150;
}
case RO_PRICE_FIXED:
return (uint16_t)ctx->GetOption(priceSettings.fixedPrice).GetContextOptionIndex() * 5;
return (uint16_t)ctx->GetOption(priceSettings.fixedPrice).Get() * 5;
case RO_PRICE_RANGE:{
uint16_t range1 = (uint16_t)ctx->GetOption(priceSettings.range1).GetContextOptionIndex() * 5;
uint16_t range2 = (uint16_t)ctx->GetOption(priceSettings.range2).GetContextOptionIndex() * 5;
uint16_t range1 = (uint16_t)ctx->GetOption(priceSettings.range1).Get() * 5;
uint16_t range2 = (uint16_t)ctx->GetOption(priceSettings.range2).Get() * 5;
return range1 < range2 ? Random(range1, range2+1) : Random(range2, range1+1);
}
case RO_PRICE_SET_BY_WALLET:{
bool isTycoon = ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET).GetContextOptionIndex();
uint16_t noWeight = ctx->GetOption(priceSettings.noWallet).GetContextOptionIndex();
uint16_t childWeight = ctx->GetOption(priceSettings.childWallet).GetContextOptionIndex();
uint16_t adultWeight = ctx->GetOption(priceSettings.adultWallet).GetContextOptionIndex();
uint16_t giantWeight = ctx->GetOption(priceSettings.giantWallet).GetContextOptionIndex();
uint16_t tycoonWeight = isTycoon ? ctx->GetOption(priceSettings.tycoonWallet).GetContextOptionIndex() : 0;
bool isTycoon = ctx->GetOption(RSK_INCLUDE_TYCOON_WALLET).Get();
uint16_t noWeight = ctx->GetOption(priceSettings.noWallet).Get();
uint16_t childWeight = ctx->GetOption(priceSettings.childWallet).Get();
uint16_t adultWeight = ctx->GetOption(priceSettings.adultWallet).Get();
uint16_t giantWeight = ctx->GetOption(priceSettings.giantWallet).Get();
uint16_t tycoonWeight = isTycoon ? ctx->GetOption(priceSettings.tycoonWallet).Get() : 0;
uint16_t totalWeight = noWeight + childWeight + adultWeight + giantWeight + tycoonWeight;
if (totalWeight == 0){ //if no weight, return from sane range
return Random(0, 501);

View File

@ -2,13 +2,14 @@
#include "../dungeon.h"
#include "../static_data.h"
#include "../context.h"
#include "../settings.h"
#include "../entrance.h"
#include "random.hpp"
#include "../trial.h"
#include "hints.hpp"
#include "pool_functions.hpp"
#include "soh/Enhancements/randomizer/randomizer_check_objects.h"
#include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h"
#include <nlohmann/json.hpp>
#include <cstdio>
@ -45,7 +46,7 @@ std::string placementtxt;
void GenerateHash() {
auto ctx = Rando::Context::GetInstance();
std::string hash = ctx->GetSettings()->GetHash();
std::string hash = ctx->GetHash();
// adds leading 0s to the hash string if it has less than 10 digits.
while (hash.length() < 10) {
hash = "0" + hash;
@ -91,8 +92,8 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance)
int16_t destinationIndex = -1;
int16_t replacementIndex = entrance->GetReplacement()->GetIndex();
int16_t replacementDestinationIndex = -1;
std::string name = entrance->GetName();
std::string text = entrance->GetConnectedRegion()->regionName + " from " + entrance->GetReplacement()->GetParentRegion()->regionName;
std::string name = GetEntranceData(originalIndex)->source;
std::string text = GetEntranceData(replacementIndex)->destination;
// Track the reverse destination, useful for savewarp handling
if (entrance->GetReverse() != nullptr) {
@ -138,10 +139,10 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance)
// Writes the settings (without excluded locations, starting inventory and tricks) to the spoilerLog document.
static void WriteSettings() {
auto ctx = Rando::Context::GetInstance();
std::array<Rando::Option, RSK_MAX> options = ctx->GetSettings()->GetAllOptions();
std::array<Rando::Option, RSK_MAX> options = Rando::Settings::GetInstance()->GetAllOptions();
for (const Rando::Option& option : options) {
if (option.GetName() != ""){
jsonData["settings"][option.GetName()] = option.GetSelectedOptionText();
jsonData["settings"][option.GetName()] = option.GetOptionText(ctx->GetOption(option.GetKey()).Get());
}
}
}
@ -156,9 +157,9 @@ std::string RemoveLineBreaks(std::string s) {
static void WriteExcludedLocations() {
auto ctx = Rando::Context::GetInstance();
for (size_t i = 1; i < ctx->GetSettings()->GetExcludeLocationsOptions().size(); i++) {
for (const auto& location : ctx->GetSettings()->GetExcludeLocationsOptions()[i]) {
if (location->GetContextOptionIndex() == RO_LOCATION_INCLUDE) {
for (size_t i = 1; i < Rando::Settings::GetInstance()->GetExcludeLocationsOptions().size(); i++) {
for (const auto& location : Rando::Settings::GetInstance()->GetExcludeLocationsOptions()[i]) {
if (ctx->GetOption(location->GetKey()).Get() == RO_LOCATION_INCLUDE) {
continue;
}
@ -171,11 +172,11 @@ static void WriteExcludedLocations() {
// Writes the starting inventory to the spoiler log, if there is any.
static void WriteStartingInventory() {
auto ctx = Rando::Context::GetInstance();
const Rando::OptionGroup& optionGroup = ctx->GetSettings()->GetOptionGroup(RSG_STARTING_INVENTORY);
const Rando::OptionGroup& optionGroup = Rando::Settings::GetInstance()->GetOptionGroup(RSG_STARTING_INVENTORY);
for (const Rando::OptionGroup* subGroup : optionGroup.GetSubGroups()) {
if (subGroup->GetContainsType() == Rando::OptionGroupType::DEFAULT) {
for (Rando::Option* option : subGroup->GetOptions()) {
jsonData["settings"][option->GetName()] = option->GetSelectedOptionText();
jsonData["settings"][option->GetName()] = option->GetOptionText(ctx->GetOption(option->GetKey()).Get());
}
}
}
@ -185,8 +186,8 @@ static void WriteStartingInventory() {
static void WriteEnabledTricks() {
auto ctx = Rando::Context::GetInstance();
for (const auto& setting : ctx->GetSettings()->GetOptionGroup(RSG_TRICKS).GetOptions()) {
if (setting->GetContextOptionIndex() != RO_GENERIC_ON) {
for (const auto& setting : Rando::Settings::GetInstance()->GetOptionGroup(RSG_TRICKS).GetOptions()) {
if (ctx->GetOption(setting->GetKey()).IsNot(RO_GENERIC_ON)) {
continue;
}
jsonData["enabledTricks"].push_back(RemoveLineBreaks(setting->GetName()).c_str());
@ -321,8 +322,8 @@ const char* SpoilerLog_Write() {
jsonData["version"] = (char*) gBuildVersion;
jsonData["git_branch"] = (char*) gGitBranch;
jsonData["git_commit"] = (char*) gGitCommitHash;
jsonData["seed"] = ctx->GetSettings()->GetSeedString();
jsonData["finalSeed"] = ctx->GetSettings()->GetSeed();
jsonData["seed"] = ctx->GetSeedString();
jsonData["finalSeed"] = ctx->GetSeed();
// Write Hash
int index = 0;

View File

@ -112,7 +112,7 @@ void GenerateStartingInventory() {
// AddItemToInventory(RG_EMPTY_BOTTLE, 1);
// }
// AddItemToInventory(RG_RUTOS_LETTER, StartingRutoBottle.Value<uint8_t>());
AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).GetContextOptionIndex());
AddItemToInventory(RG_PROGRESSIVE_OCARINA, ctx->GetOption(RSK_STARTING_OCARINA).Get());
AddItemToInventory(RG_ZELDAS_LULLABY, ctx->GetOption(RSK_STARTING_ZELDAS_LULLABY) ? 1 : 0);
AddItemToInventory(RG_EPONAS_SONG, ctx->GetOption(RSK_STARTING_EPONAS_SONG) ? 1 : 0);
AddItemToInventory(RG_SARIAS_SONG, ctx->GetOption(RSK_STARTING_SARIAS_SONG) ? 1 : 0);
@ -153,21 +153,21 @@ void GenerateStartingInventory() {
// AddItemToInventory(RG_SPIRIT_MEDALLION, StartingSpiritMedallion.Value<uint8_t>());
// AddItemToInventory(RG_SHADOW_MEDALLION, StartingShadowMedallion.Value<uint8_t>());
// AddItemToInventory(RG_LIGHT_MEDALLION, StartingLightMedallion.Value<uint8_t>());
AddItemToInventory(RG_GOLD_SKULLTULA_TOKEN, ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).GetContextOptionIndex());
AddItemToInventory(RG_GOLD_SKULLTULA_TOKEN, ctx->GetOption(RSK_STARTING_SKULLTULA_TOKEN).Get());
int8_t hearts = ctx->GetOption(RSK_STARTING_HEARTS).GetContextOptionIndex() - 2;
int8_t hearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() - 2;
AdditionalHeartContainers = 0;
if (hearts < 0) {
AddItemToInventory(RG_PIECE_OF_HEART, 4);
// Plentiful and minimal have less than 4 standard pieces of heart so also replace the winner heart
if (ctx->GetOption(RSK_ITEM_POOL).GetContextOptionIndex() == 0 || ctx->GetOption(RSK_ITEM_POOL).GetContextOptionIndex() == 3) {
if (ctx->GetOption(RSK_ITEM_POOL).Get() == 0 || ctx->GetOption(RSK_ITEM_POOL).Get() == 3) {
AddItemToInventory(RG_TREASURE_GAME_HEART);
}
AdditionalHeartContainers = 1 - hearts;
} else if (hearts > 0) {
// 16 containers in plentiful, 8 in balanced and 0 in the others
uint8_t maxContainers = 8 * std::max(0, 2 - ctx->GetOption(RSK_ITEM_POOL).GetContextOptionIndex());
uint8_t maxContainers = 8 * std::max(0, 2 - ctx->GetOption(RSK_ITEM_POOL).Get());
if (hearts <= maxContainers) {
AddItemToInventory(RG_HEART_CONTAINER, hearts);

View File

@ -0,0 +1,154 @@
#include <libultraship/libultraship.h>
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include "soh/ShipInit.hpp"
extern "C" {
extern PlayState* gPlayState;
#include "macros.h"
#include "src/overlays/actors/ovl_En_Door/z_en_door.h"
}
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
using SceneDoorParamsPair = std::pair<int, int>;
std::map<SceneDoorParamsPair, RandomizerInf> lookupTable = {
{{ SCENE_MARKET_ENTRANCE_DAY, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED },
{{ SCENE_MARKET_ENTRANCE_NIGHT, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED },
{{ SCENE_MARKET_ENTRANCE_RUINS, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED },
{{ SCENE_MARKET_GUARD_HOUSE, 447 }, RAND_INF_GUARD_HOUSE_UNLOCKED },
{{ SCENE_MARKET_DAY, 4543 }, RAND_INF_MARKET_BAZAAR_UNLOCKED },
{{ SCENE_MARKET_NIGHT, 4753 }, RAND_INF_MARKET_BAZAAR_UNLOCKED },
{{ SCENE_MARKET_DAY, 1471 }, RAND_INF_MARKET_POTION_SHOP_UNLOCKED },
{{ SCENE_MARKET_NIGHT, 1678 }, RAND_INF_MARKET_POTION_SHOP_UNLOCKED },
{{ SCENE_MARKET_DAY, 3519 }, RAND_INF_MASK_SHOP_UNLOCKED },
{{ SCENE_MARKET_NIGHT, 3728 }, RAND_INF_MASK_SHOP_UNLOCKED },
{{ SCENE_MARKET_DAY, 2495 }, RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED },
{{ SCENE_MARKET_NIGHT, 2703 }, RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED },
{{ SCENE_SHOOTING_GALLERY, 447 }, RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED },
{{ SCENE_MARKET_DAY, 5567 }, RAND_INF_BOMBCHU_BOWLING_UNLOCKED },
{{ SCENE_MARKET_NIGHT, 5567 }, RAND_INF_BOMBCHU_BOWLING_UNLOCKED },
{{ SCENE_BOMBCHU_BOWLING_ALLEY, 447 }, RAND_INF_BOMBCHU_BOWLING_UNLOCKED },
{{ SCENE_MARKET_DAY, 653 }, RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED },
{{ SCENE_MARKET_NIGHT, 447 }, RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED },
{{ SCENE_TREASURE_BOX_SHOP, 6591 }, RAND_INF_TREASURE_CHEST_GAME_BUILDING_UNLOCKED },
{{ SCENE_BACK_ALLEY_DAY, 2689 }, RAND_INF_BOMBCHU_SHOP_UNLOCKED },
{{ SCENE_BACK_ALLEY_NIGHT, 2495 }, RAND_INF_BOMBCHU_SHOP_UNLOCKED },
{{ SCENE_BACK_ALLEY_DAY, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED },
{{ SCENE_BACK_ALLEY_NIGHT, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED },
{{ SCENE_DOG_LADY_HOUSE, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED },
{{ SCENE_DOG_LADY_HOUSE, 447 }, RAND_INF_RICHARDS_HOUSE_UNLOCKED },
{{ SCENE_BACK_ALLEY_HOUSE, 447 }, RAND_INF_ALLEY_HOUSE_UNLOCKED },
{{ SCENE_BACK_ALLEY_DAY, 1665 }, RAND_INF_ALLEY_HOUSE_UNLOCKED },
{{ SCENE_BACK_ALLEY_NIGHT, 1471 }, RAND_INF_ALLEY_HOUSE_UNLOCKED },
{{ SCENE_KAKARIKO_VILLAGE, 6801 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Adult Night
{{ SCENE_KAKARIKO_VILLAGE, 6591 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Adult Day
{{ SCENE_KAKARIKO_VILLAGE, 6813 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Child Day
{{ SCENE_KAKARIKO_VILLAGE, 6814 }, RAND_INF_KAK_BAZAAR_UNLOCKED }, // Child Night
{{ SCENE_KAKARIKO_VILLAGE, 8871 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Child Day/Night Rear
{{ SCENE_KAKARIKO_VILLAGE, 8846 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Adult Night Rear
{{ SCENE_KAKARIKO_VILLAGE, 8639 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Adult Day Rear
{{ SCENE_KAKARIKO_VILLAGE, 7822 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Adult Night
{{ SCENE_KAKARIKO_VILLAGE, 7615 }, RAND_INF_KAK_POTION_SHOP_UNLOCKED }, // Child Day/Night and Adult Day
{{ SCENE_KAKARIKO_VILLAGE, 2495 }, RAND_INF_BOSS_HOUSE_UNLOCKED },
{{ SCENE_KAKARIKO_CENTER_GUEST_HOUSE, 447 }, RAND_INF_BOSS_HOUSE_UNLOCKED },
{{ SCENE_KAKARIKO_VILLAGE, 3750 }, RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED }, // Child
{{ SCENE_KAKARIKO_VILLAGE, 3519 }, RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED }, // Adult
{{ SCENE_POTION_SHOP_GRANNY, 447 }, RAND_INF_GRANNYS_POTION_SHOP_UNLOCKED },
{{ SCENE_KAKARIKO_VILLAGE, 5567 }, RAND_INF_SKULLTULA_HOUSE_UNLOCKED },
{{ SCENE_HOUSE_OF_SKULLTULA, 447 }, RAND_INF_SKULLTULA_HOUSE_UNLOCKED },
{{ SCENE_KAKARIKO_VILLAGE, 1471 }, RAND_INF_IMPAS_HOUSE_UNLOCKED },
{{ SCENE_IMPAS_HOUSE, 447 }, RAND_INF_IMPAS_HOUSE_UNLOCKED },
{{ SCENE_KAKARIKO_VILLAGE, 447 }, RAND_INF_WINDMILL_UNLOCKED },
{{ SCENE_WINDMILL_AND_DAMPES_GRAVE, 2495 }, RAND_INF_WINDMILL_UNLOCKED },
{{ SCENE_KAKARIKO_VILLAGE, 4543 }, RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED }, // Day
{{ SCENE_KAKARIKO_VILLAGE, 4751 }, RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED }, // Night
{{ SCENE_SHOOTING_GALLERY, 447 }, RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED },
{{ SCENE_GRAVEYARD, 645 }, RAND_INF_DAMPES_HUT_UNLOCKED }, // Child Day
{{ SCENE_GRAVEYARD, 447 }, RAND_INF_DAMPES_HUT_UNLOCKED }, // Child Evening & Adult
{{ SCENE_GRAVEYARD, 774 }, RAND_INF_DAMPES_HUT_UNLOCKED }, // Child Night (After Dampes Tour)
{{ SCENE_GRAVEKEEPERS_HUT, 447 }, RAND_INF_DAMPES_HUT_UNLOCKED },
{{ SCENE_LON_LON_RANCH, 2495 }, RAND_INF_TALONS_HOUSE_UNLOCKED },
{{ SCENE_LON_LON_RANCH, 2473 }, RAND_INF_TALONS_HOUSE_UNLOCKED },
{{ SCENE_LON_LON_RANCH, 2729 }, RAND_INF_TALONS_HOUSE_UNLOCKED },
{{ SCENE_LON_LON_BUILDINGS, 1471 }, RAND_INF_TALONS_HOUSE_UNLOCKED },
{{ SCENE_LON_LON_RANCH, 1471 }, RAND_INF_STABLES_UNLOCKED },
{{ SCENE_STABLE, 447 }, RAND_INF_STABLES_UNLOCKED },
{{ SCENE_LON_LON_RANCH, 447 }, RAND_INF_BACK_TOWER_UNLOCKED },
{{ SCENE_LON_LON_BUILDINGS, 447 }, RAND_INF_BACK_TOWER_UNLOCKED },
{{ SCENE_LAKE_HYLIA, 447 }, RAND_INF_HYLIA_LAB_UNLOCKED },
{{ SCENE_LAKESIDE_LABORATORY, 447 }, RAND_INF_HYLIA_LAB_UNLOCKED },
{{ SCENE_LAKE_HYLIA, 1471 }, RAND_INF_FISHING_HOLE_UNLOCKED },
{{ SCENE_FISHING_POND, 447 }, RAND_INF_FISHING_HOLE_UNLOCKED },
};
static void OnDoorInit(void* actorRef) {
EnDoor* enDoor = static_cast<EnDoor*>(actorRef);
enDoor->randomizerInf = RAND_INF_MAX;
auto it = lookupTable.find({gPlayState->sceneNum, enDoor->actor.params});
if (it != lookupTable.end()) {
if (it->second == RAND_INF_MARKET_SHOOTING_GALLERY_UNLOCKED && gSaveContext.entranceIndex == 0x3B) {
// Adult shooting gallery uses same scene and door params as child, so we manually handle it
enDoor->randomizerInf = RAND_INF_KAK_SHOOTING_GALLERY_UNLOCKED;
} else {
enDoor->randomizerInf = it->second;
}
if (!Flags_GetRandomizerInf(enDoor->randomizerInf)) {
// We don't want to override checkable doors, we still want those to not be openable even if they have a key
if (((enDoor->actor.params >> 7) & 7) != DOOR_CHECKABLE) {
enDoor->actor.params = (enDoor->actor.params & ~0x380) | (DOOR_LOCKED << 7);
enDoor->actionFunc = EnDoor_SetupType;
} else {
enDoor->lockTimer = 10;
}
}
}
}
void RegisterLockOverworldDoors() {
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_LOCK_OVERWORLD_DOORS);
COND_ID_HOOK(OnActorInit, ACTOR_EN_DOOR, shouldRegister, OnDoorInit);
COND_VB_SHOULD(VB_CONSUME_SMALL_KEY, shouldRegister, {
EnDoor* enDoor = va_arg(args, EnDoor*);
if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) {
Flags_SetRandomizerInf(enDoor->randomizerInf);
*should = false;
}
});
COND_VB_SHOULD(VB_NOT_HAVE_SMALL_KEY, shouldRegister, {
EnDoor* enDoor = va_arg(args, EnDoor*);
if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) {
*should = !Flags_GetRandomizerInf((RandomizerInf)(enDoor->randomizerInf + 1));
}
});
COND_VB_SHOULD(VB_DOOR_BE_LOCKED, shouldRegister, {
EnDoor* enDoor = va_arg(args, EnDoor*);
if (enDoor->randomizerInf >= RAND_INF_GUARD_HOUSE_UNLOCKED && enDoor->randomizerInf <= RAND_INF_FISHING_HOLE_KEY_OBTAINED) {
*should = !Flags_GetRandomizerInf(enDoor->randomizerInf);
}
});
// The door actor uses the same param to indicate if a door should be locked or be a scene transition, so it cannot be both. Here we're
// overriding the check for scene transition to also check if the door is being unlocked and should be a scene transition.
COND_VB_SHOULD(VB_DOOR_PLAY_SCENE_TRANSITION, shouldRegister, {
EnDoor* enDoor = va_arg(args, EnDoor*);
if (!*should && (
enDoor->actor.id == ACTOR_EN_DOOR &&
((enDoor->actor.params >> 7) & 7) == 1 &&
enDoor->randomizerInf != RAND_INF_MAX
)) {
*should = true;
}
});
}
static RegisterShipInitFunc initFunc(RegisterLockOverworldDoors, { "IS_RANDO" });

View File

@ -77,7 +77,7 @@ std::unordered_map<RandomizerGet, std::string> ocarinaButtonNames = {
{ RG_OCARINA_C_RIGHT_BUTTON, "C-RHT" },
};
std::map<RandomizerGet, ImVec4> bossSoulMapping = {
std::map<RandomizerGet, ImVec4> bossSoulColorMapping = {
{ RG_GOHMA_SOUL, { 0.00f, 1.00f, 0.00f, 1.0f } },
{ RG_KING_DODONGO_SOUL, { 1.00f, 0.00f, 0.39f, 1.0f } },
{ RG_BARINADE_SOUL, { 0.20f, 1.00f, 1.00f, 1.0f } },
@ -339,7 +339,7 @@ ImVec4 plandomizerGetItemColor(Rando::Item randoItem) {
}
if (randoItem.GetRandomizerGet() >= RG_GOHMA_SOUL && randoItem.GetRandomizerGet() <= RG_GANON_SOUL) {
itemColor = bossSoulMapping.at(randoItem.GetRandomizerGet());
itemColor = bossSoulColorMapping.at(randoItem.GetRandomizerGet());
}
return itemColor;

View File

@ -23,7 +23,7 @@ void ShuffleFreestanding_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* sh
Rando::Location* loc = OTRGlobals::Instance->gRandomizer->GetCheckObjectFromActor(item00->actor.id, gPlayState->sceneNum, params);
uint8_t isDungeon = loc->IsDungeon();
uint8_t freestandingSetting =
Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FREESTANDING).GetContextOptionIndex();
Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_FREESTANDING).Get();
RandomizerCheck randomizerCheck = loc->GetRandomizerCheck();
bool checkObtained = Rando::Context::GetInstance()->GetItemLocation(randomizerCheck)->HasObtained();

View File

@ -28,7 +28,7 @@ extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) {
uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) {
RandomizerCheck rc = potActor->potIdentity.randomizerCheck;
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
uint8_t potSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).GetContextOptionIndex();
uint8_t potSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).Get();
// Don't pull randomized item if pot isn't randomized or is already checked
if (!IS_RANDO || (potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) ||
@ -87,7 +87,7 @@ void ShufflePots_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va
// Unlock early Ganon's Boss Key doors to allow access to the pots there when pots are shuffled in dungeon
if (id == VB_LOCK_BOSS_DOOR) {
DoorShutter* doorActor = va_arg(args, DoorShutter*);
uint8_t shufflePotSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).GetContextOptionIndex();
uint8_t shufflePotSetting = Rando::Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).Get();
if (gPlayState->sceneNum == SCENE_GANONS_TOWER && doorActor->dyna.actor.world.pos.y == 800 &&
(shufflePotSetting == RO_SHUFFLE_POTS_DUNGEONS || shufflePotSetting == RO_SHUFFLE_POTS_ALL)) {
*should = false;

View File

@ -28,8 +28,31 @@ Context::Context() {
mDungeons = std::make_shared<Dungeons>();
mLogic = std::make_shared<Logic>();
mTrials = std::make_shared<Trials>();
mSettings = std::make_shared<Settings>();
mFishsanity = std::make_shared<Fishsanity>();
VanillaLogicDefaults = {
// RANDOTODO check what this does
&mOptions[RSK_LINKS_POCKET],
&mOptions[RSK_SHUFFLE_DUNGEON_REWARDS],
&mOptions[RSK_SHUFFLE_SONGS],
&mOptions[RSK_SHOPSANITY],
&mOptions[RSK_SHOPSANITY_COUNT],
&mOptions[RSK_SHOPSANITY_PRICES],
&mOptions[RSK_SHOPSANITY_PRICES_AFFORDABLE],
&mOptions[RSK_FISHSANITY],
&mOptions[RSK_FISHSANITY_POND_COUNT],
&mOptions[RSK_FISHSANITY_AGE_SPLIT],
&mOptions[RSK_SHUFFLE_SCRUBS],
&mOptions[RSK_SHUFFLE_BEEHIVES],
&mOptions[RSK_SHUFFLE_COWS],
&mOptions[RSK_SHUFFLE_POTS],
&mOptions[RSK_SHUFFLE_FREESTANDING],
&mOptions[RSK_SHUFFLE_MERCHANTS],
&mOptions[RSK_SHUFFLE_FROG_SONG_RUPEES],
&mOptions[RSK_SHUFFLE_ADULT_TRADE],
&mOptions[RSK_SHUFFLE_100_GS_REWARD],
&mOptions[RSK_SHUFFLE_FAIRIES],
&mOptions[RSK_GOSSIP_STONE_HINTS],
};
}
RandomizerArea Context::GetAreaFromString(std::string str) {
@ -94,7 +117,7 @@ void Context::PlaceItemInLocation(const RandomizerCheck locKey, const Randomizer
const auto loc = GetItemLocation(locKey);
SPDLOG_DEBUG(StaticData::RetrieveItem(item).GetName().GetEnglish() + " placed at " + StaticData::GetLocation(locKey)->GetName() + "\n");
if (applyEffectImmediately || mSettings->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS) || mSettings->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
if (applyEffectImmediately || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_GLITCHLESS) || mOptions[RSK_LOGIC_RULES].Is(RO_LOGIC_VANILLA)) {
StaticData::RetrieveItem(item).ApplyEffect();
}
@ -130,17 +153,17 @@ bool Context::IsQuestOfLocationActive(RandomizerCheck rc) {
void Context::GenerateLocationPool() {
allLocations.clear();
if (mSettings->GetOption(RSK_TRIFORCE_HUNT)) {
if (mOptions[RSK_TRIFORCE_HUNT]) {
AddLocation(RC_TRIFORCE_COMPLETED);
}
AddLocations(StaticData::GetOverworldLocations());
if (mSettings->GetOption(RSK_FISHSANITY).IsNot(RO_FISHSANITY_OFF)) {
if (mOptions[RSK_FISHSANITY].IsNot(RO_FISHSANITY_OFF)) {
AddLocations(mFishsanity->GetFishsanityLocations().first);
}
if (mSettings->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_OVERWORLD) ||
mSettings->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL)) {
if (mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_OVERWORLD) ||
mOptions[RSK_SHUFFLE_POTS].Is(RO_SHUFFLE_POTS_ALL)) {
AddLocations(StaticData::GetOverworldPotLocations());
}
@ -153,7 +176,17 @@ void Context::AddExcludedOptions() {
AddLocations(dungeon->GetEveryLocation(), &everyPossibleLocation);
}
for (const RandomizerCheck rc : everyPossibleLocation) {
GetItemLocation(rc)->AddExcludeOption();
bool alreadyAdded = false;
Location* loc = StaticData::GetLocation(rc);
for (Option* location : Rando::Settings::GetInstance()->GetExcludeOptionsForArea(loc->GetArea()))
{
if (location->GetName() == loc->GetExcludedOption()->GetName()) {
alreadyAdded = true;
}
}
if (!alreadyAdded) {
Rando::Settings::GetInstance()->GetExcludeOptionsForArea(loc->GetArea()).push_back(loc->GetExcludedOption());
}
}
}
@ -289,7 +322,7 @@ void Context::ParseSpoiler(const char* spoilerFileName) {
nlohmann::json spoilerFileJson;
spoilerFileStream >> spoilerFileJson;
ParseHashIconIndexesJson(spoilerFileJson);
mSettings->ParseJson(spoilerFileJson);
Rando::Settings::GetInstance()->ParseJson(spoilerFileJson);
ParseItemLocationsJson(spoilerFileJson);
ParseHintJson(spoilerFileJson);
mEntranceShuffler->ParseJson(spoilerFileJson);
@ -362,10 +395,6 @@ void Context::ParseHintJson(nlohmann::json spoilerFileJson) {
CreateStaticHints();
}
std::shared_ptr<Settings> Context::GetSettings() {
return mSettings;
}
std::shared_ptr<EntranceShuffler> Context::GetEntranceShuffler() {
return mEntranceShuffler;
}
@ -405,12 +434,28 @@ Sprite* Context::GetSeedTexture(const uint8_t index) {
return &gSeedTextures[index];
}
Option& Context::GetOption(const RandomizerSettingKey key) const {
return mSettings->GetOption(key);
OptionValue& Context::GetOption(const RandomizerSettingKey key) {
return mOptions[key];
}
TrickOption& Context::GetTrickOption(const RandomizerTrick key) const {
return mSettings->GetTrickOption(key);
OptionValue& Context::GetOption(const RandomizerTrick key) {
return mTrickOptions[key];
}
OptionValue& Context::GetOption(const RandomizerCheck key) {
return itemLocationTable[key].GetExcludedOption();
}
OptionValue& Context::GetTrickOption(const RandomizerTrick key) {
return mTrickOptions[key];
}
OptionValue& Context::GetLocationOption(const RandomizerCheck key) {
return itemLocationTable[key].GetExcludedOption();
}
RandoOptionLACSCondition Context::LACSCondition() const {
return mLACSCondition;
}
std::shared_ptr<Kaleido> Context::GetKaleido() {
@ -419,4 +464,28 @@ std::shared_ptr<Kaleido> Context::GetKaleido() {
}
return mKaleido;
}
std::string Context::GetHash() const {
return mHash;
}
void Context::SetHash(std::string hash) {
mHash = std::move(hash);
}
const std::string& Context::GetSeedString() const {
return mSeedString;
}
void Context::SetSeedString(std::string seedString) {
mSeedString = std::move(seedString);
}
uint32_t Context::GetSeed() const {
return mFinalSeed;
}
void Context::SetSeed(const uint32_t seed) {
mFinalSeed = seed;
}
} // namespace Rando

View File

@ -25,7 +25,6 @@
namespace Rando {
class EntranceShuffler;
class Logic;
class Settings;
class Dungeons;
class DungeonInfo;
class TrialInfo;
@ -63,7 +62,24 @@ class Context {
void SetSeedGenerated(bool seedGenerated = true);
bool IsSpoilerLoaded() const;
void SetSpoilerLoaded(bool spoilerLoaded = true);
std::shared_ptr<Settings> GetSettings();
/**
* @brief Reset all RandomizerTrick keys.
*/
void ResetTrickOptions();
/**
* @brief Runs before seed generation to ensure all options are compatible with each
* other and resolve options that have been set to random (such as random trial count,
* or starting age).
*
* @param excludedLocations Set of locations that should be forced to have junk items.
* @param enabledTricks Set of tricks that should be considered logically possible. Tricks
* are things that are possible to do in gameplay but are difficult, not intuitive or that
* require more extensive game knowledge, i.e. opening invisible chests without the Lens of Truth.
*/
void FinalizeSettings(const std::set<RandomizerCheck>& excludedLocations,
const std::set<RandomizerTrick>& enabledTricks);
std::shared_ptr<EntranceShuffler> GetEntranceShuffler();
std::shared_ptr<Dungeons> GetDungeons();
std::shared_ptr<Fishsanity> GetFishsanity();
@ -74,8 +90,19 @@ class Context {
TrialInfo* GetTrial(size_t key) const;
TrialInfo* GetTrial(TrialKey key) const;
static Sprite* GetSeedTexture(uint8_t index);
Option& GetOption(RandomizerSettingKey key) const;
TrickOption& GetTrickOption(RandomizerTrick key) const;
OptionValue& GetOption(RandomizerSettingKey key);
OptionValue& GetOption(RandomizerTrick key);
OptionValue& GetOption(RandomizerCheck key);
OptionValue& GetTrickOption(RandomizerTrick key);
OptionValue& GetLocationOption(RandomizerCheck key);
/**
* @brief Gets the resolved Light Arrow CutScene check condition.
* There is no direct option for this, it is inferred based on the value of a few other options.
*
* @return RandoOptionLACSCondition
*/
RandoOptionLACSCondition LACSCondition() const;
GetItemEntry GetFinalGIEntry(RandomizerCheck rc, bool checkObtainability = true, GetItemID ogItemId = GI_NONE);
void ParseSpoiler(const char* spoilerFileName);
void ParseHashIconIndexesJson(nlohmann::json spoilerFileJson);
@ -87,16 +114,61 @@ class Context {
std::vector<RandomizerCheck> everyPossibleLocation = {};
std::vector<RandomizerGet> possibleIceTrapModels = {};
std::unordered_map<RandomizerCheck, RandomizerGet> iceTrapModels = {};
std::vector<OptionValue*> VanillaLogicDefaults = {};
std::array<uint8_t, 5> hashIconIndexes = {};
bool playthroughBeatable = false;
bool allLocationsReachable = false;
RandomizerArea GetAreaFromString(std::string str);
/**
* @brief Get the hash for the current seed.
*
* @return std::string
*/
std::string GetHash() const;
/**
* @brief Get the Seed String
*
* @return const std::string&
*/
const std::string& GetSeedString() const;
/**
* @brief Set the Seed String
*
* @param seedString
*/
void SetSeedString(std::string seedString);
/**
* @brief Get the Seed
*
* @return const uint32_t
*/
uint32_t GetSeed() const;
/**
* @brief Set the Seed
*
* @param seed
*/
void SetSeed(uint32_t seed);
/**
* @brief Set the Seed Hash for the current seed.
*
* @param hash
*/
void SetHash(std::string hash);
private:
static std::weak_ptr<Context> mContext;
std::array<Hint, RH_MAX> hintTable = {};
std::array<ItemLocation, RC_MAX> itemLocationTable = {};
std::shared_ptr<Settings> mSettings;
std::array<OptionValue, RSK_MAX> mOptions;
std::array<OptionValue, RT_MAX> mTrickOptions;
RandoOptionLACSCondition mLACSCondition = RO_LACS_VANILLA;
std::shared_ptr<EntranceShuffler> mEntranceShuffler;
std::shared_ptr<Dungeons> mDungeons;
std::shared_ptr<Logic> mLogic;
@ -105,5 +177,8 @@ class Context {
std::shared_ptr<Kaleido> mKaleido;
bool mSeedGenerated = false;
bool mSpoilerLoaded = false;
std::string mHash;
std::string mSeedString;
uint32_t mFinalSeed = 0;
};
} // namespace Rando

View File

@ -38,32 +38,45 @@ extern PlayState* gPlayState;
extern SaveContext gSaveContext;
}
const char* SmallBaseCvarValue[10] = {
CVAR_COSMETIC("Key.ForestSmallBase.Value"),
CVAR_COSMETIC("Key.FireSmallBase.Value"),
CVAR_COSMETIC("Key.WaterSmallBase.Value"),
CVAR_COSMETIC("Key.SpiritSmallBase.Value"),
CVAR_COSMETIC("Key.ShadowSmallBase.Value"),
CVAR_COSMETIC("Key.WellSmallBase.Value"),
CVAR_COSMETIC("Key.GTGSmallBase.Value"),
CVAR_COSMETIC("Key.FortSmallBase.Value"),
CVAR_COSMETIC("Key.GanonsSmallBase.Value"),
CVAR_COSMETIC("Key.ChestGameSmallBase.Value"),
const char* SmallBodyCvarValue[10] = {
CVAR_COSMETIC("Key.ForestSmallBody.Value"),
CVAR_COSMETIC("Key.FireSmallBody.Value"),
CVAR_COSMETIC("Key.WaterSmallBody.Value"),
CVAR_COSMETIC("Key.SpiritSmallBody.Value"),
CVAR_COSMETIC("Key.ShadowSmallBody.Value"),
CVAR_COSMETIC("Key.WellSmallBody.Value"),
CVAR_COSMETIC("Key.GTGSmallBody.Value"),
CVAR_COSMETIC("Key.FortSmallBody.Value"),
CVAR_COSMETIC("Key.GanonsSmallBody.Value"),
CVAR_COSMETIC("Key.ChestGameSmallBody.Value"),
};
const char* SmallEmblemCvarValue[10] = {
CVAR_COSMETIC("Key.ForestEmblem.Value"),
CVAR_COSMETIC("Key.FireEmblem.Value"),
CVAR_COSMETIC("Key.WaterEmblem.Value"),
CVAR_COSMETIC("Key.SpiritEmblem.Value"),
CVAR_COSMETIC("Key.ShadowEmblem.Value"),
CVAR_COSMETIC("Key.WellEmblem.Value"),
CVAR_COSMETIC("Key.GTGEmblem.Value"),
CVAR_COSMETIC("Key.FortEmblem.Value"),
CVAR_COSMETIC("Key.GanonsEmblem.Value"),
CVAR_COSMETIC("Key.ForestSmallEmblem.Value"),
CVAR_COSMETIC("Key.FireSmallEmblem.Value"),
CVAR_COSMETIC("Key.WaterSmallEmblem.Value"),
CVAR_COSMETIC("Key.SpiritSmallEmblem.Value"),
CVAR_COSMETIC("Key.ShadowSmallEmblem.Value"),
CVAR_COSMETIC("Key.WellSmallEmblem.Value"),
CVAR_COSMETIC("Key.GTGSmallEmblem.Value"),
CVAR_COSMETIC("Key.FortSmallEmblem.Value"),
CVAR_COSMETIC("Key.GanonsSmallEmblem.Value"),
CVAR_COSMETIC("Key.ChestGameEmblem.Value"),
};
Color_RGB8 SmallEmblemDefaultValue[10] = {
{ 4, 195, 46 }, // Forest
{ 237, 95, 95 }, // Fire
{ 85, 180, 223 }, // Water
{ 222, 158, 47 }, // Spirit
{ 126, 16, 177 }, // Shadow
{ 227, 110, 255 }, // Well
{ 221, 212, 60 }, // GTG
{ 255, 255, 255 }, // Fortress
{ 80, 80, 80 }, // Ganons
{ 255, 255, 255 }, // Chest Game
};
extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry) {
@ -91,7 +104,7 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn
G_MTX_MODELVIEW | G_MTX_LOAD);
Color_RGB8 keyColor = { 255, 255, 255 };
keyColor = CVarGetColor24(SmallBaseCvarValue[slot], keyColor);
keyColor = CVarGetColor24(SmallBodyCvarValue[slot], keyColor);
if (isCustomKeysEnabled) {
gDPSetEnvColor(POLY_OPA_DISP++, keyColor.r, keyColor.g, keyColor.b, 255);
@ -99,7 +112,7 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
Color_RGB8 emblemColor = { 255, 0, 0 };
Color_RGB8 emblemColor = SmallEmblemDefaultValue[slot];
emblemColor = CVarGetColor24(SmallEmblemCvarValue[slot], emblemColor);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
@ -166,12 +179,12 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
s16 slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_BOSS_KEY;
std::string CvarValue[6] = {
"gCosmetics.Key.Forest",
"gCosmetics.Key.Fire",
"gCosmetics.Key.Water",
"gCosmetics.Key.Spirit",
"gCosmetics.Key.Shadow",
"gCosmetics.Key.Ganons",
"gCosmetics.Key.ForestBoss",
"gCosmetics.Key.FireBoss",
"gCosmetics.Key.WaterBoss",
"gCosmetics.Key.SpiritBoss",
"gCosmetics.Key.ShadowBoss",
"gCosmetics.Key.GanonsBoss",
};
Gfx* CustomdLists[] = {
@ -192,13 +205,13 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
Color_RGB8 keyColor = { 255, 255, 0 };
//Supposed to use CVAR_COSMETIC but I can't figure out the syntax
keyColor = CVarGetColor24((CvarValue[slot] + "BossBase.Value").c_str(), keyColor);
keyColor = CVarGetColor24((CvarValue[slot] + "Body.Value").c_str(), keyColor);
if (isCustomKeysEnabled){
gDPSetEnvColor(POLY_OPA_DISP++, keyColor.r, keyColor.g, keyColor.b, 255);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gBossKeyCustomDL);
} else {
if (CVarGetInteger((CvarValue[slot] + "BossBase.Changed").c_str(), false)){
if (CVarGetInteger((CvarValue[slot] + "Body.Changed").c_str(), false)){
gDPSetGrayscaleColor(POLY_OPA_DISP++, keyColor.r, keyColor.g, keyColor.b, 255);
gSPGrayscale(POLY_OPA_DISP++, true);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiBossKeyDL);
@ -213,15 +226,15 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
Color_RGB8 emblemColor = { 255, 0, 0 };
emblemColor = CVarGetColor24((CvarValue[slot] + "Emblem.Value").c_str(), emblemColor);
Color_RGB8 gemColor = { 255, 0, 0 };
gemColor = CVarGetColor24((CvarValue[slot] + "Gem.Value").c_str(), gemColor);
if (isCustomKeysEnabled){
gDPSetEnvColor(POLY_XLU_DISP++, emblemColor.r, emblemColor.g, emblemColor.b, 255);
gDPSetEnvColor(POLY_XLU_DISP++, gemColor.r, gemColor.g, gemColor.b, 255);
gSPDisplayList(POLY_XLU_DISP++, CustomdLists[slot]);
} else {
if (CVarGetInteger((CvarValue[slot] + "Emblem.Changed").c_str(), false)){
gDPSetGrayscaleColor(POLY_XLU_DISP++, emblemColor.r, emblemColor.g, emblemColor.b, 255);
if (CVarGetInteger((CvarValue[slot] + "Gem.Changed").c_str(), false)){
gDPSetGrayscaleColor(POLY_XLU_DISP++, gemColor.r, gemColor.g, gemColor.b, 255);
gSPGrayscale(POLY_XLU_DISP++, true);
gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiBossKeyGemDL);
gSPGrayscale(POLY_XLU_DISP++, false);
@ -296,7 +309,7 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt
Gfx_SetupDL_25Opa(play->state.gfxCtx);
Color_RGB8 keyColor = { 255, 255, 255 };
keyColor = CVarGetColor24(SmallBaseCvarValue[slot], keyColor);
keyColor = CVarGetColor24(SmallBodyCvarValue[slot], keyColor);
if (isCustomKeysEnabled) {
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
@ -314,7 +327,7 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt
gDPSetEnvColor(POLY_OPA_DISP++, ringColor.r, ringColor.g, ringColor.b, 255);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gKeyringRingDL);
Color_RGB8 emblemColor = { 255, 0, 0 };
Color_RGB8 emblemColor = SmallEmblemDefaultValue[slot];
emblemColor = CVarGetColor24(SmallEmblemCvarValue[slot], emblemColor);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
@ -933,7 +946,13 @@ extern "C" void DrawGanon(PlayState* play) {
}
extern "C" void Randomizer_DrawBossSoul(PlayState* play, GetItemEntry* getItemEntry) {
s16 slot = getItemEntry->getItemId - RG_GOHMA_SOUL;
s16 slot;
if (getItemEntry->getItemId != RG_ICE_TRAP) {
slot = getItemEntry->getItemId - RG_GOHMA_SOUL;
} else {
slot = getItemEntry->drawItemId - RG_GOHMA_SOUL;
}
s16 flameColors[9][3] = {
{ 0, 255, 0 }, // Gohma
{ 255, 0, 100 }, // King Dodongo
@ -1210,3 +1229,18 @@ extern "C" void Randomizer_DrawBombchuBagInLogic(PlayState* play, GetItemEntry*
CLOSE_DISPS(play->state.gfxCtx);
}
}
extern "C" void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255);
gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gHouseKeyDL);
CLOSE_DISPS(play->state.gfxCtx);
}

View File

@ -25,6 +25,7 @@ void Randomizer_DrawSkeletonKey(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry getItemEntry);
void Randomizer_DrawBombchuBagInLogic(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getItemEntry);
#define GET_ITEM_MYSTERY \
{ ITEM_NONE_FE, 0, 0, 0, 0, MOD_RANDOMIZER, MOD_RANDOMIZER, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, ITEM_NONE_FE, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem }

View File

@ -148,8 +148,8 @@ void DungeonInfo::PlaceVanillaSmallKeys() const {
// Gets the chosen dungeon locations for a playthrough (so either MQ or Vanilla)
std::vector<RandomizerCheck> DungeonInfo::GetDungeonLocations() const {
auto locations = masterQuest ? mqLocations : vanillaLocations;
if (Context::GetInstance()->GetSettings()->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_DUNGEONS) ||
Context::GetInstance()->GetSettings()->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL)) {
if (Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_DUNGEONS) ||
Context::GetInstance()->GetOption(RSK_SHUFFLE_POTS).Is(RO_SHUFFLE_POTS_ALL)) {
auto potLocations = masterQuest ? mqPots : vanillaPots;
AddElementsToPool(locations, potLocations);
}

View File

@ -21,14 +21,10 @@ void Entrance::SetCondition(ConditionFn newCondition) {
bool Entrance::GetConditionsMet() const {
auto ctx = Rando::Context::GetInstance();
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
return true;
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
return condition_function();
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) {
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
return condition_function();
}
return false;
return true;
}
std::string Entrance::to_string() const {
@ -1322,12 +1318,12 @@ int EntranceShuffler::ShuffleAllEntrances() {
(ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES) ? 1 : 0) + (ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES) ? 1 : 0) +
(ctx->GetOption(RSK_MIX_GROTTO_ENTRANCES) ? 1 : 0);
if (totalMixedPools < 2) {
ctx->GetOption(RSK_MIXED_ENTRANCE_POOLS).SetContextIndex(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_DUNGEON_ENTRANCES).SetContextIndex(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_BOSS_ENTRANCES).SetContextIndex(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES).SetContextIndex(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES).SetContextIndex(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_GROTTO_ENTRANCES).SetContextIndex(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIXED_ENTRANCE_POOLS).Set(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_DUNGEON_ENTRANCES).Set(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_BOSS_ENTRANCES).Set(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_OVERWORLD_ENTRANCES).Set(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_INTERIOR_ENTRANCES).Set(RO_GENERIC_OFF);
ctx->GetOption(RSK_MIX_GROTTO_ENTRANCES).Set(RO_GENERIC_OFF);
}
if (ctx->GetOption(RSK_MIXED_ENTRANCE_POOLS)) {
std::set<EntranceType> poolsToMix = {};

View File

@ -17,7 +17,7 @@ extern PlayState* gPlayState;
#define FSi OTRGlobals::Instance->gRandoContext->GetFishsanity()
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex()
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
/**
* @brief Parallel list of pond fish checks for both ages

View File

@ -559,23 +559,23 @@ CustomMessage Hint::GetBridgeReqsText() {
}
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES)) {
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_STONES_HINT].GetHintMessage();
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).GetContextOptionIndex());
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get());
}
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS)) {
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_MEDALLIONS_HINT].GetHintMessage();
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).GetContextOptionIndex());
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get());
}
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS)) {
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_REWARDS_HINT].GetHintMessage();
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex());
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get());
}
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS)) {
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_DUNGEONS_HINT].GetHintMessage();
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex());
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get());
}
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS)) {
bridgeMessage = StaticData::hintTextTable[RHT_BRIDGE_TOKENS_HINT].GetHintMessage();
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex());
bridgeMessage.InsertNumber(ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get());
}
else if (ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG)) {
return StaticData::hintTextTable[RHT_BRIDGE_GREG_HINT].GetHintMessage();
@ -613,23 +613,23 @@ CustomMessage Hint::GetGanonBossKeyText() {
}
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_STONES)) {
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_STONES_HINT].GetHintMessage();
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).GetContextOptionIndex());
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_STONE_COUNT).Get());
}
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_MEDALLIONS)) {
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_MEDALLIONS_HINT].GetHintMessage();
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).GetContextOptionIndex());
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get());
}
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_REWARDS)) {
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_REWARDS_HINT].GetHintMessage();
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex());
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_REWARD_COUNT).Get());
}
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_DUNGEONS)) {
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_DUNGEONS_HINT].GetHintMessage();
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex());
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get());
}
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_LACS_TOKENS)) {
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_TOKENS_HINT].GetHintMessage();
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex());
ganonBossKeyMessage.InsertNumber(ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get());
}
else if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_TRIFORCE_HUNT)) {
return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage();

View File

@ -69,7 +69,7 @@ extern void EnMk_Wait(EnMk* enMk, PlayState* play);
extern void func_80ABA778(EnNiwLady* enNiwLady, PlayState* play);
}
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).GetContextOptionIndex()
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
bool LocMatchesQuest(Rando::Location loc) {
if (loc.GetQuest() == RCQUEST_BOTH) {
@ -273,7 +273,9 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() {
RandomizerCheck rc = randomizerQueuedChecks.front();
auto loc = Rando::Context::GetInstance()->GetItemLocation(rc);
GetItemEntry getItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)Rando::StaticData::GetLocation(rc)->GetVanillaItem());
RandomizerGet vanillaRandomizerGet = Rando::StaticData::GetLocation(rc)->GetVanillaItem();
GetItemID vanillaItem = (GetItemID)Rando::StaticData::RetrieveItem(vanillaRandomizerGet).GetItemID();
GetItemEntry getItemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(rc, true, (GetItemID)vanillaRandomizerGet);
if (loc->HasObtained()) {
SPDLOG_INFO("RC {} already obtained, skipping", static_cast<uint32_t>(rc));
@ -645,7 +647,7 @@ void RandomizerOnDialogMessageHandler() {
MessageContext *msgCtx = &gPlayState->msgCtx;
Actor *actor = msgCtx->talkActor;
auto ctx = Rando::Context::GetInstance();
bool revealMerchant = ctx->GetOption(RSK_MERCHANT_TEXT_HINT).GetContextOptionIndex() != RO_GENERIC_OFF;
bool revealMerchant = ctx->GetOption(RSK_MERCHANT_TEXT_HINT).Get() != RO_GENERIC_OFF;
bool nonBeanMerchants = ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL_BUT_BEANS) ||
ctx->GetOption(RSK_SHUFFLE_MERCHANTS).Is(RO_SHUFFLE_MERCHANTS_ALL);
@ -714,7 +716,7 @@ void RandomizerOnDialogMessageHandler() {
}
break;
case TEXT_SCRUB_RANDOM:
if (ctx->GetOption(RSK_SCRUB_TEXT_HINT).GetContextOptionIndex() != RO_GENERIC_OFF) {
if (ctx->GetOption(RSK_SCRUB_TEXT_HINT).Get() != RO_GENERIC_OFF) {
EnDns* enDns = (EnDns*)actor;
reveal = OTRGlobals::Instance->gRandomizer->GetCheckFromRandomizerInf((RandomizerInf)enDns->sohScrubIdentity.randomizerInf);
}
@ -2370,6 +2372,8 @@ void RandomizerRegisterHooks() {
static uint32_t shuffleFreestandingOnVanillaBehaviorHook = 0;
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
ShipInit::Init("IS_RANDO");
randomizerQueuedChecks = std::queue<RandomizerCheck>();
randomizerQueuedCheck = RC_UNKNOWN_CHECK;
randomizerQueuedItemEntry = GET_ITEM_NONE;

View File

@ -383,7 +383,7 @@ bool Item::IsBottleItem() const {
bool Item::IsMajorItem() const {
const auto ctx = Context::GetInstance();
if (type == ITEMTYPE_TOKEN) {
return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) || ctx->GetSettings()->LACSCondition() == RO_LACS_TOKENS;
return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) || ctx->LACSCondition() == RO_LACS_TOKENS;
}
if (type == ITEMTYPE_DROP || type == ITEMTYPE_EVENT || type == ITEMTYPE_SHOP || type == ITEMTYPE_MAP ||

View File

@ -159,6 +159,54 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_GANONS_CASTLE_SMALL_KEY] = Item(RG_GANONS_CASTLE_SMALL_KEY, Text{ "Ganon's Castle Small Key", "Petite Clé du Château de Ganon", "Kleiner Schlüssel für Ganons Schloß" }, ITEMTYPE_SMALLKEY, 0xB7, true, LOGIC_GANONS_CASTLE_KEYS, RHT_GANONS_CASTLE_SMALL_KEY, RG_GANONS_CASTLE_SMALL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GANONS_CASTLE_SMALL_KEY].SetCustomDrawFunc(Randomizer_DrawSmallKey);
itemTable[RG_TREASURE_GAME_SMALL_KEY] = Item(RG_TREASURE_GAME_SMALL_KEY, Text{ "Chest Game Small Key", "Petite Clé du jeu la Chasse-aux-Trésors", "Kleiner Schlüssel für das Truhenspiel" }, ITEMTYPE_SMALLKEY, GI_DOOR_KEY, true, LOGIC_TREASURE_GAME_KEYS, RHT_TREASURE_GAME_SMALL_KEY, ITEM_KEY_SMALL, OBJECT_GI_KEY, GID_KEY_SMALL, 0xF3, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_NONE);
itemTable[RG_GUARD_HOUSE_KEY] = Item(RG_GUARD_HOUSE_KEY, Text{ "Guard House Key", "", "Schlüssel für das Haus der Wachen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GUARD_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_GUARD_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GUARD_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_MARKET_BAZAAR_KEY] = Item(RG_MARKET_BAZAAR_KEY, Text{ "Market Bazaar Key", "", "Schlüssel für den Basar des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_MARKET_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_MARKET_BAZAAR_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_MARKET_POTION_SHOP_KEY] = Item(RG_MARKET_POTION_SHOP_KEY, Text{ "Market Potion Shop Key", "", "Schlüssel für den Magie-Laden des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MARKET_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_MARKET_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_MASK_SHOP_KEY] = Item(RG_MASK_SHOP_KEY, Text{ "Mask Shop Key", "", "Schlüssel für den Maskenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MASK_SHOP_KEY, RHT_OVERWORLD_KEY, RG_MASK_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_MASK_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_MARKET_SHOOTING_GALLERY_KEY] = Item(RG_MARKET_SHOOTING_GALLERY_KEY, Text{ "Market Shooting Gallery Key", "", "Schlüssel für die Schießbude des Marktes" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_MARKET_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_MARKET_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_MARKET_SHOOTING_GALLERY_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_BOMBCHU_BOWLING_KEY] = Item(RG_BOMBCHU_BOWLING_KEY, Text{ "Bombchu Bowling Alley Key", "", "Schlüssel für die Minenbowlingbahn" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_BOWLING_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_BOWLING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_BOMBCHU_BOWLING_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_TREASURE_CHEST_GAME_BUILDING_KEY] = Item(RG_TREASURE_CHEST_GAME_BUILDING_KEY, Text{ "Treasure Chest Game Building Key", "", "Schlüssel für das Haus des Schatzkisten-Pokers" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TREASURE_CHEST_GAME_BUILDING_KEY,RHT_OVERWORLD_KEY, RG_TREASURE_CHEST_GAME_BUILDING_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_TREASURE_CHEST_GAME_BUILDING_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_BOMBCHU_SHOP_KEY] = Item(RG_BOMBCHU_SHOP_KEY, Text{ "Bombchu Shop Key", "", "Schlüssel für den Krabbelminenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOMBCHU_SHOP_KEY, RHT_OVERWORLD_KEY, RG_BOMBCHU_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_BOMBCHU_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_RICHARDS_HOUSE_KEY] = Item(RG_RICHARDS_HOUSE_KEY, Text{ "Richard's House Key", "", "Schlüssel für das Haus von Richard" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_RICHARDS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_RICHARDS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_RICHARDS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_ALLEY_HOUSE_KEY] = Item(RG_ALLEY_HOUSE_KEY, Text{ "Alley House Key", "", "Schlüssel für das Gäßchenhaus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_ALLEY_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_ALLEY_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_ALLEY_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_KAK_BAZAAR_KEY] = Item(RG_KAK_BAZAAR_KEY, Text{ "Kakariko Bazaar Key", "", "Schlüssel für den Basar von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_BAZAAR_KEY, RHT_OVERWORLD_KEY, RG_KAK_BAZAAR_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_KAK_BAZAAR_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_KAK_POTION_SHOP_KEY] = Item(RG_KAK_POTION_SHOP_KEY, Text{ "Kakariko Potion Shop Key", "", "Schlüssel für den Magie-Laden von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_KAK_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_KAK_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_BOSS_HOUSE_KEY] = Item(RG_BOSS_HOUSE_KEY, Text{ "Boss's House Key", "", "Schlüssel für das Haus des Chefs" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BOSS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_BOSS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_BOSS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_GRANNYS_POTION_SHOP_KEY] = Item(RG_GRANNYS_POTION_SHOP_KEY, Text{ "Granny's Potion Shop Key", "", "Schlüssel für Asas Hexenladen" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_GRANNYS_POTION_SHOP_KEY, RHT_OVERWORLD_KEY, RG_GRANNYS_POTION_SHOP_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_GRANNYS_POTION_SHOP_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_SKULLTULA_HOUSE_KEY] = Item(RG_SKULLTULA_HOUSE_KEY, Text{ "Skulltula House Key", "", "Schlüssel für das Skulltula-Haus" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_SKULLTULA_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_SKULLTULA_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_SKULLTULA_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_IMPAS_HOUSE_KEY] = Item(RG_IMPAS_HOUSE_KEY, Text{ "Impa's House Key", "", "Schlüssel für das Haus von Impa" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_IMPAS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_IMPAS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_IMPAS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_WINDMILL_KEY] = Item(RG_WINDMILL_KEY, Text{ "Windmill Key", "", "Schlüssel für die Windmühle" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_WINDMILL_KEY, RHT_OVERWORLD_KEY, RG_WINDMILL_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_WINDMILL_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_KAK_SHOOTING_GALLERY_KEY] = Item(RG_KAK_SHOOTING_GALLERY_KEY, Text{ "Kakariko Shooting Gallery Key", "", "Schlüssel für die Schießbude von Kakariko" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_KAK_SHOOTING_GALLERY_KEY, RHT_OVERWORLD_KEY, RG_KAK_SHOOTING_GALLERY_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_KAK_SHOOTING_GALLERY_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_DAMPES_HUT_KEY] = Item(RG_DAMPES_HUT_KEY, Text{ "Dampe's Hut Key", "", "Schlüssel für die Hütte von Boris" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_DAMPES_HUT_KEY, RHT_OVERWORLD_KEY, RG_DAMPES_HUT_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_DAMPES_HUT_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_TALONS_HOUSE_KEY] = Item(RG_TALONS_HOUSE_KEY, Text{ "Talon's House Key", "", "Schlüssel für das Haus von Talon" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_TALONS_HOUSE_KEY, RHT_OVERWORLD_KEY, RG_TALONS_HOUSE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_TALONS_HOUSE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_STABLES_KEY] = Item(RG_STABLES_KEY, Text{ "Stables Key", "", "Schlüssel für die Ställe" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_STABLES_KEY, RHT_OVERWORLD_KEY, RG_STABLES_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_STABLES_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_BACK_TOWER_KEY] = Item(RG_BACK_TOWER_KEY, Text{ "Back Tower Key", "", "Schlüssel für den hinteren Turm" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_BACK_TOWER_KEY, RHT_OVERWORLD_KEY, RG_BACK_TOWER_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_BACK_TOWER_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_HYLIA_LAB_KEY] = Item(RG_HYLIA_LAB_KEY, Text{ "Hylia Laboratory Key", "", "Schlüssel für das Hylia-Labor" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_HYLIA_LAB_KEY, RHT_OVERWORLD_KEY, RG_HYLIA_LAB_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_HYLIA_LAB_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
itemTable[RG_FISHING_HOLE_KEY] = Item(RG_FISHING_HOLE_KEY, Text{ "Fishing Hole Key", "", "Schlüssel für den Fischweiher" }, ITEMTYPE_ITEM, GI_DOOR_KEY, true, LOGIC_FISHING_HOLE_KEY, RHT_OVERWORLD_KEY, RG_FISHING_HOLE_KEY, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_FISHING_HOLE_KEY].SetCustomDrawFunc(Randomizer_DrawOverworldKey);
// Key Rings
itemTable[RG_FOREST_TEMPLE_KEY_RING] = Item(RG_FOREST_TEMPLE_KEY_RING, Text{ "Forest Temple Key Ring", "Trousseau du Temple de la Forêt", "Schlüsselbund für den Waldtempel" }, ITEMTYPE_SMALLKEY, 0xD5, true, LOGIC_FOREST_TEMPLE_KEYS, RHT_FOREST_TEMPLE_KEY_RING, RG_FOREST_TEMPLE_KEY_RING, OBJECT_GI_KEY, GID_KEY_SMALL, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_SHORT, ITEM_CATEGORY_SMALL_KEY,MOD_RANDOMIZER);
itemTable[RG_FOREST_TEMPLE_KEY_RING].SetCustomDrawFunc(Randomizer_DrawKeyRing);

View File

@ -178,34 +178,15 @@ void ItemLocation::SetHidden(const bool hidden_) {
}
bool ItemLocation::IsExcluded() {
return excludedOption.GetContextOptionIndex();
return excludedOption.Is(RO_LOCATION_EXCLUDE);
}
Option* ItemLocation::GetExcludedOption() {
return &excludedOption;
OptionValue& ItemLocation::GetExcludedOption() {
return excludedOption;
}
void ItemLocation::AddExcludeOption() {
if (const std::string name = StaticData::GetLocation(rc)->GetName(); name.length() < 23) {
excludedOption = Option::Bool(name, {"Include", "Exclude"}, OptionCategory::Setting, "", "", WidgetType::Checkbox, RO_LOCATION_INCLUDE);
} else {
const size_t lastSpace = name.rfind(' ', 23);
std::string settingText = name;
settingText.replace(lastSpace, 1, "\n ");
excludedOption = Option::Bool(settingText, {"Include", "Exclude"}, OptionCategory::Setting, "", "", WidgetType::Checkbox, RO_LOCATION_INCLUDE);
}
// RANDOTODO: this without string compares and loops
bool alreadyAdded = false;
const Location* loc = StaticData::GetLocation(rc);
for (Option* location : Context::GetInstance()->GetSettings()->GetExcludeOptionsForArea(loc->GetArea())) {
if (location->GetName() == excludedOption.GetName()) {
alreadyAdded = true;
}
}
if (!alreadyAdded) {
Context::GetInstance()->GetSettings()->GetExcludeOptionsForArea(loc->GetArea()).push_back(&excludedOption);
}
void ItemLocation::SetExcludedOption(uint8_t val) {
excludedOption.Set(val);
}
bool ItemLocation::IsVisible() const {

View File

@ -3,7 +3,7 @@
#include "randomizerTypes.h"
#include "3drando/text.hpp"
#include "static_data.h"
#include "settings.h"
#include "option.h"
namespace Rando {
class ItemLocation {
@ -46,8 +46,8 @@ class ItemLocation {
void AddHintedBy(RandomizerHint hintKey);
bool IsHidden() const;
bool IsExcluded();
void AddExcludeOption();
Option* GetExcludedOption();
OptionValue& GetExcludedOption();
void SetExcludedOption(uint8_t val);
void SetHidden(bool hidden_);
bool IsVisible() const;
void SetVisible(bool visibleInImGui_);
@ -65,7 +65,7 @@ class ItemLocation {
bool addedToPool = false;
RandomizerGet placedItem = RG_NONE;
RandomizerGet delayedItem = RG_NONE;
Option excludedOption = Option::Bool(StaticData::GetLocation(rc)->GetName(), {"Include", "Exclude"}, OptionCategory::Setting, "", "", WidgetType::Checkbox, RO_LOCATION_INCLUDE);
OptionValue excludedOption = OptionValue(RO_LOCATION_INCLUDE);
uint16_t price = 0;
RandomizerRegion parentRegion = RR_NONE;
std::set<RandomizerArea> areas = {};

View File

@ -2,6 +2,7 @@
#include "static_data.h"
#include <algorithm>
#include <assert.h>
#include "option.h"
RandomizerCheck Rando::Location::GetRandomizerCheck() const {
return rc;
@ -86,6 +87,10 @@ int16_t Rando::Location::GetVanillaPrice() const {
return vanillaPrice;
}
Rando::Option* Rando::Location::GetExcludedOption() {
return &excludedOption;
}
RandomizerCheckArea GetAreaFromScene(uint8_t scene) {
switch (scene) {
case SCENE_LINKS_HOUSE:

View File

@ -10,6 +10,7 @@
#include "z64actor_enum.h"
#include "z64scene.h"
#include "../../util.h"
#include "option.h"
namespace Rando {
class SpoilerCollectionCheck {
@ -59,7 +60,17 @@ class Location {
: rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_),
scene(scene_), actorParams(actorParams_), shortName(std::move(shortName_)),
spoilerName(std::move(spoilerName_)), hintKey(hintKey_), vanillaItem(vanillaItem_),
isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {}
isVanillaCompletion(isVanillaCompletion_), collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {
if (spoilerName.length() < 23) {
excludedOption = LocationOption(rc, spoilerName);
} else {
const size_t lastSpace = spoilerName.rfind(' ', 23);
std::string settingText = spoilerName;
settingText.replace(lastSpace, 1, "\n ");
excludedOption = LocationOption(rc, spoilerName);
}
}
Location(const RandomizerCheck rc_, const RandomizerCheckQuest quest_, const RandomizerCheckType checkType_, const RandomizerCheckArea area_, const ActorID actorId_,
const SceneID scene_, const int32_t actorParams_, std::string shortName_, const RandomizerHintTextKey hintKey_, const RandomizerGet vanillaItem_,
@ -67,7 +78,17 @@ class Location {
const int vanillaPrice_ = 0)
: rc(rc_), quest(quest_), checkType(checkType_), area(area_), actorId(actorId_), scene(scene_), actorParams(actorParams_), shortName(shortName_),
spoilerName(SpoilerNameFromShortName(shortName_, area_)), hintKey(hintKey_), vanillaItem(vanillaItem_), isVanillaCompletion(isVanillaCompletion_),
collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {}
collectionCheck(collectionCheck_), vanillaPrice(vanillaPrice_) {
if (spoilerName.length() < 23) {
excludedOption = LocationOption(rc, spoilerName);
} else {
const size_t lastSpace = spoilerName.rfind(' ', 23);
std::string settingText = spoilerName;
settingText.replace(lastSpace, 1, "\n ");
excludedOption = LocationOption(rc, spoilerName);
}
}
static std::string SpoilerNameFromShortName(std::string shortName, RandomizerCheckArea area) {
if (area < 0 || area >= RCAREA_INVALID) {
@ -96,10 +117,13 @@ class Location {
const HintText& GetHint() const;
RandomizerGet GetVanillaItem() const;
int16_t GetVanillaPrice() const;
Option* GetExcludedOption();
static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_, std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(), bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0);
static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_,
ActorID actorId_, SceneID scene_, int32_t actorParams_, std::string&& shortName_,
std::string&& spoilerName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem,
SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(),
bool isVanillaCompletion_ = false, uint16_t vanillaPrice_ = 0);
static Location Base(RandomizerCheck rc, RandomizerCheckQuest quest_, RandomizerCheckType checkType_, ActorID actorId_, SceneID scene_, int32_t actorParams_,
std::string&& shortName_, RandomizerHintTextKey hintKey, RandomizerGet vanillaItem, SpoilerCollectionCheck collectionCheck = SpoilerCollectionCheck(),
@ -205,5 +229,6 @@ class Location {
SpoilerCollectionCheck collectionCheck;
int16_t vanillaPrice;
bool isHintable = false;
Option excludedOption;
};
} // namespace Rando

View File

@ -267,7 +267,7 @@ void RegionTable_Init() {
}, {
//Locations
LOCATION(RC_LINKS_POCKET, true),
LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->ship.quest.data.randomizer.triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).GetContextOptionIndex() + 1;),
LOCATION(RC_TRIFORCE_COMPLETED, logic->GetSaveContext()->ship.quest.data.randomizer.triforcePiecesCollected >= ctx->GetOption(RSK_TRIFORCE_HUNT_PIECES_REQUIRED).Get() + 1;),
LOCATION(RC_SARIA_SONG_HINT, logic->CanUse(RG_SARIAS_SONG)),
}, {
//Exits
@ -409,7 +409,7 @@ void ReplaceAllInString(std::string& s, std::string const& toReplace, std::strin
std::string CleanCheckConditionString(std::string condition) {
ReplaceAllInString(condition, "logic->", "");
ReplaceAllInString(condition, "ctx->", "");
ReplaceAllInString(condition, ".GetContextOptionIndex()", "");
ReplaceAllInString(condition, ".Get()", "");
ReplaceAllInString(condition, "GetSaveContext()->", "");
return condition;
}

View File

@ -23,14 +23,10 @@ class EventAccess {
bool ConditionsMet() const {
auto ctx = Rando::Context::GetInstance();
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
return true;
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
return condition_function();
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) {
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
return condition_function();
}
return false;
return true;
}
bool CheckConditionAtAgeTime(bool& age, bool& time) {
@ -71,14 +67,10 @@ class LocationAccess {
bool GetConditionsMet() const {
auto ctx = Rando::Context::GetInstance();
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_NO_LOGIC) || ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_VANILLA)) {
return true;
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
return condition_function();
} else if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHED)) {
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
return condition_function();
}
return false;
return true;
}
bool CheckConditionAtAgeTime(bool& age, bool& time) const;

View File

@ -71,6 +71,7 @@ void RegionTable_Init_DeathMountainTrail() {
LOCATION(RC_DMT_COW_GROTTO_RUPEE_5, true),
LOCATION(RC_DMT_COW_GROTTO_RUPEE_6, true),
LOCATION(RC_DMT_COW_GROTTO_RED_RUPEE, true),
LOCATION(RC_DMT_COW_GROTTO_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),
}, {
//Exits
Entrance(RR_DEATH_MOUNTAIN_SUMMIT, []{return true;}),

View File

@ -24,7 +24,7 @@ void RegionTable_Init_Graveyard() {
Entrance(RR_GRAVEYARD_COMPOSERS_GRAVE, []{return logic->CanUse(RG_ZELDAS_LULLABY);}),
Entrance(RR_GRAVEYARD_HEART_PIECE_GRAVE, []{return logic->IsAdult || logic->AtNight;}),
Entrance(RR_GRAVEYARD_DAMPES_GRAVE, []{return logic->IsAdult;}),
Entrance(RR_GRAVEYARD_DAMPES_HOUSE, []{return logic->IsAdult /*|| logic->AtDampeTime*/;}), //TODO: This needs to be handled in ToD rework
Entrance(RR_GRAVEYARD_DAMPES_HOUSE, []{return logic->IsAdult && logic->CanOpenOverworldDoor(RG_DAMPES_HUT_KEY) /*|| logic->AtDampeTime*/;}), //TODO: This needs to be handled in ToD rework
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_GRAVEYARD_WARP_PAD_REGION, []{return false;}),
});
@ -65,6 +65,7 @@ void RegionTable_Init_Graveyard() {
//Locations
LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_CHEST, logic->HasFireSource()),
LOCATION(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, logic->CanUseProjectile() || logic->CanJumpslash()),
LOCATION(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits
Entrance(RR_THE_GRAVEYARD, []{return true;}),
@ -103,7 +104,7 @@ void RegionTable_Init_Graveyard() {
LOCATION(RC_DAMPE_HINT, logic->IsAdult),
}, {
//Exits
Entrance(RR_THE_GRAVEYARD, []{return true;}),
Entrance(RR_THE_GRAVEYARD, []{return logic->CanOpenOverworldDoor(RG_DAMPES_HUT_KEY);}),
});
areaTable[RR_GRAVEYARD_WARP_PAD_REGION] = Region("Graveyard Warp Pad Region", "Graveyard", {RA_THE_GRAVEYARD}, NO_DAY_NIGHT_CYCLE, {

View File

@ -33,14 +33,14 @@ void RegionTable_Init_Kakariko() {
}, {
//Exits
Entrance(RR_HYRULE_FIELD, []{return true;}),
Entrance(RR_KAK_CARPENTER_BOSS_HOUSE, []{return true;}),
Entrance(RR_KAK_HOUSE_OF_SKULLTULA, []{return true;}),
Entrance(RR_KAK_IMPAS_HOUSE, []{return true;}),
Entrance(RR_KAK_WINDMILL, []{return true;}),
Entrance(RR_KAK_BAZAAR, []{return logic->IsAdult && logic->AtDay;}),
Entrance(RR_KAK_SHOOTING_GALLERY, []{return logic->IsAdult && logic->AtDay;}),
Entrance(RR_KAK_CARPENTER_BOSS_HOUSE, []{return logic->CanOpenOverworldDoor(RG_BOSS_HOUSE_KEY);}),
Entrance(RR_KAK_HOUSE_OF_SKULLTULA, []{return logic->CanOpenOverworldDoor(RG_SKULLTULA_HOUSE_KEY);}),
Entrance(RR_KAK_IMPAS_HOUSE, []{return logic->CanOpenOverworldDoor(RG_IMPAS_HOUSE_KEY);}),
Entrance(RR_KAK_WINDMILL, []{return logic->CanOpenOverworldDoor(RG_WINDMILL_KEY);}),
Entrance(RR_KAK_BAZAAR, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_BAZAAR_KEY);}),
Entrance(RR_KAK_SHOOTING_GALLERY, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_SHOOTING_GALLERY_KEY);}),
Entrance(RR_KAK_WELL, []{return logic->IsAdult || logic->DrainWell || logic->CanUse(RG_IRON_BOOTS);}),
Entrance(RR_KAK_POTION_SHOP_FRONT, []{return logic->AtDay || logic->IsChild;}),
Entrance(RR_KAK_POTION_SHOP_FRONT, []{return (logic->AtDay || logic->IsChild) && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}),
Entrance(RR_KAK_REDEAD_GROTTO, []{return logic->CanOpenBombGrotto();}),
Entrance(RR_KAK_IMPAS_LEDGE, []{return (logic->IsChild && logic->AtDay) || (logic->IsAdult && ctx->GetTrickOption(RT_VISIBLE_COLLISION));}),
Entrance(RR_KAK_WATCHTOWER, []{return logic->IsAdult || logic->AtDay || logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_LONGSHOT) || (ctx->GetTrickOption(RT_KAK_TOWER_GS) && logic->CanJumpslashExceptHammer());}),
@ -95,8 +95,8 @@ void RegionTable_Init_Kakariko() {
//Exits
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_KAK_OPEN_GROTTO, []{return true;}),
Entrance(RR_KAK_ODD_POTION_BUILDING, []{return logic->IsAdult;}),
Entrance(RR_KAK_POTION_SHOP_BACK, []{return logic->IsAdult && logic->AtDay;}),
Entrance(RR_KAK_ODD_POTION_BUILDING, []{return logic->IsAdult && logic->CanOpenOverworldDoor(RG_GRANNYS_POTION_SHOP_KEY);}),
Entrance(RR_KAK_POTION_SHOP_BACK, []{return logic->IsAdult && logic->AtDay && logic->CanOpenOverworldDoor(RG_KAK_POTION_SHOP_KEY);}),
});
areaTable[RR_KAK_CARPENTER_BOSS_HOUSE] = Region("Kak Carpenter Boss House", "Kak Carpenter Boss House", {}, NO_DAY_NIGHT_CYCLE, {
@ -104,7 +104,7 @@ void RegionTable_Init_Kakariko() {
EventAccess(&logic->WakeUpAdultTalon, []{return logic->IsAdult && logic->CanUse(RG_POCKET_EGG);}),
}, {}, {
//Exits
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_BOSS_HOUSE_KEY);}),
});
areaTable[RR_KAK_HOUSE_OF_SKULLTULA] = Region("Kak House of Skulltula", "Kak House of Skulltula", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -117,7 +117,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_100_GOLD_SKULLTULA_REWARD, logic->GetGSCount() >= 100),
}, {
//Exits
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_SKULLTULA_HOUSE_KEY);}),
});
areaTable[RR_KAK_IMPAS_HOUSE] = Region("Kak Impas House", "Kak Impas House", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -125,7 +125,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_IMPAS_HOUSE_COW, logic->CanUse(RG_EPONAS_SONG)),
}, {
//Exits
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_IMPAS_HOUSE_KEY);}),
});
areaTable[RR_KAK_IMPAS_HOUSE_BACK] = Region("Kak Impas House Back", "Kak Impas House", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -146,7 +146,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_SONG_FROM_WINDMILL, logic->IsAdult && logic->HasItem(RG_FAIRY_OCARINA)),
}, {
//Exits
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_WINDMILL_KEY);}),
});
areaTable[RR_KAK_BAZAAR] = Region("Kak Bazaar", "Kak Bazaar", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -169,7 +169,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_SHOOTING_GALLERY_REWARD, logic->HasItem(RG_CHILD_WALLET) && logic->IsAdult && logic->CanUse(RG_FAIRY_BOW)),
}, {
//Exits
Entrance(RR_KAKARIKO_VILLAGE, []{return true;}),
Entrance(RR_KAKARIKO_VILLAGE, []{return logic->CanOpenOverworldDoor(RG_KAK_SHOOTING_GALLERY_KEY);}),
});
areaTable[RR_KAK_POTION_SHOP_FRONT] = Region("Kak Potion Shop Front", "Kak Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -203,7 +203,7 @@ void RegionTable_Init_Kakariko() {
LOCATION(RC_KAK_GRANNYS_SHOP, logic->IsAdult && (logic->CanUse(RG_ODD_MUSHROOM) || logic->TradeQuestStep(RG_ODD_MUSHROOM))),
}, {
// Exits
Entrance(RR_KAK_BACKYARD, []{return true;}),
Entrance(RR_KAK_BACKYARD, []{return logic->CanOpenOverworldDoor(RG_GRANNYS_POTION_SHOP_KEY);}),
});
areaTable[RR_KAK_REDEAD_GROTTO] = Region("Kak Redead Grotto", "Kak Redead Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -44,7 +44,7 @@ void RegionTable_Init_LakeHylia() {
Entrance(RR_ZORAS_DOMAIN, []{return logic->IsChild && (logic->HasItem(RG_SILVER_SCALE) || logic->CanUse(RG_IRON_BOOTS));}),
Entrance(RR_LH_OWL_FLIGHT, []{return logic->IsChild;}),
Entrance(RR_LH_FISHING_ISLAND, []{return ((logic->IsChild || logic->WaterTempleClear) && logic->HasItem(RG_BRONZE_SCALE)) || (logic->IsAdult && (logic->CanUse(RG_SCARECROW) || CanPlantBean(RR_LAKE_HYLIA)));}),
Entrance(RR_LH_LAB, []{return true;}),
Entrance(RR_LH_LAB, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}),
Entrance(RR_WATER_TEMPLE_ENTRYWAY, []{return logic->CanUse(RG_HOOKSHOT) && ((logic->CanUse(RG_IRON_BOOTS) || (ctx->GetTrickOption(RT_LH_WATER_HOOKSHOT) && logic->HasItem(RG_GOLDEN_SCALE))) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT) && logic->HasItem(RG_GOLDEN_SCALE)));}),
Entrance(RR_LH_GROTTO, []{return true;}),
});
@ -52,7 +52,7 @@ void RegionTable_Init_LakeHylia() {
areaTable[RR_LH_FISHING_ISLAND] = Region("LH Fishing Island", "Lake Hylia", {RA_LAKE_HYLIA}, DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_LAKE_HYLIA, []{return logic->HasItem(RG_BRONZE_SCALE);}),
Entrance(RR_LH_FISHING_POND, []{return true;}),
Entrance(RR_LH_FISHING_POND, []{return logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY);}),
});
areaTable[RR_LH_OWL_FLIGHT] = Region("LH Owl Flight", "Lake Hylia", {RA_LAKE_HYLIA}, NO_DAY_NIGHT_CYCLE, {}, {}, {
@ -70,7 +70,7 @@ void RegionTable_Init_LakeHylia() {
LOCATION(RC_LH_LAB_RIGHT_RUPEE, logic->CanUse(RG_IRON_BOOTS) || logic->HasItem(RG_GOLDEN_SCALE)),
}, {
//Exits
Entrance(RR_LAKE_HYLIA, []{return true;}),
Entrance(RR_LAKE_HYLIA, []{return logic->CanOpenOverworldDoor(RG_HYLIA_LAB_KEY);}),
});
// TODO: should some of these helpers be done via events instead?
@ -115,7 +115,7 @@ void RegionTable_Init_LakeHylia() {
LOCATION(RC_FISHING_POLE_HINT, true),
}, {
//Exits
Entrance(RR_LH_FISHING_ISLAND, []{return true;}),
Entrance(RR_LH_FISHING_ISLAND, []{return logic->CanOpenOverworldDoor(RG_FISHING_HOLE_KEY);}),
});
areaTable[RR_LH_GROTTO] = Region("LH Grotto", "LH Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -25,9 +25,9 @@ void RegionTable_Init_LonLonRanch() {
}, {
//Exits
Entrance(RR_HYRULE_FIELD, []{return true;}),
Entrance(RR_LLR_TALONS_HOUSE, []{return true;}),
Entrance(RR_LLR_STABLES, []{return true;}),
Entrance(RR_LLR_TOWER, []{return true;}),
Entrance(RR_LLR_TALONS_HOUSE, []{return logic->CanOpenOverworldDoor(RG_TALONS_HOUSE_KEY);}),
Entrance(RR_LLR_STABLES, []{return logic->CanOpenOverworldDoor(RG_STABLES_KEY);}),
Entrance(RR_LLR_TOWER, []{return logic->CanOpenOverworldDoor(RG_BACK_TOWER_KEY);}),
Entrance(RR_LLR_GROTTO, []{return logic->IsChild;}),
});
@ -39,7 +39,7 @@ void RegionTable_Init_LonLonRanch() {
LOCATION(RC_LLR_TALONS_HOUSE_POT_3, logic->CanBreakPots()),
}, {
//Exits
Entrance(RR_LON_LON_RANCH, []{return true;}),
Entrance(RR_LON_LON_RANCH, []{return logic->CanOpenOverworldDoor(RG_TALONS_HOUSE_KEY);}),
});
areaTable[RR_LLR_STABLES] = Region("LLR Stables", "LLR Stables", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -48,7 +48,7 @@ void RegionTable_Init_LonLonRanch() {
LOCATION(RC_LLR_STABLES_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)),
}, {
//Exits
Entrance(RR_LON_LON_RANCH, []{return true;}),
Entrance(RR_LON_LON_RANCH, []{return logic->CanOpenOverworldDoor(RG_STABLES_KEY);}),
});
areaTable[RR_LLR_TOWER] = Region("LLR Tower", "LLR Tower", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -58,7 +58,7 @@ void RegionTable_Init_LonLonRanch() {
LOCATION(RC_LLR_TOWER_RIGHT_COW, logic->CanUse(RG_EPONAS_SONG)),
}, {
//Exits
Entrance(RR_LON_LON_RANCH, []{return true;}),
Entrance(RR_LON_LON_RANCH, []{return logic->CanOpenOverworldDoor(RG_BACK_TOWER_KEY);}),
});
areaTable[RR_LLR_GROTTO] = Region("LLR Grotto", "LLR Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {

View File

@ -108,6 +108,7 @@ void RegionTable_Init_LostWoods() {
LOCATION(RC_LW_DEKU_SCRUB_GROTTO_REAR, logic->CanStunDeku()),
LOCATION(RC_LW_DEKU_SCRUB_GROTTO_FRONT, logic->CanStunDeku()),
LOCATION(RC_LW_DEKU_SCRUB_GROTTO_BEEHIVE, logic->CanBreakUpperBeehives()),
LOCATION(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
}, {
//Exits
Entrance(RR_LW_BEYOND_MIDO, []{return true;}),

View File

@ -8,7 +8,7 @@ void RegionTable_Init_Market() {
//Exits
Entrance(RR_HYRULE_FIELD, []{return logic->IsAdult || logic->AtDay;}),
Entrance(RR_THE_MARKET, []{return true;}),
Entrance(RR_MARKET_GUARD_HOUSE, []{return true;}),
Entrance(RR_MARKET_GUARD_HOUSE, []{return logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}),
});
areaTable[RR_THE_MARKET] = Region("Market", "Market", {RA_THE_MARKET}, NO_DAY_NIGHT_CYCLE, {}, {}, {
@ -16,21 +16,21 @@ void RegionTable_Init_Market() {
Entrance(RR_MARKET_ENTRANCE, []{return true;}),
Entrance(RR_TOT_ENTRANCE, []{return true;}),
Entrance(RR_CASTLE_GROUNDS, []{return true;}),
Entrance(RR_MARKET_BAZAAR, []{return logic->IsChild && logic->AtDay;}),
Entrance(RR_MARKET_MASK_SHOP, []{return logic->IsChild && logic->AtDay;}),
Entrance(RR_MARKET_SHOOTING_GALLERY, []{return logic->IsChild && logic->AtDay;}),
Entrance(RR_MARKET_BOMBCHU_BOWLING, []{return logic->IsChild;}),
Entrance(RR_MARKET_TREASURE_CHEST_GAME, []{return logic->IsChild && logic->AtNight;}),
Entrance(RR_MARKET_POTION_SHOP, []{return logic->IsChild && logic->AtDay;}),
Entrance(RR_MARKET_BAZAAR, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MARKET_BAZAAR_KEY);}),
Entrance(RR_MARKET_MASK_SHOP, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MASK_SHOP_KEY);}),
Entrance(RR_MARKET_SHOOTING_GALLERY, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MARKET_SHOOTING_GALLERY_KEY);}),
Entrance(RR_MARKET_BOMBCHU_BOWLING, []{return logic->IsChild && logic->CanOpenOverworldDoor(RG_BOMBCHU_BOWLING_KEY);}),
Entrance(RR_MARKET_TREASURE_CHEST_GAME, []{return logic->IsChild && logic->AtNight && logic->CanOpenOverworldDoor(RG_TREASURE_CHEST_GAME_BUILDING_KEY);}),
Entrance(RR_MARKET_POTION_SHOP, []{return logic->IsChild && logic->AtDay && logic->CanOpenOverworldDoor(RG_MARKET_POTION_SHOP_KEY);}),
Entrance(RR_MARKET_BACK_ALLEY, []{return logic->IsChild;}),
});
areaTable[RR_MARKET_BACK_ALLEY] = Region("Market Back Alley", "Market", {RA_THE_MARKET}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_THE_MARKET, []{return true;}),
Entrance(RR_MARKET_BOMBCHU_SHOP, []{return logic->AtNight;}),
Entrance(RR_MARKET_DOG_LADY_HOUSE, []{return true;}),
Entrance(RR_MARKET_MAN_IN_GREEN_HOUSE, []{return logic->AtNight;}),
Entrance(RR_MARKET_BOMBCHU_SHOP, []{return logic->AtNight && logic->CanOpenOverworldDoor(RG_BOMBCHU_SHOP_KEY);}),
Entrance(RR_MARKET_DOG_LADY_HOUSE, []{return logic->CanOpenOverworldDoor(RG_RICHARDS_HOUSE_KEY);}),
Entrance(RR_MARKET_MAN_IN_GREEN_HOUSE, []{return logic->AtNight && logic->CanOpenOverworldDoor(RG_ALLEY_HOUSE_KEY);}),
});
areaTable[RR_MARKET_GUARD_HOUSE] = Region("Market Guard House", "Market Guard House", {}, NO_DAY_NIGHT_CYCLE, {
@ -98,7 +98,7 @@ void RegionTable_Init_Market() {
LOCATION(RC_MK_GUARD_HOUSE_ADULT_POT_11, logic->IsAdult && logic->CanBreakPots()),
}, {
//Exits
Entrance(RR_MARKET_ENTRANCE, []{return true;}),
Entrance(RR_MARKET_ENTRANCE, []{return logic->CanOpenOverworldDoor(RG_GUARD_HOUSE_KEY);}),
});
areaTable[RR_MARKET_BAZAAR] = Region("Market Bazaar", "Market Bazaar", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -133,7 +133,7 @@ void RegionTable_Init_Market() {
LOCATION(RC_MARKET_SHOOTING_GALLERY_REWARD, logic->IsChild && logic->HasItem(RG_CHILD_WALLET)),
}, {
//Exits
Entrance(RR_THE_MARKET, []{return true;}),
Entrance(RR_THE_MARKET, []{return logic->CanOpenOverworldDoor(RG_MARKET_SHOOTING_GALLERY_KEY);}),
});
areaTable[RR_MARKET_BOMBCHU_BOWLING] = Region("Market Bombchu Bowling", "Market Bombchu Bowling", {}, NO_DAY_NIGHT_CYCLE, {
@ -145,7 +145,7 @@ void RegionTable_Init_Market() {
LOCATION(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, logic->CouldPlayBowling && logic->BombchusEnabled()),
}, {
//Exits
Entrance(RR_THE_MARKET, []{return true;}),
Entrance(RR_THE_MARKET, []{return logic->CanOpenOverworldDoor(RG_BOMBCHU_BOWLING_KEY);}),
});
areaTable[RR_MARKET_POTION_SHOP] = Region("Market Potion Shop", "Market Potion Shop", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -179,7 +179,7 @@ void RegionTable_Init_Market() {
LOCATION(RC_MARKET_TREASURE_CHEST_GAME_ITEM_5, logic->HasItem(RG_CHILD_WALLET) && ((ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_SINGLE_KEYS) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 5)) || (ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME).Is(RO_CHEST_GAME_PACK) && logic->SmallKeys(RR_MARKET_TREASURE_CHEST_GAME, 1)) || (logic->CanUse(RG_LENS_OF_TRUTH) && !ctx->GetOption(RSK_SHUFFLE_CHEST_MINIGAME)))),
}, {
//Exits
Entrance(RR_THE_MARKET, []{return true;}),
Entrance(RR_THE_MARKET, []{return logic->CanOpenOverworldDoor(RG_TREASURE_CHEST_GAME_BUILDING_KEY);}),
});
areaTable[RR_MARKET_BOMBCHU_SHOP] = Region("Market Bombchu Shop", "Market Bombchu Shop", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -202,7 +202,7 @@ void RegionTable_Init_Market() {
LOCATION(RC_MARKET_LOST_DOG, logic->IsChild && logic->AtNight),
}, {
//Exits
Entrance(RR_MARKET_BACK_ALLEY, []{return true;}),
Entrance(RR_MARKET_BACK_ALLEY, []{return logic->CanOpenOverworldDoor(RG_RICHARDS_HOUSE_KEY);}),
});
areaTable[RR_MARKET_MAN_IN_GREEN_HOUSE] = Region("Market Man in Green House", "Market Man in Green House", {}, NO_DAY_NIGHT_CYCLE, {}, {
@ -212,6 +212,6 @@ void RegionTable_Init_Market() {
LOCATION(RC_MK_BACK_ALLEY_HOUSE_POT_3, logic->CanBreakPots()),
}, {
//Exits
Entrance(RR_MARKET_BACK_ALLEY, []{return true;}),
Entrance(RR_MARKET_BACK_ALLEY, []{return logic->CanOpenOverworldDoor(RG_ALLEY_HOUSE_KEY);}),
});
}

View File

@ -1800,8 +1800,11 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_HF_POND_STORMS_FAIRY] = Location::Fairy(RC_HF_POND_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_HYRULE_FIELD, TWO_ACTOR_PARAMS(0x1000, 5012), "Pond Song of Storms Fairy", "Pond Song of Storms Fairy", RHT_HF_POND_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_POND_STORMS_FAIRY));
locationTable[RC_HF_FENCE_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_HF_FENCE_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -308), "Inside Fence Storms Fairy", "Inside Fence Storms Fairy", RHT_HF_FENCE_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_HF_FENCE_GROTTO_STORMS_FAIRY));
locationTable[RC_DMT_FLAG_SUN_FAIRY] = Location::Fairy(RC_DMT_FLAG_SUN_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_DEATH_MOUNTAIN_TRAIL, TWO_ACTOR_PARAMS(0x1000, 464), "Flag Sun's Song Fairy", "Flag Sun's Song Fairy", RHT_DMT_FLAG_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_FLAG_SUN_FAIRY));
locationTable[RC_DMT_COW_GROTTO_STORMS_FAIRY] = Location::Fairy(RC_DMT_COW_GROTTO_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, -311), "Cow Grotto Song of Storms Fairy", "Cow Grotto Song of Storms Fairy", RHT_DMT_COW_GROTTO_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_DMT_COW_GROTTO_STORMS_FAIRY));
locationTable[RC_LW_SHORTCUT_STORMS_FAIRY] = Location::Fairy(RC_LW_SHORTCUT_STORMS_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_LOST_WOODS, TWO_ACTOR_PARAMS(0x1000, -795), "Shortcuts Song of Storms Fairy", "Shortcuts Song of Storms Fairy", RHT_LW_SHORTCUT_STORMS_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_SHORTCUT_STORMS_FAIRY));
locationTable[RC_GF_KITCHEN_SUN_FAIRY] = Location::Fairy(RC_GF_KITCHEN_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GERUDO_FORTRESS, SCENE_THIEVES_HIDEOUT, TWO_ACTOR_PARAMS(0x1000, -621), "Kitchen Sun's Song Fairy", "Kitchen Sun's Song Fairy", RHT_GF_KITCHEN_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GF_KITCHEN_SUN_FAIRY));
locationTable[RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY] = Location::Fairy(RC_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x1000, 741), "Scrub Grotto Sun's Song Fairy", "Scrub Grotto Sun's Song Fairy", RHT_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_LW_DEKU_SCRUB_GROTTO_SUN_FAIRY));
locationTable[RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY] = Location::Fairy(RC_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, RCQUEST_BOTH, RCAREA_GRAVEYARD, SCENE_ROYAL_FAMILYS_TOMB, TWO_ACTOR_PARAMS(0x1000, 1476), "Composer's Grave Sun's Song Fairy", "Composer's Grave Sun's Song Fairy", RHT_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_GRAVEYARD_ROYAL_FAMILYS_TOMB_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -1896), "After Boulder Room Sun's Song Fairy", "After Boulder Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_BOULDER_ROOM_SUN_FAIRY));
locationTable[RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY] = Location::Fairy(RC_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, RCQUEST_VANILLA,RCAREA_SPIRIT_TEMPLE, SCENE_SPIRIT_TEMPLE, TWO_ACTOR_PARAMS(0x1000, -220), "Four Armos Room Sun's Song Fairy", "Four Armos Room Sun's Song Fairy", RHT_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY, SpoilerCollectionCheck::RandomizerInf(RAND_INF_SPIRIT_TEMPLE_ARMOS_ROOM_SUN_FAIRY));

View File

@ -140,6 +140,31 @@ namespace Rando {
case RG_TWINROVA_SOUL:
case RG_GANON_SOUL:
case RG_SKELETON_KEY:
// Overworld Keys
case RG_GUARD_HOUSE_KEY:
case RG_MARKET_BAZAAR_KEY:
case RG_MARKET_POTION_SHOP_KEY:
case RG_MASK_SHOP_KEY:
case RG_MARKET_SHOOTING_GALLERY_KEY:
case RG_BOMBCHU_BOWLING_KEY:
case RG_TREASURE_CHEST_GAME_BUILDING_KEY:
case RG_BOMBCHU_SHOP_KEY:
case RG_RICHARDS_HOUSE_KEY:
case RG_ALLEY_HOUSE_KEY:
case RG_KAK_BAZAAR_KEY:
case RG_KAK_POTION_SHOP_KEY:
case RG_BOSS_HOUSE_KEY:
case RG_GRANNYS_POTION_SHOP_KEY:
case RG_SKULLTULA_HOUSE_KEY:
case RG_IMPAS_HOUSE_KEY:
case RG_WINDMILL_KEY:
case RG_KAK_SHOOTING_GALLERY_KEY:
case RG_DAMPES_HUT_KEY:
case RG_TALONS_HOUSE_KEY:
case RG_STABLES_KEY:
case RG_BACK_TOWER_KEY:
case RG_HYLIA_LAB_KEY:
case RG_FISHING_HOLE_KEY:
return CheckRandoInf(RandoGetToRandInf.at(itemName));
// Boss Keys
case RG_EPONA:
@ -382,6 +407,18 @@ namespace Rando {
}
}
bool Logic::CanOpenOverworldDoor(RandomizerGet key) {
if (!ctx->GetOption(RSK_LOCK_OVERWORLD_DOORS)) {
return true;
}
if (HasItem(RG_SKELETON_KEY)) {
return true;
}
return HasItem(key);
}
uint8_t GetDifficultyValueFromString(Rando::Option& glitchOption) {
return 0;
}
@ -1038,7 +1075,7 @@ namespace Rando {
10 for OHKO.
This is the number of shifts to apply, not a real multiplier
*/
uint8_t Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).GetContextOptionIndex() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).GetContextOptionIndex() : 10;
uint8_t Multiplier = (ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Get() < 6) ? ctx->GetOption(RSK_DAMAGE_MULTIPLIER).Get() : 10;
//(Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) is quarter hearts after DD
//>> Multiplier halves on normal and does nothing on half, meaning we're working with half hearts on normal damage
return ((Hearts() << (2 + HasItem(RG_DOUBLE_DEFENSE))) >> Multiplier) +
@ -1168,21 +1205,21 @@ namespace Rando {
bool Logic::CanBuildRainbowBridge(){
return ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_ALWAYS_OPEN) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_VANILLA) && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION) && CanUse(RG_LIGHT_ARROWS)) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).GetContextOptionIndex()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).GetContextOptionIndex()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).GetContextOptionIndex()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).GetContextOptionIndex()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && GetGSCount() >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).GetContextOptionIndex()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_STONES) && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_STONE_COUNT).Get()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_MEDALLIONS) && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_MEDALLION_COUNT).Get()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEON_REWARDS) && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_REWARD_COUNT).Get()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_DUNGEONS) && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_BRIDGE_OPTIONS).Is(RO_BRIDGE_GREG_REWARD)) >= ctx->GetOption(RSK_RAINBOW_BRIDGE_DUNGEON_COUNT).Get()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_TOKENS) && GetGSCount() >= ctx->GetOption(RSK_RAINBOW_BRIDGE_TOKEN_COUNT).Get()) ||
(ctx->GetOption(RSK_RAINBOW_BRIDGE).Is(RO_BRIDGE_GREG) && HasItem(RG_GREG_RUPEE));
}
bool Logic::CanTriggerLACS(){
return (ctx->GetSettings()->LACSCondition() == RO_LACS_VANILLA && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION)) ||
(ctx->GetSettings()->LACSCondition() == RO_LACS_STONES && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_STONE_COUNT).GetContextOptionIndex()) ||
(ctx->GetSettings()->LACSCondition() == RO_LACS_MEDALLIONS && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_MEDALLION_COUNT).GetContextOptionIndex()) ||
(ctx->GetSettings()->LACSCondition() == RO_LACS_REWARDS && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_REWARD_COUNT).GetContextOptionIndex()) ||
(ctx->GetSettings()->LACSCondition() == RO_LACS_DUNGEONS && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_DUNGEON_COUNT).GetContextOptionIndex()) ||
(ctx->GetSettings()->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).GetContextOptionIndex());
return (ctx->LACSCondition() == RO_LACS_VANILLA && HasItem(RG_SHADOW_MEDALLION) && HasItem(RG_SPIRIT_MEDALLION)) ||
(ctx->LACSCondition() == RO_LACS_STONES && StoneCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_STONE_COUNT).Get()) ||
(ctx->LACSCondition() == RO_LACS_MEDALLIONS && MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_MEDALLION_COUNT).Get()) ||
(ctx->LACSCondition() == RO_LACS_REWARDS && StoneCount() + MedallionCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_REWARD_COUNT).Get()) ||
(ctx->LACSCondition() == RO_LACS_DUNGEONS && DungeonCount() + (HasItem(RG_GREG_RUPEE) && ctx->GetOption(RSK_LACS_OPTIONS).Is(RO_LACS_GREG_REWARD)) >= ctx->GetOption(RSK_LACS_DUNGEON_COUNT).Get()) ||
(ctx->LACSCondition() == RO_LACS_TOKENS && GetGSCount() >= ctx->GetOption(RSK_LACS_TOKEN_COUNT).Get());
}
bool Logic::SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount) {
@ -1293,7 +1330,31 @@ namespace Rando {
{ RG_OCARINA_C_RIGHT_BUTTON, RAND_INF_HAS_OCARINA_C_RIGHT },
{ RG_SKELETON_KEY, RAND_INF_HAS_SKELETON_KEY },
{ RG_GREG_RUPEE, RAND_INF_GREG_FOUND },
{ RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND }
{ RG_FISHING_POLE, RAND_INF_FISHING_POLE_FOUND },
{ RG_GUARD_HOUSE_KEY, RAND_INF_GUARD_HOUSE_KEY_OBTAINED },
{ RG_MARKET_BAZAAR_KEY, RAND_INF_MARKET_BAZAAR_KEY_OBTAINED },
{ RG_MARKET_POTION_SHOP_KEY, RAND_INF_MARKET_POTION_SHOP_KEY_OBTAINED },
{ RG_MASK_SHOP_KEY, RAND_INF_MASK_SHOP_KEY_OBTAINED },
{ RG_MARKET_SHOOTING_GALLERY_KEY, RAND_INF_MARKET_SHOOTING_GALLERY_KEY_OBTAINED },
{ RG_BOMBCHU_BOWLING_KEY, RAND_INF_BOMBCHU_BOWLING_KEY_OBTAINED },
{ RG_TREASURE_CHEST_GAME_BUILDING_KEY, RAND_INF_TREASURE_CHEST_GAME_BUILDING_KEY_OBTAINED },
{ RG_BOMBCHU_SHOP_KEY, RAND_INF_BOMBCHU_SHOP_KEY_OBTAINED },
{ RG_RICHARDS_HOUSE_KEY, RAND_INF_RICHARDS_HOUSE_KEY_OBTAINED },
{ RG_ALLEY_HOUSE_KEY, RAND_INF_ALLEY_HOUSE_KEY_OBTAINED },
{ RG_KAK_BAZAAR_KEY, RAND_INF_KAK_BAZAAR_KEY_OBTAINED },
{ RG_KAK_POTION_SHOP_KEY, RAND_INF_KAK_POTION_SHOP_KEY_OBTAINED },
{ RG_BOSS_HOUSE_KEY, RAND_INF_BOSS_HOUSE_KEY_OBTAINED },
{ RG_GRANNYS_POTION_SHOP_KEY, RAND_INF_GRANNYS_POTION_SHOP_KEY_OBTAINED },
{ RG_SKULLTULA_HOUSE_KEY, RAND_INF_SKULLTULA_HOUSE_KEY_OBTAINED },
{ RG_IMPAS_HOUSE_KEY, RAND_INF_IMPAS_HOUSE_KEY_OBTAINED },
{ RG_WINDMILL_KEY, RAND_INF_WINDMILL_KEY_OBTAINED },
{ RG_KAK_SHOOTING_GALLERY_KEY, RAND_INF_KAK_SHOOTING_GALLERY_KEY_OBTAINED },
{ RG_DAMPES_HUT_KEY, RAND_INF_DAMPES_HUT_KEY_OBTAINED },
{ RG_TALONS_HOUSE_KEY, RAND_INF_TALONS_HOUSE_KEY_OBTAINED },
{ RG_STABLES_KEY, RAND_INF_STABLES_KEY_OBTAINED },
{ RG_BACK_TOWER_KEY, RAND_INF_BACK_TOWER_KEY_OBTAINED },
{ RG_HYLIA_LAB_KEY, RAND_INF_HYLIA_LAB_KEY_OBTAINED },
{ RG_FISHING_HOLE_KEY, RAND_INF_FISHING_HOLE_KEY_OBTAINED },
};
std::map<uint32_t, uint32_t> Logic::RandoGetToDungeonScene = {
@ -1370,6 +1431,18 @@ namespace Rando {
{ RG_GERUDO_MEMBERSHIP_CARD, QUEST_GERUDO_CARD },
};
std::map<uint32_t, uint32_t> BottleRandomizerGetToItemID = {
{ RG_BOTTLE_WITH_RED_POTION, ITEM_POTION_RED },
{ RG_BOTTLE_WITH_GREEN_POTION, ITEM_POTION_GREEN },
{ RG_BOTTLE_WITH_BLUE_POTION, ITEM_POTION_BLUE },
{ RG_BOTTLE_WITH_FAIRY, ITEM_FAIRY },
{ RG_BOTTLE_WITH_FISH, ITEM_FISH },
{ RG_BOTTLE_WITH_BLUE_FIRE, ITEM_BLUE_FIRE },
{ RG_BOTTLE_WITH_BUGS, ITEM_BUG },
{ RG_BOTTLE_WITH_POE, ITEM_POE },
{ RG_BOTTLE_WITH_BIG_POE, ITEM_BIG_POE },
};
uint32_t HookshotLookup[3] = { ITEM_NONE, ITEM_HOOKSHOT, ITEM_LONGSHOT };
uint32_t OcarinaLookup[3] = { ITEM_NONE, ITEM_OCARINA_FAIRY, ITEM_OCARINA_TIME };
@ -1614,7 +1687,11 @@ namespace Rando {
}
slot++;
}
mSaveContext->inventory.items[slot] = item.GetGIEntry()->itemId;
uint16_t itemId = item.GetGIEntry()->itemId;
if (BottleRandomizerGetToItemID.contains(randoGet)) {
itemId = BottleRandomizerGetToItemID[randoGet];
}
mSaveContext->inventory.items[slot] = itemId;
} break;
case RG_RUTOS_LETTER:
SetEventChkInf(EVENTCHKINF_OBTAINED_RUTOS_LETTER, state);
@ -1635,6 +1712,30 @@ namespace Rando {
case RG_OCARINA_C_RIGHT_BUTTON:
case RG_GREG_RUPEE:
case RG_FISHING_POLE:
case RG_GUARD_HOUSE_KEY:
case RG_MARKET_BAZAAR_KEY:
case RG_MARKET_POTION_SHOP_KEY:
case RG_MASK_SHOP_KEY:
case RG_MARKET_SHOOTING_GALLERY_KEY:
case RG_BOMBCHU_BOWLING_KEY:
case RG_TREASURE_CHEST_GAME_BUILDING_KEY:
case RG_BOMBCHU_SHOP_KEY:
case RG_RICHARDS_HOUSE_KEY:
case RG_ALLEY_HOUSE_KEY:
case RG_KAK_BAZAAR_KEY:
case RG_KAK_POTION_SHOP_KEY:
case RG_BOSS_HOUSE_KEY:
case RG_GRANNYS_POTION_SHOP_KEY:
case RG_SKULLTULA_HOUSE_KEY:
case RG_IMPAS_HOUSE_KEY:
case RG_WINDMILL_KEY:
case RG_KAK_SHOOTING_GALLERY_KEY:
case RG_DAMPES_HUT_KEY:
case RG_TALONS_HOUSE_KEY:
case RG_STABLES_KEY:
case RG_BACK_TOWER_KEY:
case RG_HYLIA_LAB_KEY:
case RG_FISHING_HOLE_KEY:
SetRandoInf(RandoGetToRandInf.at(randoGet), state);
break;
case RG_TRIFORCE_PIECE:
@ -2116,7 +2217,7 @@ namespace Rando {
//Bottle Count
Bottles = 0;
NumBottles = 0;
CanEmptyBigPoes = true;
CanEmptyBigPoes = false;
//Drops and Bottle Contents Access
NutPot = false;
@ -2153,7 +2254,7 @@ namespace Rando {
//CanPlantBean = false;
BigPoeKill = false;
BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).GetContextOptionIndex() + 1;
BaseHearts = ctx->GetOption(RSK_STARTING_HEARTS).Get() + 1;
//Bridge Requirements
@ -2162,7 +2263,7 @@ namespace Rando {
//Other
AtDay = false;
AtNight = false;
GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).GetContextOptionIndex();
GetSaveContext()->linkAge = !ctx->GetOption(RSK_SELECTED_STARTING_AGE).Get();
//Events
ShowedMidoSwordAndShield = false;

View File

@ -186,6 +186,7 @@ class Logic {
bool HasProjectile(HasProjectileAge age);
bool HasItem(RandomizerGet itemName);
bool HasBossSoul(RandomizerGet itemName);
bool CanOpenOverworldDoor(RandomizerGet itemName);
bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmount);
bool SmallKeys(RandomizerRegion dungeon, uint8_t requiredAmountGlitchless, uint8_t requiredAmountGlitched);
bool CanDoGlitch(GlitchType glitch);

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