Merge branch 'develop' into accessible-checks

This commit is contained in:
Anthony Stewart 2025-03-19 21:53:54 -05:00
commit 56995398a1
84 changed files with 2339 additions and 2920 deletions

View file

@ -1,11 +1,10 @@
<DisplayList Version="0">
<ClearGeometryMode G_LIGHTING="1" />
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_cull" VertexBufferIndex="0" VertexOffset="0" Count="8"/>
<SetGeometryMode G_LIGHTING="1" />
<CullDisplayList Start="0" End="7"/>
<CallDisplayList Path="objects/object_keyring/mat_gKeyringIconGerudoFortressDL_f3dlite_IconMetal_GerudoFortress"/>
<CallDisplayList Path="objects/object_keyring/gKeyringIconGerudoFortressDL_tri_0"/>
<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

@ -1,213 +1,110 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="4" V02="5"/>
<Triangle1 V00="6" V01="2" V02="4"/>
<Triangle1 V00="7" V01="8" V02="9"/>
<Triangle1 V00="10" V01="9" V02="11"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="12" V01="14" V02="15"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="16" 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="6" V01="3" 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="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="12" V02="13"/>
<Triangle1 V00="14" V01="13" V02="15"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="32" 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="4" V01="5" V02="3"/>
<Triangle1 V00="5" V01="6" V02="3"/>
<Triangle1 V00="5" V01="7" V02="6"/>
<Triangle1 V00="7" V01="8" V02="6"/>
<Triangle1 V00="7" V01="9" V02="8"/>
<Triangle1 V00="9" V01="10" V02="8"/>
<Triangle1 V00="9" V01="11" V02="10"/>
<Triangle1 V00="11" V01="12" V02="10"/>
<Triangle1 V00="11" V01="13" V02="12"/>
<Triangle1 V00="10" V01="12" V02="14"/>
<Triangle1 V00="10" V01="14" V02="15"/>
<Triangle1 V00="8" V01="10" V02="15"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="48" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="0" V02="2"/>
<Triangle1 V00="3" V01="2" V02="4"/>
<Triangle1 V00="5" V01="3" V02="4"/>
<Triangle1 V00="5" V01="4" V02="6"/>
<Triangle1 V00="7" V01="8" V02="9"/>
<Triangle1 V00="7" V01="9" V02="10"/>
<Triangle1 V00="10" V01="9" V02="11"/>
<Triangle1 V00="10" V01="11" V02="12"/>
<Triangle1 V00="12" V01="11" V02="13"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="15" V01="12" V02="14"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="64" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="0" V02="2"/>
<Triangle1 V00="3" V01="2" V02="4"/>
<Triangle1 V00="5" V01="0" V02="3"/>
<Triangle1 V00="5" V01="6" V02="0"/>
<Triangle1 V00="7" V01="6" V02="5"/>
<Triangle1 V00="7" V01="8" V02="6"/>
<Triangle1 V00="8" V01="9" V02="6"/>
<Triangle1 V00="8" V01="10" V02="9"/>
<Triangle1 V00="6" V01="9" V02="11"/>
<Triangle1 V00="6" V01="11" V02="0"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="15" V01="12" V02="14"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="80" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="4" V02="5"/>
<Triangle1 V00="3" V01="6" V02="4"/>
<Triangle1 V00="3" V01="7" V02="6"/>
<Triangle1 V00="3" V01="8" V02="7"/>
<Triangle1 V00="9" V01="6" V02="7"/>
<Triangle1 V00="6" V01="9" V02="10"/>
<Triangle1 V00="10" V01="9" V02="11"/>
<Triangle1 V00="12" V01="11" V02="9"/>
<Triangle1 V00="9" V01="13" V02="12"/>
<Triangle1 V00="13" V01="9" V02="7"/>
<Triangle1 V00="13" V01="7" V02="14"/>
<Triangle1 V00="15" V01="12" V02="13"/>
<Triangle1 V00="12" V01="15" V02="11"/>
<Triangle1 V00="10" V01="11" V02="15"/>
<Triangle1 V00="6" V01="10" V02="15"/>
<Triangle1 V00="15" V01="4" V02="6"/>
<Triangle1 V00="13" V01="4" V02="15"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="96" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="1" V02="0"/>
<Triangle1 V00="3" V01="0" V02="4"/>
<Triangle1 V00="5" V01="6" V02="7"/>
<Triangle1 V00="5" V01="7" V02="8"/>
<Triangle1 V00="9" V01="8" V02="7"/>
<Triangle1 V00="9" V01="7" V02="10"/>
<Triangle1 V00="11" V01="8" V02="9"/>
<Triangle1 V00="11" V01="5" V02="8"/>
<Triangle1 V00="11" V01="12" V02="5"/>
<Triangle1 V00="13" V01="12" V02="11"/>
<Triangle1 V00="13" V01="11" V02="14"/>
<Triangle1 V00="15" V01="14" V02="11"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="112" 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="7"/>
<Triangle1 V00="8" V01="7" V02="6"/>
<Triangle1 V00="8" V01="6" V02="9"/>
<Triangle1 V00="10" V01="8" V02="9"/>
<Triangle1 V00="10" V01="9" V02="11"/>
<Triangle1 V00="12" V01="8" V02="10"/>
<Triangle1 V00="13" V01="8" V02="12"/>
<Triangle1 V00="13" V01="7" V02="8"/>
<Triangle1 V00="13" V01="5" V02="7"/>
<Triangle1 V00="13" V01="14" V02="5"/>
<Triangle1 V00="14" V01="2" V02="5"/>
<Triangle1 V00="14" V01="0" V02="2"/>
<Triangle1 V00="12" V01="10" V02="15"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="128" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="2" V02="1"/>
<Triangle1 V00="4" V01="5" V02="6"/>
<Triangle1 V00="7" V01="5" V02="4"/>
<Triangle1 V00="8" V01="5" V02="7"/>
<Triangle1 V00="8" V01="7" V02="9"/>
<Triangle1 V00="7" V01="10" V02="9"/>
<Triangle1 V00="10" V01="6" V02="9"/>
<Triangle1 V00="8" V01="9" V02="11"/>
<Triangle1 V00="5" V01="8" V02="11"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="14" V01="13" V02="15"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="144" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="4" V01="5" V02="6"/>
<Triangle1 V00="5" V01="4" V02="7"/>
<Triangle1 V00="5" V01="7" V02="8"/>
<Triangle1 V00="8" V01="7" V02="9"/>
<Triangle1 V00="9" V01="7" V02="10"/>
<Triangle1 V00="9" V01="10" V02="11"/>
<Triangle1 V00="9" V01="12" V02="8"/>
<Triangle1 V00="9" V01="13" V02="12"/>
<Triangle1 V00="13" V01="9" V02="14"/>
<Triangle1 V00="15" V01="14" V02="9"/>
<Triangle1 V00="5" V01="13" V02="14"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="160" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="2" V02="1"/>
<Triangle1 V00="2" V01="3" V02="4"/>
<Triangle1 V00="5" V01="4" V02="3"/>
<Triangle1 V00="5" V01="0" V02="4"/>
<Triangle1 V00="2" V01="4" V02="0"/>
<Triangle1 V00="1" V01="6" V02="7"/>
<Triangle1 V00="8" V01="7" V02="6"/>
<Triangle1 V00="1" V01="7" V02="9"/>
<Triangle1 V00="10" V01="11" V02="12"/>
<Triangle1 V00="10" V01="12" V02="13"/>
<Triangle1 V00="14" V01="13" V02="12"/>
<Triangle1 V00="14" V01="12" V02="15"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="176" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="0" V01="4" V02="3"/>
<Triangle1 V00="5" V01="4" V02="0"/>
<Triangle1 V00="5" V01="0" V02="6"/>
<Triangle1 V00="7" V01="6" V02="0"/>
<Triangle1 V00="7" V01="0" V02="8"/>
<Triangle1 V00="0" V01="2" V02="8"/>
<Triangle1 V00="8" V01="2" V02="9"/>
<Triangle1 V00="8" V01="9" V02="10"/>
<Triangle1 V00="10" V01="9" V02="11"/>
<Triangle1 V00="10" V01="11" V02="12"/>
<Triangle1 V00="13" V01="12" V02="11"/>
<Triangle1 V00="13" V01="11" V02="14"/>
<Triangle1 V00="4" V01="13" V02="14"/>
<Triangle1 V00="4" V01="14" V02="3"/>
<Triangle1 V00="15" V01="13" V02="4"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="192" Count="14"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="0" V01="4" V02="3"/>
<Triangle1 V00="0" V01="5" V02="4"/>
<Triangle1 V00="5" V01="6" V02="4"/>
<Triangle1 V00="5" V01="7" V02="6"/>
<Triangle1 V00="2" V01="8" V02="9"/>
<Triangle1 V00="10" V01="11" V02="12"/>
<Triangle1 V00="13" V01="12" V02="11"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="206" Count="15"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="0" V02="2"/>
<Triangle1 V00="3" V01="4" V02="0"/>
<Triangle1 V00="3" V01="5" V02="4"/>
<Triangle1 V00="3" V01="6" V02="5"/>
<Triangle1 V00="5" V01="6" V02="1"/>
<Triangle1 V00="4" V01="5" V02="7"/>
<Triangle1 V00="4" V01="7" V02="0"/>
<Triangle1 V00="8" V01="9" V02="10"/>
<Triangle1 V00="8" V01="10" V02="11"/>
<Triangle1 V00="12" V01="10" V02="13"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="221" Count="10"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="1" V01="0" V02="3"/>
<Triangle1 V00="1" V01="3" V02="4"/>
<Triangle1 V00="4" V01="2" V02="1"/>
<Triangle1 V00="5" V01="6" V02="7"/>
<Triangle1 V00="6" V01="5" V02="8"/>
<Triangle1 V00="6" V01="8" V02="9"/>
<Triangle1 V00="9" V01="7" V02="6"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="4" V12="5" Flag1="0"/>
<Triangles2 V00="6" V01="2" V02="4" Flag0="0" V10="7" V11="8" V12="9" Flag1="0"/>
<Triangles2 V00="10" V01="9" V02="11" Flag0="0" V10="12" V11="13" V12="14" Flag1="0"/>
<Triangles2 V00="12" V01="14" V02="15" Flag0="0" V10="15" V11="14" V12="16" Flag1="0"/>
<Triangles2 V00="15" V01="16" V02="17" Flag0="0" V10="17" V11="16" V12="18" Flag1="0"/>
<Triangles2 V00="17" V01="18" V02="19" Flag0="0" V10="20" V11="17" V12="19" Flag1="0"/>
<Triangles2 V00="20" V01="19" V02="21" Flag0="0" V10="22" V11="20" V12="21" Flag1="0"/>
<Triangles2 V00="22" V01="21" V02="23" Flag0="0" V10="24" V11="22" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="23" V02="25" Flag0="0" V10="26" V11="24" V12="25" Flag1="0"/>
<Triangles2 V00="26" V01="25" V02="27" Flag0="0" V10="28" V11="26" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="27" V02="29" Flag0="0" V10="30" V11="26" V12="28" Flag1="0"/>
<Triangle1 V00="30" V01="31" V02="26"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="32" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="3" V12="1" Flag1="0"/>
<Triangles2 V00="3" V01="4" V02="1" Flag0="0" V10="3" V11="5" V12="4" Flag1="0"/>
<Triangles2 V00="5" V01="6" V02="4" Flag0="0" V10="5" V11="7" V12="6" Flag1="0"/>
<Triangles2 V00="7" V01="8" V02="6" Flag0="0" V10="7" V11="9" V12="8" Flag1="0"/>
<Triangles2 V00="9" V01="10" V02="8" Flag0="0" V10="9" V11="11" V12="10" Flag1="0"/>
<Triangles2 V00="8" V01="10" V02="12" Flag0="0" V10="8" V11="12" V12="13" Flag1="0"/>
<Triangles2 V00="6" V01="8" V02="13" Flag0="0" V10="6" V11="13" V12="14" Flag1="0"/>
<Triangles2 V00="4" V01="6" V02="14" Flag0="0" V10="4" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="1" V01="4" V02="15" Flag0="0" V10="1" V11="15" V12="16" Flag1="0"/>
<Triangles2 V00="17" V01="18" V02="19" Flag0="0" V10="17" V11="19" V12="20" Flag1="0"/>
<Triangles2 V00="20" V01="19" V02="21" Flag0="0" V10="20" V11="21" V12="22" Flag1="0"/>
<Triangles2 V00="22" V01="21" V02="23" Flag0="0" V10="22" V11="23" V12="24" Flag1="0"/>
<Triangles2 V00="25" V01="22" V02="24" Flag0="0" V10="25" V11="24" V12="26" Flag1="0"/>
<Triangles2 V00="27" V01="25" V02="26" Flag0="0" V10="27" V11="26" V12="28" Flag1="0"/>
<Triangles2 V00="29" V01="25" V02="27" Flag0="0" V10="29" V11="30" V12="25" Flag1="0"/>
<Triangle1 V00="31" V01="30" V02="29"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="64" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="1" V11="3" V12="2" Flag1="0"/>
<Triangles2 V00="1" V01="4" V02="3" Flag0="0" V10="2" V11="3" V12="5" Flag1="0"/>
<Triangles2 V00="2" V01="5" V02="6" Flag0="0" V10="7" V11="8" V12="9" Flag1="0"/>
<Triangles2 V00="10" V01="7" V02="9" Flag0="0" V10="10" V11="11" V12="7" Flag1="0"/>
<Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="12" V11="15" V12="13" Flag1="0"/>
<Triangles2 V00="12" V01="16" V02="15" Flag0="0" V10="12" V11="17" V12="16" Flag1="0"/>
<Triangles2 V00="18" V01="15" V02="16" Flag0="0" V10="15" V11="18" V12="19" Flag1="0"/>
<Triangles2 V00="19" V01="18" V02="20" Flag0="0" V10="21" V11="20" V12="18" Flag1="0"/>
<Triangles2 V00="18" V01="22" V02="21" Flag0="0" V10="22" V11="18" V12="16" Flag1="0"/>
<Triangles2 V00="22" V01="16" V02="23" Flag0="0" V10="24" V11="21" V12="22" Flag1="0"/>
<Triangles2 V00="21" V01="24" V02="20" Flag0="0" V10="19" V11="20" V12="24" Flag1="0"/>
<Triangles2 V00="15" V01="19" V02="24" Flag0="0" V10="24" V11="13" V12="15" Flag1="0"/>
<Triangles2 V00="22" V01="13" V02="24" Flag0="0" V10="22" V11="25" V12="13" Flag1="0"/>
<Triangles2 V00="26" V01="25" V02="22" Flag0="0" V10="26" V11="22" V12="27" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="30" Flag0="0" V10="28" V11="30" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="96" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="1" V02="0" Flag0="0" V10="4" V11="5" V12="1" Flag1="0"/>
<Triangles2 V00="4" V01="6" V02="5" Flag0="0" V10="7" V11="6" V12="4" Flag1="0"/>
<Triangles2 V00="7" V01="4" V02="8" Flag0="0" V10="9" V11="8" V12="4" Flag1="0"/>
<Triangles2 V00="9" V01="4" V02="10" Flag0="0" V10="4" V11="0" V12="10" Flag1="0"/>
<Triangles2 V00="10" V01="0" V02="11" Flag0="0" V10="10" V11="11" V12="12" Flag1="0"/>
<Triangles2 V00="12" V01="11" V02="13" Flag0="0" V10="12" V11="13" V12="14" Flag1="0"/>
<Triangles2 V00="15" V01="14" V02="13" Flag0="0" V10="15" V11="13" V12="16" Flag1="0"/>
<Triangles2 V00="6" V01="15" V02="16" Flag0="0" V10="6" V11="16" V12="5" Flag1="0"/>
<Triangles2 V00="17" V01="15" V02="6" Flag0="0" V10="18" V11="15" V12="17" Flag1="0"/>
<Triangles2 V00="18" V01="14" V02="15" Flag0="0" V10="18" V11="12" V12="14" Flag1="0"/>
<Triangles2 V00="18" V01="19" V02="12" Flag0="0" V10="19" V11="10" V12="12" Flag1="0"/>
<Triangles2 V00="19" V01="9" V02="10" Flag0="0" V10="17" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="23" V11="22" V12="21" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="27" V11="25" V12="24" Flag1="0"/>
<Triangles2 V00="28" V01="25" V02="27" Flag0="0" V10="28" V11="27" V12="29" Flag1="0"/>
<Triangles2 V00="27" V01="30" V02="29" Flag0="0" V10="30" V11="26" V12="29" Flag1="0"/>
<Triangles2 V00="28" V01="29" V02="31" Flag0="0" V10="25" V11="28" V12="31" Flag1="0"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="128" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="2" V11="1" V12="3" Flag1="0"/>
<Triangles2 V00="4" V01="5" V02="6" Flag0="0" V10="4" V11="6" V12="7" Flag1="0"/>
<Triangles2 V00="8" V01="9" V02="10" Flag0="0" V10="9" V11="8" V12="11" Flag1="0"/>
<Triangles2 V00="9" V01="11" V02="12" Flag0="0" V10="12" V11="11" V12="13" Flag1="0"/>
<Triangles2 V00="13" V01="11" V02="14" Flag0="0" V10="13" V11="14" V12="15" Flag1="0"/>
<Triangles2 V00="13" V01="16" V02="12" Flag0="0" V10="13" V11="17" V12="16" Flag1="0"/>
<Triangles2 V00="17" V01="13" V02="18" Flag0="0" V10="19" V11="18" V12="13" Flag1="0"/>
<Triangles2 V00="9" V01="17" V02="18" Flag0="0" V10="17" V11="9" V12="20" Flag1="0"/>
<Triangles2 V00="12" V01="20" V02="9" Flag0="0" V10="20" V11="12" V12="21" Flag1="0"/>
<Triangles2 V00="16" V01="21" V02="12" Flag0="0" V10="16" V11="17" V12="21" Flag1="0"/>
<Triangles2 V00="20" V01="21" V02="17" Flag0="0" V10="9" V11="18" V12="22" Flag1="0"/>
<Triangles2 V00="23" V01="22" V02="18" Flag0="0" V10="9" V11="22" V12="24" Flag1="0"/>
<Triangles2 V00="25" V01="26" V02="27" Flag0="0" V10="25" V11="27" V12="28" Flag1="0"/>
<Triangles2 V00="29" V01="28" V02="27" Flag0="0" V10="29" V11="27" V12="30" Flag1="0"/>
<Triangles2 V00="31" V01="28" V02="29" Flag0="0" V10="31" V11="25" V12="28" Flag1="0"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="160" Count="32"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="1" V12="0" Flag1="0"/>
<Triangles2 V00="3" V01="0" V02="4" Flag0="0" V10="5" V11="4" V12="0" Flag1="0"/>
<Triangles2 V00="5" V01="0" V02="6" Flag0="0" V10="0" V11="7" V12="6" Flag1="0"/>
<Triangles2 V00="6" V01="7" V02="8" Flag0="0" V10="6" V11="8" V12="9" Flag1="0"/>
<Triangles2 V00="9" V01="8" V02="10" Flag0="0" V10="9" V11="10" V12="11" Flag1="0"/>
<Triangles2 V00="12" V01="11" V02="10" Flag0="0" V10="12" V11="10" V12="13" Flag1="0"/>
<Triangles2 V00="1" V01="12" V02="13" Flag0="0" V10="1" V11="13" V12="2" Flag1="0"/>
<Triangles2 V00="14" V01="12" V02="1" Flag0="0" V10="15" V11="12" V12="14" Flag1="0"/>
<Triangles2 V00="15" V01="11" V02="12" Flag0="0" V10="15" V11="9" V12="11" Flag1="0"/>
<Triangles2 V00="15" V01="16" V02="9" Flag0="0" V10="16" V11="6" V12="9" Flag1="0"/>
<Triangles2 V00="16" V01="5" V02="6" Flag0="0" V10="14" V11="1" V12="3" Flag1="0"/>
<Triangles2 V00="17" V01="18" V02="19" Flag0="0" V10="20" V11="19" V12="18" Flag1="0"/>
<Triangles2 V00="21" V01="22" V02="23" Flag0="0" V10="24" V11="21" V12="23" Flag1="0"/>
<Triangles2 V00="24" V01="25" V02="21" Flag0="0" V10="24" V11="26" V12="25" Flag1="0"/>
<Triangles2 V00="24" V01="27" V02="26" Flag0="0" V10="26" V11="27" V12="22" Flag1="0"/>
<Triangles2 V00="25" V01="26" V02="28" Flag0="0" V10="25" V11="28" V12="21" Flag1="0"/>
<Triangle1 V00="29" V01="30" V02="31"/>
<LoadVertices Path="objects/object_keyring/gKeyringIconGerudoFortressDL_vtx_0" VertexBufferIndex="0" VertexOffset="192" Count="16"/>
<Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="1" V12="4" Flag1="0"/>
<Triangles2 V00="3" V01="4" V02="5" Flag0="0" V10="6" V11="7" V12="8" Flag1="0"/>
<Triangles2 V00="7" V01="6" V02="9" Flag0="0" V10="7" V11="9" V12="10" Flag1="0"/>
<Triangles2 V00="10" V01="8" V02="7" Flag0="0" V10="11" V11="12" V12="13" Flag1="0"/>
<Triangles2 V00="12" V01="11" V02="14" Flag0="0" V10="12" V11="14" V12="15" Flag1="0"/>
<Triangle1 V00="15" V01="13" V02="12"/>
<EndDisplayList/>
</DisplayList>

View file

