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,49 +1741,42 @@ 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);
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());
auto buttonColor = ImGui::GetStyleColorVec4(ImGuiCol_Button);
auto buttonHoveredColor = ImGui::GetStyleColorVec4(ImGuiCol_ButtonHovered);
GetButtonColorsForDeviceType(Ship::PhysicalDeviceType::SDLGamepad, buttonColor, buttonHoveredColor);
ImGui::PushStyleColor(ImGuiCol_Button, buttonColor);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, buttonHoveredColor);
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("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();
}
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::Button("Cancel")) {
shouldClose = true;
ImGui::CloseCurrentPopup();
}
if (ImGui::Button("Set defaults")) {
Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->ClearAllMappingsForDevice(lusIndex);
Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings(
lusIndex);
shouldClose = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
if (ImGui::Button("Set defaults")) {
Ship::Context::GetInstance()
->GetControlDeck()
->GetControllerByPort(portIndex)
->ClearAllMappingsForDeviceType(Ship::PhysicalDeviceType::SDLGamepad);
Ship::Context::GetInstance()->GetControlDeck()->GetControllerByPort(portIndex)->AddDefaultMappings(
Ship::PhysicalDeviceType::SDLGamepad);
shouldClose = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
if (ImGui::Button("Cancel") || shouldClose) {

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"));
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 };
// 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"));
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 };
// 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"));
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 };
// 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"));
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 };
// 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"));
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 };
// 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.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.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};
// 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"));
// 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.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};
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};
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};
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};
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};
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};
//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};
}
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};
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};
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.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};
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};
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,9 +180,7 @@ 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]));
}
gSPInvalidateTexCache(play->state.gfxCtx->polyOpa.p++, reinterpret_cast<uintptr_t>(&font->charTexBuf[i]));
}
R_TEXT_CHAR_SCALE = 75;
R_TEXT_LINE_SPACING = 12;

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,22 +2,23 @@
#include "global.h"
#include "z64.h"
#include "game-interactor/GameInteractor.h"
#include "soh/OTRGlobals.h"
static const int songMessageMap[] = {
TEXT_WARP_MINUET_OF_FOREST,
TEXT_WARP_BOLERO_OF_FIRE,
TEXT_WARP_SERENADE_OF_WATER,
TEXT_WARP_REQUIEM_OF_SPIRIT,
TEXT_WARP_NOCTURNE_OF_SHADOW,
TEXT_WARP_PRELUDE_OF_LIGHT
TEXT_WARP_MINUET_OF_FOREST,
TEXT_WARP_BOLERO_OF_FIRE,
TEXT_WARP_SERENADE_OF_WATER,
TEXT_WARP_REQUIEM_OF_SPIRIT,
TEXT_WARP_NOCTURNE_OF_SHADOW,
TEXT_WARP_PRELUDE_OF_LIGHT
};
static const int ocarinaSongMap[] = {
OCARINA_SONG_MINUET,
OCARINA_SONG_BOLERO,
OCARINA_SONG_SERENADE,
OCARINA_SONG_REQUIEM,
OCARINA_SONG_NOCTURNE,
OCARINA_SONG_MINUET,
OCARINA_SONG_BOLERO,
OCARINA_SONG_SERENADE,
OCARINA_SONG_REQUIEM,
OCARINA_SONG_NOCTURNE,
OCARINA_SONG_PRELUDE
};
@ -31,12 +32,12 @@ static const int entranceIndexMap[] = {
};
static const int songAudioMap[] = {
NA_BGM_OCA_MINUET,
NA_BGM_OCA_BOLERO,
NA_BGM_OCA_SERENADE,
NA_BGM_OCA_REQUIEM,
NA_BGM_OCA_NOCTURNE,
NA_BGM_OCA_LIGHT
NA_BGM_OCA_MINUET,
NA_BGM_OCA_BOLERO,
NA_BGM_OCA_SERENADE,
NA_BGM_OCA_REQUIEM,
NA_BGM_OCA_NOCTURNE,
NA_BGM_OCA_LIGHT
};
static bool isWarpActive = false;
@ -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) {

File diff suppressed because it is too large Load Diff

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

@ -1935,6 +1935,24 @@ void StaticData::HintTable_Init_Exclude_Overworld() {
hintTextTable[RHT_DMC_UPPER_GROTTO_GOSSIP_STONE_FAIRY_BIG] = HintText(CustomMessage("They say that #playing a stormy tune for an odd stone within the side of a crater# reveals #[[1]]#.",
/*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

@ -20,15 +20,11 @@ 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)) {
return condition_function();
}
return false;
auto ctx = Rando::Context::GetInstance();
if (ctx->GetOption(RSK_LOGIC_RULES).Is(RO_LOGIC_GLITCHLESS)) {
return condition_function();
}
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;}),
});
@ -63,8 +63,9 @@ void RegionTable_Init_Graveyard() {
areaTable[RR_GRAVEYARD_COMPOSERS_GRAVE] = Region("Graveyard Composers Grave", "Graveyard Composers Grave", {}, NO_DAY_NIGHT_CYCLE, {}, {
//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_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

@ -105,9 +105,10 @@ void RegionTable_Init_LostWoods() {
areaTable[RR_LW_SCRUBS_GROTTO] = Region("LW Scrubs Grotto", "LW Scrubs Grotto", {}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
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_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