@ -1,233 +1,210 @@
<Vertex Version="0">
<Vtx X="-21" Y="-11" Z="13" S="-175" T="-1122" R="234" G="7" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-175" T="-1122" R="233" G="7" B="125" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-161" T="-1207" R="227" G="123" B="244" A="254"/>
<Vtx X="-29" Y="-12" Z="12" S="-70" T="-1316" R="235" G="11" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-184" T="-1036" R="234" G="7" B="125" A="254"/>
<Vtx X="-28" Y="-14" Z="11" S="-5" T="-1276" R="2" G="129" B="8" A="254"/>
<Vtx X="-22" Y="-15" Z="12" S="-52" T="-1033" R="246" G="130" B="6" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-215" T="-994" R="234" G="7" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-215" T="-994" R="21" G="245" B="131" A="254"/>
<Vtx X="-15" Y="-16" Z="13" S="-70" T="-1316" R="22" G="249" B="131" A="254"/>
<Vtx X="-29" Y="-12" Z="12" S="-70" T="-1316" R="234" G="11" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-184" T="-1036" R="233" G="7" B="125" A="254"/>
<Vtx X="-28" Y="-14" Z="11" S="-5" T="-1276" R="2" G="129" B="9" A="254"/>
<Vtx X="-22" Y="-15" Z="12" S="-52" T="-1033" R="245" G="130" B="7" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-215" T="-994" R="233" G="7" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-215" T="-994" R="21" G="244" B="131" A="254"/>
<Vtx X="-15" Y="-16" Z="13" S="-70" T="-1316" R="23" G="248" B="131" A="254"/>
<Vtx X="-16" Y="-18" Z="13" S="-5" T="-1276" R="191" G="147" B="254" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-184" T="-1036" R="21" G="245" B="131" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-184" T="-1036" R="21" G="244" B="131" A="254"/>
<Vtx X="-22" Y="-15" Z="12" S="-52" T="-1033" R="202" G="141" B="0" A="254"/>
<Vtx X="-14" Y="16" Z="15" S="-666" T="-580" R="231" G="237" B="123" A="255"/>
<Vtx X="-14" Y="16" Z="15" S="-666" T="-580" R="231" G="236" B="123" A="255"/>
<Vtx X="-36" Y="10" Z="12" S="-580" T="-580" R="2" G="244" B="126" A="255"/>
<Vtx X="-35" Y="10" Z="6" S="-580" T="-751" R="38" G="228" B="138" A="255"/>
<Vtx X="-13" Y="16" Z="8" S="-666" T="-751" R="10" G="220" B="135" A="255"/>
<Vtx X="-13" Y="16" Z="8" S="-666" T="-751" R="10" G="220" B="135" A="255"/>
<Vtx X="-35" Y="10" Z="6" S="-580" T="-751" R="38" G="228" B="138" A="255"/>
<Vtx X="-13" Y="16" Z="8" S="-666" T="-751" R="11" G="220" B="135" A="255"/>
<Vtx X="-39" Y="14" Z="8" S="-580" T="-922" R="167" G="89" B="237" A="255"/>
<Vtx X="-12" Y="21" Z="11" S="-666" T="-922" R="33" G="123" B="253" A="255"/>
<Vtx X="-36" Y="10" Z="12" S="-580" T="-1092" R="2" G="244" B="126" A="255"/>
<Vtx X="-14" Y="16" Z="15" S="-666" T="-1092" R="231" G="237" B="123" A="255"/>
<Vtx X="8" Y="1" Z="16" S="-751" T="-922" R="122" G="33" B="15" A="255"/>
<Vtx X="2" Y="0" Z="18" S="-751" T="-1092" R="211" G="0" B="119" A="255"/>
<Vtx X="-14" Y="16" Z="15" S="-666" T="-1092" R="231" G="236" B="123" A="255"/>
<Vtx X="8" Y="1" Z="16" S="-751" T="-922" R="121" G="34" B="16" A="255"/>
<Vtx X="2" Y="0" Z="18" S="-751" T="-1092" R="210" G="1" B="119" A="255"/>
<Vtx X="0" Y="-26" Z="16" S="-836" T="-922" R="89" G="167" B="19" A="255"/>
<Vtx X="-4" Y="-22" Z="19" S="-836" T="-1092" R="218" G="28" B="118" A="255"/>
<Vtx X="-27" Y="-34" Z="13" S="-922" T="-922" R="223" G="133" B="3" A="255"/>
<Vtx X="-26" Y="-29" Z="16" S="-922" T="-1092" R="246" G="36" B="121" A="255"/>
<Vtx X="-47" Y="-14" Z="9" S="-1007" T="-922" R="134" G="223" B="241" A="255"/>
<Vtx X="-42" Y="-12" Z="12" S="-1007" T="-1092" R="9" G="15" B="126" A="255"/>
<Vtx X="-26" Y="-29" Z="16" S="-922" T="-1092" R="245" G="36" B="121" A="255"/>
<Vtx X="-47" Y="-14" Z="9" S="-1007" T="-922" R="135" G="222" B="240" A="255"/>
<Vtx X="-42" Y="-12" Z="12" S="-1007" T="-1092" R="10" G="16" B="126" A="255"/>
<Vtx X="-39" Y="14" Z="8" S="-1092" T="-922" R="167" G="89" B="237" A="255"/>
<Vtx X="-36" Y="10" Z="12" S="-1092" T="-1092" R="2" G="244" B="126" A="255"/>
<Vtx X="-35" Y="10" Z="6" S="-1092" T="-751" R="38" G="228" B="138" A="255"/>
<Vtx X="-47" Y="-14" Z="9" S="-1007" T="-922" R="134" G="223" B="241" A="255"/>
<Vtx X="-39" Y="14" Z="8" S="-1092" T="-922" R="167" G="89" B="237" A="255"/>
<Vtx X="-41" Y="-13" Z="6" S="-1007" T="-751" R="45" G="0" B="137" A="255"/>
<Vtx X="-41" Y="-13" Z="6" S="-1007" T="-751" R="46" G="255" B="137" A="255"/>
<Vtx X="-36" Y="10" Z="12" S="-1092" T="-580" R="2" G="244" B="126" A="255"/>
<Vtx X="-42" Y="-12" Z="12" S="-1007" T="-580" R="9" G="15" B="126" A="255"/>
<Vtx X="-25" Y="-29" Z="10" S="-922" T="-751" R="25" G="19" B="133" A="255"/>
<Vtx X="-26" Y="-29" Z="16" S="-922" T="-580" R="246" G="36" B="121" A="255"/>
<Vtx X="-41" Y="-13" Z="6" S="-1007" T="-751" R="46" G="255" B="137" A="255"/>
<Vtx X="-35" Y="10" Z="6" S="-1092" T="-751" R="38" G="228" B="138" A="255"/>
<Vtx X="-42" Y="-12" Z="12" S="-1007" T="-580" R="10" G="16" B="126" A="255"/>
<Vtx X="-25" Y="-29" Z="10" S="-922" T="-751" R="25" G="20" B="133" A="255"/>
<Vtx X="-26" Y="-29" Z="16" S="-922" T="-580" R="245" G="36" B="121" A="255"/>
<Vtx X="-3" Y="-23" Z="13" S="-836" T="-751" R="254" G="12" B="130" A="255"/>
<Vtx X="-4" Y="-22" Z="19" S="-836" T="-580" R="218" G="28" B="118" A="255"/>
<Vtx X="3" Y="0" Z="12" S="-751" T="-751" R="247" G="241" B="130" A="255"/>
<Vtx X="2" Y="0" Z="18" S="-751" T="-580" R="211" G="0" B="119" A="255"/>
<Vtx X="-13" Y="16" Z="8" S="-666" T="-751" R="10" G="220" B="135" A="255"/>
<Vtx X="-14" Y="16" Z="15" S="-666" T="-580" R="231" G="237" B="123" A="255"/>
<Vtx X="3" Y="0" Z="12" S="-751" T="-751" R="246" G="240" B="130" A="255"/>
<Vtx X="2" Y="0" Z="18" S="-751" T="-580" R="210" G="1" B="119" A="255"/>
<Vtx X="-13" Y="16" Z="8" S="-666" T="-751" R="11" G="220" B="135" A="255"/>
<Vtx X="-14" Y="16" Z="15" S="-666" T="-580" R="231" G="236" B="123" A="255"/>
<Vtx X="-12" Y="21" Z="11" S="-666" T="-922" R="33" G="123" B="253" A="255"/>
<Vtx X="8" Y="1" Z="16" S="-751" T="-922" R="122" G="33" B="15" A="255"/>
<Vtx X="-3" Y="-23" Z="13" S="-836" T="-751" R="254" G="12" B="130" A="255"/>
<Vtx X="8" Y="1" Z="16" S="-751" T="-922" R="122" G="33" B="15" A="255"/>
<Vtx X="8" Y="1" Z="16" S="-751" T="-922" R="121" G="34" B="16" A="255"/>
<Vtx X="0" Y="-26" Z="16" S="-836" T="-922" R="89" G="167" B="19" A="255"/>
<Vtx X="-25" Y="-29" Z="10" S="-922" T="-751" R="25" G="19" B="133" A="255"/>
<Vtx X="-27" Y="-34" Z="13" S="-922" T="-922" R="223" G="133" B="3" A="255"/>
<Vtx X="-41" Y="-13" Z="6" S="-1007" T="-751" R="45" G="0" B="137" A="255"/>
<Vtx X="-47" Y="-14" Z="9" S="-1007" T="-922" R="134" G="223" B="241" A="255"/>
<Vtx X="-47" Y="-14" Z="9" S="-1007" T="-922" R="135" G="222" B="240" A="255"/>
<Vtx X="-15" Y="27" Z="12" S="-708" T="-580" R="242" G="1" B="126" A="255"/>
<Vtx X="-18" Y="17" Z="12" S="-580" T="-580" R="255" G="3" B="127" A="255"/>
<Vtx X="-17" Y="17" Z="9" S="-580" T="-751" R="35" G="244" B="134" A="255"/>
<Vtx X="-15" Y="27" Z="9" S="-708" T="-751" R="22" G="241" B="132" A="255"/>
<Vtx X="-18" Y="17" Z="12" S="-580" T="-580" R="255" G="4" B="127" A="255"/>
<Vtx X="-17" Y="17" Z="9" S="-580" T="-751" R="35" G="243" B="135" A="255"/>
<Vtx X="-15" Y="27" Z="9" S="-708" T="-751" R="23" G="241" B="132" A="255"/>
<Vtx X="-20" Y="16" Z="11" S="-580" T="-922" R="135" G="32" B="236" A="255"/>
<Vtx X="-16" Y="29" Z="10" S="-708" T="-922" R="194" G="110" B="240" A="255"/>
<Vtx X="-18" Y="17" Z="12" S="-580" T="-1092" R="255" G="3" B="127" A="255"/>
<Vtx X="-16" Y="29" Z="10" S="-708" T="-922" R="194" G="109" B="240" A="255"/>
<Vtx X="-18" Y="17" Z="12" S="-580" T="-1092" R="255" G="4" B="127" A="255"/>
<Vtx X="-15" Y="27" Z="12" S="-708" T="-1092" R="242" G="1" B="126" A="255"/>
<Vtx X="-5" Y="26" Z="12" S="-836" T="-922" R="109" G="64" B="11" A="255"/>
<Vtx X="-5" Y="26" Z="12" S="-836" T="-922" R="109" G="64" B="11" A="255"/>
<Vtx X="-15" Y="27" Z="12" S="-708" T="-1092" R="242" G="1" B="126" A="255"/>
<Vtx X="-7" Y="25" Z="13" S="-836" T="-1092" R="231" G="4" B="124" A="255"/>
<Vtx X="-5" Y="26" Z="12" S="-836" T="-922" R="109" G="64" B="12" A="255"/>
<Vtx X="-7" Y="25" Z="13" S="-836" T="-1092" R="230" G="4" B="124" A="255"/>
<Vtx X="-8" Y="13" Z="12" S="-964" T="-922" R="121" G="224" B="20" A="255"/>
<Vtx X="-10" Y="15" Z="14" S="-964" T="-1092" R="221" G="12" B="122" A="255"/>
<Vtx X="-9" Y="15" Z="11" S="-964" T="-751" R="1" G="253" B="129" A="255"/>
<Vtx X="-7" Y="25" Z="10" S="-836" T="-751" R="11" G="244" B="130" A="255"/>
<Vtx X="-10" Y="15" Z="14" S="-964" T="-580" R="221" G="12" B="122" A="255"/>
<Vtx X="-7" Y="25" Z="13" S="-836" T="-580" R="231" G="4" B="124" A="255"/>
<Vtx X="-15" Y="27" Z="9" S="-708" T="-751" R="22" G="241" B="132" A="255"/>
<Vtx X="-10" Y="15" Z="14" S="-964" T="-1092" R="221" G="13" B="121" A="255"/>
<Vtx X="-9" Y="15" Z="11" S="-964" T="-751" R="1" G="252" B="129" A="255"/>
<Vtx X="-7" Y="25" Z="10" S="-836" T="-751" R="11" G="243" B="130" A="255"/>
<Vtx X="-10" Y="15" Z="14" S="-964" T="-580" R="221" G="13" B="121" A="255"/>
<Vtx X="-10" Y="15" Z="14" S="-964" T="-580" R="221" G="13" B="121" A="255"/>
<Vtx X="-7" Y="25" Z="13" S="-836" T="-580" R="230" G="4" B="124" A="255"/>
<Vtx X="-7" Y="25" Z="10" S="-836" T="-751" R="11" G="243" B="130" A="255"/>
<Vtx X="-15" Y="27" Z="9" S="-708" T="-751" R="23" G="241" B="132" A="255"/>
<Vtx X="-15" Y="27" Z="12" S="-708" T="-580" R="242" G="1" B="126" A="255"/>
<Vtx X="-16" Y="29" Z="10" S="-708" T="-922" R="194" G="110" B="240" A="255"/>
<Vtx X="-29" Y="-11" Z="11" S="-130" T="-1349" R="229" G="124" B="245" A="254"/>
<Vtx X="-29" Y="-12" Z="12" S="-70" T="-1316" R="235" G="11" B="125" A="254"/>
<Vtx X="-16" Y="29" Z="10" S="-708" T="-922" R="194" G="109" B="240" A="255"/>
<Vtx X="-5" Y="26" Z="12" S="-836" T="-922" R="109" G="64" B="12" A="255"/>
<Vtx X="-29" Y="-11" Z="11" S="-130" T="-1349" R="229" G="123" B="244" A="254"/>
<Vtx X="-29" Y="-12" Z="12" S="-70" T="-1316" R="234" G="11" B="125" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-155" T="-1302" R="227" G="123" B="244" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-161" T="-1207" R="14" G="247" B="130" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-161" T="-1207" R="14" G="247" B="130" A="254"/>
<Vtx X="-29" Y="-13" Z="11" S="-70" T="-1316" R="15" G="251" B="130" A="254"/>
<Vtx X="-29" Y="-11" Z="11" S="-130" T="-1349" R="229" G="124" B="245" A="254"/>
<Vtx X="-14" Y="-14" Z="13" S="-159" T="-765" R="46" G="138" B="14" A="254"/>
<Vtx X="-12" Y="-7" Z="14" S="-454" T="-732" R="236" G="12" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-159" T="-765" R="234" G="7" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-161" T="-1207" R="14" G="246" B="130" A="254"/>
<Vtx X="-29" Y="-13" Z="11" S="-70" T="-1316" R="15" G="250" B="130" A="254"/>
<Vtx X="-14" Y="-14" Z="13" S="-159" T="-765" R="46" G="138" B="15" A="254"/>
<Vtx X="-12" Y="-7" Z="14" S="-454" T="-732" R="236" G="13" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-159" T="-765" R="233" G="7" B="125" A="254"/>
<Vtx X="-8" Y="-11" Z="14" S="-349" T="-544" R="88" G="166" B="19" A="254"/>
<Vtx X="-11" Y="-7" Z="13" S="-454" T="-732" R="16" G="253" B="130" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-161" T="-824" R="14" G="247" B="130" A="254"/>
<Vtx X="-8" Y="-2" Z="13" S="-679" T="-646" R="16" G="0" B="130" A="254"/>
<Vtx X="-4" Y="-3" Z="14" S="-681" T="-493" R="124" G="239" B="19" A="254"/>
<Vtx X="-11" Y="-7" Z="13" S="-454" T="-732" R="16" G="252" B="130" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-161" T="-824" R="14" G="246" B="130" A="254"/>
<Vtx X="-8" Y="-2" Z="13" S="-679" T="-646" R="17" G="255" B="130" A="254"/>
<Vtx X="-4" Y="-3" Z="14" S="-681" T="-493" R="124" G="238" B="19" A="254"/>
<Vtx X="-5" Y="7" Z="13" S="-1012" T="-643" R="26" G="124" B="252" A="254"/>
<Vtx X="-10" Y="-1" Z="13" S="-688" T="-724" R="157" G="77" B="237" A="254"/>
<Vtx X="-13" Y="-5" Z="13" S="-510" T="-819" R="182" G="102" B="239" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-215" T="-994" R="14" G="247" B="130" A="254"/>
<Vtx X="-10" Y="-1" Z="13" S="-688" T="-724" R="157" G="77" B="236" A="254"/>
<Vtx X="-13" Y="-5" Z="13" S="-510" T="-819" R="182" G="102" B="238" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-215" T="-994" R="14" G="246" B="130" A="254"/>
<Vtx X="-8" Y="-2" Z="14" S="-679" T="-646" R="236" G="16" B="124" A="254"/>
<Vtx X="-13" Y="-5" Z="13" S="-510" T="-819" R="182" G="102" B="239" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-215" T="-994" R="234" G="7" B="125" A="254"/>
<Vtx X="-12" Y="-7" Z="14" S="-454" T="-732" R="236" G="12" B="125" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-215" T="-994" R="233" G="7" B="125" A="254"/>
<Vtx X="-20" Y="-8" Z="12" S="-310" T="-1033" R="198" G="112" B="240" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-245" T="-1035" R="14" G="247" B="130" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-245" T="-1035" R="14" G="246" B="130" A="254"/>
<Vtx X="-37" Y="-14" Z="10" S="-772" T="-836" R="180" G="206" B="89" A="255"/>
<Vtx X="-37" Y="-14" Z="10" S="-644" T="-836" R="164" G="17" B="86" A="255"/>
<Vtx X="-37" Y="-13" Z="10" S="-644" T="-964" R="142" G="53" B="236" A="255"/>
<Vtx X="-37" Y="-15" Z="10" S="-772" T="-964" R="171" G="161" B="250" A="255"/>
<Vtx X="-37" Y="-15" Z="10" S="-772" T="-836" R="208" G="193" B="156" A="255"/>
<Vtx X="-37" Y="-13" Z="10" S="-644" T="-964" R="143" G="53" B="236" A="255"/>
<Vtx X="-37" Y="-15" Z="10" S="-772" T="-964" R="171" G="162" B="250" A="255"/>
<Vtx X="-37" Y="-15" Z="10" S="-772" T="-836" R="208" G="193" B="157" A="255"/>
<Vtx X="-37" Y="-15" Z="10" S="-772" T="-964" R="171" G="162" B="250" A="255"/>
<Vtx X="-37" Y="-13" Z="10" S="-644" T="-964" R="143" G="53" B="236" A="255"/>
<Vtx X="-37" Y="-14" Z="10" S="-644" T="-836" R="193" G="4" B="146" A="255"/>
<Vtx X="-36" Y="-15" Z="10" S="-772" T="-964" R="0" G="129" B="8" A="255"/>
<Vtx X="-36" Y="-14" Z="11" S="-772" T="-836" R="231" G="206" B="114" A="255"/>
<Vtx X="-37" Y="-14" Z="10" S="-772" T="-836" R="180" G="206" B="89" A="255"/>
<Vtx X="-36" Y="-14" Z="11" S="-772" T="-836" R="230" G="206" B="114" A="255"/>
<Vtx X="-30" Y="-13" Z="12" S="-900" T="-836" R="249" G="213" B="119" A="255"/>
<Vtx X="-30" Y="-14" Z="11" S="-900" T="-964" R="24" G="132" B="11" A="255"/>
<Vtx X="-30" Y="-13" Z="10" S="-900" T="-836" R="26" G="198" B="146" A="255"/>
<Vtx X="-30" Y="-13" Z="10" S="-900" T="-836" R="26" G="198" B="146" A="255"/>
<Vtx X="-36" Y="-15" Z="10" S="-772" T="-964" R="0" G="129" B="8" A="255"/>
<Vtx X="-30" Y="-14" Z="11" S="-900" T="-964" R="24" G="132" B="12" A="255"/>
<Vtx X="-30" Y="-13" Z="10" S="-900" T="-836" R="27" G="198" B="146" A="255"/>
<Vtx X="-36" Y="-15" Z="10" S="-772" T="-836" R="7" G="191" B="147" A="255"/>
<Vtx X="-37" Y="-15" Z="10" S="-772" T="-836" R="208" G="193" B="156" A="255"/>
<Vtx X="-37" Y="-14" Z="10" S="-772" T="-708" R="193" G="4" B="146" A="255"/>
<Vtx X="-36" Y="-13" Z="9" S="-772" T="-708" R="244" G="38" B="135" A="255"/>
<Vtx X="-37" Y="-13" Z="10" S="-772" T="-580" R="142" G="53" B="236" A="255"/>
<Vtx X="-36" Y="-13" Z="10" S="-772" T="-580" R="208" G="117" B="242" A="255"/>
<Vtx X="-36" Y="-13" Z="9" S="-772" T="-708" R="244" G="39" B="136" A="255"/>
<Vtx X="-37" Y="-13" Z="10" S="-772" T="-580" R="143" G="53" B="236" A="255"/>
<Vtx X="-36" Y="-13" Z="10" S="-772" T="-580" R="208" G="117" B="241" A="255"/>
<Vtx X="-36" Y="-13" Z="11" S="-772" T="-708" R="211" G="54" B="106" A="255"/>
<Vtx X="-37" Y="-14" Z="10" S="-772" T="-708" R="164" G="17" B="86" A="255"/>
<Vtx X="-36" Y="-14" Z="11" S="-772" T="-836" R="231" G="206" B="114" A="255"/>
<Vtx X="-37" Y="-14" Z="10" S="-772" T="-836" R="180" G="206" B="89" A="255"/>
<Vtx X="-30" Y="-12" Z="12" S="-900" T="-708" R="229" G="61" B="108" A="255"/>
<Vtx X="-30" Y="-11" Z="11" S="-900" T="-580" R="232" G="124" B="245" A="255"/>
<Vtx X="-30" Y="-12" Z="10" S="-900" T="-708" R="6" G="45" B="137" A="255"/>
<Vtx X="-30" Y="-13" Z="12" S="-900" T="-836" R="249" G="213" B="119" A="255"/>
<Vtx X="-31" Y="-13" Z="12" S="21" T="-445" R="206" G="35" B="111" A="254"/>
<Vtx X="-32" Y="-20" Z="11" S="-730" T="-1234" R="23" G="132" B="11" A="254"/>
<Vtx X="-30" Y="-11" Z="11" S="-900" T="-580" R="232" G="124" B="244" A="255"/>
<Vtx X="-30" Y="-12" Z="10" S="-900" T="-708" R="6" G="46" B="138" A="255"/>
<Vtx X="-31" Y="-13" Z="12" S="21" T="-445" R="206" G="36" B="111" A="254"/>
<Vtx X="-32" Y="-20" Z="11" S="-730" T="-1234" R="23" G="132" B="12" A="254"/>
<Vtx X="-28" Y="-14" Z="11" S="-843" T="-464" R="113" G="201" B="20" A="254"/>
<Vtx X="-31" Y="-13" Z="9" S="21" T="-445" R="241" G="20" B="131" A="254"/>
<Vtx X="-31" Y="-13" Z="9" S="21" T="-445" R="240" G="20" B="132" A="254"/>
<Vtx X="-29" Y="-12" Z="12" S="-926" T="-640" R="35" G="21" B="120" A="254"/>
<Vtx X="-31" Y="-13" Z="12" S="-621" T="-564" R="206" G="35" B="111" A="254"/>
<Vtx X="-31" Y="-13" Z="12" S="-621" T="-564" R="206" G="36" B="111" A="254"/>
<Vtx X="-28" Y="-14" Z="11" S="-986" T="-592" R="113" G="201" B="20" A="254"/>
<Vtx X="-29" Y="-11" Z="11" S="-912" T="-702" R="97" G="82" B="8" A="254"/>
<Vtx X="-32" Y="-8" Z="10" S="-768" T="-807" R="217" G="120" B="243" A="254"/>
<Vtx X="-31" Y="-13" Z="9" S="-621" T="-564" R="241" G="20" B="131" A="254"/>
<Vtx X="-29" Y="-11" Z="11" S="-912" T="-702" R="97" G="82" B="9" A="254"/>
<Vtx X="-32" Y="-8" Z="10" S="-768" T="-807" R="217" G="120" B="242" A="254"/>
<Vtx X="-31" Y="-13" Z="9" S="-621" T="-564" R="240" G="20" B="132" A="254"/>
<Vtx X="-29" Y="-13" Z="11" S="-926" T="-640" R="68" G="6" B="149" A="254"/>
<Vtx X="-31" Y="-13" Z="11" S="-621" T="-564" R="139" G="46" B="236" A="254"/>
<Vtx X="-29" Y="-13" Z="11" S="-70" T="-1316" R="15" G="251" B="130" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-184" T="-1036" R="14" G="247" B="130" A="254"/>
<Vtx X="-28" Y="-14" Z="11" S="-5" T="-1276" R="2" G="129" B="8" A="254"/>
<Vtx X="-22" Y="-15" Z="12" S="-52" T="-1033" R="246" G="130" B="6" A="254"/>
<Vtx X="-14" Y="-14" Z="13" S="-155" T="-1302" R="87" G="92" B="6" A="254"/>
<Vtx X="-13" Y="-15" Z="14" S="-130" T="-1349" R="87" G="92" B="6" A="254"/>
<Vtx X="-15" Y="-16" Z="13" S="-70" T="-1316" R="22" G="249" B="131" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-158" T="-1244" R="21" G="245" B="131" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-215" T="-994" R="21" G="245" B="131" A="254"/>
<Vtx X="-24" Y="-2" Z="11" S="-510" T="-819" R="115" G="52" B="13" A="254"/>
<Vtx X="-29" Y="-13" Z="11" S="-70" T="-1316" R="15" G="250" B="130" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-184" T="-1036" R="14" G="246" B="130" A="254"/>
<Vtx X="-28" Y="-14" Z="11" S="-5" T="-1276" R="2" G="129" B="9" A="254"/>
<Vtx X="-22" Y="-15" Z="12" S="-52" T="-1033" R="245" G="130" B="7" A="254"/>
<Vtx X="-14" Y="-14" Z="13" S="-155" T="-1302" R="87" G="92" B="7" A="254"/>
<Vtx X="-13" Y="-15" Z="14" S="-130" T="-1349" R="87" G="92" B="7" A="254"/>
<Vtx X="-15" Y="-16" Z="13" S="-70" T="-1316" R="23" G="248" B="131" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-158" T="-1244" R="21" G="244" B="131" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-215" T="-994" R="21" G="244" B="131" A="254"/>
<Vtx X="-24" Y="-2" Z="11" S="-510" T="-819" R="115" G="52" B="14" A="254"/>
<Vtx X="-20" Y="-8" Z="12" S="-310" T="-1033" R="106" G="69" B="11" A="254"/>
<Vtx X="-27" Y="-3" Z="10" S="-454" T="-732" R="22" G="251" B="131" A="254"/>
<Vtx X="-27" Y="3" Z="10" S="-679" T="-646" R="24" G="254" B="131" A="254"/>
<Vtx X="-32" Y="-4" Z="10" S="-349" T="-544" R="134" G="223" B="240" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-161" T="-824" R="21" G="245" B="131" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-159" T="-765" R="157" G="176" B="247" A="254"/>
<Vtx X="-27" Y="-3" Z="10" S="-454" T="-732" R="22" G="250" B="131" A="254"/>
<Vtx X="-27" Y="3" Z="10" S="-679" T="-646" R="24" G="253" B="131" A="254"/>
<Vtx X="-32" Y="-4" Z="10" S="-349" T="-544" R="135" G="223" B="240" A="254"/>
<Vtx X="-21" Y="-11" Z="12" S="-161" T="-824" R="21" G="244" B="131" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-159" T="-765" R="158" G="176" B="247" A="254"/>
<Vtx X="-31" Y="4" Z="10" S="-681" T="-493" R="139" G="46" B="236" A="254"/>
<Vtx X="-28" Y="3" Z="11" S="-679" T="-646" R="243" G="14" B="126" A="254"/>
<Vtx X="-27" Y="-3" Z="12" S="-454" T="-732" R="242" G="11" B="126" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-161" T="-824" R="157" G="176" B="247" A="254"/>
<Vtx X="-28" Y="3" Z="11" S="-679" T="-646" R="243" G="14" B="126" A="254"/>
<Vtx X="-24" Y="-2" Z="11" S="-510" T="-819" R="115" G="52" B="13" A="254"/>
<Vtx X="-25" Y="3" Z="11" S="-688" T="-724" R="125" G="17" B="17" A="254"/>
<Vtx X="-27" Y="3" Z="10" S="-679" T="-646" R="24" G="254" B="131" A="254"/>
<Vtx X="-27" Y="-3" Z="12" S="-454" T="-732" R="241" G="11" B="126" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-161" T="-824" R="158" G="176" B="247" A="254"/>
<Vtx X="-25" Y="3" Z="11" S="-688" T="-724" R="125" G="18" B="17" A="254"/>
<Vtx X="-25" Y="12" Z="10" S="-1012" T="-643" R="40" G="121" B="254" A="254"/>
<Vtx X="-31" Y="4" Z="10" S="-681" T="-493" R="139" G="46" B="236" A="254"/>
<Vtx X="-27" Y="-3" Z="12" S="-454" T="-732" R="242" G="11" B="126" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-215" T="-994" R="241" G="5" B="126" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-164" T="-862" R="157" G="176" B="247" A="254"/>
<Vtx X="-28" Y="-10" Z="11" S="-164" T="-862" R="158" G="176" B="247" A="254"/>
<Vtx X="-20" Y="-8" Z="12" S="-310" T="-1033" R="106" G="69" B="11" A="254"/>
<Vtx X="-9" Y="-22" Z="14" S="-772" T="-836" R="39" G="170" B="171" A="255"/>
<Vtx X="-8" Y="-21" Z="14" S="-644" T="-836" R="87" G="221" B="171" A="255"/>
<Vtx X="-7" Y="-21" Z="15" S="-644" T="-964" R="125" G="247" B="19" A="255"/>
<Vtx X="-7" Y="-21" Z="15" S="-644" T="-964" R="125" G="246" B="19" A="255"/>
<Vtx X="-9" Y="-22" Z="15" S="-772" T="-964" R="26" G="132" B="12" A="255"/>
<Vtx X="-9" Y="-22" Z="15" S="-772" T="-836" R="11" G="183" B="103" A="255"/>
<Vtx X="-8" Y="-21" Z="15" S="-644" T="-836" R="58" G="234" B="111" A="255"/>
<Vtx X="-8" Y="-21" Z="15" S="-644" T="-836" R="58" G="234" B="110" A="255"/>
<Vtx X="-10" Y="-22" Z="15" S="-772" T="-964" R="193" G="146" B="254" A="255"/>
<Vtx X="-10" Y="-22" Z="15" S="-772" T="-964" R="193" G="146" B="254" A="255"/>
<Vtx X="-9" Y="-22" Z="15" S="-772" T="-964" R="26" G="132" B="12" A="255"/>
<Vtx X="-9" Y="-22" Z="15" S="-772" T="-836" R="11" G="183" B="103" A="255"/>
<Vtx X="-9" Y="-22" Z="14" S="-772" T="-836" R="39" G="170" B="171" A="255"/>
<Vtx X="-9" Y="-22" Z="14" S="-772" T="-836" R="252" G="194" B="145" A="255"/>
<Vtx X="-14" Y="-17" Z="13" S="-900" T="-836" R="240" G="210" B="139" A="255"/>
<Vtx X="-14" Y="-18" Z="14" S="-900" T="-964" R="173" G="160" B="251" A="255"/>
<Vtx X="-14" Y="-17" Z="14" S="-900" T="-836" R="206" G="225" B="113" A="255"/>
<Vtx X="-9" Y="-22" Z="14" S="-772" T="-836" R="39" G="170" B="171" A="255"/>
<Vtx X="-14" Y="-17" Z="13" S="-900" T="-836" R="239" G="209" B="139" A="255"/>
<Vtx X="-14" Y="-18" Z="14" S="-900" T="-964" R="173" G="160" B="250" A="255"/>
<Vtx X="-14" Y="-17" Z="14" S="-900" T="-836" R="205" G="225" B="112" A="255"/>
<Vtx X="-10" Y="-21" Z="15" S="-772" T="-836" R="219" G="209" B="112" A="255"/>
<Vtx X="-8" Y="-21" Z="15" S="-772" T="-708" R="58" G="234" B="111" A="255"/>
<Vtx X="-9" Y="-20" Z="15" S="-772" T="-708" R="31" G="33" B="119" A="255"/>
<Vtx X="-7" Y="-21" Z="15" S="-772" T="-580" R="125" G="247" B="19" A="255"/>
<Vtx X="-8" Y="-20" Z="15" S="-772" T="-580" R="101" G="77" B="9" A="255"/>
<Vtx X="-9" Y="-22" Z="15" S="-772" T="-836" R="11" G="183" B="103" A="255"/>
<Vtx X="-8" Y="-21" Z="15" S="-772" T="-708" R="58" G="234" B="110" A="255"/>
<Vtx X="-9" Y="-20" Z="15" S="-772" T="-708" R="32" G="33" B="118" A="255"/>
<Vtx X="-7" Y="-21" Z="15" S="-772" T="-580" R="125" G="246" B="19" A="255"/>
<Vtx X="-8" Y="-20" Z="15" S="-772" T="-580" R="100" G="77" B="10" A="255"/>
<Vtx X="-8" Y="-20" Z="14" S="-772" T="-708" R="65" G="18" B="148" A="255"/>
<Vtx X="-8" Y="-21" Z="14" S="-772" T="-708" R="87" G="221" B="171" A="255"/>
<Vtx X="-13" Y="-16" Z="13" S="-900" T="-708" R="52" G="33" B="145" A="255"/>
<Vtx X="-13" Y="-16" Z="14" S="-900" T="-580" R="83" G="96" B="5" A="255"/>
<Vtx X="-8" Y="-20" Z="14" S="-772" T="-708" R="65" G="18" B="148" A="255"/>
<Vtx X="-13" Y="-16" Z="13" S="-900" T="-708" R="52" G="33" B="145" A="255"/>
<Vtx X="-8" Y="-20" Z="15" S="-772" T="-580" R="101" G="77" B="9" A="255"/>
<Vtx X="-9" Y="-20" Z="15" S="-772" T="-708" R="31" G="33" B="119" A="255"/>
<Vtx X="-13" Y="-16" Z="14" S="-900" T="-708" R="18" G="48" B="116" A="255"/>
<Vtx X="-10" Y="-21" Z="15" S="-772" T="-836" R="219" G="209" B="112" A="255"/>
<Vtx X="-14" Y="-17" Z="14" S="-900" T="-836" R="206" G="225" B="113" A="255"/>
<Vtx X="-9" Y="-22" Z="14" S="-772" T="-836" R="252" G="194" B="145" A="255"/>
<Vtx X="-14" Y="-17" Z="13" S="-900" T="-836" R="240" G="210" B="139" A="255"/>
<Vtx X="-13" Y="-16" Z="14" S="-900" T="-580" R="83" G="96" B="6" A="255"/>
<Vtx X="-13" Y="-16" Z="14" S="-900" T="-708" R="19" G="49" B="116" A="255"/>
<Vtx X="-13" Y="-18" Z="12" S="21" T="-445" R="60" G="0" B="144" A="254"/>
<Vtx X="-16" Y="-24" Z="14" S="-730" T="-1234" R="173" G="160" B="251" A="254"/>
<Vtx X="-16" Y="-24" Z="14" S="-730" T="-1234" R="173" G="160" B="250" A="254"/>
<Vtx X="-16" Y="-18" Z="13" S="-843" T="-464" R="131" G="8" B="237" A="254"/>
<Vtx X="-13" Y="-18" Z="15" S="21" T="-445" R="25" G="15" B="124" A="254"/>
<Vtx X="-13" Y="-18" Z="15" S="21" T="-445" R="25" G="16" B="123" A="254"/>
<Vtx X="-13" Y="-18" Z="12" S="-621" T="-564" R="60" G="0" B="144" A="254"/>
<Vtx X="-16" Y="-18" Z="13" S="-986" T="-592" R="131" G="8" B="237" A="254"/>
<Vtx X="-15" Y="-16" Z="13" S="-926" T="-640" R="235" G="30" B="134" A="254"/>
<Vtx X="-13" Y="-15" Z="14" S="-912" T="-702" R="213" G="119" B="242" A="254"/>
<Vtx X="-10" Y="-13" Z="14" S="-768" T="-807" R="94" G="85" B="8" A="254"/>
<Vtx X="-13" Y="-18" Z="15" S="-621" T="-564" R="25" G="15" B="124" A="254"/>
<Vtx X="-13" Y="-18" Z="15" S="-621" T="-564" R="25" G="16" B="123" A="254"/>
<Vtx X="-15" Y="-16" Z="14" S="-926" T="-640" R="201" G="45" B="105" A="254"/>
<Vtx X="-13" Y="-18" Z="14" S="-621" T="-564" R="124" G="239" B="19" A="254"/>
<Vtx X="-14" Y="-14" Z="13" S="-158" T="-1244" R="87" G="92" B="6" A="254"/>
<Vtx X="-14" Y="-14" Z="13" S="-158" T="-1244" R="87" G="92" B="7" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-161" T="-1207" R="241" G="5" B="126" A="254"/>
<Vtx X="-15" Y="-16" Z="14" S="-70" T="-1316" R="242" G="9" B="126" A="254"/>
<Vtx X="-13" Y="-15" Z="14" S="-130" T="-1349" R="87" G="92" B="6" A="254"/>
<Vtx X="-14" Y="-14" Z="13" S="-158" T="-1244" R="87" G="92" B="7" A="254"/>
<Vtx X="-15" Y="-16" Z="14" S="-70" T="-1316" R="242" G="9" B="126" A="254"/>
<Vtx X="-13" Y="-15" Z="14" S="-130" T="-1349" R="87" G="92" B="7" A="254"/>
<Vtx X="-16" Y="-18" Z="13" S="-5" T="-1276" R="191" G="147" B="254" A="254"/>
<Vtx X="-21" Y="-11" Z="13" S="-184" T="-1036" R="241" G="5" B="126" A="254"/>
<Vtx X="-22" Y="-15" Z="12" S="-52" T="-1033" R="202" G="141" B="0" A="254"/>
<Vtx X="-31" Y="-13" Z="12" S="-1985" T="-486" R="206" G="35" B="111" A="254"/>
<Vtx X="-31" Y="-13" Z="12" S="-1985" T="-486" R="206" G="36" B="111" A="254"/>
<Vtx X="-37" Y="-18" Z="10" S="20" T="-600" R="136" G="218" B="241" A="254"/>
<Vtx X="-32" Y="-20" Z="11" S="-430" T="-1143" R="23" G="132" B="11" A="254"/>
<Vtx X="-32" Y="-20" Z="11" S="-430" T="-1143" R="23" G="132" B="12" A="254"/>
<Vtx X="-31" Y="-13" Z="11" S="-1985" T="-486" R="139" G="46" B="236" A="254"/>
<Vtx X="-31" Y="-13" Z="9" S="-1985" T="-486" R="241" G="20" B="131" A="254"/>
<Vtx X="-31" Y="-13" Z="9" S="-1985" T="-486" R="240" G="20" B="132" A="254"/>
<Vtx X="-13" Y="-18" Z="12" S="-1985" T="-486" R="60" G="0" B="144" A="254"/>
<Vtx X="-10" Y="-24" Z="15" S="20" T="-600" R="86" G="164" B="18" A="254"/>
<Vtx X="-16" Y="-24" Z="14" S="-430" T="-1143" R="173" G="160" B="251" A="254"/>
<Vtx X="-10" Y="-24" Z="15" S="20" T="-600" R="85" G="164" B="19" A="254"/>
<Vtx X="-16" Y="-24" Z="14" S="-430" T="-1143" R="173" G="160" B="250" A="254"/>
<Vtx X="-13" Y="-18" Z="14" S="-1985" T="-486" R="124" G="239" B="19" A="254"/>
<Vtx X="-13" Y="-18" Z="15" S="-1985" T="-486" R="25" G="15" B="124" A="254"/>
<Vtx X="-13" Y="-18" Z="15" S="-1985" T="-486" R="25" G="16" B="123" A="254"/>
</Vertex>

View file

@ -0,0 +1,10 @@
<Vertex Version="0">
<Vtx X="-47" Y="-34" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-47" Y="-34" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-47" Y="29" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-47" Y="29" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="-34" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="-34" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="29" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="29" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
</Vertex>

View file

@ -1,21 +1,15 @@
<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_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_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"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_keyring/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/>
<SetTextureImage Path="objects/object_keyring/Hilite_new.rgba16" 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="0" ShiftS="0" MaskT="0" ShiftT="0"/>
<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"/>
<SetEnvColor R="255" G="255" B="204" A="255"/>
<EndDisplayList/>
</DisplayList>

View file

@ -0,0 +1,10 @@
<Vertex Version="0">
<Vtx X="-47" Y="-34" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-47" Y="-34" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-47" Y="29" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="-47" Y="29" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="-34" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="-34" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="29" Z="19" S="0" T="0" R="0" G="0" B="0" A="0"/>
<Vtx X="8" Y="29" Z="6" S="0" T="0" R="0" G="0" B="0" A="0"/>
</Vertex>

View file

@ -10,6 +10,12 @@ void Custom_EnMThunder_Update(Actor* thisx, PlayState* play) {
f32 blueRadius;
s32 redGreen;
// If thunder effect doesn't exist (aka player doesn't have magic),
// don't do anything.
if (enMThunder->actionFunc == nullptr) {
return;
}
enMThunder->actionFunc(enMThunder, play);
// don't call this part, it's what makes the spin attack darkness happen
// func_80A9F314(play, this->unk_1BC);

View file

@ -488,6 +488,85 @@ void AudioEditor::DrawElement() {
UIWidgets::PushStyleTabs(THEME_COLOR);
if (ImGui::BeginTabBar("SfxContextTabBar", ImGuiTabBarFlags_NoCloseWithMiddleMouseButton)) {
static ImVec2 cellPadding(8.0f, 8.0f);
if (ImGui::BeginTabItem("Audio Options")) {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
ImGui::BeginTable("Audio Options", 1, ImGuiTableFlags_SizingStretchSame);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) {
UIWidgets::CVarCheckbox(
"Mute Low HP Alarm", CVAR_AUDIO("LowHPAlarm"),
UIWidgets::CheckboxOptions().Color(THEME_COLOR).Tooltip("Disable the low HP beeping sound."));
UIWidgets::CVarCheckbox("Disable Navi Call Audio", CVAR_AUDIO("DisableNaviCallAudio"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the voice audio when Navi calls you."));
UIWidgets::CVarCheckbox(
"Disable Enemy Proximity Music", CVAR_AUDIO("EnemyBGMDisable"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the music change when getting close to enemies. Useful for hearing "
"your custom music for each scene more often."));
UIWidgets::CVarCheckbox(
"Disable Leading Music in Lost Woods", CVAR_AUDIO("LostWoodsConsistentVolume"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the volume shifting in the Lost Woods. Useful for hearing "
"your custom music in the Lost Woods if you don't need the navigation assitance "
"the volume changing provides. If toggling this while in the Lost Woods, reload "
"the area for the effect to kick in."));
UIWidgets::CVarCheckbox(
"Display Sequence Name on Overlay", CVAR_AUDIO("SeqNameOverlay"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Displays the name of the current sequence in the corner of the screen whenever a new "
"sequence "
"is loaded to the main sequence player (does not apply to fanfares or enemy BGM)."));
UIWidgets::CVarSliderInt("Overlay Duration: %d seconds", CVAR_AUDIO("SeqNameOverlayDuration"),
UIWidgets::IntSliderOptions()
.Min(1)
.Max(10)
.DefaultValue(5)
.Size(ImVec2(300.0f, 0.0f))
.Color(THEME_COLOR));
UIWidgets::CVarSliderFloat("Link's voice pitch multiplier", CVAR_AUDIO("LinkVoiceFreqMultiplier"),
UIWidgets::FloatSliderOptions()
.IsPercentage()
.Min(0.4f)
.Max(2.5f)
.DefaultValue(1.0f)
.Size(ImVec2(300.0f, 0.0f))
.Color(THEME_COLOR));
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPos().y + 40.f);
if (UIWidgets::Button("Reset##linkVoiceFreqMultiplier",
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f);
}
UIWidgets::CVarCheckbox(
"Randomize All Music and Sound Effects on New Scene", CVAR_AUDIO("RandomizeAllOnNewScene"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip(
"Enables randomizing all unlocked music and sound effects when you enter a new scene."));
UIWidgets::CVarCheckbox(
"Lower Octaves of Unplayable High Notes", CVAR_AUDIO("ExperimentalOctaveDrop"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Some custom sequences may have notes that are too high for the game's audio "
"engine to play. Enabling this checkbox will cause these notes to drop a "
"couple of octaves so they can still harmonize with the other notes of the "
"sequence."));
}
ImGui::EndChild();
ImGui::EndTable();
ImGui::PopStyleVar(1);
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Background Music")) {
Draw_SfxTab("backgroundMusic", SEQ_BGM_WORLD, "Background Music");
ImGui::EndTabItem();
@ -518,78 +597,6 @@ void AudioEditor::DrawElement() {
ImGui::EndTabItem();
}
static ImVec2 cellPadding(8.0f, 8.0f);
if (ImGui::BeginTabItem("Options")) {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);
ImGui::BeginTable("Options", 1, ImGuiTableFlags_SizingStretchSame);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginChild("SfxOptions", ImVec2(0, -8))) {
UIWidgets::CVarCheckbox(
"Disable Enemy Proximity Music", CVAR_AUDIO("EnemyBGMDisable"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the music change when getting close to enemies. Useful for hearing "
"your custom music for each scene more often."));
UIWidgets::CVarCheckbox(
"Disable Leading Music in Lost Woods", CVAR_AUDIO("LostWoodsConsistentVolume"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Disables the volume shifting in the Lost Woods. Useful for hearing "
"your custom music in the Lost Woods if you don't need the navigation assitance "
"the volume changing provides. If toggling this while in the Lost Woods, reload "
"the area for the effect to kick in."));
UIWidgets::CVarCheckbox(
"Display Sequence Name on Overlay", CVAR_AUDIO("SeqNameOverlay"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Displays the name of the current sequence in the corner of the screen whenever a new "
"sequence "
"is loaded to the main sequence player (does not apply to fanfares or enemy BGM)."));
UIWidgets::CVarSliderInt("Overlay Duration: %d seconds", CVAR_AUDIO("SeqNameOverlayDuration"),
UIWidgets::IntSliderOptions()
.Min(1)
.Max(10)
.DefaultValue(5)
.Size(ImVec2(300.0f, 0.0f))
.Color(THEME_COLOR));
UIWidgets::CVarSliderFloat("Link's voice pitch multiplier",
CVAR_AUDIO("LinkVoiceFreqMultiplier"),
UIWidgets::FloatSliderOptions()
.IsPercentage()
.Min(0.4f)
.Max(2.5f)
.DefaultValue(1.0f)
.Size(ImVec2(300.0f, 0.0f))
.Color(THEME_COLOR));
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPos().y + 40.f);
if (UIWidgets::Button("Reset##linkVoiceFreqMultiplier",
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
CVarSetFloat(CVAR_AUDIO("LinkVoiceFreqMultiplier"), 1.0f);
}
UIWidgets::CVarCheckbox(
"Randomize All Music and Sound Effects on New Scene", CVAR_AUDIO("RandomizeAllOnNewScene"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip(
"Enables randomizing all unlocked music and sound effects when you enter a new scene."));
UIWidgets::CVarCheckbox(
"Lower Octaves of Unplayable High Notes", CVAR_AUDIO("ExperimentalOctaveDrop"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR)
.Tooltip("Some custom sequences may have notes that are too high for the game's audio "
"engine to play. Enabling this checkbox will cause these notes to drop a "
"couple of octaves so they can still harmonize with the other notes of the "
"sequence."));
}
ImGui::EndChild();
ImGui::EndTable();
ImGui::PopStyleVar(1);
ImGui::EndTabItem();
}
static bool excludeTabOpen = false;
if (ImGui::BeginTabItem("Audio Shuffle Pool Management")) {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, cellPadding);

View file

@ -428,7 +428,6 @@ InputViewerSettingsWindow::~InputViewerSettingsWindow() {
}
void InputViewerSettingsWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
// gInputViewer.Scale
CVarSliderFloat("Input Viewer Scale: %.2f", CVAR_INPUT_VIEWER("Scale"),
FloatSliderOptions().Color(THEME_COLOR).DefaultValue(1.0f).Min(0.1f).Max(5.0f).ShowButtons(true).Tooltip("Sets the on screen size of the input viewer"));
@ -565,7 +564,7 @@ void InputViewerSettingsWindow::DrawElement() {
ImGui::Unindent();
}
UIWidgets:PaddedSeparator(true, true);
UIWidgets::PaddedSeparator(true, true);
}
if (ImGui::CollapsingHeader("Analog Stick")) {
@ -640,5 +639,4 @@ void InputViewerSettingsWindow::DrawElement() {
}
}
PopStyleHeader();
ImGui::PopFont();
}

View file

@ -283,13 +283,13 @@ static std::map<std::string, CosmeticOption> cosmeticOptions = {
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.WellSmallEmblem", "Well Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(227, 110, 255, 255), false, true, false),
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.FortSmallEmblem", "Fortress Small Key Emblem",COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 255, 255, 255), false, true, false),
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.GTGSmallEmblem", "GTG Small Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(221, 212, 60, 255), false, true, false),
//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.ChestGameEmblem", "Chest Game Key Emblem", COSMETICS_GROUP_SMALL_KEYS, ColorRGBA8(255, 0, 0, 255), false, true, false),
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),
@ -1523,7 +1523,7 @@ void Draw_Placements(){
CVarSetInteger(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Changed"), 1);
}
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 24);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2));
if (UIWidgets::Button("Reset##EnemyHealthBarWidth",
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
CVarClear(CVAR_COSMETIC("HUD.EnemyHealthBar.Width.Value"));
@ -1537,7 +1537,7 @@ void Draw_Placements(){
void Reset_Option_Single(const char* Button_Title, const char* name) {
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 24);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2));
if (UIWidgets::Button(Button_Title,
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
CVarClear(name);
@ -1546,7 +1546,7 @@ void Reset_Option_Single(const char* Button_Title, const char* name) {
void Reset_Option_Double(const char* Button_Title, const char* name) {
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 24);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2));
if (UIWidgets::Button(Button_Title,
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
CVarClear((std::string(name) + ".Value").c_str());
@ -1578,7 +1578,7 @@ void DrawSillyTab() {
CVarSetInteger(CVAR_COSMETIC("Link.BodySize.Changed"), 1);
}
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 24);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2));
if (UIWidgets::Button("Reset##Link_BodySize",
UIWidgets::ButtonOptions().Size(ImVec2(80, 36)).Padding(ImVec2(5.0f, 0.0f)))) {
CVarClear(CVAR_COSMETIC("Link.BodySize.Value"));
@ -2045,8 +2045,8 @@ void CosmeticsEditorWindow::DrawElement() {
UIWidgets::ComboboxOptions()
.DefaultIndex(COLORSCHEME_N64)
.Color(THEME_COLOR)
.LabelPosition(UIWidgets::LabelPosition::Near)
.ComponentAlignment(UIWidgets::ComponentAlignment::Right));
.LabelPosition(UIWidgets::LabelPositions::Near)
.ComponentAlignment(UIWidgets::ComponentAlignments::Right));
UIWidgets::CVarCheckbox("Sync Rainbow colors", CVAR_COSMETIC("RainbowSync"),
UIWidgets::CheckboxOptions()
.Color(THEME_COLOR));
@ -2194,7 +2194,7 @@ void CosmeticsEditorWindow::DrawElement() {
CVarSetInteger(CVAR_COSMETIC("Trails.Duration.Changed"), 1);
}
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 24);
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + (ImGui::CalcTextSize("g").y * 2));
if (UIWidgets::Button("Reset##Trails_Duration", UIWidgets::ButtonOptions()
.Size(ImVec2(80, 36))
.Padding(ImVec2(5.0f, 0.0f)))) {

View file

@ -79,6 +79,7 @@ static bool ActorSpawnHandler(std::shared_ptr<Ship::Console> Console, const std:
if (args[8][0] != ',') {
spawnPoint.rot.z = std::stoi(args[8]);
}
[[fallthrough]];
case 6:
if (args[3][0] != ',') {
spawnPoint.pos.x = std::stoi(args[3]);

View file

@ -26,7 +26,6 @@ void MessageViewer::InitElement() {
}
void MessageViewer::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontMonoLargest);
ImGui::Text("Table ID");
ImGui::SameLine();
PushStyleInput(THEME_COLOR);
@ -86,7 +85,6 @@ void MessageViewer::DrawElement() {
mDisplayCustomMessageClicked = true;
}
PopStyleButton();
ImGui::PopFont();
}
void MessageViewer::UpdateElement() {

View file

@ -934,8 +934,6 @@ void ActorViewerWindow::DrawElement() {
static s16 currentSelectedInDropdown;
static std::vector<u16> actors;
ImGui::PushFont(OTRGlobals::Instance->fontMonoLargest);
if (gPlayState != nullptr) {
needs_reset = lastSceneId != gPlayState->sceneNum;
if (needs_reset) {
@ -1234,7 +1232,6 @@ void ActorViewerWindow::DrawElement() {
actors.clear();
}
}
ImGui::PopFont();
}
void ActorViewerWindow::InitElement() {

View file

@ -1550,7 +1550,7 @@ void ResetBaseOptions() {
intSliderOptionsBase.Color(THEME_COLOR).Size({320.0f, 0.0f}).Tooltip("");
buttonOptionsBase.Color(THEME_COLOR).Size(Sizes::Inline).Tooltip("");
checkboxOptionsBase.Color(THEME_COLOR).Tooltip("");
comboboxOptionsBase.Color(THEME_COLOR).ComponentAlignment(ComponentAlignment::Left).LabelPosition(LabelPosition::Near).Tooltip("");
comboboxOptionsBase.Color(THEME_COLOR).ComponentAlignment(ComponentAlignments::Left).LabelPosition(LabelPositions::Near).Tooltip("");
}
void SaveEditorWindow::DrawElement() {

View file

@ -91,7 +91,6 @@ void PerformDisplayListSearch() {
}
void DLViewerWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
// Debounce the search field as listing otr files is expensive
UIWidgets::PushStyleInput(THEME_COLOR);
if (ImGui::InputText("Search Display Lists", searchString, ARRAY_COUNT(searchString))) {
@ -122,7 +121,6 @@ void DLViewerWindow::DrawElement() {
UIWidgets::PopStyleCombobox();
if (activeDisplayList == "") {
ImGui::PopFont();
return;
}
@ -131,7 +129,6 @@ void DLViewerWindow::DrawElement() {
if (res->GetInitData()->Type != static_cast<uint32_t>(Fast::ResourceType::DisplayList)) {
ImGui::Text("Resource type is not a Display List. Please choose another.");
ImGui::PopFont();
return;
}
@ -329,10 +326,8 @@ void DLViewerWindow::DrawElement() {
}
} catch (const std::exception& e) {
ImGui::Text("Error displaying DL instructions.");
ImGui::PopFont();
return;
}
ImGui::PopFont();
}
void DLViewerWindow::InitElement() {

View file

@ -4,28 +4,29 @@
#include <string>
#include <version>
static std::unordered_map<const char*, std::unordered_map<HOOK_ID, HookInfo>*> hookData;
static std::map<const char*, std::map<HOOK_ID, HookInfo>*> hookData;
const ImVec4 grey = ImVec4(0.75, 0.75, 0.75, 1);
const ImVec4 yellow = ImVec4(1, 1, 0, 1);
const ImVec4 red = ImVec4(1, 0, 0, 1);
void DrawHookRegisteringInfos(const char* hookName) {
if ((*hookData[hookName]).size() == 0) {
size_t numHooks = (*hookData[hookName]).size();
if (numHooks == 0) {
ImGui::TextColored(grey, "No hooks found");
return;
}
if (ImGui::BeginTable(
("Table##" + std::string(hookName)).c_str(),
4,
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit
)) {
ImGui::TableSetupColumn("Id");
ImGui::TableSetupColumn("Type");
ImGui::TableSetupColumn("Registration Info");
//ImGui::TableSetupColumn("Stub");
ImGui::TableSetupColumn("Number of Calls");
ImGui::Text("Total Registered: %d", numHooks);
if (ImGui::BeginTable(("Table##" + std::string(hookName)).c_str(), 4,
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable |
ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableSetupColumn("Registration Info", ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn("# Calls", ImGuiTableColumnFlags_WidthFixed);
ImGui::TableHeadersRow();
for (auto& [id, hookInfo] : (*hookData[hookName])) {
ImGui::TableNextRow();
@ -39,7 +40,7 @@ void DrawHookRegisteringInfos(const char* hookName) {
ImGui::Text("Normal");
break;
case HOOK_TYPE_ID:
ImGui::Text("Id");
ImGui::Text("ID");
break;
case HOOK_TYPE_PTR:
ImGui::Text("Ptr");
@ -54,27 +55,19 @@ void DrawHookRegisteringInfos(const char* hookName) {
ImGui::TableNextColumn();
if (hookInfo.registering.valid) {
ImGui::Text("%s(%d:%d) %s", hookInfo.registering.file, hookInfo.registering.line, hookInfo.registering.column, hookInfo.registering.function);
// Replace the space after the return type of the parent function with a non-breaking space
std::string parentFunction = std::string(hookInfo.registering.function);
size_t pos = parentFunction.find_first_of(" ");
if (pos != std::string::npos) {
parentFunction.replace(pos, 1, "\u00A0");
}
// Non breaking space to keep the arrow with the parent function
ImGui::TextWrapped("%s(%d:%d) <-\u00A0%s", hookInfo.registering.file, hookInfo.registering.line,
hookInfo.registering.column, parentFunction.c_str());
} else {
ImGui::TextColored(yellow, "[Unavaliable]");
ImGui::TextColored(yellow, "[Unavailable]");
}
//TODO: not currently possible
/*
ImGui::TableNextColumn();
ImGui::BeginDisabled();
bool stubButtonPressed = ImGui::Button(("Stub##" + std::to_string(id)).c_str());
UIWidgets::SetLastItemHoverText("Stub this hook.\nThis is not possible to automatically undo.");
if (stubButtonPressed) {
//stub
}
ImGui::EndDisabled();
*/
ImGui::TableNextColumn();
ImGui::Text("%d", hookInfo.calls);
}
@ -84,12 +77,9 @@ void DrawHookRegisteringInfos(const char* hookName) {
void HookDebuggerWindow::DrawElement() {
#ifndef __cpp_lib_source_location
ImGui::TextColored(
yellow,
"Some features of the Hook Debugger are unavaliable because SoH was compiled "
"without \"<source_location>\" support "
"(\"__cpp_lib_source_location\" not defined in \"<version>\")."
);
ImGui::TextColored(yellow, "Some features of the Hook Debugger are unavailable because SoH was compiled "
"without \"<source_location>\" support "
"(\"__cpp_lib_source_location\" not defined in \"<version>\").");
#endif
for (auto& [hookName, _] : hookData) {
@ -101,9 +91,9 @@ void HookDebuggerWindow::DrawElement() {
}
void HookDebuggerWindow::InitElement() {
#define DEFINE_HOOK(name, _) hookData.insert({#name, GameInteractor::Instance->GetHookData<GameInteractor::name>()});
#define DEFINE_HOOK(name, _) hookData.insert({ #name, GameInteractor::Instance->GetHookData<GameInteractor::name>() });
#include "../game-interactor/GameInteractor_HookTable.h"
#include "../game-interactor/GameInteractor_HookTable.h"
#undef DEFINE_HOOK
#undef DEFINE_HOOK
}

View file

@ -143,7 +143,6 @@ void RegisterValueViewerHooks() {
RegisterShipInitFunc initFunc(RegisterValueViewerHooks, { CVAR_NAME });
void ValueViewerWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontMonoLargest);
UIWidgets::CVarCheckbox("Enable Printing", CVAR_NAME, UIWidgets::CheckboxOptions().Color(THEME_COLOR));
ImGui::BeginGroup();
@ -264,7 +263,6 @@ void ValueViewerWindow::DrawElement() {
}
ImGui::EndGroup();
}
ImGui::PopFont();
}
void ValueViewerWindow::InitElement() {

View file

@ -286,7 +286,7 @@ void GetSelectedEnemies() {
for (int i = 0; i < 49; i++) {
if (CVarGetInteger(CVAR_ENHANCEMENT("RandomizedEnemyList.All"), 0)) {
selectedEnemyList.push_back(randomizedEnemySpawnTable[i]);
} else if (CVarGetInteger(enemyCVarList[i], 0)) {
} else if (CVarGetInteger(enemyCVarList[i], 1)) {
selectedEnemyList.push_back(randomizedEnemySpawnTable[i]);
}
}

View file

@ -4,8 +4,8 @@
#define GameInteractor_h
#include "libultraship/libultraship.h"
#include "GameInteractionEffect.h"
#include "vanilla-behavior/GIVanillaBehavior.h"
#include "GameInteractionEffect.h"
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include <z64.h>
@ -92,19 +92,20 @@ void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state);
}
#endif
#ifdef __cplusplus
#include <stdarg.h>
#include <thread>
#include <map>
#include <unordered_map>
#include <vector>
#include <functional>
#include <string>
#include <version>
#ifdef __cpp_lib_source_location
#include <source_location>
#else
#pragma message("Compiling without <source_location> support, the Hook Debugger will not be avaliable")
#pragma message("Compiling without <source_location> support, the Hook Debugger will not be available")
#endif
typedef uint32_t HOOK_ID;
@ -124,24 +125,31 @@ struct HookRegisteringInfo {
const char* function;
HookType type;
HookRegisteringInfo() : valid(false), file("unknown file"), line(0), column(0), function("unknown function"), type(HOOK_TYPE_NORMAL) {}
HookRegisteringInfo()
: valid(false), file("unknown file"), line(0), column(0), function("unknown function"), type(HOOK_TYPE_NORMAL) {
}
HookRegisteringInfo(const char* _file, std::uint_least32_t _line, std::uint_least32_t _column, const char* _function, HookType _type) :
valid(true), file(_file), line(_line), column(_column), function(_function), type(_type) {}
HookRegisteringInfo(const char* _file, std::uint_least32_t _line, std::uint_least32_t _column,
const char* _function, HookType _type)
: valid(true), file(_file), line(_line), column(_column), function(_function), type(_type) {
// Trim off user parent directories
const char* trimmed = strstr(_file, "soh/soh/");
if (trimmed != nullptr) {
file = trimmed;
}
}
};
struct HookInfo {
uint32_t calls;
HookRegisteringInfo registering;
HookInfo() : calls(0), registering(HookRegisteringInfo{}) {}
HookInfo(HookRegisteringInfo _registering) : calls(0), registering(_registering) {}
};
#ifdef __cpp_lib_source_location
#define GET_CURRENT_REGISTERING_INFO(type) HookRegisteringInfo{location.file_name(), location.line(), location.column(), location.function_name(), type}
#define GET_CURRENT_REGISTERING_INFO(type) \
(HookRegisteringInfo{ location.file_name(), location.line(), location.column(), location.function_name(), type })
#else
#define GET_CURRENT_REGISTERING_INFO(type) HookRegisteringInfo{}
#define GET_CURRENT_REGISTERING_INFO(type) (HookRegisteringInfo{})
#endif
#define REGISTER_VB_SHOULD(flag, body) \
@ -171,23 +179,23 @@ struct HookInfo {
hookId = GameInteractor::Instance->RegisterGameHookForID<GameInteractor::hookType>(id, body); \
} \
}
#define COND_VB_SHOULD(id, condition, body) \
{ \
static HOOK_ID hookId = 0; \
#define COND_VB_SHOULD(id, condition, body) \
{ \
static HOOK_ID hookId = 0; \
GameInteractor::Instance->UnregisterGameHookForID<GameInteractor::OnVanillaBehavior>(hookId); \
hookId = 0; \
if (condition) { \
hookId = REGISTER_VB_SHOULD(id, body); \
} \
hookId = 0; \
if (condition) { \
hookId = REGISTER_VB_SHOULD(id, body); \
} \
}
class GameInteractor {
public:
public:
static GameInteractor* Instance;
// Game State
class State {
public:
public:
static bool NoUIActive;
static GILinkSize LinkSize;
static bool InvisibleLinkActive;
@ -219,14 +227,15 @@ public:
// Game Hooks
HOOK_ID nextHookId = 1;
template <typename H> struct RegisteredGameHooks {
inline static std::unordered_map<HOOK_ID, typename H::fn> functions;
inline static std::unordered_map<int32_t, std::unordered_map<HOOK_ID, typename H::fn>> functionsForID;
inline static std::unordered_map<uintptr_t, std::unordered_map<HOOK_ID, typename H::fn>> functionsForPtr;
inline static std::unordered_map<HOOK_ID, std::pair<typename H::filter, typename H::fn>> functionsForFilter;
//Used for the hook debugger
inline static std::unordered_map<HOOK_ID, HookInfo> hookData;
// Used for the hook debugger
inline static std::map<HOOK_ID, HookInfo> hookData;
};
template <typename H> struct HooksToUnregister {
@ -236,39 +245,43 @@ public:
inline static std::vector<HOOK_ID> hooksForFilter;
};
template <typename H> std::unordered_map<uint32_t, HookInfo>* GetHookData() {
template <typename H> std::map<uint32_t, HookInfo>* GetHookData() {
return &RegisteredGameHooks<H>::hookData;
}
// General Hooks
template <typename H> HOOK_ID RegisterGameHook(
typename H::fn h
template <typename H>
#ifdef __cpp_lib_source_location
, const std::source_location location = std::source_location::current()
HOOK_ID RegisterGameHook(typename H::fn h, const std::source_location location = std::source_location::current()) {
#else
HOOK_ID RegisterGameHook(typename H::fn h) {
#endif
) {
// Ensure hook id is unique and not 0, which is reserved for invalid hooks
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX)
this->nextHookId = 1;
while (RegisteredGameHooks<H>::functions.find(this->nextHookId) != RegisteredGameHooks<H>::functions.end()) {
this->nextHookId++;
}
RegisteredGameHooks<H>::functions[this->nextHookId] = h;
RegisteredGameHooks<H>::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_NORMAL)};
RegisteredGameHooks<H>::hookData[this->nextHookId] =
HookInfo{ 0, GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_NORMAL) };
return this->nextHookId++;
}
template <typename H> void UnregisterGameHook(HOOK_ID hookId) {
if (hookId == 0) return;
if (hookId == 0)
return;
HooksToUnregister<H>::hooks.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooks(Args&&... args) {
// Remove pending hooks for this type
for (auto& hookId : HooksToUnregister<H>::hooks) {
RegisteredGameHooks<H>::functions.erase(hookId);
RegisteredGameHooks<H>::hookData.erase(hookId);
}
HooksToUnregister<H>::hooks.clear();
// Execute hooks
for (auto& hook : RegisteredGameHooks<H>::functions) {
hook.second(std::forward<Args>(args)...);
RegisteredGameHooks<H>::hookData[hook.first].calls += 1;
@ -276,39 +289,60 @@ public:
}
// ID based Hooks
template <typename H> HOOK_ID RegisterGameHookForID(
int32_t id, typename H::fn h
template <typename H>
#ifdef __cpp_lib_source_location
, const std::source_location location = std::source_location::current()
HOOK_ID RegisterGameHookForID(int32_t id, typename H::fn h,
std::source_location location = std::source_location::current()) {
#else
HOOK_ID RegisterGameHookForID(int32_t id, typename H::fn h) {
#endif
) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForID[id].find(this->nextHookId) != RegisteredGameHooks<H>::functionsForID[id].end()) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX)
this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForID[id].find(this->nextHookId) !=
RegisteredGameHooks<H>::functionsForID[id].end()) {
this->nextHookId++;
}
RegisteredGameHooks<H>::functionsForID[id][this->nextHookId] = h;
RegisteredGameHooks<H>::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_ID)};
RegisteredGameHooks<H>::hookData[this->nextHookId] = HookInfo{ 0, GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_ID) };
return this->nextHookId++;
}
template <typename H> void UnregisterGameHookForID(HOOK_ID hookId) {
if (hookId == 0) return;
if (hookId == 0)
return;
HooksToUnregister<H>::hooksForID.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooksForID(int32_t id, Args&&... args) {
for (auto& hookId : HooksToUnregister<H>::hooksForID) {
for (auto it = RegisteredGameHooks<H>::functionsForID[id].begin(); it != RegisteredGameHooks<H>::functionsForID[id].end(); ) {
if (it->first == hookId) {
// Remove pending hooks for this type
for (auto hookIdIt = HooksToUnregister<H>::hooksForID.begin();
hookIdIt != HooksToUnregister<H>::hooksForID.end();) {
bool remove = false;
if (RegisteredGameHooks<H>::functionsForID[id].size() == 0) {
break;
}
for (auto it = RegisteredGameHooks<H>::functionsForID[id].begin();
it != RegisteredGameHooks<H>::functionsForID[id].end();) {
if (it->first == *hookIdIt) {
it = RegisteredGameHooks<H>::functionsForID[id].erase(it);
HooksToUnregister<H>::hooksForID.erase(std::remove(HooksToUnregister<H>::hooksForID.begin(), HooksToUnregister<H>::hooksForID.end(), hookId), HooksToUnregister<H>::hooksForID.end());
RegisteredGameHooks<H>::hookData.erase(hookId);
RegisteredGameHooks<H>::hookData.erase(*hookIdIt);
remove = true;
break;
} else {
++it;
}
}
if (remove) {
hookIdIt = HooksToUnregister<H>::hooksForID.erase(hookIdIt);
} else {
++hookIdIt;
}
}
// Execute hooks
for (auto& hook : RegisteredGameHooks<H>::functionsForID[id]) {
hook.second(std::forward<Args>(args)...);
RegisteredGameHooks<H>::hookData[hook.first].calls += 1;
@ -316,39 +350,60 @@ public:
}
// PTR based Hooks
template <typename H> HOOK_ID RegisterGameHookForPtr(
uintptr_t ptr, typename H::fn h
template <typename H>
#ifdef __cpp_lib_source_location
, const std::source_location location = std::source_location::current()
HOOK_ID RegisterGameHookForPtr(uintptr_t ptr, typename H::fn h,
const std::source_location location = std::source_location::current()) {
#else
HOOK_ID RegisterGameHookForPtr(uintptr_t ptr, typename H::fn h) {
#endif
) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForPtr[ptr].find(this->nextHookId) != RegisteredGameHooks<H>::functionsForPtr[ptr].end()) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX)
this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForPtr[ptr].find(this->nextHookId) !=
RegisteredGameHooks<H>::functionsForPtr[ptr].end()) {
this->nextHookId++;
}
RegisteredGameHooks<H>::functionsForPtr[ptr][this->nextHookId] = h;
RegisteredGameHooks<H>::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_PTR)};
RegisteredGameHooks<H>::hookData[this->nextHookId] = HookInfo{ 0, GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_PTR) };
return this->nextHookId++;
}
template <typename H> void UnregisterGameHookForPtr(HOOK_ID hookId) {
if (hookId == 0) return;
if (hookId == 0)
return;
HooksToUnregister<H>::hooksForPtr.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooksForPtr(uintptr_t ptr, Args&&... args) {
for (auto& hookId : HooksToUnregister<H>::hooksForPtr) {
for (auto it = RegisteredGameHooks<H>::functionsForPtr[ptr].begin(); it != RegisteredGameHooks<H>::functionsForPtr[ptr].end(); ) {
if (it->first == hookId) {
// Remove pending hooks for this type
for (auto hookIdIt = HooksToUnregister<H>::hooksForPtr.begin();
hookIdIt != HooksToUnregister<H>::hooksForPtr.end();) {
bool remove = false;
if (RegisteredGameHooks<H>::functionsForPtr[ptr].size() == 0) {
break;
}
for (auto it = RegisteredGameHooks<H>::functionsForPtr[ptr].begin();
it != RegisteredGameHooks<H>::functionsForPtr[ptr].end();) {
if (it->first == *hookIdIt) {
it = RegisteredGameHooks<H>::functionsForPtr[ptr].erase(it);
HooksToUnregister<H>::hooksForPtr.erase(std::remove(HooksToUnregister<H>::hooksForPtr.begin(), HooksToUnregister<H>::hooksForPtr.end(), hookId), HooksToUnregister<H>::hooksForPtr.end());
RegisteredGameHooks<H>::hookData.erase(hookId);
RegisteredGameHooks<H>::hookData.erase(*hookIdIt);
remove = true;
break;
} else {
++it;
}
}
if (remove) {
hookIdIt = HooksToUnregister<H>::hooksForPtr.erase(hookIdIt);
} else {
++hookIdIt;
}
}
// Execute hooks
for (auto& hook : RegisteredGameHooks<H>::functionsForPtr[ptr]) {
hook.second(std::forward<Args>(args)...);
RegisteredGameHooks<H>::hookData[hook.first].calls += 1;
@ -356,33 +411,40 @@ public:
}
// Filter based Hooks
template <typename H> HOOK_ID RegisterGameHookForFilter(
typename H::filter f, typename H::fn h
template <typename H>
#ifdef __cpp_lib_source_location
, const std::source_location location = std::source_location::current()
HOOK_ID RegisterGameHookForFilter(typename H::filter f, typename H::fn h,
const std::source_location location = std::source_location::current()) {
#else
HOOK_ID RegisterGameHookForFilter(typename H::filter f, typename H::fn h) {
#endif
) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForFilter.find(this->nextHookId) != RegisteredGameHooks<H>::functionsForFilter.end()) {
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX)
this->nextHookId = 1;
while (RegisteredGameHooks<H>::functionsForFilter.find(this->nextHookId) !=
RegisteredGameHooks<H>::functionsForFilter.end()) {
this->nextHookId++;
}
RegisteredGameHooks<H>::functionsForFilter[this->nextHookId] = std::make_pair(f, h);
RegisteredGameHooks<H>::hookData[this->nextHookId] = HookInfo{GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_FILTER)};
RegisteredGameHooks<H>::hookData[this->nextHookId] =
HookInfo{ 0, GET_CURRENT_REGISTERING_INFO(HOOK_TYPE_FILTER) };
return this->nextHookId++;
}
template <typename H> void UnregisterGameHookForFilter(HOOK_ID hookId) {
if (hookId == 0) return;
if (hookId == 0)
return;
HooksToUnregister<H>::hooksForFilter.push_back(hookId);
}
template <typename H, typename... Args> void ExecuteHooksForFilter(Args&&... args) {
// Remove pending hooks for this type
for (auto& hookId : HooksToUnregister<H>::hooksForFilter) {
RegisteredGameHooks<H>::functionsForFilter.erase(hookId);
RegisteredGameHooks<H>::hookData.erase(hookId);
}
HooksToUnregister<H>::hooksForFilter.clear();
// Execute hooks
for (auto& hook : RegisteredGameHooks<H>::functionsForFilter) {
if (hook.second.first(std::forward<Args>(args)...)) {
hook.second.second(std::forward<Args>(args)...);
@ -391,8 +453,62 @@ public:
}
}
template <typename H> void ProcessUnregisteredHooks() {
// Normal
for (auto& hookId : HooksToUnregister<H>::hooks) {
RegisteredGameHooks<H>::functions.erase(hookId);
RegisteredGameHooks<H>::hookData.erase(hookId);
}
HooksToUnregister<H>::hooks.clear();
// ID
for (auto& hookId : HooksToUnregister<H>::hooksForID) {
for (auto& idGroup : RegisteredGameHooks<H>::functionsForID) {
for (auto it = idGroup.second.begin(); it != idGroup.second.end();) {
if (it->first == hookId) {
it = idGroup.second.erase(it);
RegisteredGameHooks<H>::hookData.erase(hookId);
} else {
++it;
}
}
}
}
HooksToUnregister<H>::hooksForID.clear();
// Ptr
for (auto& hookId : HooksToUnregister<H>::hooksForPtr) {
for (auto& ptrGroup : RegisteredGameHooks<H>::functionsForPtr) {
for (auto it = ptrGroup.second.begin(); it != ptrGroup.second.end();) {
if (it->first == hookId) {
it = ptrGroup.second.erase(it);
RegisteredGameHooks<H>::hookData.erase(hookId);
} else {
++it;
}
}
}
}
HooksToUnregister<H>::hooksForPtr.clear();
// Filter
for (auto& hookId : HooksToUnregister<H>::hooksForFilter) {
RegisteredGameHooks<H>::functionsForFilter.erase(hookId);
RegisteredGameHooks<H>::hookData.erase(hookId);
}
HooksToUnregister<H>::hooksForFilter.clear();
}
void RemoveAllQueuedHooks() {
#define DEFINE_HOOK(name, _) ProcessUnregisteredHooks<name>();
#include "GameInteractor_HookTable.h"
#undef DEFINE_HOOK
}
class HookFilter {
public:
public:
static auto ActorNotPlayer(Actor* actor) {
return actor->id != ACTOR_PLAYER;
}
@ -401,15 +517,11 @@ public:
return actor->id != ACTOR_PLAYER;
}
static auto ActorMatchIdAndParams(int16_t id, int16_t params) {
return [id, params](Actor* actor) {
return actor->id == id && actor->params == params;
};
return [id, params](Actor* actor) { return actor->id == id && actor->params == params; };
}
// For use with Should hooks
static auto SActorMatchIdAndParams(int16_t id, int16_t params) {
return [id, params](Actor* actor, bool* result) {
return actor->id == id && actor->params == params;
};
return [id, params](Actor* actor, bool* result) { return actor->id == id && actor->params == params; };
}
};
@ -430,7 +542,7 @@ public:
static bool CanAddOrTakeAmmo(int16_t amount, int16_t item);
class RawAction {
public:
public:
static void SetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag);
static void UnsetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag);
static bool CheckFlag(int16_t flagType, int16_t flag);

View file

@ -19,6 +19,9 @@ void GameInteractor_ExecuteOnExitGame(int32_t fileNum) {
}
void GameInteractor_ExecuteOnGameStateMainStart() {
// Cleanup all hooks at the start of each frame
GameInteractor::Instance->RemoveAllQueuedHooks();
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnGameStateMainStart>();
}

View file

@ -1,5 +1,6 @@
#pragma once
#include "vanilla-behavior/GIVanillaBehavior.h"
#include "GameInteractor.h"
#include <stdarg.h>

View file

@ -564,7 +564,7 @@ void GameInteractor::RawAction::SetRandomWind(bool active) {
void GameInteractor::RawAction::SetPlayerInvincibility(bool active) {
Player* player = GET_PLAYER(gPlayState);
if (active) {
player->invincibilityTimer = 1000;
player->invincibilityTimer = -20;
} else {
player->invincibilityTimer = 0;
}

View file

@ -1,3 +1,8 @@
#pragma once
#ifndef GI_VANILLA_BEHAVIOR_H
#define GI_VANILLA_BEHAVIOR_H
typedef enum {
// #### `result`
// ```c
@ -1265,6 +1270,14 @@ typedef enum {
// - None
VB_PLAY_BOLERO_OF_FIRE_CS,
// #### `result`
// ```c
// true
// ```
// #### `args`
// - `*EnDaiku`
VB_PLAY_CARPENTER_FREE_CS,
// #### `result`
// Close enough & various cutscene checks
// ```c
@ -1869,3 +1882,5 @@ typedef enum {
// - `*EnWonderTalk2`
VB_WONDER_TALK,
} GIVanillaBehavior;
#endif

View file

@ -16,7 +16,6 @@
#include "soh/Enhancements/timesaver_hook_handlers.h"
#include "soh/Enhancements/TimeSavers/TimeSavers.h"
#include "soh/Enhancements/randomizer/hook_handlers.h"
#include "objects/object_gi_compass/object_gi_compass.h"
#include "src/overlays/actors/ovl_En_Bb/z_en_bb.h"
#include "src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.h"
@ -810,8 +809,10 @@ void RegisterRandomizedEnemySizes() {
Actor* actor = static_cast<Actor*>(refActor);
// Exclude wobbly platforms in Jabu because they need to act like platforms.
// Exclude demo effect for Zora sapphire being re-categorized as a "boss".
// Exclude Dead Hand hands and Bongo Bongo main body because they make the fights (near) impossible.
uint8_t excludedEnemy = actor->id == ACTOR_EN_BROB || actor->id == ACTOR_EN_DHA || (actor->id == ACTOR_BOSS_SST && actor->params == -1);
uint8_t excludedEnemy = actor->id == ACTOR_EN_BROB || actor->id == ACTOR_EN_DHA ||
actor->id == ACTOR_DEMO_EFFECT || (actor->id == ACTOR_BOSS_SST && actor->params == -1);
// Dodongo, Volvagia and Dead Hand are always smaller because they're impossible when bigger.
uint8_t smallOnlyEnemy = actor->id == ACTOR_BOSS_DODONGO || actor->id == ACTOR_BOSS_FD ||
@ -998,26 +999,6 @@ void RegisterPauseMenuHooks() {
});
}
extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
void PatchCompasses() {
s8 compassesCanBeOutsideDungeon = IS_RANDO && DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_SHUFFLE_MAPANDCOMPASS);
s8 isColoredCompassesEnabled = compassesCanBeOutsideDungeon && CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MatchCompassColors"), 1);
if (isColoredCompassesEnabled) {
ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_PrimColor", 5, gsDPNoOp());
ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_EnvColor", 6, gsDPNoOp());
} else {
ResourceMgr_UnpatchGfxByName(gGiCompassDL, "Compass_PrimColor");
ResourceMgr_UnpatchGfxByName(gGiCompassDL, "Compass_EnvColor");
}
}
void RegisterRandomizerCompasses() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadFile>([](int32_t _unused) {
PatchCompasses();
});
}
void RegisterCustomSkeletons() {
static int8_t previousTunic = -1;
@ -1065,7 +1046,6 @@ void InitMods() {
RegisterRandomizedEnemySizes();
RegisterOpenAllHours();
RegisterToTMedallions();
RegisterRandomizerCompasses();
NameTag_RegisterHooks();
RegisterFloorSwitchesHook();
RegisterPatchHandHandler();

View file

@ -11,7 +11,6 @@ void UpdateDirtPathFixState(int32_t sceneNum);
void UpdateMirrorModeState(int32_t sceneNum);
void UpdateHurtContainerModeState(bool newState);
void PatchToTMedallions();
void PatchCompasses();
void UpdatePermanentHeartLossState();
void UpdateHyperEnemiesState();
void UpdateHyperBossesState();

View file

@ -50,7 +50,7 @@ void DrawPresetSelector(PresetType presetTypeId) {
comboboxTooltip += std::string(iter->second.label) + " - " + std::string(iter->second.description);
}
ImGui::Text("Presets", false, true);
ImGui::Text("Presets");
UIWidgets::PushStyleCombobox(THEME_COLOR);
if (ImGui::BeginCombo("##PresetsComboBox", selectedPresetDef.label)) {
for ( auto iter = presetTypeDef.presets.begin(); iter != presetTypeDef.presets.end(); ++iter ) {

View file

@ -242,7 +242,7 @@ const std::vector<PresetEntry> enhancedPresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1),
// Disable Navi Call Audio
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1),
PRESET_ENTRY_S32(CVAR_AUDIO("DisableNaviCallAudio"), 1),
// Equipment Toggle
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1),
@ -373,7 +373,7 @@ const std::vector<PresetEntry> randomizerPresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("SeparateArrows"), 1),
// Disable Navi Call Audio
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1),
PRESET_ENTRY_S32(CVAR_AUDIO("DisableNaviCallAudio"), 1),
// Equipment Toggle
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1),
@ -436,7 +436,7 @@ const std::vector<PresetEntry> spockRacePresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterBlockPush"), 5),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FasterHeavyBlockLift"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NoForcedNavi"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1),
PRESET_ENTRY_S32(CVAR_AUDIO("DisableNaviCallAudio"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastChests"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastDrops"), 1),
PRESET_ENTRY_S32(CVAR_SETTING("DpadInText"), 1),
@ -531,7 +531,7 @@ const std::vector<PresetEntry> spockRaceNoLogicPresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("CustomizeFishing"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DampeAllNight"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DayGravePull"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 1),
PRESET_ENTRY_S32(CVAR_AUDIO("DisableNaviCallAudio"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("DpadNoDropOcarinaInput"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("EquipmentCanBeRemoved"), 1),
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("FastBoomerang"), 1),

View file

@ -2,258 +2,9 @@
#include "../../custom-message/CustomMessageManager.h"
#include "z64item.h"
#include <array>
#include <set>
#include <sstream>
namespace CustomMessages {
using namespace std::literals::string_literals;
class MessageEntryComp {
public:
bool operator()(const MessageEntry& lhs, const MessageEntry& rhs) const {
return lhs.id < rhs.id;
}
};
constexpr std::array EnglishDungeonNames = {
"Deku Tree",
"Dodongo's Cavern",
"Jabu Jabu's Belly",
"Forest Temple",
"Fire Temple",
"Water Temple",
"Spirit Temple",
"Shadow Temple",
"Bottom of the Well",
"Ice Cavern",
"Ganon's Tower",
"Gerudo Training Ground",
"Gerudo Fortress",
"Ganon's Castle",
};
constexpr std::array FrenchDungeonNames = {
"Vénérable Arbre Mojo",
"Caverne Dodongo",
"Ventre de Jabu-Jabu",
"Temple de la Forêt",
"Temple du Feu",
"Temple de l'Eau",
"Temple de l'Esprit",
"Temple de l'Ombre",
"Puits",
"Caverne Polaire",
"Tour de Ganon",
"Gymnase Gerudo",
"Repaire des Voleurs",
"Château de Ganon",
};
constexpr std::array FrenchDungeonArticles = {
"du ",
"de la ",
"du ",
"du ",
"du ",
"du ",
"du ",
"du ",
"du ",
"de la ",
"",
"du ",
"de la ",
"du ",
};
constexpr std::array SpanishDungeonNames = {
"Gran Árbol Deku",
"Cueva de los Dodongos",
"Tripa de Jabu-Jabu",
"Templo del Bosque",
"Templo del Fuego",
"Templo del Agua",
"Templo del Espíritu",
"Templo de las Sombras",
"Fondo del pozo",
"Caverna de hielo",
"Torre de Ganon",
"Centro de Instrucción Gerudo",
"Fortaleza Gerudo",
"Castillo de Ganon",
};
constexpr std::array SpanishDungeonArticles = {
"del",
"de la",
"de la",
"del",
"del",
"del",
"del",
"del",
"del",
"de la",
"de la",
"del",
"de la",
"del",
};
constexpr std::array DungeonColors = {
QM_GREEN,
QM_RED,
QM_BLUE,
QM_GREEN,
QM_RED,
QM_BLUE,
QM_YELLOW,
QM_PINK,
QM_PINK,
QM_LBLUE,
QM_BLACK,
QM_YELLOW,
QM_YELLOW,
QM_RED,
};
std::set<MessageEntry, MessageEntryComp> messageEntries;
std::stringstream messageData;
//textBoxType and textBoxPosition are defined here: https://wiki.cloudmodding.com/oot/Text_Format#Message_Id
void CreateMessage(uint32_t textId, uint32_t unk_04, uint32_t textBoxType, uint32_t textBoxPosition,
std::string englishText, std::string frenchText, std::string spanishText) {
MessageEntry newEntry = { textId, unk_04, textBoxType, textBoxPosition, { 0 } };
while ((englishText.size() % 4) != 0) {
englishText += "\0"s;
}
messageData.seekg(0, messageData.end);
newEntry.info[ENGLISH_U].offset = (char*)((int)messageData.tellg());
newEntry.info[ENGLISH_U].length = englishText.size();
messageData << englishText;
while ((frenchText.size() % 4) != 0) {
frenchText += "\0"s;
}
messageData.seekg(0, messageData.end);
newEntry.info[FRENCH_U].offset = (char*)((int)messageData.tellg());
newEntry.info[FRENCH_U].length = frenchText.size();
messageData << frenchText;
while ((spanishText.size() % 4) != 0) {
spanishText += "\0"s;
}
messageData.seekg(0, messageData.end);
newEntry.info[SPANISH_U].offset = (char*)((int)messageData.tellg());
newEntry.info[SPANISH_U].length = spanishText.size();
messageData << spanishText;
messageEntries.insert(newEntry);
}
void CreateMessageFromTextObject(uint32_t textId, uint32_t unk_04, uint32_t textBoxType, uint32_t textBoxPosition, const Text& text) {
CreateMessage(textId, unk_04, textBoxType, textBoxPosition, text.GetEnglish(), text.GetFrench(), text.GetSpanish());
}
Text AddColorsAndFormat(Text text, const std::vector<std::string>& colors /*= {}*/) {
//for each language
for (std::string* textStr : {&text.english, &text.french, &text.spanish}) {
//insert playername
size_t atSymbol = textStr->find('@');
while (atSymbol != std::string::npos) {
textStr->replace(atSymbol, 1, PLAYER_NAME());
atSymbol = textStr->find('@');
}
//insert newlines either manually or when encountering a '&'
constexpr size_t lineLength = 44;
size_t lastNewline = 0;
while (lastNewline + lineLength < textStr->length()) {
size_t carrot = textStr->find('^', lastNewline);
size_t ampersand = textStr->find('&', lastNewline);
size_t lastSpace = textStr->rfind(' ', lastNewline + lineLength);
size_t lastPeriod = textStr->rfind('.', lastNewline + lineLength);
//replace '&' first if it's within the newline range
if (ampersand < lastNewline + lineLength) {
textStr->replace(ampersand, 1, NEWLINE());
lastNewline = ampersand + NEWLINE().length();
//or move the lastNewline cursor to the next line if a '^' is encountered
} else if (carrot < lastNewline + lineLength) {
lastNewline = carrot + 1;
//some lines need to be split but don't have spaces, look for periods instead
} else if (lastSpace == std::string::npos) {
textStr->replace(lastPeriod, 1, "."+NEWLINE());
lastNewline = lastPeriod + NEWLINE().length() + 1;
} else {
textStr->replace(lastSpace, 1, NEWLINE());
lastNewline = lastSpace + NEWLINE().length();
}
}
//clean up any remaining '&' characters
size_t ampersand = textStr->find('&');
while (ampersand != std::string::npos) {
textStr->replace(ampersand, 1, NEWLINE());
ampersand = textStr->find('&');
}
//insert box break
size_t carrotSymbol = textStr->find('^');
while (carrotSymbol != std::string::npos) {
textStr->replace(carrotSymbol, 1, INSTANT_TEXT_OFF()+WAIT_FOR_INPUT()+INSTANT_TEXT_ON());
carrotSymbol = textStr->find('^');
}
//If there's a two-way choice and only 1 newline before it in the same text box, add another one
size_t choice = textStr->find(TWO_WAY_CHOICE());
if (choice != std::string::npos) {
size_t newLinesCount = 0;
size_t lastBoxBreak = textStr->rfind(WAIT_FOR_INPUT(), choice);
lastNewline = choice;
if (lastBoxBreak == std::string::npos) {
lastBoxBreak = 0;
}
while ((lastNewline != std::string::npos)) {
lastNewline = textStr->rfind(NEWLINE(), lastNewline - 1);
if (lastNewline != std::string::npos && lastNewline > lastBoxBreak) {
newLinesCount++;
} else {
break;
}
}
if (newLinesCount <= 1) {
textStr->replace(choice, TWO_WAY_CHOICE().length(), NEWLINE()+TWO_WAY_CHOICE());
}
}
//add colors
for (auto color : colors) {
size_t firstHashtag = textStr->find('#');
if (firstHashtag != std::string::npos) {
textStr->replace(firstHashtag, 1, COLOR(color));
size_t secondHashtag = textStr->find('#');
if (secondHashtag == std::string::npos) {
//CitraPrint("ERROR: Couldn't find second '#' in " + (*textStr));
} else {
textStr->replace(secondHashtag, 1, COLOR(QM_WHITE));
}
}
}
}
return Text{"","",""}+UNSKIPPABLE()+INSTANT_TEXT_ON()+text+INSTANT_TEXT_OFF()+MESSAGE_END();
}
void ClearMessages() {
messageEntries.clear();
messageData.str("");
}
std::string MESSAGE_END() { return "\x7F\x00"s; }
std::string WAIT_FOR_INPUT() { return "\x7F\x01"s; }
std::string HORIZONTAL_SPACE(uint8_t x) {
@ -280,7 +31,7 @@ constexpr std::array DungeonColors = {
std::string SET_SPEED(uint8_t x) {
return "\x7F\x10"s + char(x);
}
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; } //RANDOTODO just refernce the versions in CustomMessage
std::string SKULLTULAS_DESTROYED() { return "\x7F\x15"s; }
std::string CURRENT_TIME() { return "\x7F\x17"s; }
std::string UNSKIPPABLE() { return "\x7F\x19"s; }
std::string TWO_WAY_CHOICE() { return "\x1B"s; }

View file

@ -1,50 +1,11 @@
#pragma once
#include <string>
#include <utility>
#include <vector>
#include <cstdint>
#include "text.hpp"
namespace CustomMessages {
typedef struct {
// In the true file format, offset is the offset into the QM file.
// In randomizer, offset will be a pointer to the text in the game's address space.
// Since these pointers will be much larger as u32 than the original script's offsets,
// We will be able to distinguish between original and custom text using their numerical value.
const char* offset;
uint32_t length;
} MessageLanguageInfo;
typedef enum {
/* 0x00 */ JAPANESE_J,
/* 0x01 */ ENGLISH_U,
/* 0x02 */ ENGLISH_E,
/* 0x03 */ GERMAN_E,
/* 0x04 */ FRENCH_E,
/* 0x05 */ FRENCH_U,
/* 0x06 */ SPANISH_E,
/* 0x07 */ SPANISH_U,
/* 0x08 */ ITALIAN_E,
/* 0x09 */ DUTCH_E,
} MessageLanguage;
typedef struct {
uint32_t id;
uint32_t unk_04;
uint32_t unk_08;
uint32_t unk_0C;
MessageLanguageInfo info[10];
} MessageEntry; // size = 0x60
void CreateMessage(uint32_t textId, uint32_t unk_04, uint32_t textBoxType, uint32_t textBoxPosition,
std::string englishText, std::string frenchText, std::string spanishText);
void CreateMessageFromTextObject(uint32_t textId, uint32_t unk_04, uint32_t textBoxType, uint32_t textBoxPosition, const Text& text);
Text AddColorsAndFormat(Text text, const std::vector<uint8_t>& colors = {});
void ClearMessages();
std::string MESSAGE_END();
std::string WAIT_FOR_INPUT();
std::string HORIZONTAL_SPACE(uint8_t x);

View file

@ -1,6 +1,5 @@
#include "fill.hpp"
#include "custom_messages.hpp"
#include "../dungeon.h"
#include "../context.h"
#include "item_pool.hpp"
@ -19,7 +18,6 @@
#include <set>
#include <spdlog/spdlog.h>
using namespace CustomMessages;
using namespace Rando;

View file

@ -2070,23 +2070,23 @@ void StaticData::HintTable_Init_Item() {
CustomMessage("a rightward tone", /*german*/"ein rechtsseitiger Ton", /*french*/"une tonalité vers la droite")});
// /*spanish*/un tono hacia la derecha
hintTextTable[RHT_FISHING_POLE] = HintText(CustomMessage("a fishing pole", /*german*/"eine Angelrute", /*french*/"canne à pêche"),
hintTextTable[RHT_FISHING_POLE] = HintText(CustomMessage("a fishing pole", /*german*/"eine Angelrute", /*french*/"une canne à pêche"),
// /*spanish*/caña de pescar
{
CustomMessage("the pond owner's property", /*german*/"der Besitz des Teicheigners", /*french*/"(canne à pêche)")
CustomMessage("the pond owner's property", /*german*/"der Besitz des Teicheigners", /*french*/"(un truc qui appartient au propriétaire de l'étang)")
// /*spanish*/(caña de pescar)
}, {
CustomMessage("a fish-puller", /*german*/"ein Fischzieher", /*french*/"(canne à pêche)")});
CustomMessage("a fish-puller", /*german*/"ein Fischzieher", /*french*/"(un aimant à poisson)")});
// /*spanish*/(caña de pescar)
hintTextTable[RHT_BOMBCHU_BAG] = HintText(CustomMessage("Bombchu Bag", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_BOMBCHU_BAG] = HintText(CustomMessage("Bombchu Bag", /*german*/"!!!", /*french*/"un Sac de Missiles Teigneux"),
{
CustomMessage("explosives", /*german*/"ein Explosivpaket", /*french*/"un paquet d'explosifs"),
// /*spanish*/un montón de explosivos
CustomMessage("something that can remove boulders", /*german*/"etwas, das Geröll entfernen kann", /*french*/"une chose qui enlève les rochers")
// /*spanish*/algo que pueda quitar rocas
}, {
CustomMessage("sack of mice", /*german*/"!!!", /*french*/"!!!")});
CustomMessage("sack of mice", /*german*/"!!!", /*french*/"un Sac rempli de souris")});
hintTextTable[RHT_SKELETON_KEY] = HintText(CustomMessage("a Skeleton Key", /*german*/ "ein Universalschlüssel", /*french*/ "une Clé Squelette"),
// /*spanish*/una Llave Maestra
@ -2096,49 +2096,49 @@ void StaticData::HintTable_Init_Item() {
},
{ CustomMessage("a master unlocker", /*german*/ "ein Meisterentsperrer", /*french*/ "un Kit de Déverrouillage") });
// /*spanish*/un desbloqueador maestro
hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_QUIVER_INF] = HintText(CustomMessage("an infinite Quiver", /*german*/"!!!", /*french*/"un Carquois Infini"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {
CustomMessage("", /*german*/"!!!", /*french*/"!!!")});
hintTextTable[RHT_BOMB_BAG_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_BOMB_BAG_INF] = HintText(CustomMessage("an infinite Bomb Bag", /*german*/"!!!", /*french*/"un Sac de Bombe sans fond"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {
CustomMessage("", /*german*/"!!!", /*french*/"!!!")});
hintTextTable[RHT_BULLET_BAG_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_BULLET_BAG_INF] = HintText(CustomMessage("an infinite Bullet Bag", /*german*/"!!!", /*french*/"un Sac de Graine sans fond"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {
CustomMessage("", /*german*/"!!!", /*french*/"!!!")});
hintTextTable[RHT_STICK_UPGRADE_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_STICK_UPGRADE_INF] = HintText(CustomMessage("infinite Deku Sticks", /*german*/"!!!", /*french*/" des Bâtons Mojo illimités"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {
CustomMessage("", /*german*/"!!!", /*french*/"!!!")});
hintTextTable[RHT_NUT_UPGRADE_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_NUT_UPGRADE_INF] = HintText(CustomMessage("infinite Deku Nut", /*german*/"!!!", /*french*/"des Noix Mojo illimitées"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {
CustomMessage("", /*german*/"!!!", /*french*/"!!!")});
hintTextTable[RHT_MAGIC_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_MAGIC_INF] = HintText(CustomMessage("unlimited Magic", /*german*/"!!!", /*french*/"de la Magie infinie"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {
CustomMessage("", /*german*/"!!!", /*french*/"!!!")});
hintTextTable[RHT_BOMBCHU_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_BOMBCHU_INF] = HintText(CustomMessage("infinite Bombchus", /*german*/"!!!", /*french*/"des Missiles Teigneux illimités"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {
CustomMessage("", /*german*/"!!!", /*french*/"!!!")});
hintTextTable[RHT_WALLET_INF] = HintText(CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
hintTextTable[RHT_WALLET_INF] = HintText(CustomMessage("an infinite Wallet", /*german*/"!!!", /*french*/"une Bourse sans fond"),
{
CustomMessage("", /*german*/"!!!", /*french*/"!!!"),
}, {

View file

@ -1297,7 +1297,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).Get() >= 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->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

@ -2,7 +2,6 @@
#include <libultraship/libultraship.h>
#include <boost_custom/container_hash/hash_32.hpp>
#include "custom_messages.hpp"
#include "fill.hpp"
#include "../location_access.h"
#include "random.hpp"
@ -23,7 +22,6 @@ int Playthrough_Init(uint32_t seed, std::set<RandomizerCheck> excludedLocations,
auto ctx = Rando::Context::GetInstance();
ctx->overrides.clear();
CustomMessages::ClearMessages();
ctx->ItemReset();
ctx->HintReset();
ctx->GetLogic()->Reset();

View file

@ -57,7 +57,7 @@ void GenerateStartingInventory() {
// Add Ganon's Boss key with Triforce Hunt so the game thinks it's obtainable from the start.
// During save init, the boss key isn't actually given and it's instead given when completing the triforce.
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH) ||
ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_TRIFORCE_HUNT)) {
ctx->GetOption(RSK_TRIFORCE_HUNT)) {
AddItemToInventory(RG_GANONS_CASTLE_BOSS_KEY);
}

View file

@ -0,0 +1,43 @@
#include <libultraship/bridge.h>
#include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/ResourceManagerHelpers.h"
#include "soh/ShipInit.hpp"
#include "z64save.h"
#include "objects/object_gi_compass/object_gi_compass.h"
#include "objects/object_gi_map/object_gi_map.h"
extern "C" {
extern SaveContext gSaveContext;
#include "variables.h"
#include "macros.h"
u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
}
#define CVAR_COLORED_MAPS_AND_COMPASSES_NAME CVAR_RANDOMIZER_ENHANCEMENT("ColoredMapsAndCompasses")
#define CVAR_COLORED_MAPS_AND_COMPASSES_DEFAULT 1
#define CVAR_COLORED_MAPS_AND_COMPASSES_VALUE CVarGetInteger(CVAR_COLORED_MAPS_AND_COMPASSES_NAME, CVAR_COLORED_MAPS_AND_COMPASSES_DEFAULT)
void OnLoadFileColoredMapsAndCompasses(int32_t _) {
s8 mapsAndCompassesCanBeOutsideDungeon = IS_RANDO && DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_SHUFFLE_MAPANDCOMPASS);
s8 isColoredMapsAndCompassesEnabled = mapsAndCompassesCanBeOutsideDungeon && CVAR_COLORED_MAPS_AND_COMPASSES_VALUE;
if (isColoredMapsAndCompassesEnabled) {
ResourceMgr_PatchGfxByName(gGiDungeonMapDL, "Map_PrimColor", 5, gsDPNoOp());
ResourceMgr_PatchGfxByName(gGiDungeonMapDL, "Map_EnvColor", 6, gsDPNoOp());
ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_PrimColor", 5, gsDPNoOp());
ResourceMgr_PatchGfxByName(gGiCompassDL, "Compass_EnvColor", 6, gsDPNoOp());
} else {
ResourceMgr_UnpatchGfxByName(gGiDungeonMapDL, "Map_PrimColor");
ResourceMgr_UnpatchGfxByName(gGiDungeonMapDL, "Map_EnvColor");
ResourceMgr_UnpatchGfxByName(gGiCompassDL, "Compass_PrimColor");
ResourceMgr_UnpatchGfxByName(gGiCompassDL, "Compass_EnvColor");
}
}
void RegisterColoredMapsAndCompasses() {
COND_HOOK(OnLoadFile, CVAR_COLORED_MAPS_AND_COMPASSES_VALUE, OnLoadFileColoredMapsAndCompasses)
//Also need to call it directly to patch/unpatch on cvar change
OnLoadFileColoredMapsAndCompasses(0);
}
static RegisterShipInitFunc initFunc(RegisterColoredMapsAndCompasses, { CVAR_COLORED_MAPS_AND_COMPASSES_NAME });

View file

@ -838,8 +838,8 @@ void PlandomizerDrawItemSlots(uint32_t index) {
void PlandomizerDrawShopSlider(uint32_t index) {
ImGui::PushID(index);
UIWidgets::SliderInt("Price:", &plandoLogData[index].shopPrice, UIWidgets::IntSliderOptions()
.Color(THEME_COLOR).Format("%d Rupees").Min(0).Max(999).LabelPosition(UIWidgets::LabelPosition::Near)
.ComponentAlignment(UIWidgets::ComponentAlignment::Right).Size(UIWidgets::Sizes::Inline));
.Color(THEME_COLOR).Format("%d Rupees").Min(0).Max(999).LabelPosition(UIWidgets::LabelPositions::Near)
.ComponentAlignment(UIWidgets::ComponentAlignments::Right).Size(UIWidgets::Sizes::Inline));
ImGui::PopID();
}
@ -878,7 +878,7 @@ void PlandomizerDrawIceTrapSetup(uint32_t index) {
}
ImGui::SameLine();
}
if (UIWidgets::InputString("##TrapName", &trapTextInput, UIWidgets::InputOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPosition::None))) {
if (UIWidgets::InputString("##TrapName", &trapTextInput, UIWidgets::InputOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None))) {
plandoLogData[index].iceTrapName = trapTextInput.c_str();
}
@ -933,7 +933,7 @@ void PlandomizerDrawOptions() {
PlandomizerPopulateSeedList();
static size_t selectedList = 0;
if (existingSeedList.size() != 0) {
UIWidgets::Combobox("##JsonFiles", &selectedList, existingSeedList, UIWidgets::ComboboxOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPosition::None));
UIWidgets::Combobox("##JsonFiles", &selectedList, existingSeedList, UIWidgets::ComboboxOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None));
}
else {
ImGui::Text("No Spoiler Logs found.");
@ -1024,7 +1024,7 @@ void PlandomizerDrawOptions() {
}
if (getTabID == TAB_LOCATIONS) {
if (plandoLogData.size() > 0) {
UIWidgets::Combobox("Filter by Area:##AreaFilter", &selectedArea, rcAreaNameMap, UIWidgets::ComboboxOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPosition::Near).ComponentAlignment(UIWidgets::ComponentAlignment::Right));
UIWidgets::Combobox("Filter by Area:##AreaFilter", &selectedArea, rcAreaNameMap, UIWidgets::ComboboxOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::Near).ComponentAlignment(UIWidgets::ComponentAlignments::Right));
ImGui::SameLine();
if (UIWidgets::Button("Empty All Rewards", UIWidgets::ButtonOptions().Color(THEME_COLOR).Size(UIWidgets::Sizes::Inline).Padding(ImVec2(10.f, 6.f)))) {
PlandomizerRemoveAllItems();
@ -1061,7 +1061,7 @@ void PlandomizerDrawHintsWindow() {
}
ImGui::SameLine();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - 10);
if (UIWidgets::InputString("##HintMessage", &hintInputText, UIWidgets::InputOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPosition::None).Tooltip(plandomizerHintsTooltip().c_str()))) {
if (UIWidgets::InputString("##HintMessage", &hintInputText, UIWidgets::InputOptions().Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::None).Tooltip(plandomizerHintsTooltip().c_str()))) {
plandoHintData[index].hintText = hintInputText.c_str();
}
index++;

View file

@ -54,9 +54,6 @@ void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor, PlayState* play) {
void ObjTsubo_RandomizerInit(void* actorRef) {
Actor* actor = static_cast<Actor*>(actorRef);
// Check for Lake Hylia specifically because the game spawns 2 pots out of bounds there for some reason.
if (actor->id != ACTOR_OBJ_TSUBO || gPlayState->sceneNum == SCENE_LAKE_HYLIA || gPlayState->sceneNum == SCENE_HYRULE_CASTLE) return;
ObjTsubo* potActor = static_cast<ObjTsubo*>(actorRef);
potActor->potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z);

View file

@ -11,6 +11,7 @@
#include "objects/object_gi_key/object_gi_key.h"
#include "objects/object_gi_bosskey/object_gi_bosskey.h"
#include "objects/object_gi_compass/object_gi_compass.h"
#include "objects/object_gi_map/object_gi_map.h"
#include "objects/object_gi_hearts/object_gi_hearts.h"
#include "objects/object_gi_scale/object_gi_scale.h"
#include "objects/object_gi_fire/object_gi_fire.h"
@ -80,7 +81,7 @@ Color_RGB8 SmallEmblemDefaultValue[10] = {
extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry) {
s8 isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 0);
s8 isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1);
int slot = getItemEntry->drawItemId - RG_FOREST_TEMPLE_SMALL_KEY;
Gfx* customIconDLs[] = {
@ -131,15 +132,35 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" {
void GetItem_DrawCompass(PlayState* play, s16 drawId);
void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName);
extern "C" void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry) {
s16 color_slot = getItemEntry->drawItemId - RG_DEKU_TREE_MAP;
s16 colors[12][3] = {
{ 4, 100, 46 }, // Deku Tree
{ 140, 30, 30 }, // Dodongo's Cavern
{ 30, 60, 255 }, // Jabu Jabu's Belly
{ 4, 195, 46 }, // Forest Temple
{ 237, 95, 95 }, // Fire Temple
{ 85, 180, 223 }, // Water Temple
{ 222, 158, 47 }, // Spirit Temple
{ 126, 16, 177 }, // Shadow Temple
{ 227, 110, 255 }, // Bottom of the Well
{ 0, 255, 255 }, // Ice Cavern
};
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255);
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiDungeonMapDL);
CLOSE_DISPS(play->state.gfxCtx);
}
extern "C" void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEntry) {
s16 color_slot = getItemEntry->getItemId - RG_DEKU_TREE_COMPASS;
s16 color_slot = getItemEntry->drawItemId - RG_DEKU_TREE_COMPASS;
s16 colors[12][3] = {
{ 4, 100, 46 }, // Deku Tree
{ 140, 30, 30 }, // Dodongo's Cavern
@ -158,8 +179,7 @@ extern "C" void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEnt
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 255);
gDPSetEnvColor(POLY_OPA_DISP++, colors[color_slot][0] / 2, colors[color_slot][1] / 2, colors[color_slot][2] / 2, 255);
@ -167,8 +187,7 @@ extern "C" void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEnt
gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gGiCompassDL);
POLY_XLU_DISP = Gfx_SetupDL(POLY_XLU_DISP, 5);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiCompassGlassDL);
CLOSE_DISPS(play->state.gfxCtx);
@ -247,7 +266,7 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
}
extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry) {
s8 isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 0);
s8 isCustomKeysEnabled = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("CustomKeyModels"), 1);
int slot = getItemEntry->drawItemId - RG_FOREST_TEMPLE_KEY_RING;
Gfx* CustomIconDLs[] = {

View file

@ -10,6 +10,7 @@ typedef struct PlayState PlayState;
extern "C" {
#endif
void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawMap(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawCompass(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry);

View file

@ -587,6 +587,10 @@ CustomMessage Hint::GetGanonBossKeyText() {
auto ctx = Rando::Context::GetInstance();
CustomMessage ganonBossKeyMessage;
if (ctx->GetOption(RSK_TRIFORCE_HUNT)) {
return StaticData::hintTextTable[RHT_GANON_BK_TRIFORCE_HINT].GetHintMessage();
}
if (ctx->GetOption(RSK_GANONS_BOSS_KEY).Is(RO_GANON_BOSS_KEY_STARTWITH)) {
return StaticData::hintTextTable[RHT_GANON_BK_START_WITH_HINT].GetHintMessage();
}
@ -631,9 +635,6 @@ CustomMessage Hint::GetGanonBossKeyText() {
ganonBossKeyMessage = StaticData::hintTextTable[RHT_LACS_TOKENS_HINT].GetHintMessage();
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();
}
return ganonBossKeyMessage;
}

View file

@ -297,14 +297,19 @@ void RandomizerOnPlayerUpdateForRCQueueHandler() {
rc != RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE &&
// Always show ItemGet animation for ice traps
!(getItemEntry.modIndex == MOD_RANDOMIZER && getItemEntry.getItemId == RG_ICE_TRAP) &&
// Always show ItemGet animation outside of randomizer to keep behaviour consistent in vanilla
IS_RANDO &&
(
CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_DISABLED) == SGIA_ALL ||
(
CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_DISABLED) == SGIA_JUNK &&
(
//crude fix to ensure map hints are readable. Ideally replace with better hint tracking.
!(getItemEntry.getItemId >= RG_DEKU_TREE_MAP && getItemEntry.getItemId <= RG_ICE_CAVERN_MAP) && (
getItemEntry.getItemCategory == ITEM_CATEGORY_JUNK ||
getItemEntry.getItemCategory == ITEM_CATEGORY_SKULLTULA_TOKEN ||
getItemEntry.getItemCategory == ITEM_CATEGORY_LESSER
)
)
)
)
@ -2031,11 +2036,13 @@ void RandomizerOnActorInitHandler(void* actorRef) {
break;
}
//Deletes all actors in the boss category if the soul isn't found.
//Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual bosses,
//so ignore any "boss" if `currentBossSoulRandInf` doesn't change from RAND_INF_MAX.
// Deletes all actors in the boss category if the soul isn't found.
// Some actors, like Dark Link, Arwings, and Zora's Sapphire...?, are in this category despite not being actual bosses,
// so ignore any "boss" if `currentBossSoulRandInf` doesn't change from RAND_INF_MAX.
// Iron Knuckle (Nabooru) in Twinrova's room is a special exception, so exclude knuckles too.
if (currentBossSoulRandInf != RAND_INF_MAX) {
if (!Flags_GetRandomizerInf(currentBossSoulRandInf) && actor->category == ACTORCAT_BOSS) {
if (!Flags_GetRandomizerInf(currentBossSoulRandInf) && actor->category == ACTORCAT_BOSS &&
actor->id != ACTOR_EN_IK) {
Actor_Delete(&gPlayState->actorCtx, actor, gPlayState);
}
//Special case for Phantom Ganon's horse (and fake), as they're considered "background actors",

View file

@ -94,6 +94,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
actual = RG_DEKU_STICK_BAG;
break;
}
[[fallthrough]];
case 1:
if (infiniteUpgrades == RO_INF_UPGRADES_CONDENSED_PROGRESSIVE) {
actual = RG_STICK_UPGRADE_INF;
@ -123,6 +124,7 @@ std::shared_ptr<GetItemEntry> Item::GetGIEntry() const { // NOLINT(*-no-recursio
actual = RG_DEKU_NUT_BAG;
break;
}
[[fallthrough]];
case 1:
if (infiniteUpgrades == RO_INF_UPGRADES_CONDENSED_PROGRESSIVE) {
actual = RG_NUT_UPGRADE_INF;

View file

@ -98,15 +98,25 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_PRELUDE_OF_LIGHT] = Item(RG_PRELUDE_OF_LIGHT, Text{ "Prelude of Light", "Prélude de la Lumière", "Kantate des Lichts" }, ITEMTYPE_SONG, 0xC0, true, LOGIC_PRELUDE_OF_LIGHT, RHT_PRELUDE_OF_LIGHT, ITEM_SONG_PRELUDE, OBJECT_GI_MELODY, GID_SONG_PRELUDE, 0x78, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_NONE);
// Maps and Compasses
itemTable[RG_DEKU_TREE_MAP] = Item(RG_DEKU_TREE_MAP, Text{ "Great Deku Tree Map", "Carte de l'Arbre Mojo", "Karte des Deku-Baums" }, ITEMTYPE_MAP, 0xA5, false, LOGIC_MAP_DEKU_TREE, RHT_DEKU_TREE_MAP, RG_DEKU_TREE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DEKU_TREE_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_DODONGOS_CAVERN_MAP] = Item(RG_DODONGOS_CAVERN_MAP, Text{ "Dodongo's Cavern Map", "Carte de la Caverne Dodongo", "Karte der Dodongo-Höhle" }, ITEMTYPE_MAP, 0xA6, false, LOGIC_MAP_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_MAP, RG_DODONGOS_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DODONGOS_CAVERN_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_JABU_JABUS_BELLY_MAP] = Item(RG_JABU_JABUS_BELLY_MAP, Text{ "Jabu-Jabu's Belly Map", "Carte du Ventre de Jabu-Jabu", "Karte des Jabu-Jabu-Bauchs" }, ITEMTYPE_MAP, 0xA7, false, LOGIC_MAP_JABU_JABUS_BELLY, RHT_JABU_JABUS_BELLY_MAP, RG_JABU_JABUS_BELLY_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_JABU_JABUS_BELLY_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_FOREST_TEMPLE_MAP] = Item(RG_FOREST_TEMPLE_MAP, Text{ "Forest Temple Map", "Carte du Temple de la Forêt", "Karte des Waldtempels" }, ITEMTYPE_MAP, 0xA8, false, LOGIC_MAP_FOREST_TEMPLE, RHT_FOREST_TEMPLE_MAP, RG_FOREST_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_FOREST_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_FIRE_TEMPLE_MAP] = Item(RG_FIRE_TEMPLE_MAP, Text{ "Fire Temple Map", "Carte due Temple de Feu", "Karte des Feuertempels" }, ITEMTYPE_MAP, 0xA9, false, LOGIC_MAP_FIRE_TEMPLE, RHT_FIRE_TEMPLE_MAP, RG_FIRE_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_FIRE_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_WATER_TEMPLE_MAP] = Item(RG_WATER_TEMPLE_MAP, Text{ "Water Temple Map", "Carte du Temple de l'Eau", "Karte des Wassertempels" }, ITEMTYPE_MAP, 0xAA, false, LOGIC_MAP_WATER_TEMPLE, RHT_WATER_TEMPLE_MAP, RG_WATER_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_WATER_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_SPIRIT_TEMPLE_MAP] = Item(RG_SPIRIT_TEMPLE_MAP, Text{ "Spirit Temple Map", "Carte due Temple de l'Esprit", "Karte des Geistertempels" }, ITEMTYPE_MAP, 0xAB, false, LOGIC_MAP_SPIRIT_TEMPLE, RHT_SPIRIT_TEMPLE_MAP, RG_SPIRIT_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SPIRIT_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_SHADOW_TEMPLE_MAP] = Item(RG_SHADOW_TEMPLE_MAP, Text{ "Shadow Temple Map", "Carte du Temple de l'Ombre", "Karte des Schattentempels" }, ITEMTYPE_MAP, 0xAC, false, LOGIC_MAP_SHADOW_TEMPLE, RHT_SHADOW_TEMPLE_MAP, RG_SHADOW_TEMPLE_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_SHADOW_TEMPLE_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_BOTTOM_OF_THE_WELL_MAP] = Item(RG_BOTTOM_OF_THE_WELL_MAP, Text{ "Bottom of the Well Map", "Carte du Puits", "Karte des Grund des Brunnens" }, ITEMTYPE_MAP, 0xAD, false, LOGIC_MAP_BOTTOM_OF_THE_WELL, RHT_BOTTOM_OF_THE_WELL_MAP, RG_BOTTOM_OF_THE_WELL_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_BOTTOM_OF_THE_WELL_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_ICE_CAVERN_MAP] = Item(RG_ICE_CAVERN_MAP, Text{ "Ice Cavern Map", "Carte de la Caverne Polaire", "Karte der Eishöhle" }, ITEMTYPE_MAP, 0xAE, false, LOGIC_MAP_ICE_CAVERN, RHT_ICE_CAVERN_MAP, RG_ICE_CAVERN_MAP, OBJECT_GI_MAP, GID_DUNGEON_MAP, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_ICE_CAVERN_MAP].SetCustomDrawFunc(Randomizer_DrawMap);
itemTable[RG_DEKU_TREE_COMPASS] = Item(RG_DEKU_TREE_COMPASS, Text{ "Great Deku Tree Compass", "Boussole de l'Arbre Mojo", "Kompaß des Deku-Baums" }, ITEMTYPE_COMPASS, 0x9B, false, LOGIC_COMPASS_DEKU_TREE, RHT_DEKU_TREE_COMPASS, RG_DEKU_TREE_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_DUNGEON_MAP, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
itemTable[RG_DEKU_TREE_COMPASS].SetCustomDrawFunc(Randomizer_DrawCompass);
itemTable[RG_DODONGOS_CAVERN_COMPASS] = Item(RG_DODONGOS_CAVERN_COMPASS, Text{ "Dodongo's Cavern Compass", "Boussole de la Caverne Dodongo", "Kompaß der Dodongo-Höhle" }, ITEMTYPE_COMPASS, 0x9C, false, LOGIC_COMPASS_DODONGOS_CAVERN, RHT_DODONGOS_CAVERN_COMPASS, RG_DODONGOS_CAVERN_COMPASS, OBJECT_GI_COMPASS, GID_COMPASS, TEXT_ITEM_COMPASS, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);
@ -339,7 +349,7 @@ void Rando::StaticData::InitItemTable() {
itemTable[RG_BRONZE_SCALE] = Item(RG_BRONZE_SCALE, Text{ "Bronze Scale", "Écaille de Bronze", "Bronzene Schuppe" }, ITEMTYPE_ITEM, GI_SCALE_SILVER, true, LOGIC_PROGRESSIVE_WALLET, RHT_BRONZE_SCALE, RG_BRONZE_SCALE, OBJECT_GI_SCALE, GID_SCALE_SILVER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BRONZE_SCALE].SetCustomDrawFunc(Randomizer_DrawBronzeScale);
itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "!!!", "!!!" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOMBCHU_BAG] = Item(RG_BOMBCHU_BAG, Text{ "Bombchu Bag", "!!!", "Sac de Missiles Teigneux" }, ITEMTYPE_ITEM, RG_BOMBCHU_BAG, true, LOGIC_BOMBCHUS, RHT_BOMBCHU_BAG, RG_BOMBCHU_BAG, OBJECT_GI_BOMB_2, GID_BOMBCHU, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER);
itemTable[RG_BOMBCHU_BAG].SetCustomDrawFunc(Randomizer_DrawBombchuBag);
itemTable[RG_QUIVER_INF] = Item(RG_QUIVER_INF, Text{ "Infinite Quiver", "Carquois Infini", "Unendlicher Köcher" }, ITEMTYPE_ITEM, RG_QUIVER_INF, true, LOGIC_PROGRESSIVE_BOW, RHT_QUIVER_INF, RG_QUIVER_INF, OBJECT_GI_ARROWCASE, GID_QUIVER_50, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER);

View file

@ -71,8 +71,8 @@ void RegionTable_Init_DekuTree() {
}, {
//Locations
LOCATION(RC_DEKU_TREE_BASEMENT_CHEST, true),
LOCATION(RC_DEKU_TREE_GS_BASEMENT_GATE, logic->CanJumpslashExceptHammer() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_BOOMERANG) || logic->HasExplosives() || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE)),
LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanUseProjectile() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) && logic->CanJumpslashExceptHammer())),
LOCATION(RC_DEKU_TREE_GS_BASEMENT_GATE, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ED_SHORT_JUMPSLASH)),
LOCATION(RC_DEKU_TREE_GS_BASEMENT_VINES, logic->CanKillEnemy(RE_GOLD_SKULLTULA, ctx->GetTrickOption(RT_DEKU_MQ_COMPASS_GS) ? ED_SHORT_JUMPSLASH : ED_BOMB_THROW)),
}, {
//Exits
Entrance(RR_DEKU_TREE_LOBBY, []{return true;}),
@ -84,7 +84,7 @@ void RegionTable_Init_DekuTree() {
areaTable[RR_DEKU_TREE_BASEMENT_SCRUB_ROOM] = Region("Deku Tree Basement Scrub Room", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_DEKU_TREE_BASEMENT_LOWER, []{return true;}),
Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW);});}),
Entrance(RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT, []{return Here(RR_DEKU_TREE_BASEMENT_SCRUB_ROOM, []{return logic->CanHitEyeTargets();});}),
});
areaTable[RR_DEKU_TREE_BASEMENT_WATER_ROOM_FRONT] = Region("Deku Tree Basement Water Room Front", "Deku Tree", {RA_DEKU_TREE}, NO_DAY_NIGHT_CYCLE, {}, {}, {

View file

@ -154,6 +154,7 @@ void RegionTable_Init_DodongosCavern() {
LOCATION(RC_DODONGOS_CAVERN_BLADE_ROOM_HEART, true),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_ARMOS_ROOM, []{return true;}),
Entrance(RR_DODONGOS_CAVERN_2F_SIDE_ROOM, []{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBreakMudWalls() || (ctx->GetTrickOption(RT_DC_SCRUB_ROOM) && logic->HasItem(RG_GORONS_BRACELET));});}),
Entrance(RR_DODONGOS_CAVERN_FIRST_SLINGSHOT_ROOM, []{return Here(RR_DODONGOS_CAVERN_BOMB_ROOM_LOWER, []{return logic->CanBreakMudWalls() || logic->HasItem(RG_GORONS_BRACELET);});}),
Entrance(RR_DODONGOS_CAVERN_BOMB_ROOM_UPPER, []{return (logic->IsAdult && ctx->GetTrickOption(RT_DC_JUMP)) || logic->CanUse(RG_HOVER_BOOTS) || (logic->IsAdult && logic->CanUse(RG_LONGSHOT)) || (ctx->GetTrickOption(RT_DAMAGE_BOOST_SIMPLE) && logic->HasExplosives() && logic->CanJumpslash());}),
@ -304,6 +305,7 @@ void RegionTable_Init_DodongosCavern() {
LOCATION(RC_DODONGOS_CAVERN_MQ_STAIRCASE_POT_4, logic->CanBreakPots()),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return true;}),
//This is possible with sticks and shield, igniting a first flower by "touch" then very quickly crouch stabbing in a way that cuts the corner to light the 3rd bomb on the other side, but that's a trick
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_UPPER, []{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->HasExplosives() || logic->CanUse(RG_DINS_FIRE) || (ctx->GetTrickOption(RT_DC_STAIRCASE) && logic->CanUse(RG_FAIRY_BOW));});}),
Entrance(RR_DODONGOS_CAVERN_MQ_STAIRS_PAST_MUD_WALL, []{return Here(RR_DODONGOS_CAVERN_MQ_STAIRS_LOWER, []{return logic->CanBreakMudWalls();});}),
@ -460,9 +462,9 @@ void RegionTable_Init_DodongosCavern() {
LOCATION(RC_DODONGOS_CAVERN_MQ_POE_ROOM_POT_4, logic->CanBreakPots()),
}, {
//Exits
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_RIGHT_SIDE, []{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return true;}),
Entrance(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, []{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOBBY, []{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}),
Entrance(RR_DODONGOS_CAVERN_MQ_LOWER_LIZALFOS, []{return true;}),
Entrance(RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM, []{return Here(RR_DODONGOS_CAVERN_MQ_POES_ROOM, []{return logic->CanDetonateBombFlowers() || logic->HasItem(RG_GORONS_BRACELET);});}),
});
areaTable[RR_DODONGOS_CAVERN_MQ_MAD_SCRUB_ROOM] = Region("Dodongos Cavern Mad Scrub Room", "Dodongos Cavern", {RA_DODONGOS_CAVERN}, NO_DAY_NIGHT_CYCLE, {}, {

View file

@ -28,7 +28,7 @@ void RegionTable_Init_ForestTemple() {
areaTable[RR_FOREST_TEMPLE_SOUTH_CORRIDOR] = Region("Forest Temple South Corridor", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_FOREST_TEMPLE_FIRST_ROOM, []{return true;}),
Entrance(RR_FOREST_TEMPLE_LOBBY, []{return logic->CanAttack() || logic->CanUse(RG_NUTS);}),
Entrance(RR_FOREST_TEMPLE_LOBBY, []{return logic->CanPassEnemy(RE_BIG_SKULLTULA);}),
});
areaTable[RR_FOREST_TEMPLE_LOBBY] = Region("Forest Temple Lobby", "Forest Temple", {RA_FOREST_TEMPLE}, NO_DAY_NIGHT_CYCLE, {

View file

@ -61,7 +61,7 @@ void RegionTable_Init_GanonsCastle() {
EventAccess(&logic->ForestTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE));}),
}, {
//Locations
LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanDamage()),
LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_CHEST, logic->CanKillEnemy(RE_WOLFOS)),
LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_1, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE))),
LOCATION(RC_GANONS_CASTLE_FOREST_TRIAL_POT_2, logic->CanBreakPots() && (logic->CanUse(RG_FIRE_ARROWS) || logic->CanUse(RG_DINS_FIRE))),
}, {});
@ -78,7 +78,7 @@ void RegionTable_Init_GanonsCastle() {
areaTable[RR_GANONS_CASTLE_WATER_TRIAL] = Region("Ganon's Castle Water Trial", "Ganon's Castle", {RA_GANONS_CASTLE}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->BlueFireAccess, []{return logic->BlueFireAccess || logic->HasBottle();}),
EventAccess(&logic->BlueFireAccess, []{return true;}),
EventAccess(&logic->FairyPot, []{return logic->FairyPot || (logic->BlueFire() && logic->CanKillEnemy(RE_FREEZARD));}),
EventAccess(&logic->WaterTrialClear, []{return logic->BlueFire() && logic->IsAdult && logic->CanUse(RG_MEGATON_HAMMER) && logic->CanUse(RG_LIGHT_ARROWS);}),
}, {
@ -112,7 +112,7 @@ void RegionTable_Init_GanonsCastle() {
EventAccess(&logic->SpiritTrialClear, []{return logic->CanUse(RG_LIGHT_ARROWS) && (logic->CanUse(RG_MIRROR_SHIELD) || ctx->GetOption(RSK_SUNLIGHT_ARROWS)) && logic->CanUse(RG_BOMBCHU_5) && ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT));}),
}, {
//Locations
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanJumpslashExceptHammer()),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_CRYSTAL_SWITCH_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && (logic->CanJumpslashExceptHammer() || logic->CanUse(RG_BOMBCHU_5))),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_INVISIBLE_CHEST, (ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && (ctx->GetTrickOption(RT_LENS_GANON) || logic->CanUse(RG_LENS_OF_TRUTH))),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_1, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),
LOCATION(RC_GANONS_CASTLE_SPIRIT_TRIAL_POT_2, ((ctx->GetTrickOption(RT_GANON_SPIRIT_TRIAL_HOOKSHOT) && logic->CanJumpslashExceptHammer()) || logic->CanUse(RG_HOOKSHOT)) && logic->CanUse(RG_BOMBCHU_5) && logic->CanUse(RG_FAIRY_BOW) && (logic->CanUse(RG_MIRROR_SHIELD) || (ctx->GetOption(RSK_SUNLIGHT_ARROWS) && logic->CanUse(RG_LIGHT_ARROWS)))),

View file

@ -17,8 +17,8 @@ void RegionTable_Init_GerudoTrainingGround() {
areaTable[RR_GERUDO_TRAINING_GROUND_LOBBY] = Region("Gerudo Training Ground Lobby", "Gerudo Training Ground", {RA_GERUDO_TRAINING_GROUND}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_FAIRY_SLINGSHOT)),
LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_LEFT_CHEST, logic->CanHitEyeTargets()),
LOCATION(RC_GERUDO_TRAINING_GROUND_LOBBY_RIGHT_CHEST, logic->CanHitEyeTargets()),
LOCATION(RC_GERUDO_TRAINING_GROUND_STALFOS_CHEST, logic->CanKillEnemy(RE_STALFOS, ED_CLOSE, true, 2, true)),
LOCATION(RC_GERUDO_TRAINING_GROUND_BEAMOS_CHEST, logic->CanKillEnemy(RE_BEAMOS) && logic->CanKillEnemy(RE_DINOLFOS, ED_CLOSE, true, 2, true)),
LOCATION(RC_GERUDO_TRAINING_GROUND_ENTRANCE_STORMS_FAIRY, logic->CanUse(RG_SONG_OF_STORMS)),

View file

@ -21,18 +21,18 @@ void RegionTable_Init_IceCavern() {
}, {
//Exits
Entrance(RR_ICE_CAVERN_ENTRYWAY, []{return true;}),
Entrance(RR_ICE_CAVERN_MAIN, []{return Here(RR_ICE_CAVERN_BEGINNING, []{return (logic->CanUse(RG_MASTER_SWORD) || logic->CanUse(RG_BIGGORON_SWORD)) || logic->CanUse(RG_MEGATON_HAMMER) || logic->HasExplosives() || logic->CanUse(RG_HOOKSHOT) || logic->CanUse(RG_DINS_FIRE);});}),
Entrance(RR_ICE_CAVERN_MAIN, []{return Here(RR_ICE_CAVERN_BEGINNING, []{return logic->CanKillEnemy(RE_FREEZARD, ED_CLOSE, true, 4);});}),
});
areaTable[RR_ICE_CAVERN_MAIN] = Region("Ice Cavern", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->BlueFireAccess, []{return logic->BlueFireAccess || (logic->IsAdult && logic->HasBottle());}),
EventAccess(&logic->BlueFireAccess, []{return logic->IsAdult;}),
}, {
//Locations
LOCATION(RC_ICE_CAVERN_MAP_CHEST, logic->BlueFire() && logic->IsAdult),
LOCATION(RC_ICE_CAVERN_COMPASS_CHEST, logic->BlueFire()),
LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE))),
LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && (logic->CanJumpslash() || logic->CanUse(RG_FAIRY_SLINGSHOT) || logic->CanUse(RG_FAIRY_BOW) || logic->CanUse(RG_DINS_FIRE)) && logic->IsAdult),
LOCATION(RC_ICE_CAVERN_IRON_BOOTS_CHEST, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS)),
LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->BlueFire() && logic->CanKillEnemy(RE_WOLFOS) && logic->IsAdult),
LOCATION(RC_ICE_CAVERN_FREESTANDING_POH, logic->BlueFire()),
LOCATION(RC_ICE_CAVERN_GS_SPINNING_SCYTHE_ROOM, logic->HookshotOrBoomerang()),
LOCATION(RC_ICE_CAVERN_GS_HEART_PIECE_ROOM, logic->BlueFire() && logic->HookshotOrBoomerang()),
@ -125,8 +125,8 @@ void RegionTable_Init_IceCavern() {
LOCATION(RC_SHEIK_IN_ICE_CAVERN, logic->CanKillEnemy(RE_STALFOS)),
}, {
//Exits
Entrance(RR_ICE_CAVERN_MQ_SCARECROW_ROOM, []{return logic->BlueFire() && Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}),
Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->CanUse(RG_IRON_BOOTS) && Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}),
Entrance(RR_ICE_CAVERN_MQ_WEST_CORRIDOR, []{return Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}),
Entrance(RR_ICE_CAVERN_MQ_BEGINNING, []{return logic->CanUse(RG_IRON_BOOTS) && Here(RR_ICE_CAVERN_MQ_STALFOS_ROOM, []{return logic->CanKillEnemy(RE_STALFOS);});}),
});
areaTable[RR_ICE_CAVERN_MQ_COMPASS_ROOM] = Region("Ice Cavern MQ Compass Room", "Ice Cavern", {RA_ICE_CAVERN}, NO_DAY_NIGHT_CYCLE, {

View file

@ -24,7 +24,6 @@ void RegionTable_Init_JabuJabusBelly() {
//Combines Lift room middle and lower, 1F holes room, the forked corridor, and it's side rooms
areaTable[RR_JABU_JABUS_BELLY_MAIN] = Region("Jabu Jabus Belly Main", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->JabuRutoInB1, []{return true;}),
EventAccess(&logic->JabuWestTentacle, []{return logic->JabuRutoIn1F && logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}),
}, {
//Locations
@ -263,7 +262,7 @@ void RegionTable_Init_JabuJabusBelly() {
areaTable[RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS] = Region("Jabu Jabus Belly MQ West Forked Rooms", "Jabu Jabus Belly", {RA_JABU_JABUS_BELLY}, NO_DAY_NIGHT_CYCLE, {
//Events
EventAccess(&logic->JabuWestTentacle, []{return logic->CanUse(RG_BOOMERANG);}),
EventAccess(&logic->JabuWestTentacle, []{return logic->CanKillEnemy(RE_TENTACLE, ED_BOOMERANG);}),
}, {
//Locations
LOCATION(RC_JABU_JABUS_BELLY_MQ_GS_TAILPASARAN_ROOM, Here(RR_JABU_JABUS_BELLY_MQ_WEST_FORKED_ROOMS, []{return logic->HasExplosives();}) && logic->CanGetEnemyDrop(RE_GOLD_SKULLTULA, ED_BOOMERANG)),

View file

@ -79,8 +79,8 @@ void RegionTable_Init_ShadowTemple() {
areaTable[RR_SHADOW_TEMPLE_WIND_TUNNEL] = Region("Shadow Temple Wind Tunnel", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {
//Locations
LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_CHEST, true),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanJumpslashExceptHammer()),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, true),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_ENEMY_CHEST, logic->CanKillEnemy(RE_GIBDO, ED_CLOSE, true, 2)),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_HIDDEN_CHEST, logic->HasExplosives()),
LOCATION(RC_SHADOW_TEMPLE_GS_NEAR_SHIP, logic->CanUse(RG_LONGSHOT) && logic->SmallKeys(RR_SHADOW_TEMPLE, 4, 5)),
LOCATION(RC_SHADOW_TEMPLE_WIND_HINT_SUN_FAIRY, logic->CanUse(RG_SUNS_SONG)),
LOCATION(RC_SHADOW_TEMPLE_AFTER_WIND_POT_1, logic->CanBreakPots()),
@ -96,7 +96,7 @@ void RegionTable_Init_ShadowTemple() {
//Locations
LOCATION(RC_SHADOW_TEMPLE_SPIKE_WALLS_LEFT_CHEST, logic->CanUse(RG_DINS_FIRE)),
LOCATION(RC_SHADOW_TEMPLE_BOSS_KEY_CHEST, logic->CanUse(RG_DINS_FIRE)),
LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanJumpslashExceptHammer()),
LOCATION(RC_SHADOW_TEMPLE_INVISIBLE_FLOORMASTER_CHEST, logic->CanKillEnemy(RE_FLOORMASTER)),
//RANDOTODO check if child can reach the token
LOCATION(RC_SHADOW_TEMPLE_GS_TRIPLE_GIANT_POT, logic->IsAdult && logic->CanAttack()),
LOCATION(RC_SHADOW_TEMPLE_AFTER_BOAT_POT_1, logic->CanBreakPots()),
@ -181,7 +181,7 @@ void RegionTable_Init_ShadowTemple() {
//Room exists for if it's ever possible to go backwards or void warp into the middle of shadow
areaTable[RR_SHADOW_TEMPLE_MQ_B2_TO_B3_CORRIDOR] = Region("Shadow Temple MQ B2 to B3 Corridor", "Shadow Temple", {RA_SHADOW_TEMPLE}, NO_DAY_NIGHT_CYCLE, {}, {}, {
//Exits
Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->HasExplosives() && logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}),
Entrance(RR_SHADOW_TEMPLE_MQ_FIRST_BEAMOS, []{return logic->SmallKeys(RR_SHADOW_TEMPLE, 2);}),
Entrance(RR_SHADOW_TEMPLE_MQ_UPPER_HUGE_PIT, []{return true;}),
//bunnyhovers + lens lets you go from the very top of upper pit to the stationary invisible platform below quite easily
});

View file

@ -50,7 +50,7 @@ void RegionTable_Init_Graveyard() {
LOCATION(RC_GRAVEYARD_SHIELD_GRAVE_FAIRY_8, true),
}, {
//Exits
Entrance(RR_THE_GRAVEYARD, []{return true;}),
Entrance(RR_GRAVEYARD_SHIELD_GRAVE, []{return true;}),
});
areaTable[RR_GRAVEYARD_HEART_PIECE_GRAVE] = Region("Graveyard Heart Piece Grave", "Graveyard Heart Piece Grave", {}, NO_DAY_NIGHT_CYCLE, {}, {

View file

@ -992,7 +992,7 @@ void Rando::StaticData::InitLocationTable() { //
locationTable[RC_HF_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_HF_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_HYRULE_FIELD, SCENE_GROTTOS, -22947, "Open Grotto Gossip Stone");
locationTable[RC_KAK_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_KAK_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_KAKARIKO_VILLAGE, SCENE_GROTTOS, -22984, "Open Grotto Gossip Stone");
locationTable[RC_ZR_OPEN_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_ZORAS_RIVER, SCENE_GROTTOS, -22985, "Open Grotto Gossip Stone");
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, "Near Shortcuts Gossip Stone");
locationTable[RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_LW_NEAR_SHORTCUTS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_LOST_WOODS, SCENE_GROTTOS, -22964, "Near Shortcuts Grotto Gossip Stone");
locationTable[RC_DMT_STORMS_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMT_STORMS_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_TRAIL, SCENE_GROTTOS, -23255, "Storms Grotto Gossip Stone");
locationTable[RC_DMC_UPPER_GROTTO_GOSSIP_STONE] = Location::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, RCQUEST_BOTH, RCAREA_DEATH_MOUNTAIN_CRATER, SCENE_GROTTOS, -23802, "Upper Grotto Gossip Stone");

View file

@ -677,7 +677,7 @@ namespace Rando {
}
return killed;
case RE_BIG_OCTO:
//If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigains anyway. Bunny makes it free
//If chasing octo is annoying but with rolls you can catch him, and you need rang to get into this room without shenanigans anyway. Bunny makes it free
return CanUse(RG_KOKIRI_SWORD) || CanUse(RG_STICKS) || CanUse(RG_MASTER_SWORD);
case RE_GOHMA:
return HasBossSoul(RG_GOHMA_SOUL) && CanJumpslash() &&
@ -1793,7 +1793,7 @@ namespace Rando {
case ITEMTYPE_EQUIP:
{
RandomizerGet itemRG = item.GetRandomizerGet();
if (itemRG == RG_GIANTS_KNIFE) {
if (itemRG == RG_GIANTS_KNIFE || itemRG == RG_DEKU_SHIELD || itemRG == RG_HYLIAN_SHIELD) {
return;
}
uint32_t equipId = RandoGetToEquipFlag.find(itemRG)->second;
@ -2442,7 +2442,6 @@ namespace Rando {
MQSpiritMapRoomEnemies = false;
MQSpirit3SunsEnemies = false;
Spirit1FSilverRupees = false;
JabuRutoInB1 = false;
JabuRutoIn1F = false;
StopPerformanceTimer(PT_LOGIC_RESET);

View file

@ -175,7 +175,6 @@ class Logic {
bool MQSpiritTimeTravelChest = false;
bool MQSpirit3SunsEnemies = false;
bool Spirit1FSilverRupees = false;
bool JabuRutoInB1 = false;
bool JabuRutoIn1F = false;
/* --- END OF HELPERS AND LOCATION ACCESS --- */

View file

@ -232,7 +232,7 @@ bool Option::RenderCombobox() {
}
UIWidgets::ComboboxOptions widgetOptions = UIWidgets::ComboboxOptions().Color(THEME_COLOR).Tooltip(description.c_str());
if (this->GetKey() == RSK_LOGIC_RULES) {
widgetOptions = widgetOptions.LabelPosition(UIWidgets::LabelPosition::None).ComponentAlignment(UIWidgets::ComponentAlignment::Right);
widgetOptions = widgetOptions.LabelPosition(UIWidgets::LabelPositions::None).ComponentAlignment(UIWidgets::ComponentAlignments::Right);
}
widgetOptions.disabled = disabled;
if(UIWidgets::Combobox(name.c_str(), &selected, options, widgetOptions)) {

View file

@ -1807,7 +1807,6 @@ PotIdentity Randomizer::IdentifyPot(s32 sceneNum, s32 posX, s32 posZ) {
if (location->GetRandomizerCheck() == RC_UNKNOWN_CHECK) {
LUSLOG_WARN("IdentifyPot did not receive a valid RC value (%d).", location->GetRandomizerCheck());
assert(false);
} else {
potIdentity.randomizerInf = rcToRandomizerInf[location->GetRandomizerCheck()];
potIdentity.randomizerCheck = location->GetRandomizerCheck();
@ -2749,10 +2748,10 @@ CustomMessage Randomizer::GetMapGetItemMessageWithHint(GetItemEntry itemEntry) {
}
template<size_t N>
void CreateGetItemMessages(const std::array<GetItemMessage, N>* messageEntries) {
void CreateGetItemMessages(const std::array<GetItemMessage, N>& messageEntries) {
CustomMessageManager* customMessageManager = CustomMessageManager::Instance;
customMessageManager->AddCustomMessageTable(Randomizer::getItemMessageTableID);
for (const GetItemMessage& messageEntry : *messageEntries) {
for (const GetItemMessage& messageEntry : messageEntries) {
customMessageManager->CreateGetItemMessage(
Randomizer::getItemMessageTableID, messageEntry.giid, messageEntry.iid,
CustomMessage(messageEntry.english, messageEntry.german, messageEntry.french, TEXTBOX_TYPE_BLUE,
@ -3469,251 +3468,247 @@ void Randomizer::CreateCustomMessages() {
GIMESSAGE(RG_GUARD_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gGuard House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus der Wachen%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison des Gardes%w!"),
"Vous obtenez la %rClé %wde la&%gMaison des Gardes%w!"),
GIMESSAGE(RG_MARKET_BAZAAR_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gMarket Bazaar%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar des Marktes%w!",
"Vous obtenez une %rPetite Clé %w&du %gMarché%w!"),
"Vous obtenez la %rClé %wdu %gBazar&de la Place du Marché%w!"),
GIMESSAGE(RG_MARKET_POTION_SHOP_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gMarket Potion Shop%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden des Marktes%w!",
"Vous obtenez une %rPetite Clé %w&du %gMarché%w!"),
"Vous obtenez la %rClé %wde la&%gPlace du Marché%w!"),
GIMESSAGE(RG_MASK_SHOP_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gMask Shop%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %gMaskenladen%w!",
"Vous obtenez une %rPetite Clé %w&du %gMagasin de Masques%w!"),
"Vous obtenez la %rClé %wde la&%gFoire aux Masques%w!"),
GIMESSAGE(RG_MARKET_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gMarket Shooting Gallery%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude des Marktes%w!",
"Vous obtenez une %rPetite Clé %w&du %gStand de Tir%w!"),
"Vous obtenez la %rClé %wdu %gStand de&Tir de la Place du Marché%w!"),
GIMESSAGE(RG_BOMBCHU_BOWLING_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gBombchu Bowling Alley%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für die %gMinenbowlingbahn%w!",
"Vous obtenez une %rPetite Clé %w&du %gBowling Bombchu%w!"),
"Vous obtenez la %rClé %wdu %gBowling&Teigneux%w!"),
GIMESSAGE(RG_TREASURE_CHEST_GAME_BUILDING_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gTreasure Chest Game Building%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Schatzkisten-Pokers%w!",
"Vous obtenez une %rPetite Clé %w&du %gJeu de la Chasse au Trésor%w!"),
"Vous obtenez la %rClé %wdu %gJeu de la&Chasse au Trésor%w!"),
GIMESSAGE(RG_BOMBCHU_SHOP_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gBombchu Shop%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %gKrabbelminenladen%w!",
"Vous obtenez une %rPetite Clé %w&du %gMagasin de Bombchu%w!"),
"Vous obtenez la %rClé %wdu %gMagasin&de Missiles%w!"),
GIMESSAGE(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to&%gRichard's House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Richard%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison de Richard%w!"),
GIMESSAGE(RG_RICHARDS_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to&%gRichard's House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Richard%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison de Richard%w!"),
"Vous obtenez la %rClé %wde la %gMaison&de Kiki%w!"),
GIMESSAGE(RG_ALLEY_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to&the %gAlley House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus in der Gasse%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison de la Ruelle%w!"),
"Vous obtenez la %rClé %wde la %gMaison&de la Ruelle%w!"),
GIMESSAGE(RG_KAK_BAZAAR_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gKakariko Bazaar%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %gBasar von Kakariko%w!",
"Vous obtenez une %rPetite Clé %w&du %gMarché de Cocorico%w!"),
"Vous obtenez la %rClé %wdu %gBazar&de Cocorico%w!"),
GIMESSAGE(RG_KAK_POTION_SHOP_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gKakariko Potion Shop%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %gMagie-Laden von Kakariko%w!",
"Vous obtenez une %rPetite Clé %w&du %gMagasin de Potions de Cocorico%w!"),
"Vous obtenez la %rClé %wdu %gMagasin de&Potions de Cocorico%w!"),
GIMESSAGE(RG_BOSS_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gBoss's House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus des Chefs%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison du Boss%w!"),
"Vous obtenez la %rClé %wde la %gMaison&du chef des ouvriers%w!"),
GIMESSAGE(RG_GRANNYS_POTION_SHOP_KEY, ITEM_KEY_SMALL,
"You found the key to&%gGranny's Potion Shop%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für %gAsas Hexenladen%w!",
"Vous obtenez une %rPetite Clé %w&du %gMagasin de Potions de Grand-mère%w!"),
"Vous obtenez la %rClé %wde&l'%gApothicaire%w!"),
GIMESSAGE(RG_SKULLTULA_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gSkulltula House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gSkulltula-Haus%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison des Skulltulas%w!"),
"Vous obtenez la %rClé %wde la %gMaison&des Araignées%w!"),
GIMESSAGE(RG_IMPAS_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to&%gImpa's House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Impa%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison d'Impa%w!"),
"Vous obtenez la %rClé %wde la %gMaison&d'Impa%w!"),
GIMESSAGE(RG_WINDMILL_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gWindmill%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für die %gWindmühle%w!",
"Vous obtenez une %rPetite Clé %w&du %gMoulin à Vent%w!"),
"Vous obtenez la %rClé %w du %gMoulin%w!"),
GIMESSAGE(RG_KAK_SHOOTING_GALLERY_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gKakariko Shooting Gallery%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für die %gSchießbude von Kakariko%w!",
"Vous obtenez une %rPetite Clé %w&du %gStand de Tir de Cocorico%w!"),
"Vous obtenez la %rClé %w du %gStand de&Tir de Cocorico%w!"),
GIMESSAGE(RG_DAMPES_HUT_KEY, ITEM_KEY_SMALL,
"You found the key to&%gDampe's Hut%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für die %gHütte von Boris%w!",
"Vous obtenez une %rPetite Clé %w&du %gChalet de Dampe%w!"),
"Vous obtenez la %rClé %wde la %gCabane&d'Igor%w!"),
GIMESSAGE(RG_TALONS_HOUSE_KEY, ITEM_KEY_SMALL,
"You found the key to&%gTalon's House%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHaus von Talon%w!",
"Vous obtenez une %rPetite Clé %w&de la %gMaison de Talon%w!"),
"Vous obtenez la %rClé %wde la %gMaison&de Talon%w!"),
GIMESSAGE(RG_STABLES_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gStables%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für die %gStälle%w!",
"Vous obtenez une %rPetite Clé %w&des %gÉcuries%w!"),
"Vous obtenez la %rClé %wdes %gÉcuries%w!"),
GIMESSAGE(RG_BACK_TOWER_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gBack Tower%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %ghinteren Turm%w!",
"Vous obtenez une %rPetite Clé %w&du %gTour Arrière%w!"),
"Vous obtenez la %rClé %wdu %gSilo%w!"),
GIMESSAGE(RG_HYLIA_LAB_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gHylia Laboratory%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für das %gHylia-Labor%w!",
"Vous obtenez une %rPetite Clé %w&du %gLaboratoire d'Hylia%w!"),
"Vous obtenez la %rClé %wdu %gLaboratoire&du Lac Hylia%w!"),
GIMESSAGE(RG_FISHING_HOLE_KEY, ITEM_KEY_SMALL,
"You found the key to the&%gFishing Hole%w!",
"You found the key to the&%gPond%w!",
"Du erhältst einen %rkleinen&Schlüssel%w für den %gFischweiher%w!",
"Vous obtenez une %rPetite Clé %w&du %gTrou de Pêche%w!"),
"Vous obtenez la %rClé %wde l'%gÉtang%w!"),
GIMESSAGE(RG_GERUDO_FORTRESS_KEY_RING, ITEM_KEY_SMALL,
"You found a %yThieves Hideout &%wKeyring!",
"You found a %yThieves Hideout&%wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für das %yDiebesversteck%w!",
"Vous obtenez un trousseau de&clés du %yRepaire des Voleurs%w!"),
"Vous obtenez le trousseau de&clés du %yRepaire des Voleurs%w!"),
GIMESSAGE(RG_FOREST_TEMPLE_KEY_RING, ITEM_KEY_SMALL,
"You found a %gForest Temple &%wKeyring!",
"You found a %gForest Temple&%wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für den %gWaldtempel%w!",
"Vous obtenez un trousseau de&clés du %gTemple de la Forêt%w!"),
"Vous obtenez le trousseau de&clés du %gTemple de la Forêt%w!"),
GIMESSAGE(RG_FIRE_TEMPLE_KEY_RING, ITEM_KEY_SMALL,
"You found a %rFire Temple &%wKeyring!",
"You found a %rFire Temple&%wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für den %rFeuertempel%w!",
"Vous obtenez un trousseau de&clés du %rTemple du Feu%w!"),
"Vous obtenez le trousseau de&clés du %rTemple du Feu%w!"),
GIMESSAGE(RG_WATER_TEMPLE_KEY_RING, ITEM_KEY_SMALL,
"You found a %bWater Temple &%wKeyring!",
"You found a %bWater Temple&%wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für den %bWassertempel%w!",
"Vous obtenez un trousseau de&clés du %bTemple de l'Eau%w!"),
"Vous obtenez le trousseau de&clés du %bTemple de l'Eau%w!"),
GIMESSAGE(RG_SPIRIT_TEMPLE_KEY_RING, ITEM_KEY_SMALL,
"You found a %ySpirit Temple &%wKeyring!",
"You found a %ySpirit Temple&%wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für den %yGeistertempel%w!",
"Vous obtenez un trousseau de&clés du %yTemple de l'Esprit%w!"),
"Vous obtenez le trousseau de&clés du %yTemple de l'Esprit%w!"),
GIMESSAGE(RG_SHADOW_TEMPLE_KEY_RING, ITEM_KEY_SMALL,
"You found a %pShadow Temple &%wKeyring!",
"You found a %pShadow Temple&%wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für den %pSchattentempel%w!",
"Vous obtenez un trousseau de&clés du %pTemple de l'Ombre%w!"),
"Vous obtenez le trousseau de&clés du %pTemple de l'Ombre%w!"),
GIMESSAGE(RG_BOTTOM_OF_THE_WELL_KEY_RING, ITEM_KEY_SMALL,
"You found a %pBottom of the &Well %wKeyring!",
"You found a %pBottom of the&Well %wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für den %pGrund des Brunnens%w!",
"Vous obtenez un trousseau de&clés du %pPuits%w!"),
"Vous obtenez le trousseau de&clés du %pPuits%w!"),
GIMESSAGE(RG_GERUDO_TRAINING_GROUND_KEY_RING, ITEM_KEY_SMALL,
"You found a %yGerudo Training &Grounds %wKeyring!",
"You found a %yGerudo Training&Grounds %wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für die %yGerudo-Trainingsarena%w!",
"Vous obtenez un trousseau de&clés du %yGymnase Gerudo%w!"),
"Vous obtenez le trousseau de&clés du %yGymnase Gerudo%w!"),
GIMESSAGE(RG_GANONS_CASTLE_KEY_RING, ITEM_KEY_SMALL,
"You found a %rGanon's Castle &%wKeyring!",
"You found a %rGanon's Castle&%wKeyring!",
"Du erhältst ein %rSchlüsselbund%w&für %rGanons Schloß%w!",
"Vous obtenez un trousseau de&clés du %rChâteau de Ganon%w!"),
"Vous obtenez le trousseau de&clés du %rChâteau de Ganon%w!"),
GIMESSAGE(RG_TREASURE_GAME_KEY_RING, ITEM_KEY_SMALL,
"You found a %rTreasure Chest Game &%wKeyring!",
"You found a %rTreasure Chest Game&%wKeyring!",
"!!!",
"!!!"),
"Vous obtenez le trousseau de&clés du %rJeu de la Chasse au Trésor%w!"),
GIMESSAGE(RG_FOREST_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS,
"You found the %gForest Temple &%wBoss Key!",
"You found the %gForest Temple&%wBoss Key!",
"Du erhältst den %rMaster-Schlüssel%w&für den %gWaldtempel%w!",
"Vous obtenez la %rClé d'or %wdu&%gTemple de la Forêt%w!"),
GIMESSAGE(RG_FIRE_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS,
"You found the %rFire Temple &%wBoss Key!",
"You found the %rFire Temple&%wBoss Key!",
"Du erhältst den %rMaster-Schlüssel%w&für den %rFeuertempel%w!",
"Vous obtenez la %rClé d'or %wdu&%rTemple du Feu%w!"),
GIMESSAGE(RG_WATER_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS,
"You found the %bWater Temple &%wBoss Key!",
"You found the %bWater Temple&%wBoss Key!",
"Du erhältst den %rMaster-Schlüssel%w&für den %bWassertempel%w!",
"Vous obtenez la %rClé d'or %wdu&%bTemple de l'Eau%w!"),
GIMESSAGE(RG_SPIRIT_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS,
"You found the %ySpirit Temple &%wBoss Key!",
"You found the %ySpirit Temple&%wBoss Key!",
"Du erhältst den %rMaster-Schlüssel%w&für den %yGeistertempel%w!",
"Vous obtenez la %rClé d'or %wdu&%yTemple de l'Esprit%w!"),
GIMESSAGE(RG_SHADOW_TEMPLE_BOSS_KEY, ITEM_KEY_BOSS,
"You found the %pShadow Temple &%wBoss Key!",
"You found the %pShadow Temple&%wBoss Key!",
"Du erhältst den %rMaster-Schlüssel%w&für den %pSchattentempel%w!",
"Vous obtenez la %rClé d'or %wdu&%pTemple de l'Ombre%w!"),
GIMESSAGE(RG_GANONS_CASTLE_BOSS_KEY, ITEM_KEY_BOSS,
"You found the %rGanon's Castle &%wBoss Key!",
"You found the %rGanon's Castle&%wBoss Key!",
"Du erhältst den %rMaster-Schlüssel%w&für %rGanons Schloß%w!",
"Vous obtenez la %rClé d'or %wdu&%rChâteau de Ganon%w!"),
GIMESSAGE(RG_DEKU_TREE_MAP, ITEM_DUNGEON_MAP,
"You found the %gDeku Tree &%wMap![[typeHint]]",
"You found the %gDeku Tree&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für den&%gDeku-Baum%w![[typeHint]]",
"Vous obtenez la %rCarte %wde&l'%gArbre Mojo%w![[typeHint]]"),
GIMESSAGE(RG_DODONGOS_CAVERN_MAP, ITEM_DUNGEON_MAP,
"You found the %rDodongo's Cavern &%wMap![[typeHint]]",
"You found the %rDodongo's Cavern&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für&%rDodongos Höhle%w![[typeHint]]",
"Vous obtenez la %rCarte %wde la&%rCaverne Dodongo%w![[typeHint]]"),
GIMESSAGE(RG_JABU_JABUS_BELLY_MAP, ITEM_DUNGEON_MAP,
"You found the %bJabu Jabu's Belly &%wMap![[typeHint]]",
"You found the %bJabu Jabu's Belly&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für&%bJabu-Jabus Bauch%w![[typeHint]]",
"Vous obtenez la %rCarte %wdu &%bVentre de Jabu-Jabu%w![[typeHint]]"),
"Vous obtenez la %rCarte %wdu&%bVentre de Jabu-Jabu%w![[typeHint]]"),
GIMESSAGE(RG_FOREST_TEMPLE_MAP, ITEM_DUNGEON_MAP,
"You found the %gForest Temple &%wMap![[typeHint]]",
"You found the %gForest Temple&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für den&%gWaldtempel%w![[typeHint]]",
"Vous obtenez la %rCarte %wdu &%gTemple de la Forêt%w![[typeHint]]"),
"Vous obtenez la %rCarte %wdu&%gTemple de la Forêt%w![[typeHint]]"),
GIMESSAGE(RG_FIRE_TEMPLE_MAP, ITEM_DUNGEON_MAP,
"You found the %rFire Temple &%wMap![[typeHint]]",
"You found the %rFire Temple&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für den&%rFeuertempel%w![[typeHint]]",
"Vous obtenez la %rCarte %wdu &%rTemple du Feu%w![[typeHint]]"),
"Vous obtenez la %rCarte %wdu&%rTemple du Feu%w![[typeHint]]"),
GIMESSAGE(RG_WATER_TEMPLE_MAP, ITEM_DUNGEON_MAP,
"You found the %bWater Temple &%wMap![[typeHint]]",
"You found the %bWater Temple&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für den&%bWassertempel%w![[typeHint]]",
"Vous obtenez la %rCarte %wdu &%bTemple de l'Eau%w![[typeHint]]"),
"Vous obtenez la %rCarte %wdu&%bTemple de l'Eau%w![[typeHint]]"),
GIMESSAGE(RG_SPIRIT_TEMPLE_MAP, ITEM_DUNGEON_MAP,
"You found the %ySpirit Temple &%wMap![[typeHint]]",
"You found the %ySpirit Temple&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für den&%yGeistertempel%w![[typeHint]]",
"Vous obtenez la %rCarte %wdu &%yTemple de l'Esprit%w![[typeHint]]"),
"Vous obtenez la %rCarte %wdu&%yTemple de l'Esprit%w![[typeHint]]"),
GIMESSAGE(RG_SHADOW_TEMPLE_MAP, ITEM_DUNGEON_MAP,
"You found the %pShadow Temple &%wMap![[typeHint]]",
"You found the %pShadow Temple&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für den&%pSchattentempel%w![[typeHint]]",
"Vous obtenez la %rCarte %wdu &%pTemple de l'Ombre%w![[typeHint]]"),
"Vous obtenez la %rCarte %wdu&%pTemple de l'Ombre%w![[typeHint]]"),
GIMESSAGE(RG_BOTTOM_OF_THE_WELL_MAP, ITEM_DUNGEON_MAP,
"You found the %pBottom of the &Well %wMap![[typeHint]]",
"You found the %pBottom of the&Well %wMap![[typeHint]]",
"Du erhältst die %rKarte%w für den&%pGrund des Brunnens%w![[typeHint]]",
"Vous obtenez la %rCarte %wdu &%pPuits%w![[typeHint]]"),
"Vous obtenez la %rCarte %wdu&%pPuits%w![[typeHint]]"),
GIMESSAGE(RG_ICE_CAVERN_MAP, ITEM_DUNGEON_MAP,
"You found the %cIce Cavern &%wMap![[typeHint]]",
"You found the %cIce Cavern&%wMap![[typeHint]]",
"Du erhältst die %rKarte%w für die&%cEishöhle%w![[typeHint]]",
"Vous obtenez la %rCarte %wde &la %cCaverne Polaire%w![[typeHint]]"),
"Vous obtenez la %rCarte %wde&la %cCaverne Polaire%w![[typeHint]]"),
GIMESSAGE(RG_DEKU_TREE_COMPASS, ITEM_COMPASS,
"You found the %gDeku Tree &%wCompass!",
"You found the %gDeku Tree&%wCompass!",
"Du erhältst den %rKompaß%w für den&%gDeku-Baum%w!",
"Vous obtenez la %rBoussole %wde&l'%gArbre Mojo%w!"),
GIMESSAGE(RG_DODONGOS_CAVERN_COMPASS, ITEM_COMPASS,
"You found the %rDodongo's Cavern &%wCompass!",
"You found the %rDodongo's Cavern&%wCompass!",
"Du erhältst den %rKompaß%w für&%rDodongos Höhle%w!",
"Vous obtenez la %rBoussole %wde la&%rCaverne Dodongo%w!"),
GIMESSAGE(RG_JABU_JABUS_BELLY_COMPASS, ITEM_COMPASS,
"You found the %bJabu Jabu's Belly &%wCompass!",
"You found the %bJabu Jabu's Belly&%wCompass!",
"Du erhältst den %rKompaß%w für den&%bJabu-Jabus Bauch%w!",
"Vous obtenez la %rBoussole %wdu &%bVentre de Jabu-Jabu%w!"),
"Vous obtenez la %rBoussole %wdu&%bVentre de Jabu-Jabu%w!"),
GIMESSAGE(RG_FOREST_TEMPLE_COMPASS, ITEM_COMPASS,
"You found the %gForest Temple &%wCompass!",
"You found the %gForest Temple&%wCompass!",
"Du erhältst den %rKompaß%w für den&%gWaldtempel%w!",
"Vous obtenez la %rBoussole %wdu &%gTemple de la Forêt%w!"),
"Vous obtenez la %rBoussole %wdu&%gTemple de la Forêt%w!"),
GIMESSAGE(RG_FIRE_TEMPLE_COMPASS, ITEM_COMPASS,
"You found the %rFire Temple &%wCompass!",
"You found the %rFire Temple&%wCompass!",
"Du erhältst den %rKompaß%w für den&%rFeuertempel%w!",
"Vous obtenez la %rBoussole %wdu &%rTemple du Feu%w!"),
"Vous obtenez la %rBoussole %wdu&%rTemple du Feu%w!"),
GIMESSAGE(RG_WATER_TEMPLE_COMPASS, ITEM_COMPASS,
"You found the %bWater Temple &%wCompass!",
"You found the %bWater Temple&%wCompass!",
"Du erhältst den %rKompaß%w für den&%bWassertempel%w!",
"Vous obtenez la %rBoussole %wdu &%bTemple de l'Eau%w!"),
"Vous obtenez la %rBoussole %wdu&%bTemple de l'Eau%w!"),
GIMESSAGE(RG_SPIRIT_TEMPLE_COMPASS, ITEM_COMPASS,
"You found the %ySpirit Temple &%wCompass!",
"You found the %ySpirit Temple&%wCompass!",
"Du erhältst den %rKompaß%w für den&%yGeistertempel%w!",
"Vous obtenez la %rBoussole %wdu &%yTemple de l'Esprit%w!"),
"Vous obtenez la %rBoussole %wdu&%yTemple de l'Esprit%w!"),
GIMESSAGE(RG_SHADOW_TEMPLE_COMPASS, ITEM_COMPASS,
"You found the %pShadow Temple &%wCompass!",
"You found the %pShadow Temple&%wCompass!",
"Du erhältst den %rKompaß%w für den&%pSchattentempel%w!",
"Vous obtenez la %rBoussole %wdu &%pTemple de l'Ombre%w!"),
"Vous obtenez la %rBoussole %wdu&%pTemple de l'Ombre%w!"),
GIMESSAGE(RG_BOTTOM_OF_THE_WELL_COMPASS, ITEM_COMPASS,
"You found the %pBottom of the &Well %wCompass!",
"You found the %pBottom of the&Well %wCompass!",
"Du erhältst den %rKompaß%w für den&%pGrund des Brunnens%w!",
"Vous obtenez la %rBoussole %wdu &%pPuits%w!"),
"Vous obtenez la %rBoussole %wdu&%pPuits%w!"),
GIMESSAGE(RG_ICE_CAVERN_COMPASS, ITEM_COMPASS,
"You found the %cIce Cavern &%wCompass!",
"You found the %cIce Cavern&%wCompass!",
"Du erhältst den %rKompaß%w für die&%cEishöhle%w!",
"Vous obtenez la %rBoussole %wde &la %cCaverne Polaire%w!"),
"Vous obtenez la %rBoussole %wde&la %cCaverne Polaire%w!"),
GIMESSAGE(RG_MAGIC_BEAN_PACK, ITEM_BEAN,
"You got a %rPack of Magic Beans%w!&Find a suitable spot for a garden&and plant them. Then, wait for&something fun to happen!",
@ -3739,7 +3734,7 @@ void Randomizer::CreateCustomMessages() {
"Vous obtenez l'âme de %bBarinade%w!"),
GIMESSAGE_NO_GERMAN(RG_PHANTOM_GANON_SOUL, ITEM_BIG_POE,
"You found the soul for %gPhantom&Ganon%w!",
"Vous obtenez l'âme de %gGanon Spectral%w!"),
"Vous obtenez l'âme de %gGanon&Spectral%w!"),
GIMESSAGE_NO_GERMAN(RG_VOLVAGIA_SOUL, ITEM_BIG_POE,
"You found the soul for %rVolvagia%w!",
"Vous obtenez l'âme de %rVulcania%w!"),
@ -3748,10 +3743,10 @@ void Randomizer::CreateCustomMessages() {
"Vous obtenez l'âme de %bMorpha%w!"),
GIMESSAGE_NO_GERMAN(RG_BONGO_BONGO_SOUL, ITEM_BIG_POE,
"You found the soul for %pBongo&Bongo%w!",
"Vous obtenez l'âme de %pBongo Bongo%w!"),
"Vous obtenez l'âme de %pBongo&Bongo%w!"),
GIMESSAGE_NO_GERMAN(RG_TWINROVA_SOUL, ITEM_BIG_POE,
"You found the soul for %yTwinrova%w!",
"Vous obtenez l'âme du %yDuo Maléfique%w!"),
"Vous obtenez l'âme du %yDuo&Maléfique%w!"),
GIMESSAGE_NO_GERMAN(RG_GANON_SOUL, ITEM_BIG_POE,
"You found the soul for %cGanon%w!",
"Vous obtenez l'âme de %cGanon%w!"),
@ -3759,68 +3754,68 @@ void Randomizer::CreateCustomMessages() {
GIMESSAGE(RG_OCARINA_A_BUTTON, ITEM_OCARINA_TIME,
"You got the %b\x9f%r button for the&Ocarina%w! You can now use it&while playing songs!",
"Der %b\x9f%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!",
"Vous trouvez la %rtouche %b\x9f%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
"Vous obtenez la %rtouche %b\x9f%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
GIMESSAGE(RG_OCARINA_C_LEFT_BUTTON, ITEM_OCARINA_TIME,
"You got the %y\xa7%r button for the&Ocarina%w! You can now use it&while playing songs!",
"Der %y\xa7%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!",
"Vous trouvez la %rtouche %y\xa7%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
"Vous obtenez la %rtouche %y\xa7%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
GIMESSAGE(RG_OCARINA_C_RIGHT_BUTTON, ITEM_OCARINA_TIME,
"You got the %y\xa8%r button for the&Ocarina%w! You can now use it&while playing songs!",
"Der %y\xa8%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!",
"Vous trouvez la %rtouche %y\xa8%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
"Vous obtenez la %rtouche %y\xa8%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
GIMESSAGE(RG_OCARINA_C_UP_BUTTON, ITEM_OCARINA_TIME,
"You got the %y\xa5%r button for the&Ocarina%w! You can now use it&while playing songs!",
"Der %y\xa5%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!",
"Vous trouvez la %rtouche %y\xa5%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
"Vous obtenez la %rtouche %y\xa5%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
GIMESSAGE(RG_OCARINA_C_DOWN_BUTTON, ITEM_OCARINA_TIME,
"You got the %y\xa6%r button for the&Ocarina%w! You can now use it&while playing songs!",
"Der %y\xa6%r Knopf%w!&Du kannst ihn nun zum Spielen&von Liedern auf der %rOkarina%w&verwenden!",
"Vous trouvez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
"Vous obtenez la %rtouche %y\xa6%r de&l'Ocarina%w! Vous pouvez&maintenant l'utiliser lorsque&vous en jouez!"),
GIMESSAGE_NO_GERMAN(RG_BRONZE_SCALE, ITEM_SCALE_SILVER,
"You got the %rBronze Scale%w!&The power of buoyancy is yours!",
"Vous avez obtenu l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est à vous!"),
"Vous obtenez l'%rÉcaille de Bronze%w!&Le pouvoir de la flottabilité est&à vous!"),
GIMESSAGE_NO_GERMAN(RG_FISHING_POLE, ITEM_FISHING_POLE,
"You found a lost %rFishing Pole%w!&Time to hit the pond!",
"Vous avez trouvé une %rCanne à pêche%w perdue!&Il est temps d'aller à l'étang!"),
"Vous obtenez une %rCanne à pêche%w&perdue!&Il est temps d'aller à %gl'étang%w!"),
GIMESSAGE_NO_GERMAN(RG_BOMBCHU_BAG, ITEM_BOMBCHU,
"You found the %rBombchu Bag%w!",
"!!!"),
"Vous obtenez un %rSac de Missiles&Teigneux%w!"),
GIMESSAGE_NO_GERMAN(RG_BOMB_BAG_INF, ITEM_BOMB_BAG_40,
"You got an %rInfinite Bomb Bag%w!&Now you have %yinfinite bombs%w!",
"Vous avez obtenu un %rSac à bombes à l'infini%w!&Vous avez maintenant des %ybombes à l'infini%w!"),
"Vous obtenez un %rSac de Bombes&sans fond%w!&Vous avez maintenant des %ybombes&en quantité illimitée%w!"),
GIMESSAGE_NO_GERMAN(RG_QUIVER_INF, ITEM_QUIVER_50,
"You got an %rInfinite Quiver%w!&Now you have %yinfinite arrows%w!",
"Vous avez obtenu un %rCarquois à l'infini%w!&Vous avez maintenant des %yflèches à l'infini%w!"),
"Vous obtenez un %rCarquois Infini%w!&Vous avez maintenant des %yflèches&de manière illimitée%w!"),
GIMESSAGE_NO_GERMAN(RG_BULLET_BAG_INF, ITEM_BULLET_BAG_50,
"You got an %rInfinite Bullet Bag%w!&Now you have %yinfinite&slingshot seeds%w!",
"Vous avez obtenu un %rSac de Graine à l'infini%w!&Vous avez maintenant des %ygraines de lance-pierres à l'infini%w!"),
"Vous obtenez un %rSac de Graines&sans fond%w!&Vous avez maintenant des %ygraines&de lance-pierres à l'infini%w!"),
GIMESSAGE_NO_GERMAN(RG_STICK_UPGRADE_INF, ITEM_STICK,
"You now have %yinfinite%w %rDeku Sticks%w!",
"Vous avez maintenant des %yBâtons Mojo à l'infini%w!"),
"Vous avez maintenant des %yBâtons&Mojo de manière illimitée%w!"),
GIMESSAGE_NO_GERMAN(RG_NUT_UPGRADE_INF, ITEM_NUT,
"You now have %yinfinite%w %rDeku Nuts%w!",
"Vous avez maintenant des %yNoix Mojo à l'infini%w!"),
"Vous avez maintenant des %yNoix&Mojo de manière illimitée%w!"),
GIMESSAGE_NO_GERMAN(RG_MAGIC_INF, ITEM_MAGIC_LARGE,
"You now have %yinfinite%w %rMagic%w!",
"Vous avez maintenant de la %ymagie à l'infini%w!"),
"Vous avez maintenant une quantité&de %ymagie illimitée%w!"),
GIMESSAGE_NO_GERMAN(RG_BOMBCHU_INF, ITEM_BOMBCHU,
"You now have %yinfinite%w %rBombchus%w!",
"Vous avez maintenant des %Missiles Teigneux à l'infini%w!"),
"Vous avez maintenant des %yMissiles&Teigneux en quantité illimités%w!"),
GIMESSAGE_NO_GERMAN(RG_WALLET_INF, ITEM_WALLET_GIANT,
"You now have %yinfinite%w %rmoney%w!",
"Vous avez maintenant de l'%yargent à l'infini%w!"),
"Vous avez maintenant des %yRubis en& quantité illimitée%w!"),
GIMESSAGE_NO_GERMAN(RG_SKELETON_KEY, ITEM_KEY_SMALL,
"You found the %rSkeleton Key%w!",
"Vous avez trouvé la %rClé Squelette%w!"),
GIMESSAGE_NO_GERMAN(RG_DEKU_STICK_BAG, ITEM_STICK,
"You found the %rDeku Stick Bag%w!&You can now hold deku sticks!",
"Vous avez trouvé le %rSac de Bâtons Mojo%w!&Vous pouvez maintenant porter des Bâtons Mojo!"),
"Vous avez trouvé le %rSac de Bâtons&Mojo%w!&Vous pouvez maintenant porter des&Bâtons Mojo!"),
GIMESSAGE_NO_GERMAN(RG_DEKU_NUT_BAG, ITEM_NUT,
"You found the %rDeku Nut Bag%w!&You can now hold deku nuts!",
"Vous avez trouvé le %rSac de Noix Mojo%w!&Vous pouvez maintenant porter des Noix Mojo!"),
"Vous avez trouvé le %rSac de Noix& Mojo%w!&Vous pouvez maintenant porter des&Noix Mojo!"),
}};
CreateGetItemMessages(&getItemMessages);
CreateGetItemMessages(getItemMessages);
CreateRupeeMessages();
CreateTriforcePieceMessages();
CreateNaviRandoMessages();

View file

@ -5425,7 +5425,6 @@ typedef enum {
RO_GANON_BOSS_KEY_LACS_DUNGEONS,
RO_GANON_BOSS_KEY_LACS_TOKENS,
RO_GANON_BOSS_KEY_KAK_TOKENS,
RO_GANON_BOSS_KEY_TRIFORCE_HUNT,
} RandoOptionGanonsBossKey;
typedef enum {

View file

@ -1164,14 +1164,12 @@ void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flag
Color_Background.b / 255.0f, Color_Background.a / 255.0f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f);
ImGui::PushFont(OTRGlobals::Instance->fontStandardLarger);
ImGui::Begin(UniqueName.c_str(), &open, windowFlags);
}
void EndFloatWindows() {
ImGui::PopStyleVar();
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::PopFont();
ImGui::End();
}
@ -1846,7 +1844,6 @@ static std::unordered_map<int32_t, const char*> buttonStrings = {
{ TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" }};
void CheckTrackerSettingsWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontStandardLarger);
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f });
if (ImGui::BeginTable("CheckTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) {
ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f);
@ -1860,21 +1857,21 @@ void CheckTrackerSettingsWindow::DrawElement() {
ImGui::PopItemWidth();
UIWidgets::CVarCombobox("Window Type", CVAR_TRACKER_CHECK("WindowType"), windowType,
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPosition::Far).ComponentAlignment(UIWidgets::ComponentAlignment::Right)
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right)
.Color(THEME_COLOR).DefaultIndex(TRACKER_WINDOW_WINDOW));
if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) {
UIWidgets::CVarCheckbox("Enable Dragging", CVAR_TRACKER_CHECK("Draggable"), UIWidgets::CheckboxOptions().Color(THEME_COLOR));
UIWidgets::CVarCheckbox("Only enable while paused", CVAR_TRACKER_CHECK("ShowOnlyPaused"), UIWidgets::CheckboxOptions().Color(THEME_COLOR));
UIWidgets::CVarCombobox("Display Mode", CVAR_TRACKER_CHECK("DisplayType"), displayType,
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPosition::Far).ComponentAlignment(UIWidgets::ComponentAlignment::Right)
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right)
.Color(THEME_COLOR).DefaultIndex(0));
if (CVarGetInteger(CVAR_TRACKER_CHECK("DisplayType"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_COMBO_BUTTON) {
UIWidgets::CVarCombobox("Combo Button 1", CVAR_TRACKER_CHECK("ComboButton1"), buttonStrings,
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPosition::Far).ComponentAlignment(UIWidgets::ComponentAlignment::Right)
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right)
.Color(THEME_COLOR).DefaultIndex(TRACKER_COMBO_BUTTON_L));
UIWidgets::CVarCombobox("Combo Button 2", CVAR_TRACKER_CHECK("ComboButton2"), buttonStrings,
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPosition::Far).ComponentAlignment(UIWidgets::ComponentAlignment::Right)
UIWidgets::ComboboxOptions().LabelPosition(UIWidgets::LabelPositions::Far).ComponentAlignment(UIWidgets::ComponentAlignments::Right)
.Color(THEME_COLOR).DefaultIndex(TRACKER_COMBO_BUTTON_L));
}
}
@ -1913,7 +1910,6 @@ void CheckTrackerSettingsWindow::DrawElement() {
ImGui::PopStyleVar(1);
}
ImGui::EndTable();
ImGui::PopFont();
}
void CheckTrackerWindow::InitElement() {

View file

@ -201,12 +201,12 @@ void Entrance_Init(void) {
}
// Overwrite grotto related indices
if (originalIndex >= ENTRANCE_GROTTO_EXIT_START) {
if (originalIndex >= ENTRANCE_GROTTO_EXIT_START && originalIndex < ENTRANCE_GROTTO_EXIT_START + NUM_GROTTOS) {
Grotto_SetExitOverride(originalIndex, overrideIndex);
continue;
}
if (originalIndex >= ENTRANCE_GROTTO_LOAD_START && originalIndex < ENTRANCE_GROTTO_EXIT_START) {
if (originalIndex >= ENTRANCE_GROTTO_LOAD_START && originalIndex < ENTRANCE_GROTTO_LOAD_START + NUM_GROTTOS) {
Grotto_SetLoadOverride(originalIndex, overrideIndex);
continue;
}

View file

@ -660,7 +660,6 @@ void InitEntranceTrackingData() {
void EntranceTrackerSettingsWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontStandardLarger);
ImGui::TextWrapped("The entrance tracker will only track shuffled entrances");
UIWidgets::Spacer(0);
@ -675,8 +674,7 @@ void EntranceTrackerSettingsWindow::DrawElement() {
ImGui::Text("Sort By");
UIWidgets::CVarRadioButton("To", CVAR_TRACKER_ENTRANCE("SortBy"), 0,
UIWidgets::RadioButtonsOptions()
.Color(THEME_COLOR)
.Tooltip("Sort entrances by the original source entrance"));
.Color(THEME_COLOR).Tooltip("Sort entrances by the original source entrance"));
UIWidgets::CVarRadioButton("From", CVAR_TRACKER_ENTRANCE("SortBy"), 1,
UIWidgets::RadioButtonsOptions()
.Color(THEME_COLOR).Tooltip("Sort entrances by the overrided destination"));
@ -722,7 +720,6 @@ void EntranceTrackerSettingsWindow::DrawElement() {
ImGui::TextColored(ImColor(COLOR_GRAY), "Undiscovered Entrances");
ImGui::TreePop();
}
ImGui::PopFont();
}
void EntranceTrackerWindow::Draw() {
@ -735,12 +732,10 @@ void EntranceTrackerWindow::Draw() {
}
void EntranceTrackerWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontStandardLarger);
ImGui::SetNextWindowSize(ImVec2(600, 375), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("Entrance Tracker", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) {
ImGui::End();
ImGui::PopFont();
return;
}
@ -938,7 +933,6 @@ void EntranceTrackerWindow::DrawElement() {
}
ImGui::EndChild();
ImGui::End();
ImGui::PopFont();
}
void EntranceTrackerWindow::InitElement() {

View file

@ -952,14 +952,12 @@ void BeginFloatingWindows(std::string UniqueName, ImGuiWindowFlags flags = 0) {
ImGui::PushStyleColor(ImGuiCol_WindowBg, VecFromRGBA8(CVarGetColor(CVAR_TRACKER_ITEM("BgColor.Value"), {0, 0, 0, 0})));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f);
ImGui::PushFont(OTRGlobals::Instance->fontStandardLarger);
ImGui::Begin(UniqueName.c_str(), nullptr, windowFlags);
}
void EndFloatingWindows() {
ImGui::PopStyleVar();
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::PopFont();
ImGui::End();
}
@ -1218,9 +1216,11 @@ void ItemTrackerWindow::Draw() {
if (!IsVisible()) {
return;
}
ImGui::PushFont(OTRGlobals::Instance->fontMono);
DrawElement();
// Sync up the IsVisible flag if it was changed by ImGui
SyncVisibilityConsoleVariable();
ImGui::PopFont();
}
void ItemTrackerWindow::DrawElement() {
@ -1375,7 +1375,6 @@ static std::unordered_map<int32_t, const char*> extendedDisplayTypes = {{ SECTIO
static std::unordered_map<int32_t, const char*> minimalDisplayTypes = {{ SECTION_DISPLAY_MINIMAL_HIDDEN, "Hidden" }, { SECTION_DISPLAY_MINIMAL_SEPARATE, "Separate" }};
void ItemTrackerSettingsWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontStandardLarger);
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f });
ImGui::BeginTable("itemTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV);
ImGui::TableSetupColumn("General settings", ImGuiTableColumnFlags_WidthStretch, 200.0f);
@ -1389,8 +1388,8 @@ void ItemTrackerSettingsWindow::DrawElement() {
ImGui::PopItemWidth();
if (CVarCombobox("Window Type", CVAR_TRACKER_ITEM("WindowType"), windowTypes, ComboboxOptions()
.DefaultIndex(TRACKER_WINDOW_FLOATING).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(TRACKER_WINDOW_FLOATING).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
@ -1402,19 +1401,19 @@ void ItemTrackerSettingsWindow::DrawElement() {
shouldUpdateVectors = true;
}
if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes, ComboboxOptions()
.DefaultIndex(TRACKER_DISPLAY_ALWAYS).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(TRACKER_DISPLAY_ALWAYS).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_COMBO_BUTTON) {
if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons, ComboboxOptions()
.DefaultIndex(TRACKER_COMBO_BUTTON_L).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(TRACKER_COMBO_BUTTON_L).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons, ComboboxOptions()
.DefaultIndex(TRACKER_COMBO_BUTTON_R).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(TRACKER_COMBO_BUTTON_R).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
}
@ -1426,8 +1425,8 @@ void ItemTrackerSettingsWindow::DrawElement() {
ImGui::NewLine();
CVarCombobox("Ammo/Capacity Tracking", CVAR_TRACKER_ITEM("ItemCountType"), itemTrackerCapacityTrackOptions, ComboboxOptions()
.DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY).ComponentAlignment(ComponentAlignment::Left)
.LabelPosition(LabelPosition::Above).Color(THEME_COLOR)
.DefaultIndex(ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY).ComponentAlignment(ComponentAlignments::Left)
.LabelPosition(LabelPositions::Above).Color(THEME_COLOR)
.Tooltip("Customize what the numbers under each item are tracking."
"\n\nNote: items without capacity upgrades will track ammo even in capacity mode"));
if (CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY || CVarGetInteger(CVAR_TRACKER_ITEM("ItemCountType"), ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY) == ITEM_TRACKER_NUMBER_CURRENT_AMMO_ONLY) {
@ -1437,35 +1436,35 @@ void ItemTrackerSettingsWindow::DrawElement() {
}
CVarCombobox("Key Count Tracking", CVAR_TRACKER_ITEM("KeyCounts"), itemTrackerKeyTrackOptions, ComboboxOptions()
.DefaultIndex(KEYS_COLLECTED_MAX).ComponentAlignment(ComponentAlignment::Left)
.LabelPosition(LabelPosition::Above).Color(THEME_COLOR)
.DefaultIndex(KEYS_COLLECTED_MAX).ComponentAlignment(ComponentAlignments::Left)
.LabelPosition(LabelPositions::Above).Color(THEME_COLOR)
.Tooltip("Customize what numbers are shown for key tracking."));
CVarCombobox("Triforce Piece Count Tracking", CVAR_TRACKER_ITEM("TriforcePieceCounts"), itemTrackerTriforcePieceTrackOptions, ComboboxOptions()
.DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX).ComponentAlignment(ComponentAlignment::Left)
.LabelPosition(LabelPosition::Above).Color(THEME_COLOR)
.DefaultIndex(TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX).ComponentAlignment(ComponentAlignments::Left)
.LabelPosition(LabelPositions::Above).Color(THEME_COLOR)
.Tooltip("Customize what numbers are shown for triforce piece tracking."));
ImGui::TableNextColumn();
if (CVarCombobox("Inventory", CVAR_TRACKER_ITEM("DisplayType.Inventory"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Equipment", CVAR_TRACKER_ITEM("DisplayType.Equipment"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Misc", CVAR_TRACKER_ITEM("DisplayType.Misc"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Dungeon Rewards", CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonRewards"), SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_SEPARATE) {
@ -1474,13 +1473,13 @@ void ItemTrackerSettingsWindow::DrawElement() {
}
}
if (CVarCombobox("Songs", CVAR_TRACKER_ITEM("DisplayType.Songs"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_MAIN_WINDOW).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Dungeon Items", CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.DungeonItems"), SECTION_DISPLAY_HIDDEN) != SECTION_DISPLAY_HIDDEN) {
@ -1494,45 +1493,45 @@ void ItemTrackerSettingsWindow::DrawElement() {
}
}
if (CVarCombobox("Greg", CVAR_TRACKER_ITEM("DisplayType.Greg"), extendedDisplayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Triforce Pieces", CVAR_TRACKER_ITEM("DisplayType.TriforcePieces"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Boss Souls", CVAR_TRACKER_ITEM("DisplayType.BossSouls"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Ocarina Buttons", CVAR_TRACKER_ITEM("DisplayType.OcarinaButtons"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Fishing Pole", CVAR_TRACKER_ITEM("DisplayType.FishingPole"), extendedDisplayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_EXTENDED_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarCombobox("Total Checks", "gTrackers.ItemTracker.TotalChecks.DisplayType", minimalDisplayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_MINIMAL_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) {
if (CVarCombobox("Personal notes", CVAR_TRACKER_ITEM("DisplayType.Notes"), displayTypes, ComboboxOptions()
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignment::Right)
.LabelPosition(LabelPosition::Far).Color(THEME_COLOR))) {
.DefaultIndex(SECTION_DISPLAY_HIDDEN).ComponentAlignment(ComponentAlignments::Right)
.LabelPosition(LabelPositions::Far).Color(THEME_COLOR))) {
shouldUpdateVectors = true;
}
}
@ -1541,7 +1540,6 @@ void ItemTrackerSettingsWindow::DrawElement() {
ImGui::PopStyleVar(1);
ImGui::EndTable();
ImGui::PopFont();
}
void ItemTrackerWindow::InitElement() {

View file

@ -237,7 +237,7 @@ void Settings::CreateOptions() {
OPT_U8(RSK_KEYSANITY, "Small Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("Keysanity"), mOptionDescriptions[RSK_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_GERUDO_KEYS, "Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("GerudoKeys"), mOptionDescriptions[RSK_GERUDO_KEYS], WidgetType::Combobox, RO_GERUDO_KEYS_VANILLA);
OPT_U8(RSK_BOSS_KEYSANITY, "Boss Key Shuffle", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("BossKeysanity"), mOptionDescriptions[RSK_BOSS_KEYSANITY], WidgetType::Combobox, RO_DUNGEON_ITEM_LOC_OWN_DUNGEON);
OPT_U8(RSK_GANONS_BOSS_KEY, "Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward", "Triforce Hunt"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WidgetType::Combobox, RO_GANON_BOSS_KEY_VANILLA);
OPT_U8(RSK_GANONS_BOSS_KEY, "Ganon's Boss Key", {"Vanilla", "Own Dungeon", "Start With", "Any Dungeon", "Overworld", "Anywhere", "LACS-Vanilla", "LACS-Stones", "LACS-Medallions", "LACS-Rewards", "LACS-Dungeons", "LACS-Tokens", "100 GS Reward"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("ShuffleGanonBossKey"), mOptionDescriptions[RSK_GANONS_BOSS_KEY], WidgetType::Combobox, RO_GANON_BOSS_KEY_VANILLA);
OPT_U8(RSK_LACS_STONE_COUNT, "GCBK Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsStoneCount"), "", WidgetType::Slider, 3, true);
OPT_U8(RSK_LACS_MEDALLION_COUNT, "GCBK Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsMedallionCount"), "", WidgetType::Slider, 6, true);
OPT_U8(RSK_LACS_REWARD_COUNT, "GCBK Reward Count", {NumOpts(0, 10)}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("LacsRewardCount"), "", WidgetType::Slider, 9, true);
@ -1856,10 +1856,6 @@ void Context::FinalizeSettings(const std::set<RandomizerCheck>& excludedLocation
mOptions[RSK_STARTING_AGE].Set(RO_AGE_CHILD);
}
if (mOptions[RSK_TRIFORCE_HUNT]) {
mOptions[RSK_GANONS_BOSS_KEY].Set(RO_GANON_BOSS_KEY_TRIFORCE_HUNT);
}
// Force 100 GS Shuffle if that's where Ganon's Boss Key is
if (mOptions[RSK_GANONS_BOSS_KEY].Is(RO_GANON_BOSS_KEY_KAK_TOKENS)) {
mOptions[RSK_SHUFFLE_100_GS_REWARD].Set(1);

View file

@ -23,6 +23,7 @@ extern "C" {
#include "src/overlays/actors/ovl_Bg_Ddan_Kd/z_bg_ddan_kd.h"
#include "src/overlays/actors/ovl_En_Tk/z_en_tk.h"
#include "src/overlays/actors/ovl_En_Fu/z_en_fu.h"
#include "src/overlays/actors/ovl_En_Daiku/z_en_daiku.h"
#include "src/overlays/actors/ovl_Bg_Spot02_Objects/z_bg_spot02_objects.h"
#include "src/overlays/actors/ovl_Bg_Spot03_Taki/z_bg_spot03_taki.h"
#include "src/overlays/actors/ovl_Bg_Hidan_Kousi/z_bg_hidan_kousi.h"
@ -42,6 +43,8 @@ extern void BgSpot03Taki_ApplyOpeningAlpha(BgSpot03Taki* bgSpot03Taki, s32 buffe
extern void EnGo2_CurledUp(EnGo2* enGo2, PlayState* play);
extern void EnRu2_SetEncounterSwitchFlag(EnRu2* enRu2, PlayState* play);
extern void EnDaiku_EscapeSuccess(EnDaiku* enDaiku, PlayState* play);
}
#define RAND_GET_OPTION(option) Rando::Context::GetInstance()->GetOption(option).Get()
@ -354,6 +357,18 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
!(gPlayState->sceneNum == SCENE_ZORAS_RIVER && IS_RANDO && RAND_GET_OPTION(RSK_FROGS_HINT))) {
*should = false;
}
// If it's near a jailed carpenter, skip it along with introduction of Gerudo mini-boss
if (gPlayState->sceneNum == SCENE_THIEVES_HIDEOUT &&
CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.BossIntro"), IS_RANDO)) {
EnWonderTalk2* enWonderTalk = va_arg(args, EnWonderTalk2*);
EnDaiku* enDaiku =
(EnDaiku*)Actor_FindNearby(gPlayState, &enWonderTalk->actor, ACTOR_EN_DAIKU, ACTORCAT_NPC, 999.0f);
if (enDaiku != NULL) {
Flags_SetSwitch(gPlayState, enDaiku->startFightSwitchFlag);
*should = false;
}
}
break;
}
case VB_NAVI_TALK: {
@ -551,6 +566,17 @@ void TimeSaverOnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_li
}
break;
}
case VB_PLAY_CARPENTER_FREE_CS: {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.OnePoint"), IS_RANDO)) {
EnDaiku* enDaiku = va_arg(args, EnDaiku*);
if (enDaiku->subCamActive) {
enDaiku->subCamActive = false;
EnDaiku_EscapeSuccess(enDaiku, gPlayState);
}
*should = false;
}
break;
}
case VB_PLAY_GORON_FREE_CS: {
if (CVarGetInteger(CVAR_ENHANCEMENT("TimeSavers.SkipCutscene.Story"), IS_RANDO)) {
*should = false;
@ -1106,12 +1132,18 @@ void TimeSaverOnFlagSetHandler(int16_t flagType, int16_t flag) {
break;
case FLAG_ITEM_GET_INF:
switch (flag) {
case ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE:
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_STICK_CAPACITY_30).GetGIEntry_Copy();
case ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE: {
RandomizerGet stickUpgrade =
CUR_UPG_VALUE(UPG_STICKS) == 2 ? RG_DEKU_STICK_CAPACITY_30 : RG_DEKU_STICK_CAPACITY_20;
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(stickUpgrade).GetGIEntry_Copy();
break;
case ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE:
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(RG_DEKU_NUT_CAPACITY_40).GetGIEntry_Copy();
}
case ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE: {
RandomizerGet nutUpgrade =
CUR_UPG_VALUE(UPG_NUTS) == 2 ? RG_DEKU_NUT_CAPACITY_40 : RG_DEKU_NUT_CAPACITY_30;
vanillaQueuedItemEntry = Rando::StaticData::RetrieveItem(nutUpgrade).GetGIEntry_Copy();
break;
}
}
break;
}

View file

@ -809,7 +809,7 @@ void TimeSplitsDrawOptionsMenu() {
static uint32_t selectedItem = 0;
ImGui::Text("Select List to Load: ");
ImGui::PushItemWidth(150.0f);
Combobox("", &selectedItem, keys, ComboboxOptions().Color(THEME_COLOR).LabelPosition(LabelPosition::Near));
Combobox("", &selectedItem, keys, ComboboxOptions().Color(THEME_COLOR).LabelPosition(LabelPositions::Near));
ImGui::PopItemWidth();
ImGui::SameLine();
if (Button("Load List", ButtonOptions().Color(THEME_COLOR).Size(Sizes::Inline))) {
@ -941,7 +941,6 @@ static bool initialized = false;
void TimeSplitWindow::DrawElement() {
ImGui::SetWindowFontScale(timeSplitsWindowSize);
ImGui::PushFont(OTRGlobals::Instance->fontMonoLargest);
PushStyleTabs(THEME_COLOR);
if (ImGui::BeginTabBar("Split Tabs")) {
@ -960,7 +959,6 @@ void TimeSplitWindow::DrawElement() {
ImGui::EndTabBar();
}
PopStyleTabs();
ImGui::PopFont();
}
void TimeSplitWindow::InitElement() {

View file

@ -407,7 +407,7 @@ OTRGlobals::OTRGlobals() {
fontStandard = CreateFontWithSize(16.0f, "fonts/Montserrat-Regular.ttf");
fontStandardLarger = CreateFontWithSize(20.0f, "fonts/Montserrat-Regular.ttf");
fontStandardLargest = CreateFontWithSize(24.0f, "fonts/Montserrat-Regular.ttf");
ImGui::GetIO().FontDefault = fontMono;
ImGui::GetIO().FontDefault = fontStandardLarger;
ScaleImGui();
// Move the camera strings from read only memory onto the heap (writable memory)
@ -499,15 +499,12 @@ bool OTRGlobals::HasOriginal() {
}
uint32_t OTRGlobals::GetInterpolationFPS() {
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
return CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20);
}
if (CVarGetInteger(CVAR_SETTING("MatchRefreshRate"), 0)) {
return Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
} else if (CVarGetInteger(CVAR_VSYNC_ENABLED, 1) || !Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) {
return std::min<uint32_t>(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(), CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20));
}
return std::min<uint32_t>(Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(), CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20));
return CVarGetInteger(CVAR_SETTING("InterpolationFPS"), 20);
}
extern "C" void OTRMessage_Init();
@ -1296,6 +1293,11 @@ extern "C" void Graph_StartFrame() {
OTRGlobals::Instance->context->GetWindow()->SetLastScancode(-1);
switch (dwScancode) {
case KbScancode::LUS_KB_F1: {
std::shared_ptr<SohModalWindow> modal = static_pointer_cast<SohModalWindow>(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Modal Window"));
modal->RegisterPopup("Menu Moved", "The menubar, accessed by hitting F1, no longer exists.\nThe new menu can be accessed by hitting the Esc button instead.", "OK");
break;
}
case KbScancode::LUS_KB_F5: {
if (CVarGetInteger(CVAR_CHEAT("SaveStatesEnabled"), 0) == 0) {
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->
@ -1369,6 +1371,10 @@ extern "C" void Graph_StartFrame() {
break;
}
#endif
case KbScancode::LUS_KB_F11: {
CVarSetInteger(CVAR_SETTING("Fullscreen"), !CVarGetInteger(CVAR_SETTING("Fullscreen"), 0));
break;
}
case KbScancode::LUS_KB_TAB: {
CVarSetInteger(CVAR_ENHANCEMENT("AltAssets"), !CVarGetInteger(CVAR_ENHANCEMENT("AltAssets"), 0));
break;

View file

@ -4,6 +4,7 @@
#include "soh/Enhancements/controls/SohInputEditorWindow.h"
#include "window/gui/GuiMenuBar.h"
#include "window/gui/GuiElement.h"
#include "SohModals.h"
#include <variant>
#include <spdlog/fmt/fmt.h>
#include "variables.h"
@ -19,7 +20,9 @@ std::vector<ImVec2> windowTypeSizes = { {} };
extern std::unordered_map<s16, const char*> warpPointSceneList;
extern void Warp();
namespace SohGui {}
namespace SohGui {
extern std::shared_ptr<SohModalWindow> mModalWindow;
}
namespace Ship {
std::string disabledTempTooltip;
@ -104,6 +107,10 @@ void Menu::UpdateWindowBackendObjects() {
}
}
bool Menu::IsMenuPopped() {
return popped;
}
UIWidgets::Colors Menu::GetMenuThemeColor() {
return menuThemeIndex;
}
@ -303,21 +310,23 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me
ImGui::Separator();
} break;
case WIDGET_SEPARATOR_TEXT: {
if (widget.options->color != UIWidgets::Colors::NoColor) {
ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(widget.options->color));
auto options = std::static_pointer_cast<UIWidgets::TextOptions>(widget.options);
if (options->color != UIWidgets::Colors::NoColor) {
ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(options->color));
}
ImGui::SeparatorText(widget.name.c_str());
if (widget.options->color != UIWidgets::Colors::NoColor) {
if (options->color != UIWidgets::Colors::NoColor) {
ImGui::PopStyleColor();
}
} break;
case WIDGET_TEXT: {
if (widget.options->color != UIWidgets::Colors::NoColor) {
ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(widget.options->color));
auto options = std::static_pointer_cast<UIWidgets::TextOptions>(widget.options);
if (options->color != UIWidgets::Colors::NoColor) {
ImGui::PushStyleColor(ImGuiCol_Text, UIWidgets::ColorValues.at(options->color));
}
ImGui::AlignTextToFramePadding();
ImGui::TextWrapped("%s", widget.name.c_str());
if (widget.options->color != UIWidgets::Colors::NoColor) {
if (options->color != UIWidgets::Colors::NoColor) {
ImGui::PopStyleColor();
}
} break;
@ -530,13 +539,13 @@ void Menu::DrawElement() {
ImGui::End();
return;
}
ImGui::PushFont(OTRGlobals::Instance->fontStandardLargest);
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiStyle& style = ImGui::GetStyle();
windowHeight = window->WorkRect.GetHeight();
windowWidth = window->WorkRect.GetWidth();
ImGui::PushFont(OTRGlobals::Instance->fontStandardLargest);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(10.0f, 8.0f));
const char* headerCvar = CVAR_SETTING("Menu.ActiveHeader");
std::string headerIndex = CVarGetString(headerCvar, "Settings");
@ -559,12 +568,13 @@ void Menu::DrawElement() {
// Full screen menu with widths below 1280, heights below 800.
// 5% of screen width/height padding on both sides above those resolutions.
ImVec2 menuSize = { std::fminf(1280, windowWidth), std::fminf(800, windowHeight) };
// Menu width will never exceed a 16:9 aspect ratio.
ImVec2 menuSize = { windowWidth, windowHeight };
if (windowWidth > 1280) {
menuSize.x = floor(windowWidth * 0.9);
menuSize.x = std::fminf(windowWidth * 0.9f, (windowHeight * 1.77f));
}
if (windowHeight > 800) {
menuSize.y = floor(windowHeight * 0.9);
menuSize.y = windowHeight * 0.9f;
}
pos += window->WorkRect.GetSize() / 2 - menuSize / 2;
@ -581,22 +591,6 @@ void Menu::DrawElement() {
headerHeight += style.ScrollbarSize;
scrollbar = true;
}
UIWidgets::ButtonOptions options = {};
options.size = UIWidgets::Sizes::Inline;
options.tooltip = "Close Menu (Esc)";
if (UIWidgets::Button(ICON_FA_TIMES_CIRCLE, options)) {
ToggleVisibility();
// Update gamepad navigation after close based on if other menus are still visible
auto mImGuiIo = &ImGui::GetIO();
if (CVarGetInteger(CVAR_IMGUI_CONTROLLER_NAV, 0) &&
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetMenuOrMenubarVisible()) {
mImGuiIo->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
} else {
mImGuiIo->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
}
}
ImGui::SameLine();
ImGui::SetNextWindowSizeConstraints({ 0, headerHeight }, { headerWidth, headerHeight });
ImVec2 headerSelSize = { menuSize.x - buttonSize.x * 3 - style.ItemSpacing.x * 3, headerHeight };
if (scrollbar) {
@ -657,7 +651,22 @@ void Menu::DrawElement() {
ImGui::PopStyleColor();
}
ImGui::EndChild();
ImGui::SameLine(menuSize.x - (buttonSize.x * 2) - style.ItemSpacing.x);
ImGui::SameLine(menuSize.x - (buttonSize.x * 3) - (style.ItemSpacing.x * 2));
UIWidgets::ButtonOptions options3 = {};
options3.color = UIWidgets::Colors::Red;
options3.size = UIWidgets::Sizes::Inline;
options3.tooltip = "Quit SoH";
if (UIWidgets::Button(ICON_FA_POWER_OFF, options3)) {
SohGui::mModalWindow->RegisterPopup("Quit SoH", "Are you sure you want to quit SoH?", "Quit", "Cancel", []() {
std::shared_ptr<Menu> menu = static_pointer_cast<Menu>(Ship::Context::GetInstance()->GetWindow()->GetGui()->GetMenu());
if (!menu->IsMenuPopped()) {
menu->ToggleVisibility();
}
Ship::Context::GetInstance()->GetWindow()->Close();
}, nullptr);
}
ImGui::PopStyleVar();
ImGui::SameLine();
UIWidgets::ButtonOptions options2 = {};
options2.color = UIWidgets::Colors::Red;
options2.size = UIWidgets::Sizes::Inline;
@ -676,17 +685,21 @@ void Menu::DrawElement() {
->Dispatch("reset");
}
ImGui::SameLine();
UIWidgets::ButtonOptions options3 = {};
options3.color = UIWidgets::Colors::Red;
options3.size = UIWidgets::Sizes::Inline;
options3.tooltip = "Quit SoH";
if (UIWidgets::Button(ICON_FA_POWER_OFF, options3)) {
if (!popped) {
ToggleVisibility();
UIWidgets::ButtonOptions options = {};
options.size = UIWidgets::Sizes::Inline;
options.tooltip = "Close Menu (Esc)";
if (UIWidgets::Button(ICON_FA_TIMES_CIRCLE, options)) {
ToggleVisibility();
// Update gamepad navigation after close based on if other menus are still visible
auto mImGuiIo = &ImGui::GetIO();
if (CVarGetInteger(CVAR_IMGUI_CONTROLLER_NAV, 0) &&
Ship::Context::GetInstance()->GetWindow()->GetGui()->GetMenuOrMenubarVisible()) {
mImGuiIo->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
} else {
mImGuiIo->ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad;
}
Ship::Context::GetInstance()->GetWindow()->Close();
}
ImGui::PopStyleVar();
pos.y += headerHeight + style.ItemSpacing.y;
pos.x = centerX - menuSize.x / 2 + (style.ItemSpacing.x * (menuEntries.size() + 1));
@ -696,7 +709,12 @@ void Menu::DrawElement() {
float sectionHeight = menuSize.y - headerHeight - 4 - style.ItemSpacing.y * 2;
float columnHeight = sectionHeight - style.ItemSpacing.y * 4;
ImGui::SetNextWindowPos(pos + style.ItemSpacing * 2);
// Increase sidebar width on larger screens to accomodate people scaling their menus.
float sidebarWidth = 200 - style.ItemSpacing.x;
if (menuSize.x > 1600) {
sidebarWidth = menuSize.x * 0.15f;
}
const char* sidebarCvar = menuEntries.at(headerIndex).sidebarCvar;
@ -732,8 +750,8 @@ void Menu::DrawElement() {
}
}
ImGui::EndChild();
ImGui::PopFont();
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
pos = ImVec2{ sectionCenterX + (sidebarWidth / 2), topY } + style.ItemSpacing * 2;
window->DrawList->AddRectFilled(pos, pos + ImVec2{ 4, sectionHeight - style.FramePadding.y * 2 },
ImGui::GetColorU32({ 255, 255, 255, 255 }), true, style.WindowRounding);
@ -802,8 +820,6 @@ void Menu::DrawElement() {
if (!useColumns || menuSearchText.length() > 0) {
ImGui::EndChild();
}
ImGui::PopFont();
ImGui::PopFont();
if (!popout) {
ImGui::PopStyleVar();

View file

@ -21,6 +21,7 @@ class Menu : public GuiWindow {
void InsertSidebarSearch();
void RemoveSidebarSearch();
void UpdateWindowBackendObjects();
bool IsMenuPopped();
UIWidgets::Colors GetMenuThemeColor();
void MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors menuThemeIndex);

View file

@ -73,7 +73,7 @@ typedef enum {
using CVarVariant = std::variant<int32_t, const char*, float, Color_RGBA8, Color_RGB8>;
using OptionsVariant =
std::variant<UIWidgets::ButtonOptions, UIWidgets::CheckboxOptions, UIWidgets::ComboboxOptions,
UIWidgets::FloatSliderOptions, UIWidgets::IntSliderOptions, UIWidgets::WidgetOptions,
UIWidgets::FloatSliderOptions, UIWidgets::IntSliderOptions, UIWidgets::TextOptions, UIWidgets::WidgetOptions,
UIWidgets::WindowButtonOptions>;
// All the info needed for display and search of all widgets in the menu.
@ -145,6 +145,8 @@ struct WidgetInfo {
break;
case WIDGET_TEXT:
case WIDGET_SEPARATOR_TEXT:
options = std::make_shared<UIWidgets::TextOptions>(std::get<UIWidgets::TextOptions>(options_));
break;
case WIDGET_SEPARATOR:
default:
options = std::make_shared<UIWidgets::WidgetOptions>(std::get<UIWidgets::WidgetOptions>(options_));

View file

@ -360,10 +360,10 @@ void RegisterResolutionWidgets() {
WIDGET_TEXT)
.PreFunc(
[](WidgetInfo& info) { info.isHidden = !(!CVarGetInteger(CVAR_LOW_RES_MODE, 0) && IsDroppingFrames()); })
.Options(WidgetOptions().Color(Colors::Orange));
.Options(TextOptions().Color(Colors::Orange));
mSohMenu->AddWidget(path, ICON_FA_QUESTION_CIRCLE " \"N64 Mode\" is overriding these settings.", WIDGET_TEXT)
.PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); })
.Options(WidgetOptions().Color(Colors::LightBlue));
.Options(TextOptions().Color(Colors::LightBlue));
mSohMenu->AddWidget(path, "Click to disable N64 mode", WIDGET_BUTTON)
.PreFunc([](WidgetInfo& info) { info.isHidden = !CVarGetInteger(CVAR_LOW_RES_MODE, 0); })
.Callback([](WidgetInfo& info) {
@ -391,7 +391,7 @@ void RegisterResolutionWidgets() {
}
})
.SameLine(true)
.Options(WidgetOptions().Color(Colors::Gray));
.Options(TextOptions().Color(Colors::Gray));
// Presets
mSohMenu->AddWidget(path, "Aspect Ratio", WIDGET_COMBOBOX)
.ValuePointer(&item_aspectRatio)
@ -422,10 +422,10 @@ void RegisterResolutionWidgets() {
// Declare input interaction bools outside of IF statement to prevent Y field from disappearing.
const bool input_X = UIWidgets::SliderFloat("X", &aspectRatioX,
UIWidgets::FloatSliderOptions({{ .disabled = disabled_everything }}).Min(0.1f).Max(32.0f).Step(0.001f).Format("%3f")
.Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPosition::Near).ComponentAlignment(UIWidgets::ComponentAlignment::Right));
.Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::Near).ComponentAlignment(UIWidgets::ComponentAlignments::Right));
const bool input_Y = UIWidgets::SliderFloat("Y", &aspectRatioY,
UIWidgets::FloatSliderOptions({{ .disabled = disabled_everything }}).Min(0.1f).Max(24.0f).Step(0.001f).Format("%3f")
.Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPosition::Near).ComponentAlignment(UIWidgets::ComponentAlignment::Right));
.Color(THEME_COLOR).LabelPosition(UIWidgets::LabelPositions::Near).ComponentAlignment(UIWidgets::ComponentAlignments::Right));
if (input_X || input_Y) {
item_aspectRatio = default_aspectRatio;
update[UPDATE_aspectRatioX] = true;
@ -517,7 +517,7 @@ void UpdateResolutionVars() {
bool IsDroppingFrames() {
// a rather imprecise way of checking for frame drops.
// but it's mostly there to inform the player of large drops.
const short targetFPS = CVarGetInteger("gInterpolationFPS", 20);
const short targetFPS = OTRGlobals::Instance->GetInterpolationFPS();
const float threshold = targetFPS / 20.0f + 4.1f;
return ImGui::GetIO().Framerate < targetFPS - threshold;
}

View file

@ -64,10 +64,12 @@ WidgetInfo& SohMenu::AddWidget(WidgetPath& pathInfo, std::string widgetName, Wid
case WIDGET_COLOR_24:
case WIDGET_COLOR_32:
break;
case WIDGET_SEARCH:
case WIDGET_SEPARATOR:
case WIDGET_SEPARATOR_TEXT:
case WIDGET_TEXT:
widget.options = std::make_shared<TextOptions>();
break;
case WIDGET_SEARCH:
case WIDGET_SEPARATOR:
default:
widget.options = std::make_shared<WidgetOptions>();
}
@ -125,7 +127,7 @@ void SohMenu::InitElement() {
},
"Not Available on DirectX" } },
{ DISABLE_FOR_MATCH_REFRESH_RATE_ON,
{ [](disabledInfo& info) -> bool { return CVarGetInteger(CVAR_SETTING("gMatchRefreshRate"), 0); },
{ [](disabledInfo& info) -> bool { return CVarGetInteger(CVAR_SETTING("MatchRefreshRate"), 0); },
"Match Refresh Rate is Enabled" } },
{ DISABLE_FOR_ADVANCED_RESOLUTION_ON,
{ [](disabledInfo& info) -> bool { return CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".Enabled", 0); },
@ -140,7 +142,7 @@ void SohMenu::InitElement() {
{ DISABLE_FOR_NULL_PLAY_STATE,
{ [](disabledInfo& info) -> bool { return gPlayState == NULL; }, "Save Not Loaded" } },
{ DISABLE_FOR_DEBUG_MODE_OFF,
{ [](disabledInfo& info) -> bool { return !CVarGetInteger("gDeveloperTools.DebugEnabled", 0); },
{ [](disabledInfo& info) -> bool { return !CVarGetInteger(CVAR_DEVELOPER_TOOLS("DebugEnabled"), 0); },
"Debug Mode is Disabled" } },
{ DISABLE_FOR_FRAME_ADVANCE_OFF,
{ [](disabledInfo& info) -> bool { return !(gPlayState != nullptr && gPlayState->frameAdvCtx.enabled); },

File diff suppressed because it is too large Load diff

View file

@ -42,11 +42,11 @@ void SohMenu::AddMenuNetwork() {
.CustomFunction([](WidgetInfo& info) {
ImGui::BeginDisabled(Sail::Instance->isEnabled);
ImGui::Text("%s", info.name.c_str());
CVarInputString("##HostSail", CVAR_REMOTE_SAIL("Host"), InputOptions().Color(THEME_COLOR).PlaceholderText("127.0.0.1").DefaultValue("127.0.0.1").Size(ImVec2(ImGui::GetFontSize() * 15, 0)).LabelPosition(LabelPosition::None));
CVarInputString("##HostSail", CVAR_REMOTE_SAIL("Host"), InputOptions().Color(THEME_COLOR).PlaceholderText("127.0.0.1").DefaultValue("127.0.0.1").Size(ImVec2(ImGui::GetFontSize() * 15, 0)).LabelPosition(LabelPositions::None));
ImGui::SameLine();
ImGui::Text(":");
ImGui::SameLine();
CVarInputInt("##PortSail", CVAR_REMOTE_SAIL("Port"), InputOptions().Color(THEME_COLOR).PlaceholderText("43384").DefaultValue("43384").Size(ImVec2(ImGui::GetFontSize() * 5, 0)).LabelPosition(LabelPosition::None));
CVarInputInt("##PortSail", CVAR_REMOTE_SAIL("Port"), InputOptions().Color(THEME_COLOR).PlaceholderText("43384").DefaultValue("43384").Size(ImVec2(ImGui::GetFontSize() * 5, 0)).LabelPosition(LabelPositions::None));
ImGui::EndDisabled();
});
AddWidget(path, "Enable##Sail", WIDGET_BUTTON)
@ -104,11 +104,11 @@ void SohMenu::AddMenuNetwork() {
.CustomFunction([](WidgetInfo& info) {
ImGui::BeginDisabled(CrowdControl::Instance->isEnabled);
ImGui::Text("%s", info.name.c_str());
CVarInputString("##HostCrowdControl", CVAR_REMOTE_CROWD_CONTROL("Host"), InputOptions().Color(THEME_COLOR).PlaceholderText("127.0.0.1").DefaultValue("127.0.0.1").Size(ImVec2(ImGui::GetFontSize() * 15, 0)).LabelPosition(LabelPosition::None));
CVarInputString("##HostCrowdControl", CVAR_REMOTE_CROWD_CONTROL("Host"), InputOptions().Color(THEME_COLOR).PlaceholderText("127.0.0.1").DefaultValue("127.0.0.1").Size(ImVec2(ImGui::GetFontSize() * 15, 0)).LabelPosition(LabelPositions::None));
ImGui::SameLine();
ImGui::Text(":");
ImGui::SameLine();
CVarInputInt("##PortCrowdControl", CVAR_REMOTE_CROWD_CONTROL("Port"), InputOptions().Color(THEME_COLOR).PlaceholderText("43384").DefaultValue("43384").Size(ImVec2(ImGui::GetFontSize() * 5, 0)).LabelPosition(LabelPosition::None));
CVarInputInt("##PortCrowdControl", CVAR_REMOTE_CROWD_CONTROL("Port"), InputOptions().Color(THEME_COLOR).PlaceholderText("43384").DefaultValue("43384").Size(ImVec2(ImGui::GetFontSize() * 5, 0)).LabelPosition(LabelPositions::None));
ImGui::EndDisabled();
});
AddWidget(path, "Enable##CrowdControl", WIDGET_BUTTON)

View file

@ -17,8 +17,11 @@ void SohMenu::AddMenuRandomizer() {
.CVar(CVAR_WINDOW("RandomizerSettings"))
.WindowName("Randomizer Settings")
.Options(WindowButtonOptions().Tooltip("Enables the separate Randomizer Settings Window."));
// Enhancements
path.sidebarName = "Enhancements";
AddSidebarEntry("Randomizer", path.sidebarName, 1);
AddSidebarEntry("Randomizer", path.sidebarName, 3);
AddWidget(path, "Randomizer Enhancements", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Rando-Relevant Navi Hints", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("RandoRelevantNavi"))
.Options(CheckboxOptions().Tooltip(
@ -34,21 +37,21 @@ void SohMenu::AddMenuRandomizer() {
.Options(CheckboxOptions().Tooltip(
"Use Custom graphics for Dungeon Keys, Big and Small, so that they can be easily told apart."
).DefaultValue(true));
AddWidget(path, "Compass Colors Match Dungeon", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("MatchCompassColors"))
AddWidget(path, "Map & Compass Colors Match Dungeon", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("ColoredMapsAndCompasses"))
.PreFunc([](WidgetInfo& info) {
info.options->disabled = !(
OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).IsNot(RO_DUNGEON_ITEM_LOC_STARTWITH) &&
OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).IsNot(RO_DUNGEON_ITEM_LOC_VANILLA) &&
OTRGlobals::Instance->gRandoContext->GetOption(RSK_SHUFFLE_MAPANDCOMPASS).IsNot(RO_DUNGEON_ITEM_LOC_OWN_DUNGEON)
);
info.options->disabledTooltip = "This setting is disabled because a savefile is loaded without "
"the compass shuffle settings set to Any Dungeon, Overworld, or Anywhere.";
info.options->disabledTooltip = "This setting is disabled because a savefile is loaded without the map & compass\n"
"shuffle settings set to \"Any Dungeon\", \"Overworld\" or \"Anywhere\"";
})
.Options(CheckboxOptions().Tooltip(
"Matches the color of compasses to the dungeon they belong to. "
"This helps identify compasses from afar and adds a little bit of flair.\n\nThis only "
"applies to seeds with compasses shuffled to \"Any Dungeon\", \"Overworld\", or \"Anywhere\"."
"Matches the color of maps & compasses to the dungeon they belong to. "
"This helps identify maps & compasses from afar and adds a little bit of flair.\n\nThis only "
"applies to seeds with maps & compasses shuffled to \"Any Dungeon\", \"Overworld\", or \"Anywhere\"."
).DefaultValue(true));
AddWidget(path, "Quest Item Fanfares", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("QuestItemFanfares"))
@ -75,7 +78,9 @@ void SohMenu::AddMenuRandomizer() {
AddWidget(path, "Item Scale: %.2f", WIDGET_CVAR_SLIDER_FLOAT)
.CVar(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimationScale"))
.PreFunc([](WidgetInfo& info) {
info.isHidden = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_DISABLED) == SGIA_DISABLED;
info.options->disabled =
!CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("TimeSavers.SkipGetItemAnimation"), SGIA_DISABLED);
info.options->disabledTooltip = "This slider only applies when using the \"Skip Get Item Animations\" option.";
})
.Options(FloatSliderOptions()
.Min(5.0f)

View file

@ -55,6 +55,7 @@ void SohMenu::AddMenuSettings() {
WidgetPath path = { "Settings", "General", SECTION_COLUMN_1 };
// General - Settings
AddWidget(path, "General Settings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Menu Theme", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("Menu.Theme"))
.Options(ComboboxOptions()
@ -65,7 +66,7 @@ void SohMenu::AddMenuSettings() {
AddWidget(path, "Menu Controller Navigation", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_IMGUI_CONTROLLER_NAV)
.Options(CheckboxOptions().Tooltip(
"Allows controller navigation of the 2Ship menu (Settings, Enhancements,...)\nCAUTION: "
"Allows controller navigation of the port menu (Settings, Enhancements,...)\nCAUTION: "
"This will disable game inputs while the menu is visible.\n\nD-pad to move between "
"items, A to select, B to move up in scope."));
AddWidget(path, "Cursor Always Visible", WIDGET_CVAR_CHECKBOX)
@ -101,12 +102,26 @@ void SohMenu::AddMenuSettings() {
SDL_OpenURL(std::string("file:///" + std::filesystem::absolute(filesPath).string()).c_str());
})
.Options(ButtonOptions().Tooltip("Opens the folder that contains the save and mods folders, etc."));
AddWidget(path, "Boot", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Boot Sequence", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_ENHANCEMENT("BootSequence"))
.Options(ComboboxOptions()
.DefaultIndex(BOOTSEQUENCE_DEFAULT)
.LabelPosition(LabelPositions::Far)
.ComponentAlignment(ComponentAlignments::Right)
.ComboMap(bootSequenceLabels)
.Tooltip("Configure what happens when starting or resetting the game.\n\n"
"Default: LUS logo -> N64 logo\n"
"Authentic: N64 logo only\n"
"File Select: Skip to file select menu"));
AddWidget(path, "Languages", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Translate Title Screen", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("TitleScreenTranslation"));
AddWidget(path, "Menu Language", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("Languages"))
.Options(ComboboxOptions().LabelPosition(LabelPosition::Far).ComponentAlignment(ComponentAlignment::Right).ComboMap(languages).DefaultIndex(LANGUAGE_ENG));
.Options(ComboboxOptions().LabelPosition(LabelPositions::Far).ComponentAlignment(ComponentAlignments::Right).ComboMap(languages).DefaultIndex(LANGUAGE_ENG));
AddWidget(path, "Accessibility", WIDGET_SEPARATOR_TEXT);
#if defined(_WIN32) || defined(__APPLE__)
AddWidget(path, "Text to Speech", WIDGET_CVAR_CHECKBOX)
@ -117,11 +132,11 @@ void SohMenu::AddMenuSettings() {
.CVar(CVAR_SETTING("A11yDisableIdleCam"))
.Options(CheckboxOptions().Tooltip("Disables the automatic re-centering of the camera when idle."));
AddWidget(path, "EXPERIMENTAL", WIDGET_SEPARATOR_TEXT)
.Options(WidgetOptions().Color(Colors::Orange));
.Options(TextOptions().Color(Colors::Orange));
AddWidget(path, "ImGui Menu Scaling", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("ImGuiScale"))
.Options(ComboboxOptions().ComboMap(imguiScaleOptions).Tooltip("Changes the scaling of the ImGui menu elements.").DefaultIndex(1)
.ComponentAlignment(ComponentAlignment::Right).LabelPosition(LabelPosition::Far))
.ComponentAlignment(ComponentAlignments::Right).LabelPosition(LabelPositions::Far))
.Callback([](WidgetInfo& info) {
OTRGlobals::Instance->ScaleImGui();
});
@ -201,20 +216,13 @@ void SohMenu::AddMenuSettings() {
AddWidget(path, "Audio API (Needs reload)", WIDGET_AUDIO_BACKEND);
// Graphics Settings
static int32_t maxFps;
const char* tooltip = "";
if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) {
maxFps = 360;
tooltip = "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is "
"purely visual and does not impact game logic, execution of glitches etc.\n\nA higher target "
"FPS than your monitor's refresh rate will waste resources, and might give a worse result.";
} else {
maxFps = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
tooltip = "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is "
"purely visual and does not impact game logic, execution of glitches etc.";
}
static int32_t maxFps = 360;
const char* tooltip = "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is "
"purely visual and does not impact game logic, execution of glitches etc.\n\nA higher target "
"FPS than your monitor's refresh rate will waste resources, and might give a worse result.";
path.sidebarName = "Graphics";
AddSidebarEntry("Settings", "Graphics", 3);
AddWidget(path, "Graphics Options", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Toggle Fullscreen", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SETTING("Fullscreen"))
.Callback([](WidgetInfo& info) { Ship::Context::GetInstance()->GetWindow()->ToggleFullscreen(); })
@ -276,25 +284,14 @@ void SohMenu::AddMenuSettings() {
info.activeDisables.push_back(DISABLE_FOR_MATCH_REFRESH_RATE_ON);
})
.Options(IntSliderOptions().Tooltip(tooltip).Min(20).Max(maxFps).DefaultValue(20).Format(fpsFormat));
AddWidget(path, "Match Refresh Rate", WIDGET_BUTTON)
.Callback([](WidgetInfo& info) {
int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate();
if (hz >= 20 && hz <= 360) {
CVarSetInteger(CVAR_SETTING("InterpolationFPS"), hz);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame();
}
})
.PreFunc([](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NOT_DIRECTX).active; })
.Options(ButtonOptions().Tooltip("Matches interpolation value to the current game's window refresh rate."));
AddWidget(path, "Match Refresh Rate", WIDGET_CVAR_CHECKBOX)
.CVar("gMatchRefreshRate")
.PreFunc([](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_DIRECTX).active; })
.Options(CheckboxOptions().Tooltip("Matches interpolation value to the current game's window refresh rate."));
.CVar(CVAR_SETTING("MatchRefreshRate"))
.Options(CheckboxOptions().Tooltip("Matches interpolation value to the refresh rate of your display."));
AddWidget(path, "Renderer API (Needs reload)", WIDGET_VIDEO_BACKEND);
AddWidget(path, "Enable Vsync", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_VSYNC_ENABLED)
.PreFunc([](WidgetInfo& info) { info.isHidden = mSohMenu->disabledMap.at(DISABLE_FOR_NO_VSYNC).active; })
.Options(CheckboxOptions().Tooltip("Enables Vsync."));
.Options(CheckboxOptions().Tooltip("Removes tearing, but clamps your max FPS to your displays refresh rate."));
AddWidget(path, "Windowed Fullscreen", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_SDL_WINDOWED_FULLSCREEN)
.PreFunc([](WidgetInfo& info) {
@ -311,9 +308,12 @@ void SohMenu::AddMenuSettings() {
.CVar(CVAR_TEXTURE_FILTER)
.Options(ComboboxOptions().Tooltip("Sets the applied Texture Filtering.").ComboMap(textureFilteringMap));
path.column = SECTION_COLUMN_2;
AddWidget(path, "Advanced Graphics Options", WIDGET_SEPARATOR_TEXT);
// Controls
path.sidebarName = "Controls";
path.column = SECTION_COLUMN_1;
AddSidebarEntry("Settings", "Controls", 2);
AddWidget(path, "Controller Bindings", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Popout Bindings Window", WIDGET_WINDOW_BUTTON)
@ -321,7 +321,9 @@ void SohMenu::AddMenuSettings() {
.WindowName("Configure Controller")
.Options(WindowButtonOptions().Tooltip("Enables the separate Bindings Window."));
path.column = SECTION_COLUMN_2;
// Input Viewer
path.sidebarName = "Input Viewer";
AddSidebarEntry("Settings", path.sidebarName, 3);
AddWidget(path, "Input Viewer", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "Toggle Input Viewer", WIDGET_WINDOW_BUTTON)
.CVar(CVAR_WINDOW("InputViewer"))
@ -337,7 +339,7 @@ void SohMenu::AddMenuSettings() {
// Notifications
path.sidebarName = "Notifications";
path.column = SECTION_COLUMN_1;
AddSidebarEntry("Settings", "Notifications", 3);
AddSidebarEntry("Settings", path.sidebarName, 3);
AddWidget(path, "Position", WIDGET_CVAR_COMBOBOX)
.CVar(CVAR_SETTING("Notifications.Position"))
.Options(ComboboxOptions()

View file

@ -30,7 +30,6 @@ void SohModalWindow::Draw() {
}
void SohModalWindow::DrawElement() {
ImGui::PushFont(OTRGlobals::Instance->fontMonoLarger);
if (modals.size() > 0) {
SohModal curModal = modals.at(0);
if (!ImGui::IsPopupOpen(curModal.title_.c_str())) {
@ -62,7 +61,6 @@ void SohModalWindow::DrawElement() {
}
ImGui::EndPopup();
}
ImGui::PopFont();
}
void SohModalWindow::RegisterPopup(std::string title, std::string message, std::string button1, std::string button2, std::function<void()> button1callback, std::function<void()> button2callback) {

View file

@ -193,8 +193,8 @@ bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship:
} else {
buttonText = ICON_FA_EXTERNAL_LINK_SQUARE " " + buttonText;
}
if (Button(buttonText.c_str(), {{ options.tooltip, options.disabled, options.disabledTooltip, options.color },
options.size, options.padding })) {
if (Button(buttonText.c_str(), {{ options.tooltip, options.disabled, options.disabledTooltip },
options.size, options.padding, options.color })) {
windowPtr->ToggleVisibility();
dirty = true;
}
@ -285,10 +285,10 @@ bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) {
ImGui::BeginDisabled(options.disabled);
bool above = options.labelPosition == LabelPosition::Above;
bool lpFar = options.labelPosition == LabelPosition::Far;
bool right = options.alignment == ComponentAlignment::Right;
bool none = options.labelPosition == LabelPosition::None;
bool above = options.labelPosition == LabelPositions::Above;
bool lpFar = options.labelPosition == LabelPositions::Far;
bool right = options.alignment == ComponentAlignments::Right;
bool none = options.labelPosition == LabelPositions::None;
std::string labelStr = (none ? "##" : "");
labelStr.append(_label);
@ -327,12 +327,12 @@ bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) {
PushStyleCheckbox(options.color);
ImVec2 checkPos = pos;
ImVec2 labelPos = pos;
if (options.labelPosition == LabelPosition::Above) {
if (options.labelPosition == LabelPositions::Above) {
checkPos.y += label_size.y + (style.ItemInnerSpacing.y * 2.0f);
} else {
labelPos.y += (square_sz / 2) - (label_size.y / 2);
}
if (options.alignment == ComponentAlignment::Right) {
if (options.alignment == ComponentAlignments::Right) {
checkPos.x = total_bb.Max.x - square_sz;
} else {
float labelFarOffset = ImGui::GetContentRegionAvail().x - label_size.x;
@ -518,22 +518,22 @@ bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& option
ImGui::BeginDisabled(options.disabled);
PushStyleSlider(options.color);
float width = (options.size == ImVec2(0,0)) ? ImGui::GetContentRegionAvail().x : options.size.x;
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
if (options.labelPosition == LabelPositions::Near || options.labelPosition == LabelPositions::Far) {
width = width - (ImGui::CalcTextSize(label).x + ImGui::GetStyle().FramePadding.x);
}
ImGui::AlignTextToFramePadding();
if (options.alignment == ComponentAlignment::Right) {
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text(label, *value);
if (options.labelPosition == LabelPosition::Above) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
} else if (options.labelPosition == LabelPosition::Near) {
} else if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
} else if (options.labelPosition == LabelPositions::Far || options.labelPosition == LabelPositions::None) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
}
} else if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text(label, *value);
}
}
@ -576,11 +576,11 @@ bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& option
}
}
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text(label, *value);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
} else if (options.labelPosition == LabelPositions::Far || options.labelPosition == LabelPositions::None) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x);
ImGui::Text(label, *value);
}
@ -611,33 +611,25 @@ bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptio
}
void ClampFloat(float* value, float min, float max, float step) {
int ticks = 0;
float increment = 1.0f;
int factor = 1;
if (step < 1.0f) {
ticks++;
increment = 0.1f;
factor *= 10;
}
if (step < 0.1f) {
ticks++;
increment = 0.01f;
factor *= 10;
}
if (step < 0.01f) {
ticks++;
increment = 0.001f;
factor *= 10;
}
if (step < 0.001f) {
ticks++;
increment = 0.0001f;
factor *= 10;
}
if (step < 0.0001f) {
ticks++;
increment = 0.00001f;
factor *= 10;
}
if (step < 0.00001f) {
ticks++;
increment = 0.000001f;
factor *= 10;
}
int factor = 1 * std::pow(10, ticks);
if (*value < min) {
*value = min;
} else if (*value > max) {
@ -661,24 +653,24 @@ bool SliderFloat(const char* label, float* value, const FloatSliderOptions& opti
PushStyleSlider(options.color);
float labelSpacing = ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x;
float width = (options.size == ImVec2(0, 0)) ? ImGui::GetContentRegionAvail().x : options.size.x;
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
if (options.labelPosition == LabelPositions::Near || options.labelPosition == LabelPositions::Far) {
width = width - (ImGui::CalcTextSize(label).x + ImGui::GetStyle().FramePadding.x);
}
ImGui::AlignTextToFramePadding();
if (options.alignment == ComponentAlignment::Right) {
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text(label, *value);
if (options.labelPosition == LabelPosition::Above) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
} else if (options.labelPosition == LabelPosition::Near) {
} else if (options.labelPosition == LabelPositions::Near) {
width -= labelSpacing;
ImGui::SameLine();
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
} else if (options.labelPosition == LabelPositions::Far || options.labelPosition == LabelPositions::None) {
width -= labelSpacing;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
}
} else if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text(label, *value);
}
}
@ -715,11 +707,11 @@ bool SliderFloat(const char* label, float* value, const FloatSliderOptions& opti
}
}
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text(label, *value);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
} else if (options.labelPosition == LabelPositions::Far || options.labelPosition == LabelPositions::None) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - labelSpacing);
ImGui::Text(label, *value);
}
@ -765,19 +757,24 @@ bool InputString(const char* label, std::string* value, const InputOptions& opti
ImGui::BeginDisabled(options.disabled);
PushStyleInput(options.color);
float width = (options.size == ImVec2(0, 0)) ? ImGui::GetContentRegionAvail().x : options.size.x;
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text(label, *value->c_str());
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
} else if (options.alignment == ComponentAlignments::Right) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(width - ImGui::CalcTextSize(label).x);
ImGui::Text(label, *value->c_str());
}
}
ImGui::SetNextItemWidth(width);
if (ImGui::InputText(label, (char*)value->c_str(), value->capacity() + 1, ImGuiInputTextFlags_CallbackResize, InputTextResizeCallback, value)) {
ImGuiInputTextFlags flags = ImGuiInputTextFlags_CallbackResize;
if (options.secret) {
flags |= ImGuiInputTextFlags_Password;
}
flags |= options.addedFlags;
if (ImGui::InputText(label, (char*)value->c_str(), value->capacity() + 1, flags, InputTextResizeCallback, value)) {
dirty = true;
}
if (value->empty() && !options.placeholder.empty()) {
@ -816,19 +813,19 @@ bool InputInt(const char* label, int32_t* value, const InputOptions& options) {
ImGui::BeginDisabled(options.disabled);
PushStyleInput(options.color);
float width = (options.size == ImVec2(0, 0)) ? ImGui::GetContentRegionAvail().x : options.size.x;
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text(label, *value);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
} else if (options.alignment == ComponentAlignments::Right) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(width - ImGui::CalcTextSize(label).x);
ImGui::Text(label, *value);
}
}
ImGui::SetNextItemWidth(width);
if (ImGui::InputScalar(label, ImGuiDataType_S32, value)) {
if (ImGui::InputScalar(label, ImGuiDataType_S32, value, nullptr, nullptr, nullptr, options.addedFlags)) {
dirty = true;
}
if ((ImGui::GetItemStatusFlags() & ImGuiItemStatusFlags_Edited) && !options.placeholder.empty()) {

View file

@ -105,7 +105,7 @@ namespace UIWidgets {
const ImVec2 Fill = ImVec2(-1.0f, 0.0f);
}
enum LabelPosition {
enum LabelPositions {
Near,
Far,
Above,
@ -113,7 +113,7 @@ namespace UIWidgets {
Within,
};
enum ComponentAlignment {
enum ComponentAlignments {
Left,
Right,
};
@ -122,12 +122,7 @@ namespace UIWidgets {
const char* tooltip = "";
bool disabled = false;
const char* disabledTooltip = "";
Colors color = Colors::NoColor;
WidgetOptions& Color(Colors color_) {
color = color = color_;
return *this;
}
WidgetOptions& Tooltip(const char* tooltip_) {
tooltip = tooltip_;
return *this;
@ -142,6 +137,15 @@ namespace UIWidgets {
}
};
struct TextOptions : WidgetOptions {
Colors color = Colors::NoColor;
TextOptions& Color(Colors color_) {
color = color_;
return *this;
}
};
struct ButtonOptions : WidgetOptions {
ImVec2 size = Sizes::Fill;
ImVec2 padding = ImVec2(10.0f, 8.0f);
@ -160,7 +164,7 @@ namespace UIWidgets {
return *this;
}
ButtonOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
};
@ -185,7 +189,7 @@ namespace UIWidgets {
return *this;
}
WindowButtonOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
WindowButtonOptions& ShowButton(bool showButton_) {
@ -200,19 +204,19 @@ namespace UIWidgets {
struct CheckboxOptions : WidgetOptions {
bool defaultValue = false; // Only applicable to CVarCheckbox
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Near;
Colors color = WidgetOptions::color = Colors::LightBlue;
ComponentAlignments alignment = ComponentAlignments::Left;
LabelPositions labelPosition = LabelPositions::Near;
Colors color = Colors::LightBlue;
CheckboxOptions& DefaultValue(bool defaultValue_) {
defaultValue = defaultValue_;
return *this;
}
CheckboxOptions& ComponentAlignment(ComponentAlignment alignment_) {
CheckboxOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
CheckboxOptions& LabelPosition(LabelPosition labelPosition_) {
CheckboxOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
@ -221,7 +225,7 @@ namespace UIWidgets {
return *this;
}
CheckboxOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
CheckboxOptions& DisabledTooltip(const char* disabledTooltip_) {
@ -233,8 +237,8 @@ namespace UIWidgets {
struct ComboboxOptions : WidgetOptions {
std::unordered_map<int32_t, const char*> comboMap = {};
uint32_t defaultIndex = 0; // Only applicable to CVarCombobox
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
ComponentAlignments alignment = ComponentAlignments::Left;
LabelPositions labelPosition = LabelPositions::Above;
ImGuiComboFlags flags = 0;
Colors color = Colors::LightBlue;
@ -246,11 +250,11 @@ namespace UIWidgets {
defaultIndex = defaultIndex_;
return *this;
}
ComboboxOptions& ComponentAlignment(ComponentAlignment alignment_) {
ComboboxOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
ComboboxOptions& LabelPosition(LabelPosition labelPosition_) {
ComboboxOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
@ -259,7 +263,7 @@ namespace UIWidgets {
return *this;
}
ComboboxOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
};
@ -272,8 +276,8 @@ namespace UIWidgets {
int32_t max = 10;
int32_t defaultValue = 1;
bool clamp = true;
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
ComponentAlignments alignment = ComponentAlignments::Left;
LabelPositions labelPosition = LabelPositions::Above;
Colors color = Colors::Gray;
ImGuiSliderFlags flags = 0;
ImVec2 size = {0,0};
@ -302,11 +306,11 @@ namespace UIWidgets {
defaultValue = defaultValue_;
return *this;
}
IntSliderOptions& ComponentAlignment(ComponentAlignment alignment_) {
IntSliderOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
IntSliderOptions& LabelPosition(LabelPosition labelPosition_) {
IntSliderOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
@ -315,7 +319,7 @@ namespace UIWidgets {
return *this;
}
IntSliderOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
IntSliderOptions& Size(ImVec2 size_) {
@ -337,8 +341,8 @@ namespace UIWidgets {
float defaultValue = 1.0f;
bool clamp = true;
bool isPercentage = false; // Multiplies visual value by 100
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
ComponentAlignments alignment = ComponentAlignments::Left;
LabelPositions labelPosition = LabelPositions::Above;
Colors color = Colors::Gray;
ImGuiSliderFlags flags = 0;
ImVec2 size = {0,0};
@ -367,11 +371,11 @@ namespace UIWidgets {
defaultValue = defaultValue_;
return *this;
}
FloatSliderOptions& ComponentAlignment(ComponentAlignment alignment_) {
FloatSliderOptions& ComponentAlignment(ComponentAlignments alignment_) {
alignment = alignment_;
return *this;
}
FloatSliderOptions& LabelPosition(LabelPosition labelPosition_) {
FloatSliderOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
@ -387,7 +391,7 @@ namespace UIWidgets {
return *this;
}
FloatSliderOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
FloatSliderOptions& Size(ImVec2 size_) {
@ -402,6 +406,7 @@ namespace UIWidgets {
struct RadioButtonsOptions : WidgetOptions {
std::unordered_map<int32_t, const char*> buttonMap;
Colors color = Colors::LightBlue;
RadioButtonsOptions& ButtonMap(std::unordered_map<int32_t, const char*> buttonMap_) {
buttonMap = buttonMap_;
@ -412,26 +417,28 @@ namespace UIWidgets {
return *this;
}
RadioButtonsOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
};
struct InputOptions : WidgetOptions {
ComponentAlignment alignment = ComponentAlignment::Left;
LabelPosition labelPosition = LabelPosition::Above;
ComponentAlignments alignment = ComponentAlignments::Left;
LabelPositions labelPosition = LabelPositions::Above;
Colors color = Colors::Gray;
ImVec2 size = {0,0};
std::string placeholder = "";
InputTypes type = InputTypes::String;
std::string defaultValue = "";
bool secret = false;
ImGuiInputFlags addedFlags = 0;
InputOptions& Tooltip(const char* tooltip_) {
WidgetOptions::tooltip = tooltip_;
return *this;
}
InputOptions& Color(Colors color_) {
WidgetOptions::color = color = color_;
color = color_;
return *this;
}
InputOptions& Size(ImVec2 size_) {
@ -439,7 +446,7 @@ namespace UIWidgets {
return *this;
}
InputOptions& LabelPosition(LabelPosition labelPosition_) {
InputOptions& LabelPosition(LabelPositions labelPosition_) {
labelPosition = labelPosition_;
return *this;
}
@ -463,6 +470,11 @@ namespace UIWidgets {
defaultValue = defaultValue_;
return *this;
}
InputOptions& IsSecret(bool secret_ = false) {
secret = secret_;
return *this;
}
};
void PushStyleMenu(const ImVec4& color);
@ -508,92 +520,6 @@ namespace UIWidgets {
void Separator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f,
float extraVerticalBottomPadding = 0.0f);
/*using ComboVariant = std::variant<const std::unordered_map<int32_t, const char*>&, const std::vector<const char*>&>;
bool Combobox(const char* label, int32_t* value, ComboVariant comboSource, const ComboboxOptions& options = {}) {
bool dirty = false;
float startX = ImGui::GetCursorPosX();
std::string invisibleLabelStr = "##" + std::string(label);
const char* invisibleLabel = invisibleLabelStr.c_str();
ImGui::PushID(label);
ImGui::BeginGroup();
ImGui::BeginDisabled(options.disabled);
PushStyleCombobox(options.color);
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text("%s", label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text("%s", label);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
} else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) {
float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
}
if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f));
for (const auto& pair : comboMap) {
if (strlen(pair.second) > 1) {
if (ImGui::Selectable(pair.second, pair.first == *value)) {
*value = pair.first;
dirty = true;
}
}
}
ImGui::PopStyleVar();
ImGui::EndCombo();
}
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
ImGui::SameLine();
ImGui::Text("%s", label);
} else if (options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x);
ImGui::Text("%s", label);
}
} else if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) {
ImGui::SameLine(startX);
ImGui::Text("%s", label);
}
}
PopStyleCombobox();
ImGui::EndDisabled();
ImGui::EndGroup();
if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) {
ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str());
} else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) {
ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str());
}
ImGui::PopID();
return dirty;
}
bool CVarCombobox(const char* label, const char* cvarName, ComboVariant comboSource, const ComboboxOptions& options = {}) {
bool dirty = false;
int32_t value = CVarGetInteger(cvarName, options.defaultIndex);
if (Combobox(label, &value, comboSource, options)) {
CVarSetInteger(cvarName, value);
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
ShipInit::Init(cvarName);
dirty = true;
}
return dirty;
}*/
float CalcComboWidth(const char* preview_value, ImGuiComboFlags flags);
template <typename T>
@ -619,20 +545,20 @@ namespace UIWidgets {
float comboWidth = CalcComboWidth(longest, options.flags);
ImGui::AlignTextToFramePadding();
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Right) {
ImGui::Text(label);
if (options.labelPosition == LabelPosition::Above) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text("%s", label);
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
} else if (options.labelPosition == LabelPosition::Near) {
} else if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
}
} else if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
ImGui::Text(label);
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text("%s", label);
}
}
}
@ -652,12 +578,12 @@ namespace UIWidgets {
ImGui::EndCombo();
}
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text("%s", label);
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::Text("%s", label);
@ -699,19 +625,19 @@ namespace UIWidgets {
float comboWidth = CalcComboWidth(longest, options.flags);
ImGui::AlignTextToFramePadding();
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text("%s", label);
if (options.labelPosition == LabelPosition::Above) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
} else if (options.labelPosition == LabelPosition::Near) {
} else if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
}
} else if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text("%s", label);
}
}
@ -733,12 +659,12 @@ namespace UIWidgets {
ImGui::EndCombo();
}
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text("%s", label);
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
float width = ImGui::CalcTextSize(comboVector.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::Text("%s", label);
@ -781,19 +707,19 @@ namespace UIWidgets {
float comboWidth = CalcComboWidth(longest, options.flags);
ImGui::AlignTextToFramePadding();
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text("%s", label);
if (options.labelPosition == LabelPosition::Above) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
} else if (options.labelPosition == LabelPosition::Near) {
} else if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
}
} else if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text("%s", label);
}
}
@ -815,12 +741,12 @@ namespace UIWidgets {
ImGui::EndCombo();
}
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text("%s", label);
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
float width = ImGui::CalcTextSize(comboVector.at(*value).c_str()).x + ImGui::GetStyle().FramePadding.x * 2;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::Text("%s", label);
@ -866,19 +792,19 @@ namespace UIWidgets {
float comboWidth = CalcComboWidth(longest, options.flags);
ImGui::AlignTextToFramePadding();
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Right) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Right) {
ImGui::Text("%s", label);
if (options.labelPosition == LabelPosition::Above) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::NewLine();
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
} else if (options.labelPosition == LabelPosition::Near) {
} else if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth);
}
} else if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Above) {
} else if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Above) {
ImGui::Text("%s", label);
}
}
@ -900,12 +826,12 @@ namespace UIWidgets {
ImGui::EndCombo();
}
if (options.labelPosition != LabelPosition::None) {
if (options.alignment == ComponentAlignment::Left) {
if (options.labelPosition == LabelPosition::Near) {
if (options.labelPosition != LabelPositions::None) {
if (options.alignment == ComponentAlignments::Left) {
if (options.labelPosition == LabelPositions::Near) {
ImGui::SameLine();
ImGui::Text("%s", label);
} else if (options.labelPosition == LabelPosition::Far) {
} else if (options.labelPosition == LabelPositions::Far) {
float width = ImGui::CalcTextSize(comboArray[*value]).x + ImGui::GetStyle().FramePadding.x * 2;
ImGui::SameLine(ImGui::GetContentRegionAvail().x - width);
ImGui::Text("%s", label);

View file

@ -186,7 +186,7 @@ namespace SOH {
{ MigrationAction::Rename, "gDisableGrottoRotation", "gEnhancements.DisableGrottoRotation" },
{ MigrationAction::Rename, "gDisableKokiriDrawDistance", "gEnhancements.DisableKokiriDrawDistance" },
{ MigrationAction::Rename, "gDisableLOD", "gEnhancements.DisableLOD" },
{ MigrationAction::Rename, "gDisableNaviCallAudio", "gEnhancements.DisableNaviCallAudio" },
{ MigrationAction::Rename, "gDisableNaviCallAudio", "gAudioEditor.DisableNaviCallAudio" },
{ MigrationAction::Rename, "gDisableTunicWarningText", "gEnhancements.DisableTunicWarningText" },
{ MigrationAction::Rename, "gDogFollowsEverywhere", "gEnhancements.DogFollowsEverywhere" },
{ MigrationAction::Rename, "gDpadNoDropOcarinaInput", "gEnhancements.DpadNoDropOcarinaInput" },
@ -236,7 +236,7 @@ namespace SOH {
{ MigrationAction::Rename, "gInstantShootingGalleryWin", "gEnhancements.InstantShootingGalleryWin" },
{ MigrationAction::Rename, "gIvanCoopModeEnabled", "gEnhancements.IvanCoopModeEnabled" },
{ MigrationAction::Rename, "gLinkDefaultName", "gEnhancements.LinkDefaultName" },
{ MigrationAction::Rename, "gLowHpAlarm", "gEnhancements.LowHpAlarm" },
{ MigrationAction::Rename, "gLowHpAlarm", "gAudioEditor.LowHpAlarm" },
{ MigrationAction::Rename, "gMMBunnyHood", "gEnhancements.MMBunnyHood" },
{ MigrationAction::Rename, "gMarketSneak", "gEnhancements.MarketSneak" },
{ MigrationAction::Rename, "gMaskSelect", "gEnhancements.MaskSelect" },

View file

@ -150,17 +150,13 @@ bool Scene_CommandObjectList(PlayState* play, SOH::ISceneCommand* cmd) {
s32 i;
s32 j;
s32 k;
ObjectStatus* status;
ObjectStatus* status2;
ObjectStatus* firstStatus;
// s16* objectEntry = SEGMENTED_TO_VIRTUAL(cmd->objectList.segment);
s16* objectEntry = (s16*)cmdObj->GetRawPointer();
void* nextPtr;
k = 0;
i = play->objectCtx.unk_09;
firstStatus = &play->objectCtx.status[0];
status = &play->objectCtx.status[i];
// Loop until a mismatch in the object lists
// Then clear all object ids past that in the context object list and kill actors for those objects

View file

@ -651,7 +651,7 @@ void HealthMeter_HandleCriticalAlarm(PlayState* play) {
if (interfaceCtx->unk_22A <= 0) {
interfaceCtx->unk_22A = 0;
interfaceCtx->unk_22C = 0;
if (CVarGetInteger(CVAR_ENHANCEMENT("LowHpAlarm"), 0) == 0 && !Player_InCsMode(play) && (play->pauseCtx.state == 0) &&
if (CVarGetInteger(CVAR_AUDIO("LowHpAlarm"), 0) == 0 && !Player_InCsMode(play) && (play->pauseCtx.state == 0) &&
(play->pauseCtx.debugState == 0) && HealthMeter_IsCritical() && !Play_InCsMode(play)) {
Sfx_PlaySfxCentered(NA_SE_SY_HITPOINT_ALARM);
}

View file

@ -2832,7 +2832,7 @@ void Interface_SetNaviCall(PlayState* play, u16 naviCallState) {
if (((naviCallState == 0x1D) || (naviCallState == 0x1E)) && !interfaceCtx->naviCalling &&
(play->csCtx.state == CS_STATE_IDLE)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("DisableNaviCallAudio"), 0)) {
if (!CVarGetInteger(CVAR_AUDIO("DisableNaviCallAudio"), 0)) {
// clang-format off
if (naviCallState == 0x1E) { Audio_PlaySoundGeneral(NA_SE_VO_NAVY_CALL, &gSfxDefaultPos, 4,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); }

View file

@ -451,6 +451,10 @@ void EnDaiku_InitSubCamera(EnDaiku* this, PlayState* play) {
this->subCamActive = true;
this->escapeSubCamTimer = sEscapeSubCamParams[this->actor.params & 3].maxFramesActive;
if (!GameInteractor_Should(VB_PLAY_CARPENTER_FREE_CS, true, this)) {
return;
}
eyePosDeltaLocal.x = sEscapeSubCamParams[this->actor.params & 3].eyePosDeltaLocal.x;
eyePosDeltaLocal.y = sEscapeSubCamParams[this->actor.params & 3].eyePosDeltaLocal.y;
eyePosDeltaLocal.z = sEscapeSubCamParams[this->actor.params & 3].eyePosDeltaLocal.z;
@ -477,6 +481,10 @@ void EnDaiku_InitSubCamera(EnDaiku* this, PlayState* play) {
void EnDaiku_UpdateSubCamera(EnDaiku* this, PlayState* play) {
s32 pad;
if (!GameInteractor_Should(VB_PLAY_CARPENTER_FREE_CS, true, this)) {
return;
}
this->subCamAtTarget.x = this->actor.world.pos.x;
this->subCamAtTarget.y = this->actor.world.pos.y + 60.0f;
this->subCamAtTarget.z = this->actor.world.pos.z;
@ -493,8 +501,10 @@ void EnDaiku_EscapeSuccess(EnDaiku* this, PlayState* play) {
Actor* gerudoGuard;
Vec3f vec;
Play_ClearCamera(play, this->subCamId);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
if (GameInteractor_Should(VB_PLAY_CARPENTER_FREE_CS, true, this)) {
Play_ClearCamera(play, this->subCamId);
Play_ChangeCameraStatus(play, MAIN_CAM, CAM_STAT_ACTIVE);
}
this->subCamActive = false;
if (GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) {