Merge branch 'HarbourMasters:develop' into develop-pausewarp

This commit is contained in:
mckinlee 2023-09-27 17:04:34 +00:00 committed by GitHub
commit 22cc0cd082
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
285 changed files with 2551 additions and 967 deletions

View file

@ -0,0 +1,13 @@
<DisplayList Version="0">
<CallDisplayList Path="objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_edges"/>
<CallDisplayList Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_0"/>
<CallDisplayList Path="objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_surface"/>
<CallDisplayList Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_1"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View file

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

View file

@ -0,0 +1,7 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="6"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="4" V02="5"/>
<EndDisplayList/>
</DisplayList>

View file

@ -0,0 +1,54 @@
<Vertex Version="0">
<Vtx X="883" Y="-475" Z="103" S="344" T="380" R="103" G="6" B="75" A="255"/>
<Vtx X="809" Y="-497" Z="100" S="304" T="393" R="1" G="143" B="58" A="255"/>
<Vtx X="884" Y="-496" Z="96" S="345" T="393" R="78" G="166" B="46" A="255"/>
<Vtx X="856" Y="-477" Z="114" S="328" T="380" R="25" G="227" B="121" A="255"/>
<Vtx X="0" Y="945" Z="114" S="-58" T="-321" R="177" G="83" B="55" A="255"/>
<Vtx X="0" Y="870" Z="116" S="-58" T="-283" R="221" G="3" B="122" A="255"/>
<Vtx X="-856" Y="-477" Z="114" S="-437" T="380" R="231" G="227" B="121" A="255"/>
<Vtx X="-883" Y="-475" Z="103" S="-452" T="380" R="153" G="6" B="75" A="255"/>
<Vtx X="-809" Y="-497" Z="100" S="-412" T="393" R="255" G="143" B="58" A="255"/>
<Vtx X="-884" Y="-496" Z="96" S="-453" T="392" R="178" G="166" B="46" A="255"/>
<Vtx X="-817" Y="-464" Z="116" S="-414" T="369" R="254" G="251" B="127" A="255"/>
<Vtx X="817" Y="-464" Z="116" S="304" T="369" R="2" G="251" B="127" A="255"/>
<Vtx X="883" Y="-475" Z="-106" S="-460" T="380" R="103" G="6" B="181" A="255"/>
<Vtx X="884" Y="-496" Z="-99" S="-461" T="393" R="78" G="166" B="210" A="255"/>
<Vtx X="809" Y="-497" Z="-103" S="-420" T="393" R="1" G="143" B="198" A="255"/>
<Vtx X="856" Y="-477" Z="-117" S="-444" T="380" R="25" G="227" B="135" A="255"/>
<Vtx X="-856" Y="-477" Z="-117" S="320" T="380" R="231" G="227" B="135" A="255"/>
<Vtx X="856" Y="-477" Z="-117" S="-444" T="380" R="25" G="227" B="135" A="255"/>
<Vtx X="809" Y="-497" Z="-103" S="-420" T="393" R="1" G="143" B="198" A="255"/>
<Vtx X="-809" Y="-497" Z="-103" S="296" T="393" R="255" G="143" B="198" A="255"/>
<Vtx X="-883" Y="-475" Z="-106" S="336" T="380" R="153" G="6" B="181" A="255"/>
<Vtx X="-884" Y="-496" Z="-99" S="337" T="392" R="178" G="166" B="210" A="255"/>
<Vtx X="0" Y="945" Z="-117" S="-58" T="-321" R="177" G="83" B="201" A="255"/>
<Vtx X="0" Y="870" Z="-120" S="-58" T="-283" R="228" G="24" B="134" A="255"/>
<Vtx X="883" Y="-475" Z="-106" S="-460" T="380" R="103" G="6" B="181" A="255"/>
<Vtx X="817" Y="-464" Z="-120" S="-421" T="369" R="1" G="254" B="129" A="255"/>
<Vtx X="-817" Y="-464" Z="-120" S="297" T="369" R="255" G="254" B="129" A="255"/>
<Vtx X="-884" Y="-496" Z="-99" S="-149" T="-277" R="178" G="166" B="210" A="255"/>
<Vtx X="-809" Y="-497" Z="-103" S="-149" T="-277" R="255" G="143" B="198" A="255"/>
<Vtx X="809" Y="-497" Z="-103" S="-149" T="-277" R="1" G="143" B="198" A="255"/>
<Vtx X="884" Y="-496" Z="96" S="-149" T="-277" R="78" G="166" B="46" A="255"/>
<Vtx X="884" Y="-496" Z="-99" S="-149" T="-277" R="78" G="166" B="210" A="255"/>
<Vtx X="884" Y="-496" Z="96" S="-149" T="-277" R="78" G="166" B="46" A="255"/>
<Vtx X="884" Y="-496" Z="-99" S="-149" T="-277" R="78" G="166" B="210" A="255"/>
<Vtx X="883" Y="-475" Z="-106" S="-149" T="-277" R="103" G="6" B="181" A="255"/>
<Vtx X="883" Y="-475" Z="103" S="-149" T="-277" R="103" G="6" B="75" A="255"/>
<Vtx X="0" Y="945" Z="114" S="107" T="-277" R="177" G="83" B="55" A="255"/>
<Vtx X="0" Y="945" Z="-1" S="107" T="-149" R="169" G="92" B="0" A="255"/>
<Vtx X="0" Y="945" Z="-117" S="107" T="-277" R="177" G="83" B="201" A="255"/>
<Vtx X="-883" Y="-475" Z="103" S="-149" T="-277" R="153" G="6" B="75" A="255"/>
<Vtx X="-883" Y="-475" Z="-106" S="-149" T="-277" R="153" G="6" B="181" A="255"/>
<Vtx X="-884" Y="-496" Z="-99" S="-149" T="-277" R="178" G="166" B="210" A="255"/>
<Vtx X="-884" Y="-496" Z="96" S="-149" T="-277" R="178" G="166" B="46" A="255"/>
<Vtx X="-809" Y="-497" Z="100" S="-149" T="-277" R="255" G="143" B="58" A="255"/>
<Vtx X="809" Y="-497" Z="100" S="-149" T="-277" R="1" G="143" B="58" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="107" T="-149" R="165" G="0" B="89" A="255"/>
<Vtx X="0" Y="870" Z="-120" S="107" T="-277" R="221" G="3" B="134" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="235" T="-149" R="0" G="0" B="127" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="107" T="-149" R="165" G="0" B="89" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="235" T="-149" R="0" G="0" B="127" A="255"/>
<Vtx X="0" Y="870" Z="116" S="107" T="-277" R="221" G="3" B="122" A="255"/>
<Vtx X="0" Y="945" Z="114" S="107" T="-277" R="177" G="83" B="55" A="255"/>
</Vertex>

View file

@ -0,0 +1,8 @@
<Vertex Version="0">
<Vtx X="0" Y="870" Z="-120" S="-280" T="103" R="228" G="24" B="134" A="255"/>
<Vtx X="817" Y="-464" Z="-120" S="75" T="-550" R="1" G="254" B="129" A="255"/>
<Vtx X="-817" Y="-464" Z="-120" S="438" T="103" R="255" G="254" B="129" A="255"/>
<Vtx X="0" Y="870" Z="116" S="-280" T="103" R="221" G="3" B="122" A="255"/>
<Vtx X="-817" Y="-464" Z="116" S="438" T="103" R="254" G="251" B="127" A="255"/>
<Vtx X="817" Y="-464" Z="116" S="75" T="-550" R="2" G="251" B="127" A="255"/>
</Vertex>

View file

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

View file

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

View file

@ -0,0 +1,15 @@
<DisplayList Version="0">
<CallDisplayList Path="objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_surface"/>
<CallDisplayList Path="objects/object_triforce_piece_0/gTriforcePiece0DL_tri_0"/>
<CallDisplayList Path="objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_edges"/>
<CallDisplayList Path="objects/object_triforce_piece_0/gTriforcePiece0DL_tri_1"/>
<CallDisplayList Path="objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_shard_edge"/>
<CallDisplayList Path="objects/object_triforce_piece_0/gTriforcePiece0DL_tri_2"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View file

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

View file

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

View file

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

View file

@ -0,0 +1,18 @@
<Vertex Version="0">
<Vtx X="-123" Y="756" Z="-317" S="179" T="369" R="53" G="49" B="151" A="255"/>
<Vtx X="-309" Y="40" Z="-317" S="236" T="343" R="203" G="242" B="141" A="255"/>
<Vtx X="-419" Y="165" Z="-317" S="226" T="369" R="216" G="236" B="137" A="255"/>
<Vtx X="153" Y="372" Z="-317" S="212" T="298" R="82" G="29" B="163" A="255"/>
<Vtx X="135" Y="39" Z="-317" S="260" T="272" R="38" G="25" B="137" A="255"/>
<Vtx X="-283" Y="-340" Z="-317" S="287" T="307" R="201" G="193" B="160" A="255"/>
<Vtx X="507" Y="-162" Z="-317" S="260" T="203" R="70" G="41" B="158" A="255"/>
<Vtx X="607" Y="-764" Z="-317" S="290" T="170" R="16" G="184" B="152" A="255"/>
<Vtx X="-123" Y="756" Z="317" S="179" T="369" R="53" G="49" B="105" A="255"/>
<Vtx X="-419" Y="165" Z="317" S="226" T="369" R="216" G="236" B="119" A="255"/>
<Vtx X="-309" Y="40" Z="317" S="236" T="343" R="203" G="242" B="115" A="255"/>
<Vtx X="153" Y="372" Z="317" S="212" T="298" R="82" G="29" B="93" A="255"/>
<Vtx X="135" Y="39" Z="317" S="260" T="272" R="38" G="25" B="119" A="255"/>
<Vtx X="-283" Y="-340" Z="317" S="287" T="307" R="201" G="193" B="96" A="255"/>
<Vtx X="607" Y="-764" Z="317" S="290" T="170" R="16" G="184" B="104" A="255"/>
<Vtx X="507" Y="-162" Z="317" S="260" T="203" R="70" G="41" B="98" A="255"/>
</Vertex>

View file

@ -0,0 +1,22 @@
<Vertex Version="0">
<Vtx X="-182" Y="839" Z="-280" S="115" T="0" R="226" G="65" B="151" A="255"/>
<Vtx X="-123" Y="756" Z="-317" S="103" T="13" R="53" G="49" B="151" A="255"/>
<Vtx X="-419" Y="165" Z="-317" S="127" T="56" R="216" G="236" B="137" A="255"/>
<Vtx X="-482" Y="237" Z="-280" S="140" T="45" R="165" G="2" B="167" A="255"/>
<Vtx X="-202" Y="867" Z="-226" S="120" T="-4" R="146" G="62" B="241" A="255"/>
<Vtx X="-507" Y="266" Z="-224" S="145" T="41" R="141" G="52" B="242" A="255"/>
<Vtx X="-507" Y="266" Z="-224" S="-26" T="-277" R="141" G="52" B="242" A="255"/>
<Vtx X="-202" Y="867" Z="0" S="-9" T="-207" R="142" G="57" B="0" A="255"/>
<Vtx X="-202" Y="867" Z="-226" S="-9" T="-277" R="146" G="62" B="241" A="255"/>
<Vtx X="-507" Y="266" Z="0" S="-26" T="-215" R="142" G="57" B="0" A="255"/>
<Vtx X="-507" Y="266" Z="224" S="-26" T="-277" R="141" G="52" B="14" A="255"/>
<Vtx X="-202" Y="867" Z="226" S="-9" T="-277" R="146" G="62" B="15" A="255"/>
<Vtx X="-182" Y="839" Z="280" S="115" T="0" R="226" G="65" B="105" A="255"/>
<Vtx X="-419" Y="165" Z="317" S="127" T="56" R="216" G="236" B="119" A="255"/>
<Vtx X="-123" Y="756" Z="317" S="103" T="13" R="53" G="49" B="105" A="255"/>
<Vtx X="-482" Y="237" Z="280" S="140" T="45" R="165" G="2" B="89" A="255"/>
<Vtx X="-202" Y="867" Z="226" S="120" T="-4" R="146" G="62" B="15" A="255"/>
<Vtx X="-482" Y="237" Z="280" S="140" T="45" R="165" G="2" B="89" A="255"/>
<Vtx X="-182" Y="839" Z="280" S="115" T="0" R="226" G="65" B="105" A="255"/>
<Vtx X="-507" Y="266" Z="224" S="145" T="41" R="141" G="52" B="14" A="255"/>
</Vertex>

View file

@ -0,0 +1,49 @@
<Vertex Version="0">
<Vtx X="-182" Y="839" Z="-280" S="-14" T="2292" R="226" G="65" B="151" A="255"/>
<Vtx X="-202" Y="867" Z="-226" S="-9" T="2332" R="146" G="62" B="241" A="255"/>
<Vtx X="-202" Y="867" Z="0" S="1001" T="2332" R="103" G="74" B="0" A="255"/>
<Vtx X="-182" Y="839" Z="0" S="1001" T="2292" R="103" G="74" B="0" A="255"/>
<Vtx X="-182" Y="839" Z="280" S="-14" T="2292" R="226" G="65" B="105" A="255"/>
<Vtx X="-202" Y="867" Z="226" S="-9" T="2332" R="146" G="62" B="15" A="255"/>
<Vtx X="-123" Y="756" Z="317" S="-16" T="2174" R="53" G="49" B="105" A="255"/>
<Vtx X="-123" Y="756" Z="0" S="1001" T="2174" R="103" G="74" B="0" A="255"/>
<Vtx X="153" Y="372" Z="317" S="-16" T="1624" R="82" G="29" B="93" A="255"/>
<Vtx X="153" Y="372" Z="0" S="1001" T="1624" R="120" G="43" B="0" A="255"/>
<Vtx X="135" Y="39" Z="317" S="-16" T="1237" R="38" G="25" B="119" A="255"/>
<Vtx X="135" Y="39" Z="0" S="1001" T="1237" R="106" G="70" B="0" A="255"/>
<Vtx X="507" Y="-162" Z="317" S="-16" T="746" R="70" G="41" B="98" A="255"/>
<Vtx X="507" Y="-162" Z="0" S="1001" T="746" R="110" G="64" B="0" A="255"/>
<Vtx X="607" Y="-764" Z="317" S="-16" T="428" R="16" G="184" B="104" A="255"/>
<Vtx X="607" Y="-764" Z="0" S="1001" T="428" R="28" G="132" B="0" A="255"/>
<Vtx X="-283" Y="-340" Z="317" S="-16" T="-548" R="201" G="193" B="96" A="255"/>
<Vtx X="607" Y="-764" Z="0" S="1001" T="428" R="28" G="132" B="0" A="255"/>
<Vtx X="607" Y="-764" Z="317" S="-16" T="428" R="16" G="184" B="104" A="255"/>
<Vtx X="-283" Y="-340" Z="0" S="1001" T="-548" R="172" G="160" B="0" A="255"/>
<Vtx X="-309" Y="40" Z="317" S="-16" T="-991" R="203" G="242" B="115" A="255"/>
<Vtx X="-309" Y="40" Z="0" S="1001" T="-991" R="133" G="223" B="0" A="255"/>
<Vtx X="-419" Y="165" Z="317" S="-16" T="-1185" R="216" G="236" B="119" A="255"/>
<Vtx X="-419" Y="165" Z="0" S="1001" T="-1185" R="160" G="172" B="0" A="255"/>
<Vtx X="-482" Y="237" Z="280" S="-14" T="-1296" R="165" G="2" B="89" A="255"/>
<Vtx X="-482" Y="237" Z="0" S="1001" T="-1296" R="160" G="172" B="0" A="255"/>
<Vtx X="-507" Y="266" Z="224" S="-8" T="-1340" R="141" G="52" B="14" A="255"/>
<Vtx X="-507" Y="266" Z="0" S="1001" T="-1340" R="160" G="172" B="0" A="255"/>
<Vtx X="-507" Y="266" Z="-224" S="-8" T="-1340" R="141" G="52" B="242" A="255"/>
<Vtx X="-482" Y="237" Z="-280" S="-14" T="-1296" R="165" G="2" B="167" A="255"/>
<Vtx X="-419" Y="165" Z="-317" S="-16" T="-1185" R="216" G="236" B="137" A="255"/>
<Vtx X="-309" Y="40" Z="-317" S="-16" T="-991" R="203" G="242" B="141" A="255"/>
<Vtx X="-309" Y="40" Z="-317" S="-16" T="-991" R="203" G="242" B="141" A="255"/>
<Vtx X="-283" Y="-340" Z="-317" S="-16" T="-548" R="201" G="193" B="160" A="255"/>
<Vtx X="-283" Y="-340" Z="0" S="1001" T="-548" R="172" G="160" B="0" A="255"/>
<Vtx X="607" Y="-764" Z="0" S="1001" T="428" R="28" G="132" B="0" A="255"/>
<Vtx X="607" Y="-764" Z="-317" S="-16" T="428" R="16" G="184" B="152" A="255"/>
<Vtx X="507" Y="-162" Z="0" S="1001" T="746" R="110" G="64" B="0" A="255"/>
<Vtx X="507" Y="-162" Z="-317" S="-16" T="746" R="70" G="41" B="158" A="255"/>
<Vtx X="135" Y="39" Z="0" S="1001" T="1237" R="106" G="70" B="0" A="255"/>
<Vtx X="135" Y="39" Z="-317" S="-16" T="1237" R="38" G="25" B="137" A="255"/>
<Vtx X="153" Y="372" Z="0" S="1001" T="1624" R="120" G="43" B="0" A="255"/>
<Vtx X="153" Y="372" Z="-317" S="-16" T="1624" R="82" G="29" B="163" A="255"/>
<Vtx X="-123" Y="756" Z="0" S="1001" T="2174" R="103" G="74" B="0" A="255"/>
<Vtx X="-123" Y="756" Z="-317" S="-16" T="2174" R="53" G="49" B="151" A="255"/>
<Vtx X="-182" Y="839" Z="0" S="1001" T="2292" R="103" G="74" B="0" A="255"/>
<Vtx X="-182" Y="839" Z="-280" S="-14" T="2292" R="226" G="65" B="151" A="255"/>
</Vertex>

View file

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

View file

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

View file

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

View file

@ -0,0 +1,13 @@
<DisplayList Version="0">
<CallDisplayList Path="objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_triforce_surface"/>
<CallDisplayList Path="objects/object_triforce_piece_1/gTriforcePiece1DL_tri_0"/>
<CallDisplayList Path="objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_shard_edge"/>
<CallDisplayList Path="objects/object_triforce_piece_1/gTriforcePiece1DL_tri_1"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View file

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

View file

@ -0,0 +1,25 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="14"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="3" V01="4" V02="1"/>
<Triangle1 V00="3" V01="5" V02="4"/>
<Triangle1 V00="6" V01="7" V02="8"/>
<Triangle1 V00="6" V01="8" V02="9"/>
<Triangle1 V00="10" V01="11" V02="12"/>
<Triangle1 V00="10" V01="12" V02="13"/>
<LoadVertices Path="objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_1" VertexBufferIndex="0" VertexOffset="14" Count="14"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="4" V01="5" V02="6"/>
<Triangle1 V00="4" V01="6" V02="7"/>
<Triangle1 V00="8" V01="9" V02="10"/>
<Triangle1 V00="8" V01="11" V02="9"/>
<Triangle1 V00="9" V01="11" V02="12"/>
<Triangle1 V00="9" V01="12" V02="13"/>
<LoadVertices Path="objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_1" VertexBufferIndex="0" VertexOffset="28" Count="4"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<EndDisplayList/>
</DisplayList>

View file

@ -0,0 +1,23 @@
<Vertex Version="0">
<Vtx X="-541" Y="-249" Z="-296" S="-131" T="247" R="216" G="164" B="177" A="255"/>
<Vtx X="-905" Y="183" Z="-296" S="-95" T="240" R="166" G="44" B="178" A="255"/>
<Vtx X="-88" Y="-225" Z="-296" S="-174" T="295" R="232" G="219" B="137" A="255"/>
<Vtx X="-138" Y="176" Z="-296" S="-134" T="288" R="243" G="77" B="156" A="255"/>
<Vtx X="218" Y="94" Z="-296" S="-193" T="311" R="65" G="1" B="147" A="255"/>
<Vtx X="437" Y="375" Z="-296" S="-173" T="336" R="82" G="59" B="178" A="255"/>
<Vtx X="-22" Y="-366" Z="-296" S="-193" T="289" R="225" G="156" B="183" A="255"/>
<Vtx X="226" Y="-222" Z="-296" S="-208" T="305" R="19" G="161" B="174" A="255"/>
<Vtx X="514" Y="-258" Z="-296" S="-222" T="321" R="94" G="205" B="187" A="255"/>
<Vtx X="-541" Y="-249" Z="296" S="-131" T="247" R="216" G="164" B="79" A="255"/>
<Vtx X="-88" Y="-225" Z="296" S="-174" T="295" R="222" G="199" B="108" A="255"/>
<Vtx X="-905" Y="183" Z="296" S="-95" T="240" R="165" G="42" B="79" A="255"/>
<Vtx X="-138" Y="176" Z="296" S="-134" T="288" R="245" G="98" B="81" A="255"/>
<Vtx X="218" Y="94" Z="296" S="-193" T="311" R="65" G="1" B="109" A="255"/>
<Vtx X="-22" Y="-366" Z="296" S="-193" T="289" R="225" G="156" B="73" A="255"/>
<Vtx X="226" Y="-222" Z="296" S="-208" T="305" R="19" G="161" B="82" A="255"/>
<Vtx X="226" Y="-222" Z="296" S="-208" T="305" R="19" G="161" B="82" A="255"/>
<Vtx X="514" Y="-258" Z="296" S="-222" T="321" R="94" G="205" B="69" A="255"/>
<Vtx X="218" Y="94" Z="296" S="-193" T="311" R="65" G="1" B="109" A="255"/>
<Vtx X="437" Y="375" Z="296" S="-173" T="336" R="81" G="60" B="77" A="255"/>
<Vtx X="-138" Y="176" Z="296" S="-134" T="288" R="245" G="98" B="81" A="255"/>
</Vertex>

View file

@ -0,0 +1,34 @@
<Vertex Version="0">
<Vtx X="514" Y="-258" Z="296" S="1210" T="1071" R="94" G="205" B="69" A="255"/>
<Vtx X="226" Y="-222" Z="-296" S="-240" T="507" R="19" G="161" B="174" A="255"/>
<Vtx X="514" Y="-258" Z="-296" S="-240" T="1071" R="94" G="205" B="187" A="255"/>
<Vtx X="226" Y="-222" Z="296" S="1210" T="507" R="19" G="161" B="82" A="255"/>
<Vtx X="-22" Y="-366" Z="-296" S="-240" T="-58" R="225" G="156" B="183" A="255"/>
<Vtx X="-22" Y="-366" Z="296" S="1210" T="-58" R="225" G="156" B="73" A="255"/>
<Vtx X="-22" Y="-366" Z="296" S="1210" T="749" R="225" G="156" B="73" A="255"/>
<Vtx X="-88" Y="-225" Z="296" S="1210" T="261" R="222" G="199" B="108" A="255"/>
<Vtx X="-88" Y="-225" Z="-296" S="-240" T="261" R="232" G="219" B="137" A="255"/>
<Vtx X="-22" Y="-366" Z="-296" S="-240" T="749" R="225" G="156" B="183" A="255"/>
<Vtx X="-88" Y="-225" Z="296" S="1210" T="1064" R="222" G="199" B="108" A="255"/>
<Vtx X="-541" Y="-249" Z="296" S="1210" T="-61" R="216" G="164" B="79" A="255"/>
<Vtx X="-541" Y="-249" Z="-296" S="-240" T="-61" R="216" G="164" B="177" A="255"/>
<Vtx X="-88" Y="-225" Z="-296" S="-240" T="1064" R="232" G="219" B="137" A="255"/>
<Vtx X="437" Y="375" Z="296" S="22" T="-67" R="81" G="60" B="77" A="255"/>
<Vtx X="218" Y="94" Z="296" S="22" T="1071" R="65" G="1" B="109" A="255"/>
<Vtx X="218" Y="94" Z="-296" S="965" T="1071" R="65" G="1" B="147" A="255"/>
<Vtx X="437" Y="375" Z="-296" S="965" T="-67" R="82" G="59" B="178" A="255"/>
<Vtx X="218" Y="94" Z="296" S="-231" T="-65" R="65" G="1" B="109" A="255"/>
<Vtx X="514" Y="-258" Z="296" S="-231" T="1071" R="94" G="205" B="69" A="255"/>
<Vtx X="514" Y="-258" Z="-296" S="966" T="1071" R="94" G="205" B="187" A="255"/>
<Vtx X="218" Y="94" Z="-296" S="966" T="-65" R="65" G="1" B="147" A="255"/>
<Vtx X="-905" Y="183" Z="296" S="-231" T="-622" R="165" G="42" B="79" A="255"/>
<Vtx X="-138" Y="176" Z="-296" S="1228" T="507" R="243" G="77" B="156" A="255"/>
<Vtx X="-905" Y="183" Z="-296" S="1228" T="-622" R="166" G="44" B="178" A="255"/>
<Vtx X="-138" Y="176" Z="296" S="-231" T="507" R="245" G="98" B="81" A="255"/>
<Vtx X="437" Y="375" Z="296" S="-231" T="1636" R="81" G="60" B="77" A="255"/>
<Vtx X="437" Y="375" Z="-296" S="1228" T="1636" R="82" G="59" B="178" A="255"/>
<Vtx X="-541" Y="-249" Z="296" S="1210" T="1068" R="216" G="164" B="79" A="255"/>
<Vtx X="-905" Y="183" Z="296" S="1210" T="-59" R="165" G="42" B="79" A="255"/>
<Vtx X="-905" Y="183" Z="-296" S="-240" T="-59" R="166" G="44" B="178" A="255"/>
<Vtx X="-541" Y="-249" Z="-296" S="-240" T="1068" R="216" G="164" B="177" A="255"/>
</Vertex>

View file

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

View file

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

View file

@ -0,0 +1,15 @@
<DisplayList Version="0">
<CallDisplayList Path="objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_edges"/>
<CallDisplayList Path="objects/object_triforce_piece_2/gTriforcePiece2DL_tri_0"/>
<CallDisplayList Path="objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_surface"/>
<CallDisplayList Path="objects/object_triforce_piece_2/gTriforcePiece2DL_tri_1"/>
<CallDisplayList Path="objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_shard_edge"/>
<CallDisplayList Path="objects/object_triforce_piece_2/gTriforcePiece2DL_tri_2"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View file

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

View file

@ -0,0 +1,11 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="10"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="4" V01="3" V02="0"/>
<Triangle1 V00="5" V01="6" V02="7"/>
<Triangle1 V00="8" V01="5" V02="7"/>
<Triangle1 V00="9" V01="5" V02="8"/>
<EndDisplayList/>
</DisplayList>

View file

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

View file

@ -0,0 +1,36 @@
<Vertex Version="0">
<Vtx X="-21" Y="362" Z="-291" S="-58" T="-283" R="0" G="5" B="129" A="255"/>
<Vtx X="925" Y="-641" Z="-263" S="-126" T="-197" R="35" G="218" B="140" A="255"/>
<Vtx X="789" Y="-680" Z="-291" S="-110" T="-189" R="250" G="168" B="164" A="255"/>
<Vtx X="-20" Y="545" Z="-263" S="-58" T="-321" R="96" G="79" B="228" A="255"/>
<Vtx X="953" Y="-636" Z="-258" S="-129" T="-198" R="100" G="79" B="253" A="255"/>
<Vtx X="-20" Y="372" Z="0" S="107" T="-149" R="129" G="0" B="0" A="255"/>
<Vtx X="-20" Y="545" Z="-263" S="107" T="-277" R="129" G="0" B="0" A="255"/>
<Vtx X="-21" Y="362" Z="-291" S="107" T="-277" R="129" G="0" B="0" A="255"/>
<Vtx X="-20" Y="545" Z="0" S="107" T="-149" R="129" G="0" B="0" A="255"/>
<Vtx X="-20" Y="545" Z="263" S="107" T="-277" R="129" G="0" B="0" A="255"/>
<Vtx X="-21" Y="362" Z="291" S="107" T="-277" R="129" G="0" B="0" A="255"/>
<Vtx X="-641" Y="-449" Z="-291" S="-35" T="-239" R="199" G="189" B="164" A="255"/>
<Vtx X="-715" Y="-328" Z="-263" S="-26" T="-261" R="184" G="237" B="153" A="255"/>
<Vtx X="-20" Y="545" Z="-263" S="-58" T="-321" R="159" G="78" B="229" A="255"/>
<Vtx X="-723" Y="-322" Z="-261" S="-25" T="-262" R="156" G="79" B="255" A="255"/>
<Vtx X="-723" Y="-322" Z="-261" S="85" T="-277" R="156" G="79" B="255" A="255"/>
<Vtx X="-723" Y="-322" Z="261" S="85" T="-277" R="156" G="79" B="1" A="255"/>
<Vtx X="-20" Y="545" Z="263" S="107" T="-277" R="159" G="78" B="27" A="255"/>
<Vtx X="-20" Y="545" Z="0" S="107" T="-149" R="157" G="80" B="0" A="255"/>
<Vtx X="-20" Y="545" Z="-263" S="107" T="-277" R="159" G="78" B="229" A="255"/>
<Vtx X="-21" Y="362" Z="291" S="-58" T="-283" R="0" G="5" B="127" A="255"/>
<Vtx X="789" Y="-680" Z="291" S="-110" T="-189" R="250" G="168" B="92" A="255"/>
<Vtx X="925" Y="-641" Z="263" S="-126" T="-197" R="35" G="218" B="116" A="255"/>
<Vtx X="-20" Y="545" Z="263" S="-58" T="-321" R="96" G="79" B="28" A="255"/>
<Vtx X="953" Y="-636" Z="258" S="-129" T="-198" R="100" G="79" B="3" A="255"/>
<Vtx X="-715" Y="-328" Z="263" S="-26" T="-261" R="184" G="237" B="103" A="255"/>
<Vtx X="-641" Y="-449" Z="291" S="-35" T="-239" R="199" G="189" B="92" A="255"/>
<Vtx X="-20" Y="545" Z="263" S="-58" T="-321" R="159" G="78" B="27" A="255"/>
<Vtx X="-723" Y="-322" Z="261" S="-25" T="-262" R="156" G="79" B="1" A="255"/>
<Vtx X="-20" Y="545" Z="-263" S="107" T="-277" R="96" G="79" B="228" A="255"/>
<Vtx X="-20" Y="545" Z="0" S="107" T="-149" R="98" G="81" B="0" A="255"/>
<Vtx X="-20" Y="545" Z="263" S="107" T="-277" R="96" G="79" B="28" A="255"/>
<Vtx X="953" Y="-636" Z="-258" S="62" T="-277" R="100" G="79" B="253" A="255"/>
<Vtx X="953" Y="-636" Z="258" S="62" T="-277" R="100" G="79" B="3" A="255"/>
</Vertex>

View file

@ -0,0 +1,12 @@
<Vertex Version="0">
<Vtx X="-21" Y="362" Z="-291" S="-280" T="103" R="0" G="5" B="129" A="255"/>
<Vtx X="-179" Y="-722" Z="-291" S="-196" T="52" R="246" G="164" B="169" A="255"/>
<Vtx X="-641" Y="-449" Z="-291" S="-232" T="103" R="199" G="189" B="164" A="255"/>
<Vtx X="104" Y="-535" Z="-291" S="-236" T="55" R="4" G="156" B="178" A="255"/>
<Vtx X="789" Y="-680" Z="-291" S="-229" T="9" R="250" G="168" B="164" A="255"/>
<Vtx X="-21" Y="362" Z="291" S="-280" T="103" R="0" G="5" B="127" A="255"/>
<Vtx X="-641" Y="-449" Z="291" S="-232" T="103" R="199" G="189" B="92" A="255"/>
<Vtx X="-179" Y="-722" Z="291" S="-196" T="52" R="246" G="164" B="87" A="255"/>
<Vtx X="104" Y="-535" Z="291" S="-236" T="55" R="4" G="156" B="78" A="255"/>
<Vtx X="789" Y="-680" Z="291" S="-229" T="9" R="250" G="168" B="92" A="255"/>
</Vertex>

View file

@ -0,0 +1,18 @@
<Vertex Version="0">
<Vtx X="-723" Y="-322" Z="261" S="1659" T="-1411" R="156" G="79" B="1" A="255"/>
<Vtx X="-723" Y="-322" Z="-261" S="-669" T="-1411" R="156" G="79" B="255" A="255"/>
<Vtx X="-715" Y="-328" Z="-263" S="-683" T="-1373" R="184" G="237" B="153" A="255"/>
<Vtx X="-715" Y="-328" Z="263" S="1668" T="-1373" R="184" G="237" B="103" A="255"/>
<Vtx X="-641" Y="-449" Z="-291" S="-703" T="-945" R="199" G="189" B="164" A="255"/>
<Vtx X="-641" Y="-449" Z="291" S="1688" T="-945" R="199" G="189" B="92" A="255"/>
<Vtx X="-179" Y="-722" Z="-291" S="-703" T="289" R="246" G="164" B="169" A="255"/>
<Vtx X="-179" Y="-722" Z="291" S="1688" T="289" R="246" G="164" B="87" A="255"/>
<Vtx X="104" Y="-535" Z="-291" S="-703" T="1094" R="4" G="156" B="178" A="255"/>
<Vtx X="104" Y="-535" Z="291" S="1688" T="1094" R="4" G="156" B="78" A="255"/>
<Vtx X="789" Y="-680" Z="-291" S="-703" T="2016" R="250" G="168" B="164" A="255"/>
<Vtx X="789" Y="-680" Z="291" S="1688" T="2016" R="250" G="168" B="92" A="255"/>
<Vtx X="925" Y="-641" Z="-263" S="-683" T="2363" R="35" G="218" B="140" A="255"/>
<Vtx X="925" Y="-641" Z="263" S="1668" T="2363" R="35" G="218" B="116" A="255"/>
<Vtx X="953" Y="-636" Z="-258" S="-665" T="2403" R="100" G="79" B="253" A="255"/>
<Vtx X="953" Y="-636" Z="258" S="1649" T="2403" R="100" G="79" B="3" A="255"/>
</Vertex>

View file

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

View file

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

View file

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -18,8 +18,7 @@ The Ship does not include any copyrighted assets. You are required to provide a
### 1. Verify your ROM dump ### 1. Verify your ROM dump
You can verify you have dumped a supported copy of the game by using the compatibility checker at https://ship.equipment/. If you'd prefer to manually validate your ROM dump, you can cross-reference its `sha1` hash with the hashes [here](docs/supportedHashes.json). You can verify you have dumped a supported copy of the game by using the compatibility checker at https://ship.equipment/. If you'd prefer to manually validate your ROM dump, you can cross-reference its `sha1` hash with the hashes [here](docs/supportedHashes.json).
### 2. Download The Ship of Harkinian from [Discord](https://discord.com/invite/shipofharkinian) ### 2. Download The Ship of Harkinian from [Releases](https://github.com/HarbourMasters/Shipwright/releases)
The latest release is available in the most recent post in the `#downloads` channel.
### 3. Launch the Game! ### 3. Launch the Game!
#### Windows #### Windows

View file

@ -81,7 +81,7 @@ cd "build/x64"
``` ```
## Linux ## Linux
Requires `gcc >= 10, x11, curl, python3, sdl2 >= 2.0.22, libpng, glew >= 2.2, ninja, cmake, lld` Requires `gcc >= 10, x11, curl, python3, sdl2 >= 2.0.22, libpng, glew >= 2.2, ninja, cmake, lld, pulseaudio-libs`
**Important: For maximum performance make sure you have ninja build tools installed!** **Important: For maximum performance make sure you have ninja build tools installed!**

View file

@ -44,6 +44,18 @@ static const ALIGN_ASSET(2) char gTitleRandomizerSubtitleTex[] = dgTitleRandomiz
#define dgTitleBossRushSubtitleTex "__OTR__objects/object_mag/gTitleBossRushSubtitleTex" #define dgTitleBossRushSubtitleTex "__OTR__objects/object_mag/gTitleBossRushSubtitleTex"
static const ALIGN_ASSET(2) char gTitleBossRushSubtitleTex[] = dgTitleBossRushSubtitleTex; static const ALIGN_ASSET(2) char gTitleBossRushSubtitleTex[] = dgTitleBossRushSubtitleTex;
#define dgTriforcePiece0DL "__OTR__objects/object_triforce_piece_0/gTriforcePiece0DL"
static const ALIGN_ASSET(2) char gTriforcePiece0DL[] = dgTriforcePiece0DL;
#define dgTriforcePiece1DL "__OTR__objects/object_triforce_piece_1/gTriforcePiece1DL"
static const ALIGN_ASSET(2) char gTriforcePiece1DL[] = dgTriforcePiece1DL;
#define dgTriforcePiece2DL "__OTR__objects/object_triforce_piece_2/gTriforcePiece2DL"
static const ALIGN_ASSET(2) char gTriforcePiece2DL[] = dgTriforcePiece2DL;
#define dgTriforcePieceCompletedDL "__OTR__objects/object_triforce_completed/gTriforcePieceCompletedDL"
static const ALIGN_ASSET(2) char gTriforcePieceCompletedDL[] = dgTriforcePieceCompletedDL;
// overlays // overlays
#define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx" #define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx"
static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx; static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx;
@ -58,6 +70,9 @@ static const ALIGN_ASSET(2) char gArrowUpTex[] = dgArrowUp;
#define dgArrowDown "__OTR__textures/parameter_static/gArrowDown" #define dgArrowDown "__OTR__textures/parameter_static/gArrowDown"
static const ALIGN_ASSET(2) char gArrowDownTex[] = dgArrowDown; static const ALIGN_ASSET(2) char gArrowDownTex[] = dgArrowDown;
#define dgTriforcePiece "__OTR__textures/parameter_static/gTriforcePiece"
static const ALIGN_ASSET(2) char gTriforcePieceTex[] = dgTriforcePiece;
#define dgFileSelMQButtonTex "__OTR__textures/title_static/gFileSelMQButtonTex" #define dgFileSelMQButtonTex "__OTR__textures/title_static/gFileSelMQButtonTex"
static const ALIGN_ASSET(2) char gFileSelMQButtonTex[] = dgFileSelMQButtonTex; static const ALIGN_ASSET(2) char gFileSelMQButtonTex[] = dgFileSelMQButtonTex;

View file

@ -1257,6 +1257,8 @@ void SkelAnime_DrawLod(PlayState* play, void** skeleton, Vec3s* jointTable,
void SkelAnime_DrawFlexLod(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount, void SkelAnime_DrawFlexLod(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount,
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg,
s32 dListIndex); s32 dListIndex);
void SkelAnime_DrawSkeletonOpa(PlayState* play, SkelAnime* skelAnime, OverrideLimbDrawOpa overrideLimbDraw,
PostLimbDrawOpa postLimbDraw, void* arg);
void SkelAnime_DrawOpa(PlayState* play, void** skeleton, Vec3s* jointTable, void SkelAnime_DrawOpa(PlayState* play, void** skeleton, Vec3s* jointTable,
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg); OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg);
void SkelAnime_DrawFlexOpa(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount, void SkelAnime_DrawFlexOpa(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount,

View file

@ -171,6 +171,7 @@ extern "C"
extern u8 gWalkSpeedToggle1; extern u8 gWalkSpeedToggle1;
extern u8 gWalkSpeedToggle2; extern u8 gWalkSpeedToggle2;
extern f32 iceTrapScale; extern f32 iceTrapScale;
extern f32 triforcePieceScale;
extern const s16 D_8014A6C0[]; extern const s16 D_8014A6C0[];
#define gTatumsPerBeat (D_8014A6C0[1]) #define gTatumsPerBeat (D_8014A6C0[1])

View file

@ -16,6 +16,10 @@ struct SkelAnime;
#define ANIM_FLAG_UPDATEY (1 << 1) #define ANIM_FLAG_UPDATEY (1 << 1)
#define ANIM_FLAG_NOMOVE (1 << 4) #define ANIM_FLAG_NOMOVE (1 << 4)
#define SKELANIME_TYPE_NORMAL 0
#define SKELANIME_TYPE_FLEX 1
#define SKELANIME_TYPE_CURVE 2
typedef enum { typedef enum {
/* 0 */ ANIMMODE_LOOP, /* 0 */ ANIMMODE_LOOP,
/* 1 */ ANIMMODE_LOOP_INTERP, /* 1 */ ANIMMODE_LOOP_INTERP,
@ -57,6 +61,7 @@ typedef struct LegacyLimb {
typedef struct { typedef struct {
/* 0x00 */ void** segment; /* 0x00 */ void** segment;
/* 0x04 */ u8 limbCount; /* 0x04 */ u8 limbCount;
u8 skeletonType;
} SkeletonHeader; // size = 0x8 } SkeletonHeader; // size = 0x8
// Model has limbs with flexible meshes // Model has limbs with flexible meshes
@ -261,6 +266,7 @@ typedef struct SkelAnime {
/* 0x36 */ s16 prevRot; // Previous rotation in worldspace. /* 0x36 */ s16 prevRot; // Previous rotation in worldspace.
/* 0x38 */ Vec3s prevTransl; // Previous modelspace translation. /* 0x38 */ Vec3s prevTransl; // Previous modelspace translation.
/* 0x3E */ Vec3s baseTransl; // Base modelspace translation. /* 0x3E */ Vec3s baseTransl; // Base modelspace translation.
SkeletonHeader* skeletonHeader;
} SkelAnime; // size = 0x44 } SkelAnime; // size = 0x44
#endif #endif

View file

@ -511,6 +511,7 @@ typedef enum {
/* 0x79 */ GID_SONG_SUN, /* 0x79 */ GID_SONG_SUN,
/* 0x7A */ GID_SONG_TIME, /* 0x7A */ GID_SONG_TIME,
/* 0x7B */ GID_SONG_STORM, /* 0x7B */ GID_SONG_STORM,
/* 0x7C */ GID_TRIFORCE_PIECE,
/* 0x7C */ GID_MAXIMUM /* 0x7C */ GID_MAXIMUM
} GetItemDrawID; } GetItemDrawID;

View file

@ -409,7 +409,8 @@ typedef enum {
FLAG_ITEM_GET_INF, FLAG_ITEM_GET_INF,
FLAG_INF_TABLE, FLAG_INF_TABLE,
FLAG_EVENT_INF, FLAG_EVENT_INF,
FLAG_RANDOMIZER_INF FLAG_RANDOMIZER_INF,
FLAG_GS_TOKEN,
} FlagType; } FlagType;
typedef struct { typedef struct {
@ -620,7 +621,7 @@ typedef struct Player {
/* 0x0858 */ f32 unk_858; /* 0x0858 */ f32 unk_858;
/* 0x085C */ f32 unk_85C; // stick length among other things /* 0x085C */ f32 unk_85C; // stick length among other things
/* 0x0860 */ s16 unk_860; // stick flame timer among other things /* 0x0860 */ s16 unk_860; // stick flame timer among other things
/* 0x0862 */ s8 unk_862; // get item draw ID + 1 /* 0x0862 */ s16 unk_862; // get item draw ID + 1
/* 0x0864 */ f32 unk_864; /* 0x0864 */ f32 unk_864;
/* 0x0868 */ f32 unk_868; /* 0x0868 */ f32 unk_868;
/* 0x086C */ f32 unk_86C; /* 0x086C */ f32 unk_86C;

View file

@ -284,8 +284,7 @@ typedef struct {
/* 0x1428 */ u16 pendingSaleMod; /* 0x1428 */ u16 pendingSaleMod;
// #region SOH [General] // #region SOH [General]
// Upstream TODO: Move these to their own struct or name to more obviously specific to SoH // Upstream TODO: Move these to their own struct or name to more obviously specific to SoH
/* */ uint32_t isMasterQuest; /* */ uint8_t questId;
/* */ uint32_t isBossRush;
/* */ uint32_t isBossRushPaused; /* */ uint32_t isBossRushPaused;
/* */ uint8_t bossRushOptions[BOSSRUSH_OPTIONS_AMOUNT]; /* */ uint8_t bossRushOptions[BOSSRUSH_OPTIONS_AMOUNT];
/* */ u8 mqDungeonCount; /* */ u8 mqDungeonCount;
@ -324,9 +323,22 @@ typedef struct {
/* */ u8 seedIcons[5]; /* */ u8 seedIcons[5];
/* */ u16 randomizerInf[10]; /* */ u16 randomizerInf[10];
/* */ u16 adultTradeItems; /* */ u16 adultTradeItems;
/* */ u8 triforcePiecesCollected;
// #endregion // #endregion
} SaveContext; // size = 0x1428 } SaveContext; // size = 0x1428
typedef enum {
/* 00 */ QUEST_NORMAL,
/* 01 */ QUEST_MASTER,
/* 02 */ QUEST_RANDOMIZER,
/* 03 */ QUEST_BOSSRUSH,
} Quest;
#define IS_VANILLA (gSaveContext.questId == QUEST_NORMAL)
#define IS_MASTER_QUEST (gSaveContext.questId == QUEST_MASTER)
#define IS_RANDO (gSaveContext.questId == QUEST_RANDOMIZER)
#define IS_BOSS_RUSH (gSaveContext.questId == QUEST_BOSSRUSH)
typedef enum { typedef enum {
/* 0x00 */ BTN_ENABLED, /* 0x00 */ BTN_ENABLED,
/* 0xFF */ BTN_DISABLED = 0xFF /* 0xFF */ BTN_DISABLED = 0xFF
@ -577,11 +589,16 @@ typedef enum {
// 0xDA-0xDE // 0xDA-0xDE
#define EVENTCHKINF_SKULLTULA_REWARD_INDEX 13 #define EVENTCHKINF_SKULLTULA_REWARD_INDEX 13
#define EVENTCHKINF_SKULLTULA_REWARD_10_MASK (1 << 10) #define EVENTCHKINF_SKULLTULA_REWARD_10_SHIFT 10
#define EVENTCHKINF_SKULLTULA_REWARD_20_MASK (1 << 11) #define EVENTCHKINF_SKULLTULA_REWARD_20_SHIFT 11
#define EVENTCHKINF_SKULLTULA_REWARD_30_MASK (1 << 12) #define EVENTCHKINF_SKULLTULA_REWARD_30_SHIFT 12
#define EVENTCHKINF_SKULLTULA_REWARD_40_MASK (1 << 13) #define EVENTCHKINF_SKULLTULA_REWARD_40_SHIFT 13
#define EVENTCHKINF_SKULLTULA_REWARD_50_MASK (1 << 14) #define EVENTCHKINF_SKULLTULA_REWARD_50_SHIFT 14
#define EVENTCHKINF_SKULLTULA_REWARD_10_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_10_SHIFT)
#define EVENTCHKINF_SKULLTULA_REWARD_20_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_20_SHIFT)
#define EVENTCHKINF_SKULLTULA_REWARD_30_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_30_SHIFT)
#define EVENTCHKINF_SKULLTULA_REWARD_40_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_40_SHIFT)
#define EVENTCHKINF_SKULLTULA_REWARD_50_MASK (1 << EVENTCHKINF_SKULLTULA_REWARD_50_SHIFT)
/* /*

View file

@ -330,7 +330,7 @@ ImVec4 GetSequenceTypeColor(SeqType type) {
case SEQ_SFX: case SEQ_SFX:
return ImVec4(0.4f, 0.33f, 0.0f, 1.0f); return ImVec4(0.4f, 0.33f, 0.0f, 1.0f);
case SEQ_VOICE: case SEQ_VOICE:
return ImVec4(0.4f, 0.33f, 0.0f, 1.0f); return ImVec4(0.3f, 0.42f, 0.09f, 1.0f);
case SEQ_INSTRUMENT: case SEQ_INSTRUMENT:
return ImVec4(0.0f, 0.25f, 0.5f, 1.0f); return ImVec4(0.0f, 0.25f, 0.5f, 1.0f);
case SEQ_BGM_CUSTOM: case SEQ_BGM_CUSTOM:
@ -481,7 +481,7 @@ void AudioEditor::DrawElement() {
} }
} }
ImGui::BeginTable("sequenceTypes", 8, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders); ImGui::BeginTable("sequenceTypes", 9, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_Borders);
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Header, GetSequenceTypeColor(SEQ_BGM_WORLD)); ImGui::PushStyleColor(ImGuiCol_Header, GetSequenceTypeColor(SEQ_BGM_WORLD));

View file

@ -235,7 +235,7 @@ void BossRush_HandleBlueWarpHeal(PlayState* play) {
} }
void BossRush_HandleCompleteBoss(PlayState* play) { void BossRush_HandleCompleteBoss(PlayState* play) {
if (!gSaveContext.isBossRush) { if (!IS_BOSS_RUSH) {
return; return;
} }

View file

@ -10,6 +10,7 @@
#include <string> #include <string>
#include <libultraship/bridge.h> #include <libultraship/bridge.h>
#include <libultraship/libultraship.h> #include <libultraship/libultraship.h>
#include "soh_assets.h"
extern "C" { extern "C" {
#include <z64.h> #include <z64.h>
@ -144,6 +145,10 @@ std::map<uint32_t, ItemMapEntry> gregMapping = {
{ITEM_RUPEE_GREEN, {ITEM_RUPEE_GREEN, "ITEM_RUPEE_GREEN", "ITEM_RUPEE_GREEN_Faded", gRupeeCounterIconTex}} {ITEM_RUPEE_GREEN, {ITEM_RUPEE_GREEN, "ITEM_RUPEE_GREEN", "ITEM_RUPEE_GREEN_Faded", gRupeeCounterIconTex}}
}; };
std::map<uint32_t, ItemMapEntry> triforcePieceMapping = {
{RG_TRIFORCE_PIECE, {RG_TRIFORCE_PIECE, "RG_TRIFORCE_PIECE", "RG_TRIFORCE_PIECE_Faded", gTriforcePieceTex}}
};
// Maps entries in the GS flag array to the area name it represents // Maps entries in the GS flag array to the area name it represents
std::vector<std::string> gsMapping = { std::vector<std::string> gsMapping = {
"Deku Tree", "Deku Tree",
@ -509,6 +514,10 @@ void DrawInfoTab() {
} }
UIWidgets::InsertHelpHoverText("Z-Targeting behavior"); UIWidgets::InsertHelpHoverText("Z-Targeting behavior");
if (gSaveContext.n64ddFlag && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) {
ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U16, &gSaveContext.triforcePiecesCollected);
UIWidgets::InsertHelpHoverText("Currently obtained Triforce Pieces. For Triforce Hunt.");
}
ImGui::PushItemWidth(ImGui::GetFontSize() * 10); ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
static std::array<const char*, 7> minigameHS = { "Horseback Archery", static std::array<const char*, 7> minigameHS = { "Horseback Archery",
@ -699,7 +708,7 @@ void DrawInventoryTab() {
ImVec2(0, 0), ImVec2(1, 1), 0)) { ImVec2(0, 0), ImVec2(1, 1), 0)) {
gSaveContext.inventory.items[selectedIndex] = slotEntry.id; gSaveContext.inventory.items[selectedIndex] = slotEntry.id;
// Set adult trade item flag if you're playing adult trade shuffle in rando // Set adult trade item flag if you're playing adult trade shuffle in rando
if (gSaveContext.n64ddFlag && if (IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) &&
selectedIndex == SLOT_TRADE_ADULT && selectedIndex == SLOT_TRADE_ADULT &&
slotEntry.id >= ITEM_POCKET_EGG && slotEntry.id <= ITEM_CLAIM_CHECK) { slotEntry.id >= ITEM_POCKET_EGG && slotEntry.id <= ITEM_CLAIM_CHECK) {
@ -744,7 +753,7 @@ void DrawInventoryTab() {
// Trade quest flags are only used when shuffling the trade sequence, so // Trade quest flags are only used when shuffling the trade sequence, so
// don't show this if it isn't needed. // don't show this if it isn't needed.
if (gSaveContext.n64ddFlag && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE)
&& ImGui::TreeNode("Adult trade quest items")) { && ImGui::TreeNode("Adult trade quest items")) {
for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; i++) { for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; i++) {
DrawBGSItemFlag(i); DrawBGSItemFlag(i);
@ -1071,7 +1080,7 @@ void DrawFlagsTab() {
// If playing a Randomizer Save with Shuffle Skull Tokens on anything other than "Off" we don't want to keep // If playing a Randomizer Save with Shuffle Skull Tokens on anything other than "Off" we don't want to keep
// GS Token Count updated, since Gold Skulltulas killed will not correlate to GS Tokens Collected. // GS Token Count updated, since Gold Skulltulas killed will not correlate to GS Tokens Collected.
if (!(gSaveContext.n64ddFlag && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF)) { if (!(IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF)) {
static bool keepGsCountUpdated = true; static bool keepGsCountUpdated = true;
ImGui::Checkbox("Keep GS Count Updated", &keepGsCountUpdated); ImGui::Checkbox("Keep GS Count Updated", &keepGsCountUpdated);
UIWidgets::InsertHelpHoverText("Automatically adjust the number of gold skulltula tokens acquired based on set flags."); UIWidgets::InsertHelpHoverText("Automatically adjust the number of gold skulltula tokens acquired based on set flags.");
@ -1087,7 +1096,7 @@ void DrawFlagsTab() {
for (int i = 0; i < flagTables.size(); i++) { for (int i = 0; i < flagTables.size(); i++) {
const FlagTable& flagTable = flagTables[i]; const FlagTable& flagTable = flagTables[i];
if (flagTable.flagTableType == RANDOMIZER_INF && !gSaveContext.n64ddFlag && !gSaveContext.isBossRush) { if (flagTable.flagTableType == RANDOMIZER_INF && !IS_RANDO && !IS_BOSS_RUSH) {
continue; continue;
} }
@ -1281,7 +1290,7 @@ void DrawEquipmentTab() {
"Giant (500)", "Giant (500)",
}; };
// only display Tycoon wallet if you're in a save file that would allow it. // only display Tycoon wallet if you're in a save file that would allow it.
if (gSaveContext.n64ddFlag && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS) { if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) > RO_SHOPSANITY_ZERO_ITEMS) {
const std::string walletName = "Tycoon (999)"; const std::string walletName = "Tycoon (999)";
walletNamesImpl.push_back(walletName); walletNamesImpl.push_back(walletName);
} }
@ -1790,6 +1799,10 @@ void SaveEditorWindow::InitElement() {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, gregGreen); LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, gregGreen);
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen); LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, gregFadedGreen);
} }
for (const auto& entry : triforcePieceMapping) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));
}
for (const auto& entry : questMapping) { for (const auto& entry : questMapping) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1));
LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); LUS::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f));

View file

@ -234,7 +234,7 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *po
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) { EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) {
if (CVarGetInteger("gRandomizedEnemies", ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) { if (CVarGetInteger("gRandomizedEnemies", ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
uint32_t finalSeed = seed + (gSaveContext.n64ddFlag ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt); uint32_t finalSeed = seed + (IS_RANDO ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt);
Random_Init(finalSeed); Random_Init(finalSeed);
} }

View file

@ -47,6 +47,55 @@ GameInteractionEffectQueryResult GameInteractionEffectBase::Remove() {
namespace GameInteractionEffect { namespace GameInteractionEffect {
// MARK: - Flags
GameInteractionEffectQueryResult SetSceneFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
return GameInteractionEffectQueryResult::Possible;
}
void SetSceneFlag::_Apply() {
GameInteractor::RawAction::SetSceneFlag(parameters[0], parameters[1], parameters[2]);
}
GameInteractionEffectQueryResult UnsetSceneFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
return GameInteractionEffectQueryResult::Possible;
}
void UnsetSceneFlag::_Apply() {
GameInteractor::RawAction::UnsetSceneFlag(parameters[0], parameters[1], parameters[2]);
}
GameInteractionEffectQueryResult SetFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
return GameInteractionEffectQueryResult::Possible;
}
void SetFlag::_Apply() {
GameInteractor::RawAction::SetFlag(parameters[0], parameters[1]);
}
GameInteractionEffectQueryResult UnsetFlag::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {
return GameInteractionEffectQueryResult::TemporarilyNotPossible;
}
return GameInteractionEffectQueryResult::Possible;
}
void UnsetFlag::_Apply() {
GameInteractor::RawAction::UnsetFlag(parameters[0], parameters[1]);
}
// MARK: - ModifyHeartContainers // MARK: - ModifyHeartContainers
GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() { GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) { if (!GameInteractor::IsSaveLoaded()) {

View file

@ -18,7 +18,7 @@ public:
virtual GameInteractionEffectQueryResult CanBeRemoved(); virtual GameInteractionEffectQueryResult CanBeRemoved();
GameInteractionEffectQueryResult Apply(); GameInteractionEffectQueryResult Apply();
GameInteractionEffectQueryResult Remove(); GameInteractionEffectQueryResult Remove();
int32_t parameters[2]; int32_t parameters[3];
protected: protected:
virtual void _Apply() = 0; virtual void _Apply() = 0;
@ -26,6 +26,26 @@ public:
}; };
namespace GameInteractionEffect { namespace GameInteractionEffect {
class SetSceneFlag: public GameInteractionEffectBase {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;
};
class UnsetSceneFlag: public GameInteractionEffectBase {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;
};
class SetFlag: public GameInteractionEffectBase {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;
};
class UnsetFlag: public GameInteractionEffectBase {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;
};
class ModifyHeartContainers: public GameInteractionEffectBase { class ModifyHeartContainers: public GameInteractionEffectBase {
GameInteractionEffectQueryResult CanBeApplied() override; GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override; void _Apply() override;

View file

@ -83,6 +83,8 @@ uint8_t GameInteractor_GetRandomWindActive();
uint8_t GameInteractor_GetRandomBonksActive(); uint8_t GameInteractor_GetRandomBonksActive();
uint8_t GameInteractor_GetSlipperyFloorActive(); uint8_t GameInteractor_GetSlipperyFloorActive();
uint8_t GameInteractor_SecondCollisionUpdate(); uint8_t GameInteractor_SecondCollisionUpdate();
void GameInteractor_SetTriforceHuntPieceGiven(uint8_t state);
void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@ -123,6 +125,8 @@ public:
static uint8_t RandomBonksActive; static uint8_t RandomBonksActive;
static uint8_t SlipperyFloorActive; static uint8_t SlipperyFloorActive;
static uint8_t SecondCollisionUpdate; static uint8_t SecondCollisionUpdate;
static uint8_t TriforceHuntPieceGiven;
static uint8_t TriforceHuntCreditsWarpActive;
static void SetPacifistMode(bool active); static void SetPacifistMode(bool active);
}; };
@ -148,6 +152,10 @@ public:
DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry)); DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum)); DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum));
DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum)); DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum));
DEFINE_HOOK(OnSceneFlagSet, void(int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneFlagUnset, void(int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagSet, void(int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagUnset, void(int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneSpawnActors, void()); DEFINE_HOOK(OnSceneSpawnActors, void());
DEFINE_HOOK(OnPlayerUpdate, void()); DEFINE_HOOK(OnPlayerUpdate, void());
DEFINE_HOOK(OnOcarinaSongAction, void()); DEFINE_HOOK(OnOcarinaSongAction, void());
@ -194,6 +202,10 @@ public:
class RawAction { 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 void SetFlag(int16_t flagType, int16_t chestNum);
static void UnsetFlag(int16_t flagType, int16_t chestNum);
static void AddOrRemoveHealthContainers(int16_t amount); static void AddOrRemoveHealthContainers(int16_t amount);
static void AddOrRemoveMagic(int8_t amount); static void AddOrRemoveMagic(int8_t amount);
static void HealOrDamagePlayer(int16_t hearts); static void HealOrDamagePlayer(int16_t hearts);

View file

@ -30,6 +30,22 @@ void GameInteractor_ExecuteOnSceneInitHooks(int16_t sceneNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneInit>(sceneNum); GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneInit>(sceneNum);
} }
void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneFlagSet>(sceneNum, flagType, flag);
}
void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneFlagUnset>(sceneNum, flagType, flag);
}
void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnFlagSet>(flagType, flag);
}
void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnFlagUnset>(flagType, flag);
}
void GameInteractor_ExecuteOnSceneSpawnActors() { void GameInteractor_ExecuteOnSceneSpawnActors() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneSpawnActors>(); GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneSpawnActors>();
} }

View file

@ -11,6 +11,10 @@ void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry); void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry);
void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum); void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum);
void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum); void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum);
void GameInteractor_ExecuteOnSceneFlagSet(int16_t sceneNum, int16_t flagType, int16_t flag);
void GameInteractor_ExecuteOnSceneFlagUnset(int16_t sceneNum, int16_t flagType, int16_t flag);
void GameInteractor_ExecuteOnFlagSet(int16_t flagType, int16_t flag);
void GameInteractor_ExecuteOnFlagUnset(int16_t flagType, int16_t flag);
void GameInteractor_ExecuteOnSceneSpawnActors(); void GameInteractor_ExecuteOnSceneSpawnActors();
void GameInteractor_ExecuteOnPlayerUpdate(); void GameInteractor_ExecuteOnPlayerUpdate();
void GameInteractor_ExecuteOnOcarinaSongAction(); void GameInteractor_ExecuteOnOcarinaSongAction();

View file

@ -127,6 +127,127 @@ void GameInteractor::RawAction::KnockbackPlayer(float strength) {
func_8002F71C(gPlayState, &player->actor, strength * 5, player->actor.world.rot.y + 0x8000, strength * 5); func_8002F71C(gPlayState, &player->actor, strength * 5, player->actor.world.rot.y + 0x8000, strength * 5);
} }
void GameInteractor::RawAction::SetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag) {
switch (flagType) {
case FlagType::FLAG_SCENE_SWITCH:
if (sceneNum == gPlayState->sceneNum) {
if (flag < 0x20) {
gPlayState->actorCtx.flags.swch |= (1 << flag);
} else {
gPlayState->actorCtx.flags.tempSwch |= (1 << (flag - 0x20));
}
}
if (flag < 0x20) {
gSaveContext.sceneFlags[sceneNum].swch |= (1 << flag);
}
break;
case FlagType::FLAG_SCENE_CLEAR:
if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.clear |= (1 << flag);
gSaveContext.sceneFlags[sceneNum].clear |= (1 << flag);
break;
case FlagType::FLAG_SCENE_TREASURE:
if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.chest |= (1 << flag);
gSaveContext.sceneFlags[sceneNum].chest |= (1 << flag);
break;
case FlagType::FLAG_SCENE_COLLECTIBLE:
if (sceneNum == gPlayState->sceneNum) {
if (flag != 0) {
if (flag < 0x20) {
gPlayState->actorCtx.flags.collect |= (1 << flag);
} else {
gPlayState->actorCtx.flags.tempCollect |= (1 << (flag - 0x20));
}
}
}
if (flag != 0 && flag < 0x20) {
gSaveContext.sceneFlags[sceneNum].collect |= (1 << flag);
}
break;
}
};
void GameInteractor::RawAction::UnsetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag) {
switch (flagType) {
case FlagType::FLAG_SCENE_SWITCH:
if (sceneNum == gPlayState->sceneNum) {
if (flag < 0x20) {
gPlayState->actorCtx.flags.swch &= ~(1 << flag);
} else {
gPlayState->actorCtx.flags.tempSwch &= ~(1 << (flag - 0x20));
}
}
if (flag < 0x20) {
gSaveContext.sceneFlags[sceneNum].swch &= ~(1 << flag);
}
break;
case FlagType::FLAG_SCENE_CLEAR:
if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.clear &= ~(1 << flag);
gSaveContext.sceneFlags[sceneNum].clear &= ~(1 << flag);
break;
case FlagType::FLAG_SCENE_TREASURE:
if (sceneNum == gPlayState->sceneNum) gPlayState->actorCtx.flags.chest &= ~(1 << flag);
gSaveContext.sceneFlags[sceneNum].chest &= ~(1 << flag);
break;
case FlagType::FLAG_SCENE_COLLECTIBLE:
if (sceneNum == gPlayState->sceneNum) {
if (flag != 0) {
if (flag < 0x20) {
gPlayState->actorCtx.flags.collect &= ~(1 << flag);
} else {
gPlayState->actorCtx.flags.tempCollect &= ~(1 << (flag - 0x20));
}
}
}
if (flag != 0 && flag < 0x20) {
gSaveContext.sceneFlags[sceneNum].collect &= ~(1 << flag);
}
break;
}
};
void GameInteractor::RawAction::SetFlag(int16_t flagType, int16_t flag) {
switch (flagType) {
case FlagType::FLAG_EVENT_CHECK_INF:
gSaveContext.eventChkInf[flag >> 4] |= (1 << (flag & 0xF));
break;
case FlagType::FLAG_ITEM_GET_INF:
gSaveContext.itemGetInf[flag >> 4] |= (1 << (flag & 0xF));
break;
case FlagType::FLAG_INF_TABLE:
gSaveContext.infTable[flag >> 4] |= (1 << (flag & 0xF));
break;
case FlagType::FLAG_EVENT_INF:
gSaveContext.eventInf[flag >> 4] |= (1 << (flag & 0xF));
break;
case FlagType::FLAG_RANDOMIZER_INF:
gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
break;
case FlagType::FLAG_GS_TOKEN:
SET_GS_FLAGS((flag & 0x1F00) >> 8, flag & 0xFF);
break;
}
};
void GameInteractor::RawAction::UnsetFlag(int16_t flagType, int16_t flag) {
switch (flagType) {
case FlagType::FLAG_EVENT_CHECK_INF:
gSaveContext.eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF));
break;
case FlagType::FLAG_ITEM_GET_INF:
gSaveContext.itemGetInf[flag >> 4] &= ~(1 << (flag & 0xF));
break;
case FlagType::FLAG_INF_TABLE:
gSaveContext.infTable[flag >> 4] &= ~(1 << (flag & 0xF));
break;
case FlagType::FLAG_EVENT_INF:
gSaveContext.eventInf[flag >> 4] &= ~(1 << (flag & 0xF));
break;
case FlagType::FLAG_RANDOMIZER_INF:
gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
break;
}
};
void GameInteractor::RawAction::GiveOrTakeShield(int32_t shield) { void GameInteractor::RawAction::GiveOrTakeShield(int32_t shield) {
// When taking a shield, make sure it is unequipped as well. // When taking a shield, make sure it is unequipped as well.
// When giving a shield and the player isn't wearing one yet, // When giving a shield and the player isn't wearing one yet,

View file

@ -20,6 +20,8 @@ uint8_t GameInteractor::State::RandomWindSecondsSinceLastDirectionChange = 0;
uint8_t GameInteractor::State::RandomBonksActive = 0; uint8_t GameInteractor::State::RandomBonksActive = 0;
uint8_t GameInteractor::State::SlipperyFloorActive = 0; uint8_t GameInteractor::State::SlipperyFloorActive = 0;
uint8_t GameInteractor::State::SecondCollisionUpdate = 0; uint8_t GameInteractor::State::SecondCollisionUpdate = 0;
uint8_t GameInteractor::State::TriforceHuntPieceGiven = 0;
uint8_t GameInteractor::State::TriforceHuntCreditsWarpActive = 0;
void GameInteractor::State::SetPacifistMode(bool active) { void GameInteractor::State::SetPacifistMode(bool active) {
PacifistModeActive = active; PacifistModeActive = active;
@ -127,3 +129,13 @@ uint8_t GameInteractor_GetSlipperyFloorActive() {
uint8_t GameInteractor_SecondCollisionUpdate() { uint8_t GameInteractor_SecondCollisionUpdate() {
return GameInteractor::State::SecondCollisionUpdate; return GameInteractor::State::SecondCollisionUpdate;
} }
// MARK: - GameInteractor::State::TriforceHuntPieceGiven
void GameInteractor_SetTriforceHuntPieceGiven(uint8_t state) {
GameInteractor::State::TriforceHuntPieceGiven = state;
}
// MARK: - GameInteractor::State::TriforceHuntCreditsWarpActive
void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state) {
GameInteractor::State::TriforceHuntCreditsWarpActive = state;
}

View file

@ -793,6 +793,7 @@ void SetupDisplayNames() {
strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANON], "Ganon Defeated: "); strcpy(itemTimestampDisplayName[TIMESTAMP_DEFEAT_GANON], "Ganon Defeated: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_BOSSRUSH_FINISH], "Boss Rush Finished: "); strcpy(itemTimestampDisplayName[TIMESTAMP_BOSSRUSH_FINISH], "Boss Rush Finished: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: "); strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_TRIFORCE_COMPLETED], "Triforce Completed: ");
} }
void SetupDisplayColors() { void SetupDisplayColors() {
@ -839,6 +840,7 @@ void SetupDisplayColors() {
case ITEM_ARROW_LIGHT: case ITEM_ARROW_LIGHT:
case TIMESTAMP_DEFEAT_GANONDORF: case TIMESTAMP_DEFEAT_GANONDORF:
case TIMESTAMP_DEFEAT_GANON: case TIMESTAMP_DEFEAT_GANON:
case TIMESTAMP_TRIFORCE_COMPLETED:
itemTimestampDisplayColor[i] = COLOR_YELLOW; itemTimestampDisplayColor[i] = COLOR_YELLOW;
break; break;
case ITEM_SONG_STORMS: case ITEM_SONG_STORMS:

View file

@ -35,6 +35,7 @@ typedef enum {
/* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c /* 0xA9 */ TIMESTAMP_DEFEAT_GANON, // z_boss_ganon2.c
/* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c /* 0xA9 */ TIMESTAMP_BOSSRUSH_FINISH, // z_boss_ganon2.c
/* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c /* 0xAA */ TIMESTAMP_FOUND_GREG, // z_parameter.c
/* 0xAA */ TIMESTAMP_TRIFORCE_COMPLETED, // z_parameter.c
/* 0xAB */ TIMESTAMP_MAX /* 0xAB */ TIMESTAMP_MAX
}GameplayStatTimestamp; }GameplayStatTimestamp;

View file

@ -2,10 +2,12 @@
#include <libultraship/bridge.h> #include <libultraship/bridge.h>
#include "game-interactor/GameInteractor.h" #include "game-interactor/GameInteractor.h"
#include "tts/tts.h" #include "tts/tts.h"
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/boss-rush/BossRushTypes.h" #include "soh/Enhancements/boss-rush/BossRushTypes.h"
#include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/randomizer/3drando/random.hpp" #include "soh/Enhancements/randomizer/3drando/random.hpp"
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h" #include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
#include <soh/Enhancements/item-tables/ItemTableManager.h>
#include "soh/Enhancements/nametag.h" #include "soh/Enhancements/nametag.h"
#include "src/overlays/actors/ovl_En_Bb/z_en_bb.h" #include "src/overlays/actors/ovl_En_Bb/z_en_bb.h"
@ -231,9 +233,9 @@ void RegisterOcarinaTimeTravel() {
gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock && gPlayState->msgCtx.lastPlayedSong == OCARINA_SONG_TIME && !nearbyTimeBlockEmpty && !nearbyTimeBlock &&
!nearbyOcarinaSpot && !nearbyFrogs) { !nearbyOcarinaSpot && !nearbyFrogs) {
if (gSaveContext.n64ddFlag) { if (IS_RANDO) {
CVarSetInteger("gSwitchTimeline", 1); CVarSetInteger("gSwitchTimeline", 1);
} else if (!gSaveContext.n64ddFlag && !nearbyDoorOfTime) { } else if (!IS_RANDO && !nearbyDoorOfTime) {
// This check is made for when Link is learning the Song Of Time in a vanilla save file that load a // This check is made for when Link is learning the Song Of Time in a vanilla save file that load a
// Temple of Time scene where the only object present is the Door of Time // Temple of Time scene where the only object present is the Door of Time
CVarSetInteger("gSwitchTimeline", 1); CVarSetInteger("gSwitchTimeline", 1);
@ -469,7 +471,7 @@ void RegisterHyperBosses() {
uint8_t hyperBossesActive = uint8_t hyperBossesActive =
CVarGetInteger("gHyperBosses", 0) || CVarGetInteger("gHyperBosses", 0) ||
(gSaveContext.isBossRush && (IS_BOSS_RUSH &&
gSaveContext.bossRushOptions[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES); gSaveContext.bossRushOptions[BR_OPTIONS_HYPERBOSSES] == BR_CHOICE_HYPERBOSSES_YES);
// Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses. // Don't apply during cutscenes because it causes weird behaviour and/or crashes on some bosses.
@ -581,7 +583,7 @@ void UpdateMirrorModeState(int32_t sceneNum) {
(sceneNum == SCENE_GANON_BOSS); (sceneNum == SCENE_GANON_BOSS);
if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) { if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) {
uint32_t seed = sceneNum + (gSaveContext.n64ddFlag ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt); uint32_t seed = sceneNum + (IS_RANDO ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt);
Random_Init(seed); Random_Init(seed);
} }
@ -615,6 +617,45 @@ void RegisterMirrorModeHandler() {
}); });
} }
f32 triforcePieceScale;
void RegisterTriforceHunt() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
if (!GameInteractor::IsGameplayPaused() &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) {
// Warp to credits
if (GameInteractor::State::TriforceHuntCreditsWarpActive) {
gPlayState->nextEntranceIndex = 0x6B;
gSaveContext.nextCutsceneIndex = 0xFFF2;
gPlayState->sceneLoadFlag = 0x14;
gPlayState->fadeTransition = 3;
GameInteractor::State::TriforceHuntCreditsWarpActive = 0;
}
// Reset Triforce Piece scale for GI animation. Triforce Hunt allows for multiple triforce models,
// and cycles through them based on the amount of triforce pieces collected. It takes a little while
// for the count to increase during the GI animation, so the model is entirely hidden until that piece
// has been added. That scale has to be reset after the textbox is closed, and this is the best way
// to ensure it's done at that point in time specifically.
if (GameInteractor::State::TriforceHuntPieceGiven) {
triforcePieceScale = 0.0f;
GameInteractor::State::TriforceHuntPieceGiven = 0;
}
uint8_t currentPieces = gSaveContext.triforcePiecesCollected;
uint8_t requiredPieces = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
// Give Boss Key when player loads back into the savefile.
if (currentPieces >= requiredPieces && gPlayState->sceneLoadFlag != 0x14 &&
(1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0) {
GetItemEntry getItemEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY);
GiveItemEntryWithoutActor(gPlayState, getItemEntry);
}
}
});
}
//this map is used for enemies that can be uniquely identified by their id //this map is used for enemies that can be uniquely identified by their id
//and that are always counted //and that are always counted
//enemies that can't be uniquely identified by their id //enemies that can't be uniquely identified by their id
@ -1008,6 +1049,7 @@ void InitMods() {
RegisterBonkDamage(); RegisterBonkDamage();
RegisterMenuPathFix(); RegisterMenuPathFix();
RegisterMirrorModeHandler(); RegisterMirrorModeHandler();
RegisterTriforceHunt();
RegisterEnemyDefeatCounts(); RegisterEnemyDefeatCounts();
RegisterAltTrapTypes(); RegisterAltTrapTypes();
RegisterRandomizerSheikSpawn(); RegisterRandomizerSheikSpawn();

View file

@ -503,7 +503,9 @@ static std::vector<uint32_t> CalculateBarrenRegions() {
if (Location(loc)->GetPlacedItem().IsMajorItem() || ElementInContainer(loc, wothLocations)) { if (Location(loc)->GetPlacedItem().IsMajorItem() || ElementInContainer(loc, wothLocations)) {
AddElementsToPool(potentiallyUsefulLocations, std::vector{loc}); AddElementsToPool(potentiallyUsefulLocations, std::vector{loc});
} else { } else {
if (loc != LINKS_POCKET) { //Nobody cares to know if Link's Pocket is barren // Link's Pocket & Triforce Hunt "reward" shouldn't be considered for barren areas because it's clear what
// they have to a player.
if (loc != LINKS_POCKET && loc != TRIFORCE_COMPLETED) {
AddElementsToPool(barrenLocations, std::vector{loc}); AddElementsToPool(barrenLocations, std::vector{loc});
} }
} }
@ -723,6 +725,9 @@ static Text BuildGanonBossKeyText() {
} else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_TOKENS)) { } else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_TOKENS)) {
ganonBossKeyText = BuildCountReq(LACS_TOKENS_HINT, LACSTokenCount); ganonBossKeyText = BuildCountReq(LACS_TOKENS_HINT, LACSTokenCount);
} else if (GanonsBossKey.Is(GANONSBOSSKEY_TRIFORCE_HUNT)) {
ganonBossKeyText = Hint(GANON_BK_TRIFORCE_HINT).GetText();
} }
return Text()+"$b"+ganonBossKeyText+"^"; return Text()+"$b"+ganonBossKeyText+"^";

View file

@ -242,6 +242,7 @@ void ItemTable_Init() { // RandomizerGet
itemTable[BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{"Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Comprar poción roja [40]"}, ITEMTYPE_SHOP, 0x30, false, &noVariable, BOTTLE_WITH_RED_POTION, 40); itemTable[BUY_RED_POTION_40] = Item(RG_BUY_RED_POTION_40, Text{"Buy Red Potion [40]", "Acheter: Potion Rouge [40]", "Comprar poción roja [40]"}, ITEMTYPE_SHOP, 0x30, false, &noVariable, BOTTLE_WITH_RED_POTION, 40);
itemTable[BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{"Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Comprar poción roja [50]"}, ITEMTYPE_SHOP, 0x31, false, &noVariable, BOTTLE_WITH_RED_POTION, 50); itemTable[BUY_RED_POTION_50] = Item(RG_BUY_RED_POTION_50, Text{"Buy Red Potion [50]", "Acheter: Potion Rouge [50]", "Comprar poción roja [50]"}, ITEMTYPE_SHOP, 0x31, false, &noVariable, BOTTLE_WITH_RED_POTION, 50);
itemTable[TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{"Triforce Piece", "Triforce Piece", "Triforce Piece"}, ITEMTYPE_ITEM, 0xDF, true, &TriforcePieces, TRIFORCE_PIECE);
itemTable[TRIFORCE] = Item(RG_TRIFORCE, Text{"Triforce", "Triforce", "Trifuerza"}, ITEMTYPE_EVENT, GI_RUPEE_RED_LOSE, false, &noVariable, NONE); itemTable[TRIFORCE] = Item(RG_TRIFORCE, Text{"Triforce", "Triforce", "Trifuerza"}, ITEMTYPE_EVENT, GI_RUPEE_RED_LOSE, false, &noVariable, NONE);
itemTable[HINT] = Item(RG_HINT, Text{"Hint", "Indice", "Pista"}, ITEMTYPE_EVENT, GI_RUPEE_BLUE_LOSE, false, &noVariable, NONE); itemTable[HINT] = Item(RG_HINT, Text{"Hint", "Indice", "Pista"}, ITEMTYPE_EVENT, GI_RUPEE_BLUE_LOSE, false, &noVariable, NONE);

View file

@ -918,6 +918,7 @@ void LocationTable_Init() {
locationTable[DMC_UPPER_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, "DMC Upper Grotto Gossip Stone"); locationTable[DMC_UPPER_GROTTO_GOSSIP_STONE] = ItemLocation::HintStone(RC_DMC_UPPER_GROTTO_GOSSIP_STONE, "DMC Upper Grotto Gossip Stone");
locationTable[GANONDORF_HINT] = ItemLocation::OtherHint(RC_GANONDORF_HINT, "Ganondorf Hint"); locationTable[GANONDORF_HINT] = ItemLocation::OtherHint(RC_GANONDORF_HINT, "Ganondorf Hint");
locationTable[TRIFORCE_COMPLETED] = ItemLocation::Reward (RC_TRIFORCE_COMPLETED, 0xFF, "Completed Triforce", NONE, TRIFORCE_COMPLETED, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_NO_GROUP);
for (int i = NONE; i != KEY_ENUM_MAX; i++) for (int i = NONE; i != KEY_ENUM_MAX; i++)
locationLookupTable.insert(std::make_pair(locationTable[i].GetRandomizerCheck(), static_cast<Key>(i))); locationLookupTable.insert(std::make_pair(locationTable[i].GetRandomizerCheck(), static_cast<Key>(i)));
@ -1523,6 +1524,9 @@ void GenerateLocationPool() {
allLocations.clear(); allLocations.clear();
AddLocation(LINKS_POCKET); AddLocation(LINKS_POCKET);
if (Settings::TriforceHunt.Is(TRIFORCE_HUNT_ON)) {
AddLocation(TRIFORCE_COMPLETED);
}
AddLocations(overworldLocations); AddLocations(overworldLocations);
for (auto dungeon : Dungeon::dungeonList) { for (auto dungeon : Dungeon::dungeonList) {

View file

@ -662,9 +662,17 @@ void GenerateItemPool() {
IceTrapModels.push_back(0xD3); IceTrapModels.push_back(0xD3);
} }
if (TriforceHunt.Is(TRIFORCE_HUNT_ON)) {
IceTrapModels.push_back(0xDF);
AddItemToMainPool(TRIFORCE_PIECE, Settings::TriforceHuntTotal.Value<uint8_t>());
PlaceItemInLocation(TRIFORCE_COMPLETED, TRIFORCE); // Win condition
PlaceItemInLocation(GANON, GetJunkItem(), false, true);
} else {
PlaceItemInLocation(GANON, TRIFORCE); // Win condition
}
//Fixed item locations //Fixed item locations
PlaceItemInLocation(HC_ZELDAS_LETTER, ZELDAS_LETTER); PlaceItemInLocation(HC_ZELDAS_LETTER, ZELDAS_LETTER);
PlaceItemInLocation(GANON, TRIFORCE); //The Triforce is only used to make sure Ganon is accessible
PlaceItemInLocation(MARKET_BOMBCHU_BOWLING_BOMBCHUS, BOMBCHU_DROP); PlaceItemInLocation(MARKET_BOMBCHU_BOWLING_BOMBCHUS, BOMBCHU_DROP);
if (ShuffleKokiriSword) { if (ShuffleKokiriSword) {
@ -1135,7 +1143,7 @@ void GenerateItemPool() {
if (GanonsBossKey.Is(GANONSBOSSKEY_FINAL_GS_REWARD)) { if (GanonsBossKey.Is(GANONSBOSSKEY_FINAL_GS_REWARD)) {
PlaceItemInLocation(KAK_100_GOLD_SKULLTULA_REWARD, GANONS_CASTLE_BOSS_KEY); PlaceItemInLocation(KAK_100_GOLD_SKULLTULA_REWARD, GANONS_CASTLE_BOSS_KEY);
} else if (GanonsBossKey.Value<uint8_t>() >= GANONSBOSSKEY_LACS_VANILLA) { } else if (GanonsBossKey.Value<uint8_t>() >= GANONSBOSSKEY_LACS_VANILLA && GanonsBossKey.IsNot(GANONSBOSSKEY_TRIFORCE_HUNT)) {
PlaceItemInLocation(TOT_LIGHT_ARROWS_CUTSCENE, GANONS_CASTLE_BOSS_KEY); PlaceItemInLocation(TOT_LIGHT_ARROWS_CUTSCENE, GANONS_CASTLE_BOSS_KEY);
} else if (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA)) { } else if (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA)) {
PlaceItemInLocation(GANONS_TOWER_BOSS_KEY_CHEST, GANONS_CASTLE_BOSS_KEY); PlaceItemInLocation(GANONS_TOWER_BOSS_KEY_CHEST, GANONS_CASTLE_BOSS_KEY);

View file

@ -202,6 +202,7 @@ typedef enum {
TRIFORCE, TRIFORCE,
TRIFORCE_PIECE, TRIFORCE_PIECE,
TRIFORCE_COMPLETED,
EPONA, EPONA,
HINT, HINT,

View file

@ -256,7 +256,8 @@ void AreaTable_Init() {
//name, scene, hint text, events, locations, exits //name, scene, hint text, events, locations, exits
areaTable[ROOT] = Area("Root", "", LINKS_POCKET, NO_DAY_NIGHT_CYCLE, {}, { areaTable[ROOT] = Area("Root", "", LINKS_POCKET, NO_DAY_NIGHT_CYCLE, {}, {
//Locations //Locations
LocationAccess(LINKS_POCKET, {[]{return true;}}) LocationAccess(LINKS_POCKET, {[]{return true;}}),
LocationAccess(TRIFORCE_COMPLETED, { [] { return CanCompleteTriforce;}}),
}, { }, {
//Exits //Exits
Entrance(ROOT_EXITS, {[]{return true;}}) Entrance(ROOT_EXITS, {[]{return true;}})

View file

@ -150,6 +150,9 @@ namespace Logic {
uint8_t BottomOfTheWellKeys = 0; uint8_t BottomOfTheWellKeys = 0;
uint8_t TreasureGameKeys = 0; uint8_t TreasureGameKeys = 0;
//Triforce Pieces
uint8_t TriforcePieces = 0;
//Boss Keys //Boss Keys
bool BossKeyForestTemple = false; bool BossKeyForestTemple = false;
bool BossKeyFireTemple = false; bool BossKeyFireTemple = false;
@ -309,6 +312,7 @@ namespace Logic {
bool AtDay = false; bool AtDay = false;
bool AtNight = false; bool AtNight = false;
uint8_t Age = 0; uint8_t Age = 0;
bool CanCompleteTriforce = false;
//Events //Events
bool ShowedMidoSwordAndShield = false; bool ShowedMidoSwordAndShield = false;
@ -620,7 +624,7 @@ namespace Logic {
(LACSCondition == LACSCONDITION_REWARDS && StoneCount + MedallionCount + (Greg && GregInLogic ? 1 : 0) >= LACSRewardCount.Value<uint8_t>()) || (LACSCondition == LACSCONDITION_REWARDS && StoneCount + MedallionCount + (Greg && GregInLogic ? 1 : 0) >= LACSRewardCount.Value<uint8_t>()) ||
(LACSCondition == LACSCONDITION_DUNGEONS && DungeonCount + (Greg && GregInLogic ? 1 : 0) >= LACSDungeonCount.Value<uint8_t>()) || (LACSCondition == LACSCONDITION_DUNGEONS && DungeonCount + (Greg && GregInLogic ? 1 : 0) >= LACSDungeonCount.Value<uint8_t>()) ||
(LACSCondition == LACSCONDITION_TOKENS && GoldSkulltulaTokens >= LACSTokenCount.Value<uint8_t>()); (LACSCondition == LACSCONDITION_TOKENS && GoldSkulltulaTokens >= LACSTokenCount.Value<uint8_t>());
CanCompleteTriforce = TriforcePieces >= TriforceHuntRequired.Value<uint8_t>();
} }
bool SmallKeys(Key dungeon, uint8_t requiredAmount) { bool SmallKeys(Key dungeon, uint8_t requiredAmount) {
@ -873,7 +877,8 @@ namespace Logic {
NumBottles = 0; NumBottles = 0;
NoBottles = false; NoBottles = false;
//Triforce Pieces
TriforcePieces = 0;
//Drops and Bottle Contents Access //Drops and Bottle Contents Access
DekuNutDrop = false; DekuNutDrop = false;

View file

@ -143,6 +143,9 @@ extern uint8_t GerudoFortressKeys;
extern uint8_t GanonsCastleKeys; extern uint8_t GanonsCastleKeys;
extern uint8_t TreasureGameKeys; extern uint8_t TreasureGameKeys;
// Triforce Pieces
extern uint8_t TriforcePieces;
// Boss Keys // Boss Keys
extern bool BossKeyForestTemple; extern bool BossKeyForestTemple;
extern bool BossKeyFireTemple; extern bool BossKeyFireTemple;
@ -298,6 +301,7 @@ extern bool AtDay;
extern bool AtNight; extern bool AtNight;
extern bool LinksCow; extern bool LinksCow;
extern uint8_t Age; extern uint8_t Age;
extern bool CanCompleteTriforce;
// Events // Events
extern bool ShowedMidoSwordAndShield; extern bool ShowedMidoSwordAndShield;

View file

@ -101,6 +101,9 @@ namespace Settings {
Option BombchusInLogic = Option::Bool("Bombchus in Logic", {"Off", "On"}); Option BombchusInLogic = Option::Bool("Bombchus in Logic", {"Off", "On"});
Option AmmoDrops = Option::U8 ("Ammo Drops", {"On", "On + Bombchu", "Off"}, OptionCategory::Setting, AMMODROPS_BOMBCHU); Option AmmoDrops = Option::U8 ("Ammo Drops", {"On", "On + Bombchu", "Off"}, OptionCategory::Setting, AMMODROPS_BOMBCHU);
Option HeartDropRefill = Option::U8 ("Heart Drops and Refills",{"On", "No Drop", "No Refill", "Off"}, OptionCategory::Setting, HEARTDROPREFILL_VANILLA); Option HeartDropRefill = Option::U8 ("Heart Drops and Refills",{"On", "No Drop", "No Refill", "Off"}, OptionCategory::Setting, HEARTDROPREFILL_VANILLA);
Option TriforceHunt = Option::U8 ("Triforce Hunt", {"Off", "On"});
Option TriforceHuntTotal = Option::U8 ("Triforce Hunt Total Pieces", {NumOpts(0, 100)});
Option TriforceHuntRequired = Option::U8 ("Triforce Hunt Required Pieces", {NumOpts(0, 100)});
Option MQDungeonCount = Option::U8( Option MQDungeonCount = Option::U8(
"MQ Dungeon Count", { MultiVecOpts({ NumOpts(0, 12), { "Random" }, { "Selection" } }) }); "MQ Dungeon Count", { MultiVecOpts({ NumOpts(0, 12), { "Random" }, { "Selection" } }) });
uint8_t MQSet; uint8_t MQSet;
@ -139,6 +142,9 @@ namespace Settings {
&BombchusInLogic, &BombchusInLogic,
&AmmoDrops, &AmmoDrops,
&HeartDropRefill, &HeartDropRefill,
&TriforceHunt,
&TriforceHuntTotal,
&TriforceHuntRequired,
&MQDungeonCount, &MQDungeonCount,
&SetDungeonTypes, &SetDungeonTypes,
&MQDeku, &MQDeku,
@ -219,7 +225,7 @@ namespace Settings {
Option Keysanity = Option::U8 ("Small Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, KEYSANITY_OWN_DUNGEON); Option Keysanity = Option::U8 ("Small Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, KEYSANITY_OWN_DUNGEON);
Option GerudoKeys = Option::U8 ("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"}); Option GerudoKeys = Option::U8 ("Gerudo Fortress Keys", {"Vanilla", "Any Dungeon", "Overworld", "Anywhere"});
Option BossKeysanity = Option::U8 ("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, BOSSKEYSANITY_OWN_DUNGEON); Option BossKeysanity = Option::U8 ("Boss Keys", {"Start With", "Vanilla", "Own Dungeon", "Any Dungeon", "Overworld", "Anywhere"}, OptionCategory::Setting, BOSSKEYSANITY_OWN_DUNGEON);
Option GanonsBossKey = Option::U8 ("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, GANONSBOSSKEY_VANILLA); Option GanonsBossKey = Option::U8 ("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, GANONSBOSSKEY_VANILLA);
uint8_t LACSCondition = 0; uint8_t LACSCondition = 0;
Option LACSStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, 1, true); Option LACSStoneCount = Option::U8 ("Stone Count", {NumOpts(0, 4)}, OptionCategory::Setting, 1, true);
Option LACSMedallionCount = Option::U8 ("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, 1, true); Option LACSMedallionCount = Option::U8 ("Medallion Count", {NumOpts(0, 7)}, OptionCategory::Setting, 1, true);
@ -1685,6 +1691,13 @@ namespace Settings {
IncludeAndHide({KAK_100_GOLD_SKULLTULA_REWARD}); IncludeAndHide({KAK_100_GOLD_SKULLTULA_REWARD});
} }
//Force include Triforce Hunt if it's off
if (TriforceHunt) {
Unhide({ TRIFORCE_COMPLETED });
} else {
IncludeAndHide({ TRIFORCE_COMPLETED });
}
//Force include Map and Compass Chests when Vanilla //Force include Map and Compass Chests when Vanilla
std::vector<uint32_t> mapChests = GetLocations(everyPossibleLocation, Category::cVanillaMap); std::vector<uint32_t> mapChests = GetLocations(everyPossibleLocation, Category::cVanillaMap);
std::vector<uint32_t> compassChests = GetLocations(everyPossibleLocation, Category::cVanillaCompass); std::vector<uint32_t> compassChests = GetLocations(everyPossibleLocation, Category::cVanillaCompass);
@ -2365,7 +2378,11 @@ namespace Settings {
Keysanity.SetSelectedIndex(cvarSettings[RSK_KEYSANITY]); Keysanity.SetSelectedIndex(cvarSettings[RSK_KEYSANITY]);
GerudoKeys.SetSelectedIndex(cvarSettings[RSK_GERUDO_KEYS]); GerudoKeys.SetSelectedIndex(cvarSettings[RSK_GERUDO_KEYS]);
BossKeysanity.SetSelectedIndex(cvarSettings[RSK_BOSS_KEYSANITY]); BossKeysanity.SetSelectedIndex(cvarSettings[RSK_BOSS_KEYSANITY]);
GanonsBossKey.SetSelectedIndex(cvarSettings[RSK_GANONS_BOSS_KEY]); if (cvarSettings[RSK_TRIFORCE_HUNT]) {
GanonsBossKey.SetSelectedIndex(RO_GANON_BOSS_KEY_TRIFORCE_HUNT);
} else {
GanonsBossKey.SetSelectedIndex(cvarSettings[RSK_GANONS_BOSS_KEY]);
}
LACSStoneCount.SetSelectedIndex(cvarSettings[RSK_LACS_STONE_COUNT]); LACSStoneCount.SetSelectedIndex(cvarSettings[RSK_LACS_STONE_COUNT]);
LACSMedallionCount.SetSelectedIndex(cvarSettings[RSK_LACS_MEDALLION_COUNT]); LACSMedallionCount.SetSelectedIndex(cvarSettings[RSK_LACS_MEDALLION_COUNT]);
LACSRewardCount.SetSelectedIndex(cvarSettings[RSK_LACS_REWARD_COUNT]); LACSRewardCount.SetSelectedIndex(cvarSettings[RSK_LACS_REWARD_COUNT]);
@ -2470,6 +2487,10 @@ namespace Settings {
} }
} }
TriforceHunt.SetSelectedIndex(cvarSettings[RSK_TRIFORCE_HUNT]);
TriforceHuntTotal.SetSelectedIndex(cvarSettings[RSK_TRIFORCE_HUNT_PIECES_TOTAL]);
TriforceHuntRequired.SetSelectedIndex(cvarSettings[RSK_TRIFORCE_HUNT_PIECES_REQUIRED]);
//Set key ring for each dungeon //Set key ring for each dungeon
for (size_t i = 0; i < dungeons.size(); i++) { for (size_t i = 0; i < dungeons.size(); i++) {
dungeons[i]->ClearKeyRing(); dungeons[i]->ClearKeyRing();

View file

@ -91,6 +91,11 @@ typedef enum {
LACS_OPTION_WILDCARD, LACS_OPTION_WILDCARD,
} LACSRewardOptionsSetting; } LACSRewardOptionsSetting;
typedef enum {
TRIFORCE_HUNT_OFF,
TRIFORCE_HUNT_ON,
} TriforceHuntSetting;
typedef enum { typedef enum {
AGE_CHILD, AGE_CHILD,
AGE_ADULT, AGE_ADULT,
@ -249,6 +254,7 @@ typedef enum {
GANONSBOSSKEY_LACS_DUNGEONS, GANONSBOSSKEY_LACS_DUNGEONS,
GANONSBOSSKEY_LACS_TOKENS, GANONSBOSSKEY_LACS_TOKENS,
GANONSBOSSKEY_FINAL_GS_REWARD, GANONSBOSSKEY_FINAL_GS_REWARD,
GANONSBOSSKEY_TRIFORCE_HUNT,
} GanonsBossKeySetting; } GanonsBossKeySetting;
typedef enum { typedef enum {
@ -780,6 +786,9 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin
extern Option BombchusInLogic; extern Option BombchusInLogic;
extern Option AmmoDrops; extern Option AmmoDrops;
extern Option HeartDropRefill; extern Option HeartDropRefill;
extern Option TriforceHunt;
extern Option TriforceHuntTotal;
extern Option TriforceHuntRequired;
extern Option MQDungeonCount; extern Option MQDungeonCount;
extern Option SetDungeonTypes; extern Option SetDungeonTypes;

View file

@ -13,7 +13,7 @@ using namespace Settings;
std::vector<ItemAndPrice> NonShopItems = {}; std::vector<ItemAndPrice> NonShopItems = {};
static std::array<std::vector<Text>, 0xD5> trickNameTable; //Table of trick names for ice traps static std::array<std::vector<Text>, 0xE0> trickNameTable; // Table of trick names for ice traps
bool initTrickNames = false; //Indicates if trick ice trap names have been initialized yet bool initTrickNames = false; //Indicates if trick ice trap names have been initialized yet
//Set vanilla shop item locations before potentially shuffling //Set vanilla shop item locations before potentially shuffling
@ -698,6 +698,10 @@ void InitTrickNames() {
Text{"Crystal Heart", "Cœur de cristal", "Corazón de cristal"}, Text{"Crystal Heart", "Cœur de cristal", "Corazón de cristal"},
Text{"Life Heart", "Cœur de vie", "Vida Corazón"}, Text{"Life Heart", "Cœur de vie", "Vida Corazón"},
Text{"Lots of Love", "Beaucoup d'amour", "Mucho amor"}}; Text{"Lots of Love", "Beaucoup d'amour", "Mucho amor"}};
trickNameTable[0xDF] = {
Text{"Piece of Cheese", "Morceau de Fromage", "Piece of Cheese"},
Text{"Triforce Shard", "Éclat de Triforce", "Triforce Shard"},
Text{"Shiny Rock", "Caiiloux Brillant", "Shiny Rock"}};
/* /*
//Names for individual upgrades, in case progressive names are replaced //Names for individual upgrades, in case progressive names are replaced

View file

@ -54,7 +54,9 @@ void GenerateStartingInventory() {
AddItemToInventory(SHADOW_TEMPLE_BOSS_KEY); AddItemToInventory(SHADOW_TEMPLE_BOSS_KEY);
} }
if (GanonsBossKey.Is(GANONSBOSSKEY_START_WITH)) { // 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 (GanonsBossKey.Is(GANONSBOSSKEY_START_WITH) || GanonsBossKey.Is(GANONSBOSSKEY_TRIFORCE_HUNT)) {
AddItemToInventory(GANONS_CASTLE_BOSS_KEY); AddItemToInventory(GANONS_CASTLE_BOSS_KEY);
} }

View file

@ -3,17 +3,23 @@
#include "z64.h" #include "z64.h"
#include "macros.h" #include "macros.h"
#include "functions.h" #include "functions.h"
#include "variables.h"
#include "soh/OTRGlobals.h"
#include "randomizerTypes.h" #include "randomizerTypes.h"
#include <array> #include <array>
#include "objects/object_gi_key/object_gi_key.h" #include "objects/object_gi_key/object_gi_key.h"
#include "objects/object_gi_bosskey/object_gi_bosskey.h" #include "objects/object_gi_bosskey/object_gi_bosskey.h"
#include "objects/object_gi_hearts/object_gi_hearts.h" #include "objects/object_gi_hearts/object_gi_hearts.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h" #include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "soh_assets.h"
extern "C" {
extern SaveContext gSaveContext;
}
extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey); extern "C" u8 Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry) { extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry) {
s32 pad;
s8 keysCanBeOutsideDungeon = getItemEntry->getItemId == RG_GERUDO_FORTRESS_SMALL_KEY ? s8 keysCanBeOutsideDungeon = getItemEntry->getItemId == RG_GERUDO_FORTRESS_SMALL_KEY ?
Randomizer_GetSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA : Randomizer_GetSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA :
DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_KEYSANITY); DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_KEYSANITY);
@ -53,7 +59,6 @@ extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEn
} }
extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry) { extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry) {
s32 pad;
s8 keysCanBeOutsideDungeon = getItemEntry->getItemId == RG_GANONS_CASTLE_BOSS_KEY ? s8 keysCanBeOutsideDungeon = getItemEntry->getItemId == RG_GANONS_CASTLE_BOSS_KEY ?
DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_GANONS_BOSS_KEY) : DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_GANONS_BOSS_KEY) :
DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_BOSS_KEYSANITY); DUNGEON_ITEMS_CAN_BE_OUTSIDE_DUNGEON(RSK_BOSS_KEYSANITY);
@ -107,8 +112,6 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
} }
extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry) { extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry) {
s32 pad;
s16 color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_KEY_RING; s16 color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_KEY_RING;
s16 colors[9][3] = { s16 colors[9][3] = {
{ 4, 195, 46 }, // Forest Temple { 4, 195, 46 }, // Forest Temple
@ -155,7 +158,6 @@ extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEnt
} }
extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getItemEntry) { extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getItemEntry) {
s32 pad;
OPEN_DISPS(play->state.gfxCtx); OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Xlu(play->state.gfxCtx); Gfx_SetupDL_25Xlu(play->state.gfxCtx);
@ -173,3 +175,84 @@ extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getIt
CLOSE_DISPS(play->state.gfxCtx); CLOSE_DISPS(play->state.gfxCtx);
} }
Gfx* Randomizer_GetTriforcePieceDL(uint8_t index) {
switch (index) {
case 1:
return (Gfx*)gTriforcePiece1DL;
case 2:
return (Gfx*)gTriforcePiece2DL;
default:
return (Gfx*)gTriforcePiece0DL;
}
}
extern "C" void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
uint16_t current = gSaveContext.triforcePiecesCollected;
Matrix_Scale(0.035f, 0.035f, 0.035f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
Gfx* triforcePieceDL = Randomizer_GetTriforcePieceDL(current % 3);
gSPDisplayList(POLY_XLU_DISP++, triforcePieceDL);
CLOSE_DISPS(play->state.gfxCtx);
}
// Seperate draw function for drawing the Triforce piece when in the GI state.
// Needed for delaying showing the triforce piece slightly so the triforce shard doesn't
// suddenly snap to the new piece model or completed triforce because the piece is
// given mid textbox. Also makes it so the overworld models don't turn into the completed
// model when the player has exactly the required amount of pieces.
extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
uint16_t current = gSaveContext.triforcePiecesCollected;
uint16_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
Matrix_Scale(triforcePieceScale, triforcePieceScale, triforcePieceScale, MTXMODE_APPLY);
// For creating a delay before showing the model so the model doesn't swap visually when the triforce piece
// is given when the textbox just appears.
if (triforcePieceScale < 0.0001f) {
triforcePieceScale += 0.00003f;
}
// Animation. When not the completed triforce, create delay before showing the piece to bypass interpolation.
// If the completed triforce, make it grow slowly.
if (current != required) {
if (triforcePieceScale > 0.00008f && triforcePieceScale < 0.034f) {
triforcePieceScale = 0.034f;
} else if (triforcePieceScale < 0.035f) {
triforcePieceScale += 0.0005f;
}
} else if (triforcePieceScale > 0.00008f && triforcePieceScale < 0.035f) {
triforcePieceScale += 0.0005f;
}
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
// Show piece when not currently completing the triforce. Use the scale to create a delay so interpolation doesn't
// make the triforce twitch when the size is set to a higher value.
if (current != required && triforcePieceScale > 0.035f) {
// Get shard DL. Remove one before division to account for triforce piece given in the textbox
// to match up the shard from the overworld model.
Gfx* triforcePieceDL = Randomizer_GetTriforcePieceDL((current - 1) % 3);
gSPDisplayList(POLY_XLU_DISP++, triforcePieceDL);
} else if (current == required && triforcePieceScale > 0.00008f) {
gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gTriforcePieceCompletedDL);
}
CLOSE_DISPS(play->state.gfxCtx);
}

View file

@ -6,10 +6,18 @@
typedef struct PlayState PlayState; typedef struct PlayState PlayState;
extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry); #ifdef __cplusplus
extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry); extern "C" {
extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry); #endif
extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry);
extern "C" void Randomizer_DrawIceTrap(PlayState* play, GetItemEntry getItemEntry); void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getItemEntry);
void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getItemEntry);
void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry);
#ifdef __cplusplus
};
#endif
#endif #endif

View file

@ -55,6 +55,7 @@ const std::string Randomizer::getItemMessageTableID = "Randomizer";
const std::string Randomizer::hintMessageTableID = "RandomizerHints"; const std::string Randomizer::hintMessageTableID = "RandomizerHints";
const std::string Randomizer::merchantMessageTableID = "RandomizerMerchants"; const std::string Randomizer::merchantMessageTableID = "RandomizerMerchants";
const std::string Randomizer::rupeeMessageTableID = "RandomizerRupees"; const std::string Randomizer::rupeeMessageTableID = "RandomizerRupees";
const std::string Randomizer::triforcePieceMessageTableID = "RandomizerTriforcePiece";
const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi"; const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi";
const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap"; const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap";
const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints"; const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints";
@ -320,6 +321,9 @@ std::unordered_map<std::string, RandomizerSettingKey> SpoilerfileSettingNameToEn
{ "World Settings:Mix Interiors", RSK_MIX_INTERIOR_ENTRANCES }, { "World Settings:Mix Interiors", RSK_MIX_INTERIOR_ENTRANCES },
{ "World Settings:Mix Grottos", RSK_MIX_GROTTO_ENTRANCES }, { "World Settings:Mix Grottos", RSK_MIX_GROTTO_ENTRANCES },
{ "World Settings:Decouple Entrances", RSK_DECOUPLED_ENTRANCES }, { "World Settings:Decouple Entrances", RSK_DECOUPLED_ENTRANCES },
{ "World Settings:Triforce Hunt", RSK_TRIFORCE_HUNT },
{ "World Settings:Triforce Hunt Total Pieces", RSK_TRIFORCE_HUNT_PIECES_TOTAL },
{ "World Settings:Triforce Hunt Required Pieces", RSK_TRIFORCE_HUNT_PIECES_REQUIRED },
{ "Misc Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS }, { "Misc Settings:Gossip Stone Hints", RSK_GOSSIP_STONE_HINTS },
{ "Misc Settings:Hint Clarity", RSK_HINT_CLARITY }, { "Misc Settings:Hint Clarity", RSK_HINT_CLARITY },
{ "Misc Settings:ToT Altar Hint", RSK_TOT_ALTAR_HINT }, { "Misc Settings:ToT Altar Hint", RSK_TOT_ALTAR_HINT },
@ -799,6 +803,8 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
case RSK_BIG_POE_COUNT: case RSK_BIG_POE_COUNT:
case RSK_CUCCO_COUNT: case RSK_CUCCO_COUNT:
case RSK_STARTING_SKULLTULA_TOKEN: case RSK_STARTING_SKULLTULA_TOKEN:
case RSK_TRIFORCE_HUNT_PIECES_TOTAL:
case RSK_TRIFORCE_HUNT_PIECES_REQUIRED:
numericValueString = it.value(); numericValueString = it.value();
gSaveContext.randoSettings[index].value = std::stoi(numericValueString); gSaveContext.randoSettings[index].value = std::stoi(numericValueString);
break; break;
@ -908,6 +914,7 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
case RSK_DECOUPLED_ENTRANCES: case RSK_DECOUPLED_ENTRANCES:
case RSK_SHOPSANITY_PRICES_AFFORDABLE: case RSK_SHOPSANITY_PRICES_AFFORDABLE:
case RSK_ALL_LOCATIONS_REACHABLE: case RSK_ALL_LOCATIONS_REACHABLE:
case RSK_TRIFORCE_HUNT:
if(it.value() == "Off") { if(it.value() == "Off") {
gSaveContext.randoSettings[index].value = RO_GENERIC_OFF; gSaveContext.randoSettings[index].value = RO_GENERIC_OFF;
} else if(it.value() == "On") { } else if(it.value() == "On") {
@ -1061,6 +1068,8 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_LACS_TOKENS; gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_LACS_TOKENS;
} else if(it.value() == "100 GS Reward") { } else if(it.value() == "100 GS Reward") {
gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_KAK_TOKENS; gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_KAK_TOKENS;
} else if(it.value() == "Triforce Hunt") {
gSaveContext.randoSettings[index].value = RO_GANON_BOSS_KEY_TRIFORCE_HUNT;
} }
break; break;
case RSK_RANDOM_MQ_DUNGEONS: case RSK_RANDOM_MQ_DUNGEONS:
@ -1980,6 +1989,7 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
case RG_BUY_DEKU_NUT_10: case RG_BUY_DEKU_NUT_10:
case RG_BUY_DEKU_STICK_1: case RG_BUY_DEKU_STICK_1:
case RG_BUY_HEART: case RG_BUY_HEART:
case RG_TRIFORCE_PIECE:
default: default:
return CAN_OBTAIN; return CAN_OBTAIN;
} }
@ -2990,6 +3000,10 @@ void GenerateRandomizerImgui(std::string seed = "") {
cvarSettings[RSK_MQ_DUNGEON_COUNT] = 0; cvarSettings[RSK_MQ_DUNGEON_COUNT] = 0;
} }
cvarSettings[RSK_TRIFORCE_HUNT] = CVarGetInteger("gRandomizeTriforceHunt", 0);
cvarSettings[RSK_TRIFORCE_HUNT_PIECES_TOTAL] = CVarGetInteger("gRandomizeTriforceHuntTotalPieces", 30);
cvarSettings[RSK_TRIFORCE_HUNT_PIECES_REQUIRED] = CVarGetInteger("gRandomizeTriforceHuntRequiredPieces", 20);
cvarSettings[RSK_MQ_DEKU_TREE] = CVarGetInteger("gRandomizeMqDungeonsDekuTree", 0); cvarSettings[RSK_MQ_DEKU_TREE] = CVarGetInteger("gRandomizeMqDungeonsDekuTree", 0);
cvarSettings[RSK_MQ_DODONGOS_CAVERN] = CVarGetInteger("gRandomizeMqDungeonsDodongosCavern", 0); cvarSettings[RSK_MQ_DODONGOS_CAVERN] = CVarGetInteger("gRandomizeMqDungeonsDodongosCavern", 0);
cvarSettings[RSK_MQ_JABU_JABU] = CVarGetInteger("gRandomizeMqDungeonsJabuJabu", 0); cvarSettings[RSK_MQ_JABU_JABU] = CVarGetInteger("gRandomizeMqDungeonsJabuJabu", 0);
@ -3502,6 +3516,7 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::PaddedSeparator(); UIWidgets::PaddedSeparator();
// Master Quest Dungeons
if (OTRGlobals::Instance->HasMasterQuest() && OTRGlobals::Instance->HasOriginal()) { if (OTRGlobals::Instance->HasMasterQuest() && OTRGlobals::Instance->HasOriginal()) {
ImGui::PushItemWidth(-FLT_MIN); ImGui::PushItemWidth(-FLT_MIN);
ImGui::Text("Master Quest Dungeons"); ImGui::Text("Master Quest Dungeons");
@ -3549,8 +3564,43 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::EnhancementCheckbox("Ganon's Castle##RandomizeMqDungeons", UIWidgets::EnhancementCheckbox("Ganon's Castle##RandomizeMqDungeons",
"gRandomizeMqDungeonsGanonsCastle"); "gRandomizeMqDungeonsGanonsCastle");
} }
UIWidgets::PaddedSeparator();
} }
// Triforce Hunt
UIWidgets::EnhancementCheckbox("Triforce Hunt", "gRandomizeTriforceHunt");
UIWidgets::InsertHelpHoverText(
"Pieces of the Triforce of Courage have been scattered across the world. Find them all to finish the game!\n\n"
"When the required amount of pieces have been found, the game is saved and Ganon's Boss key is given "
"to you when you load back into the game if you desire to beat Ganon afterwards.\n\n"
"Keep in mind Ganon might not be logically beatable when \"All Locations Reachable\" is turned off."
);
if (CVarGetInteger("gRandomizeTriforceHunt", 0)) {
// Triforce Hunt (total pieces)
UIWidgets::Spacer(0);
int totalPieces = CVarGetInteger("gRandomizeTriforceHuntTotalPieces", 30);
ImGui::Text("Triforce Pieces in the world: %d", totalPieces);
UIWidgets::InsertHelpHoverText(
"The amount of Triforce pieces that will be placed in the world. "
"Keep in mind seed generation can fail if more pieces are placed than there are junk items in the item pool."
);
ImGui::SameLine();
UIWidgets::EnhancementSliderInt("", "##TriforceHuntTotalPieces", "gRandomizeTriforceHuntTotalPieces", 1, 100, "", 30);
// Triforce Hunt (required pieces)
int requiredPieces = CVarGetInteger("gRandomizeTriforceHuntRequiredPieces", 20);
ImGui::Text("Triforce Pieces to win: %d", requiredPieces);
UIWidgets::InsertHelpHoverText(
"The amount of Triforce pieces required to win the game."
);
ImGui::SameLine();
UIWidgets::EnhancementSliderInt("", "##TriforceHuntRequiredPieces", "gRandomizeTriforceHuntRequiredPieces", 1, totalPieces, "", 20);
}
UIWidgets::PaddedSeparator();
ImGui::EndChild(); ImGui::EndChild();
// COLUMN 3 - Shuffle Entrances // COLUMN 3 - Shuffle Entrances
@ -4144,7 +4194,11 @@ void RandomizerSettingsWindow::DrawElement() {
"\n" "\n"
"100 GS Reward - Ganon's Boss Key will be awarded by the cursed rich man after you collect 100 Gold Skulltula Tokens." "100 GS Reward - Ganon's Boss Key will be awarded by the cursed rich man after you collect 100 Gold Skulltula Tokens."
); );
UIWidgets::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey, RO_GANON_BOSS_KEY_VANILLA); bool disableGBK = CVarGetInteger("gRandomizeTriforceHunt", 0);
static const char* disableGBKText = "This option is disabled because Triforce Hunt is enabled. Ganon's Boss key\nwill instead be given to you after Triforce Hunt completion.";
UIWidgets::EnhancementCombobox("gRandomizeShuffleGanonBossKey", randoShuffleGanonsBossKey,
RO_GANON_BOSS_KEY_VANILLA, disableGBK, disableGBKText,
RO_GANON_BOSS_KEY_VANILLA);
ImGui::PopItemWidth(); ImGui::PopItemWidth();
switch (CVarGetInteger("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_VANILLA)) { switch (CVarGetInteger("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_VANILLA)) {
case RO_GANON_BOSS_KEY_LACS_STONES: case RO_GANON_BOSS_KEY_LACS_STONES:
@ -5461,6 +5515,70 @@ CustomMessage Randomizer::GetRupeeMessage(u16 rupeeTextId) {
return messageEntry; return messageEntry;
} }
void CreateTriforcePieceMessages() {
CustomMessage TriforcePieceMessages[NUM_TRIFORCE_PIECE_MESSAGES] = {
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. It's a start!",
"Ein %yTriforce-Splitter%w! Du hast&%g{{current}}%w von %c{{required}}%w gefunden. Es ist ein&Anfang!",
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. C'est un début!" },
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. Progress!",
"Ein %yTriforce-Splitter%w! Du hast&%g{{current}}%w von %c{{required}}%w gefunden. Es geht voran!",
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. Ça avance!" },
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. Over half-way&there!",
"Ein %yTriforce-Splitter%w! Du hast&schon %g{{current}}%w von %c{{required}}%w gefunden. Schon&über die Hälfte!",
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. Il en reste un&peu moins que la moitié!" },
{ "You found a %yTriforce Piece%w!&%g{{current}}%w down, %c{{remaining}}%w to go. Almost done!",
"Ein %yTriforce-Splitter%w! Du hast&schon %g{{current}}%w von %c{{required}}%w gefunden. Fast&geschafft!",
"Vous trouvez un %yFragment de la&Triforce%w! Vous en avez %g{{current}}%w, il en&reste %c{{remaining}}%w à trouver. C'est presque&terminé!" },
{ "You completed the %yTriforce of&Courage%w! %gGG%w!",
"Das %yTriforce des Mutes%w! Du hast&alle Splitter gefunden. %gGut gemacht%w!",
"Vous avez complété la %yTriforce&du Courage%w! %gFélicitations%w!" },
{ "You found a spare %yTriforce Piece%w!&You only needed %c{{required}}%w, but you have %g{{current}}%w!",
"Ein übriger %yTriforce-Splitter%w! Du&hast nun %g{{current}}%w von %c{{required}}%w nötigen gefunden.",
"Vous avez trouvé un %yFragment de&Triforce%w en plus! Vous n'aviez besoin&que de %c{{required}}%w, mais vous en avez %g{{current}}%w en&tout!" },
};
CustomMessageManager* customMessageManager = CustomMessageManager::Instance;
customMessageManager->AddCustomMessageTable(Randomizer::triforcePieceMessageTableID);
for (unsigned int i = 0; i <= (NUM_TRIFORCE_PIECE_MESSAGES - 1); i++) {
customMessageManager->CreateMessage(Randomizer::triforcePieceMessageTableID, i, TriforcePieceMessages[i]);
}
}
CustomMessage Randomizer::GetTriforcePieceMessage() {
// Item is only given after the textbox, so reflect that inside the textbox.
uint16_t current = gSaveContext.triforcePiecesCollected + 1;
uint16_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
uint16_t remaining = required - current;
float percentageCollected = (float)current / (float)required;
uint8_t messageIndex;
if (percentageCollected <= 0.25) {
messageIndex = TH_MESSAGE_START;
} else if (percentageCollected <= 0.5) {
messageIndex = TH_MESSAGE_PROGRESS;
} else if (percentageCollected <= 0.75) {
messageIndex = TH_MESSAGE_HALFWAY;
} else if (percentageCollected < 1) {
messageIndex = TH_MESSAGE_ALMOSTDONE;
} else if (current == required) {
messageIndex = TH_MESSAGE_FINISHED;
} else {
messageIndex = TH_MESSAGE_SURPLUS;
}
CustomMessage messageEntry =
CustomMessageManager::Instance->RetrieveMessage(Randomizer::triforcePieceMessageTableID, messageIndex);
messageEntry.Replace("{{current}}", std::to_string(current), std::to_string(current), std::to_string(current));
messageEntry.Replace("{{remaining}}", std::to_string(remaining), std::to_string(remaining), std::to_string(remaining));
messageEntry.Replace("{{required}}", std::to_string(required), std::to_string(required), std::to_string(required));
return messageEntry;
}
void CreateNaviRandoMessages() { void CreateNaviRandoMessages() {
CustomMessage NaviMessages[NUM_NAVI_MESSAGES] = { CustomMessage NaviMessages[NUM_NAVI_MESSAGES] = {
@ -5988,6 +6106,7 @@ void Randomizer::CreateCustomMessages() {
}}; }};
CreateGetItemMessages(&getItemMessages); CreateGetItemMessages(&getItemMessages);
CreateRupeeMessages(); CreateRupeeMessages();
CreateTriforcePieceMessages();
CreateNaviRandoMessages(); CreateNaviRandoMessages();
CreateIceTrapRandoMessages(); CreateIceTrapRandoMessages();
CreateFireTempleGoronMessages(); CreateFireTempleGoronMessages();
@ -6098,6 +6217,7 @@ void InitRandoItemTable() {
GET_ITEM(RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_MAGIC_BEAN_PACK), GET_ITEM(RG_MAGIC_BEAN_PACK, OBJECT_GI_BEAN, GID_BEAN, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_MAGIC_BEAN_PACK),
GET_ITEM(RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, RG_TYCOON_WALLET), GET_ITEM(RG_TYCOON_WALLET, OBJECT_GI_PURSE, GID_WALLET_GIANT, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER, RG_TYCOON_WALLET),
GET_ITEM(RG_PROGRESSIVE_BOMBCHUS, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_PROGRESSIVE_BOMBCHUS), GET_ITEM(RG_PROGRESSIVE_BOMBCHUS, OBJECT_GI_BOMB_2, GID_BOMBCHU, 0x33, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_PROGRESSIVE_BOMBCHUS),
GET_ITEM(RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER, RG_TRIFORCE_PIECE),
}; };
ItemTableManager::Instance->AddItemTable(MOD_RANDOMIZER); ItemTableManager::Instance->AddItemTable(MOD_RANDOMIZER);
for (int i = 0; i < ARRAY_COUNT(extendedVanillaGetItemTable); i++) { for (int i = 0; i < ARRAY_COUNT(extendedVanillaGetItemTable); i++) {
@ -6113,6 +6233,8 @@ void InitRandoItemTable() {
randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey; randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey;
} else if (randoGetItemTable[i].itemId == RG_DOUBLE_DEFENSE) { } else if (randoGetItemTable[i].itemId == RG_DOUBLE_DEFENSE) {
randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawDoubleDefense; randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawDoubleDefense;
} else if (randoGetItemTable[i].itemId == RG_TRIFORCE_PIECE) {
randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawTriforcePiece;
} }
ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, randoGetItemTable[i].itemId, randoGetItemTable[i]); ItemTableManager::Instance->AddItemEntry(MOD_RANDOMIZER, randoGetItemTable[i].itemId, randoGetItemTable[i]);
} }

View file

@ -14,6 +14,7 @@
#include "soh/Enhancements/item-tables/ItemTableTypes.h" #include "soh/Enhancements/item-tables/ItemTableTypes.h"
#define MAX_SEED_STRING_SIZE 1024 #define MAX_SEED_STRING_SIZE 1024
#define NUM_TRIFORCE_PIECE_MESSAGES 6
#define NUM_NAVI_MESSAGES 19 #define NUM_NAVI_MESSAGES 19
#define NUM_ICE_TRAP_MESSAGES 23 #define NUM_ICE_TRAP_MESSAGES 23
#define NUM_GORON_MESSAGES 9 #define NUM_GORON_MESSAGES 9
@ -48,6 +49,7 @@ class Randomizer {
static const std::string hintMessageTableID; static const std::string hintMessageTableID;
static const std::string merchantMessageTableID; static const std::string merchantMessageTableID;
static const std::string rupeeMessageTableID; static const std::string rupeeMessageTableID;
static const std::string triforcePieceMessageTableID;
static const std::string NaviRandoMessageTableID; static const std::string NaviRandoMessageTableID;
static const std::string IceTrapRandoMessageTableID; static const std::string IceTrapRandoMessageTableID;
static const std::string randoMiscHintsTableID; static const std::string randoMiscHintsTableID;
@ -102,6 +104,7 @@ class Randomizer {
CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry); CustomMessage GetMapGetItemMessageWithHint(GetItemEntry itemEntry);
static void CreateCustomMessages(); static void CreateCustomMessages();
static CustomMessage GetRupeeMessage(u16 rupeeTextId); static CustomMessage GetRupeeMessage(u16 rupeeTextId);
static CustomMessage GetTriforcePieceMessage();
bool CheckContainsVanillaItem(RandomizerCheck randoCheck); bool CheckContainsVanillaItem(RandomizerCheck randoCheck);
}; };

View file

@ -847,6 +847,7 @@ typedef enum {
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE, RC_ZR_NEAR_GROTTOS_GOSSIP_STONE,
RC_ZR_OPEN_GROTTO_GOSSIP_STONE, RC_ZR_OPEN_GROTTO_GOSSIP_STONE,
RC_GANONDORF_HINT, RC_GANONDORF_HINT,
RC_TRIFORCE_COMPLETED,
RC_MAX RC_MAX
} RandomizerCheck; } RandomizerCheck;
@ -1302,6 +1303,7 @@ typedef enum {
RG_BUY_RED_POTION_40, RG_BUY_RED_POTION_40,
RG_BUY_RED_POTION_50, RG_BUY_RED_POTION_50,
RG_TRIFORCE, RG_TRIFORCE,
RG_TRIFORCE_PIECE,
RG_HINT, RG_HINT,
RG_TYCOON_WALLET, RG_TYCOON_WALLET,
RG_MAX RG_MAX
@ -1453,6 +1455,9 @@ typedef enum {
RSK_ALL_LOCATIONS_REACHABLE, RSK_ALL_LOCATIONS_REACHABLE,
RSK_SHUFFLE_BOSS_ENTRANCES, RSK_SHUFFLE_BOSS_ENTRANCES,
RSK_SHUFFLE_100_GS_REWARD, RSK_SHUFFLE_100_GS_REWARD,
RSK_TRIFORCE_HUNT,
RSK_TRIFORCE_HUNT_PIECES_TOTAL,
RSK_TRIFORCE_HUNT_PIECES_REQUIRED,
RSK_MAX RSK_MAX
} RandomizerSettingKey; } RandomizerSettingKey;
@ -1613,6 +1618,7 @@ typedef enum {
RO_GANON_BOSS_KEY_LACS_DUNGEONS, RO_GANON_BOSS_KEY_LACS_DUNGEONS,
RO_GANON_BOSS_KEY_LACS_TOKENS, RO_GANON_BOSS_KEY_LACS_TOKENS,
RO_GANON_BOSS_KEY_KAK_TOKENS, RO_GANON_BOSS_KEY_KAK_TOKENS,
RO_GANON_BOSS_KEY_TRIFORCE_HUNT,
} RandoOptionGanonsBossKey; } RandoOptionGanonsBossKey;
// LACS Reward Options settings (Standard rewards, Greg as reward, Greg as wildcard) // LACS Reward Options settings (Standard rewards, Greg as reward, Greg as wildcard)
@ -1806,3 +1812,12 @@ typedef enum {
TRACKER_COMBO_BUTTON_D_LEFT, TRACKER_COMBO_BUTTON_D_LEFT,
TRACKER_COMBO_BUTTON_D_RIGHT, TRACKER_COMBO_BUTTON_D_RIGHT,
} TrackerComboButton; } TrackerComboButton;
typedef enum {
TH_MESSAGE_START,
TH_MESSAGE_PROGRESS,
TH_MESSAGE_HALFWAY,
TH_MESSAGE_ALMOSTDONE,
TH_MESSAGE_FINISHED,
TH_MESSAGE_SURPLUS,
} TriforceHuntMessages;

View file

@ -380,63 +380,63 @@ bool fortressFast;
bool fortressNormal; bool fortressNormal;
void LoadSettings() { void LoadSettings() {
//If in randomzer (n64ddFlag), then get the setting and check if in general we should be showing the settings //If in randomzer, then get the setting and check if in general we should be showing the settings
//If in vanilla, _try_ to show items that at least are needed for 100% //If in vanilla, _try_ to show items that at least are needed for 100%
showShops = gSaveContext.n64ddFlag ? ( showShops = IS_RANDO ? (
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_ZERO_ITEMS) OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_ZERO_ITEMS)
: false; : false;
showBeans = gSaveContext.n64ddFlag ? showBeans = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAGIC_BEANS) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAGIC_BEANS) == RO_GENERIC_YES
: true; : true;
showScrubs = gSaveContext.n64ddFlag ? showScrubs = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF
: false; : false;
showMerchants = gSaveContext.n64ddFlag ? showMerchants = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF
: true; : true;
showCows = gSaveContext.n64ddFlag ? showCows = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_COWS) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_COWS) == RO_GENERIC_YES
: false; : false;
showAdultTrade = gSaveContext.n64ddFlag ? showAdultTrade = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_YES
: true; : true;
showKokiriSword = gSaveContext.n64ddFlag ? showKokiriSword = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_KOKIRI_SWORD) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_KOKIRI_SWORD) == RO_GENERIC_YES
: true; : true;
showWeirdEgg = gSaveContext.n64ddFlag ? showWeirdEgg = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES
: true; : true;
showGerudoCard = gSaveContext.n64ddFlag ? showGerudoCard = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) == RO_GENERIC_YES
: true; : true;
showFrogSongRupees = gSaveContext.n64ddFlag ? showFrogSongRupees = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES
: false; : false;
showStartingMapsCompasses = gSaveContext.n64ddFlag ? showStartingMapsCompasses = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_MAPS_COMPASSES) != RO_DUNGEON_ITEM_LOC_VANILLA OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_MAPS_COMPASSES) != RO_DUNGEON_ITEM_LOC_VANILLA
: false; : false;
showKeysanity = gSaveContext.n64ddFlag ? showKeysanity = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA
: false; : false;
showBossKeysanity = gSaveContext.n64ddFlag ? showBossKeysanity = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BOSS_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BOSS_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA
: false; : false;
showGerudoFortressKeys = gSaveContext.n64ddFlag ? showGerudoFortressKeys = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA
: false; : false;
showGanonBossKey = gSaveContext.n64ddFlag ? showGanonBossKey = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_VANILLA OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_VANILLA
: false; : false;
showOcarinas = gSaveContext.n64ddFlag ? showOcarinas = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_OCARINA) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_OCARINA) == RO_GENERIC_YES
: false; : false;
show100SkullReward = gSaveContext.n64ddFlag ? show100SkullReward = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_100_GS_REWARD) == RO_GENERIC_YES OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_100_GS_REWARD) == RO_GENERIC_YES
: false; : false;
if (gSaveContext.n64ddFlag) { if (IS_RANDO) {
switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS)) { switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS)) {
case RO_TOKENSANITY_ALL: case RO_TOKENSANITY_ALL:
showOverworldTokens = true; showOverworldTokens = true;
@ -747,7 +747,7 @@ bool HasItemBeenCollected(RandomizerCheckObject obj) {
case SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER: case SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER:
// Gravedigger has a fix in place that means one of two save locations. Check both. // Gravedigger has a fix in place that means one of two save locations. Check both.
return (gSaveContext.itemGetInf[1] & 0x1000) || // vanilla flag return (gSaveContext.itemGetInf[1] & 0x1000) || // vanilla flag
((gSaveContext.n64ddFlag || CVarGetInteger("gGravediggingTourFix", 0)) && ((IS_RANDO || CVarGetInteger("gGravediggingTourFix", 0)) &&
gSaveContext.sceneFlags[scene].collect & (1 << flag)); // rando/fix flag gSaveContext.sceneFlags[scene].collect & (1 << flag)); // rando/fix flag
default: default:
return false; return false;
@ -831,7 +831,7 @@ void DrawLocation(RandomizerCheckObject rcObj, RandomizerCheckShow* thisCheckSta
case RCSHOW_SAVED: case RCSHOW_SAVED:
case RCSHOW_CHECKED: case RCSHOW_CHECKED:
case RCSHOW_SCUMMED: case RCSHOW_SCUMMED:
if (gSaveContext.n64ddFlag) if (IS_RANDO)
txt = OTRGlobals::Instance->gRandomizer txt = OTRGlobals::Instance->gRandomizer
->EnumToSpoilerfileGetName[gSaveContext.itemLocations[rcObj.rc].get.rgID][gSaveContext.language]; ->EnumToSpoilerfileGetName[gSaveContext.itemLocations[rcObj.rc].get.rgID][gSaveContext.language];
else if (gSaveContext.language == LANGUAGE_ENG) else if (gSaveContext.language == LANGUAGE_ENG)
@ -843,7 +843,7 @@ void DrawLocation(RandomizerCheckObject rcObj, RandomizerCheckShow* thisCheckSta
txt = "Skipped"; //TODO language txt = "Skipped"; //TODO language
break; break;
case RCSHOW_SEEN: case RCSHOW_SEEN:
if (gSaveContext.n64ddFlag) if (IS_RANDO)
txt = OTRGlobals::Instance->gRandomizer txt = OTRGlobals::Instance->gRandomizer
->EnumToSpoilerfileGetName[gSaveContext.itemLocations[rcObj.rc].get.fakeRgID][gSaveContext.language]; ->EnumToSpoilerfileGetName[gSaveContext.itemLocations[rcObj.rc].get.fakeRgID][gSaveContext.language];
else if (gSaveContext.language == LANGUAGE_ENG) else if (gSaveContext.language == LANGUAGE_ENG)

View file

@ -80,6 +80,10 @@ std::vector<ItemTrackerItem> gregItems = {
ITEM_TRACKER_ITEM(ITEM_RUPEE_GREEN, 0, DrawItem), ITEM_TRACKER_ITEM(ITEM_RUPEE_GREEN, 0, DrawItem),
}; };
std::vector<ItemTrackerItem> triforcePieces = {
ITEM_TRACKER_ITEM(RG_TRIFORCE_PIECE, 0, DrawItem),
};
std::vector<ItemTrackerDungeon> itemTrackerDungeonsWithMapsHorizontal = { std::vector<ItemTrackerDungeon> itemTrackerDungeonsWithMapsHorizontal = {
{ SCENE_DEKU_TREE, { ITEM_DUNGEON_MAP, ITEM_COMPASS } }, { SCENE_DEKU_TREE, { ITEM_DUNGEON_MAP, ITEM_COMPASS } },
{ SCENE_DODONGOS_CAVERN, { ITEM_DUNGEON_MAP, ITEM_COMPASS } }, { SCENE_DODONGOS_CAVERN, { ITEM_DUNGEON_MAP, ITEM_COMPASS } },
@ -243,6 +247,11 @@ typedef enum {
KEYS_CURRENT_MAX KEYS_CURRENT_MAX
} ItemTrackerKeysNumberOption; } ItemTrackerKeysNumberOption;
typedef enum {
TRIFORCE_PIECE_COLLECTED_REQUIRED,
TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX
} ItemTrackerTriforcePieceNumberOption;
typedef enum { typedef enum {
SECTION_DISPLAY_HIDDEN, SECTION_DISPLAY_HIDDEN,
SECTION_DISPLAY_MAIN_WINDOW, SECTION_DISPLAY_MAIN_WINDOW,
@ -488,6 +497,37 @@ void DrawItemCount(ItemTrackerItem item) {
ImGui::PushStyleColor(ImGuiCol_Text, maxColor); ImGui::PushStyleColor(ImGuiCol_Text, maxColor);
ImGui::Text("%s", maxString.c_str()); ImGui::Text("%s", maxString.c_str());
ImGui::PopStyleColor(); ImGui::PopStyleColor();
} else if (item.id == RG_TRIFORCE_PIECE && gSaveContext.n64ddFlag &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT) && IsValidSaveFile()) {
std::string currentString = "";
std::string requiredString = "";
std::string maxString = "";
uint8_t piecesRequired = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
uint8_t piecesTotal = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_TOTAL);
ImU32 currentColor = gSaveContext.triforcePiecesCollected >= piecesRequired ? IM_COL_GREEN : IM_COL_WHITE;
ImU32 maxColor = IM_COL_GREEN;
int32_t trackerTriforcePieceNumberDisplayMode = CVarGetInteger("gItemTrackerTriforcePieceTrack", TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX);
currentString += std::to_string(gSaveContext.triforcePiecesCollected);
currentString += "/";
// gItemTrackerTriforcePieceTrack
if (trackerTriforcePieceNumberDisplayMode == TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX) {
currentString += std::to_string(piecesRequired);
currentString += "/";
maxString += std::to_string(piecesTotal);
} else if (trackerTriforcePieceNumberDisplayMode == TRIFORCE_PIECE_COLLECTED_REQUIRED) {
maxString += std::to_string(piecesRequired);
}
ImGui::SetCursorScreenPos(
ImVec2(p.x + (iconSize / 2) - (ImGui::CalcTextSize((currentString + maxString).c_str()).x / 2), p.y - 14));
ImGui::PushStyleColor(ImGuiCol_Text, currentColor);
ImGui::Text(currentString.c_str());
ImGui::PopStyleColor();
ImGui::SameLine(0, 0.0f);
ImGui::PushStyleColor(ImGuiCol_Text, maxColor);
ImGui::Text(maxString.c_str());
ImGui::PopStyleColor();
} else { } else {
ImGui::SetCursorScreenPos(ImVec2(p.x, p.y - 14)); ImGui::SetCursorScreenPos(ImVec2(p.x, p.y - 14));
ImGui::Text(""); ImGui::Text("");
@ -520,9 +560,11 @@ void DrawQuest(ItemTrackerItem item) {
}; };
void DrawItem(ItemTrackerItem item) { void DrawItem(ItemTrackerItem item) {
uint32_t actualItemId = INV_CONTENT(item.id); uint32_t actualItemId = INV_CONTENT(item.id);
int iconSize = CVarGetInteger("gItemTrackerIconSize", 36); int iconSize = CVarGetInteger("gItemTrackerIconSize", 36);
bool hasItem = actualItemId != ITEM_NONE; bool hasItem = actualItemId != ITEM_NONE;
std::string itemName = "";
if (item.id == ITEM_NONE) { if (item.id == ITEM_NONE) {
return; return;
@ -562,6 +604,11 @@ void DrawItem(ItemTrackerItem item) {
actualItemId = item.id; actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_GREG_FOUND); hasItem = Flags_GetRandomizerInf(RAND_INF_GREG_FOUND);
break; break;
case RG_TRIFORCE_PIECE:
actualItemId = item.id;
hasItem = gSaveContext.n64ddFlag && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT);
itemName = "Triforce Piece";
break;
} }
if (hasItem && item.id != actualItemId && actualItemTrackerItemMap.find(actualItemId) != actualItemTrackerItemMap.end()) { if (hasItem && item.id != actualItemId && actualItemTrackerItemMap.find(actualItemId) != actualItemTrackerItemMap.end()) {
@ -569,13 +616,18 @@ void DrawItem(ItemTrackerItem item) {
} }
ImGui::BeginGroup(); ImGui::BeginGroup();
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded), ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded),
ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1)); ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1));
DrawItemCount(item); DrawItemCount(item);
ImGui::EndGroup(); ImGui::EndGroup();
UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(item.id)); if (itemName == "") {
itemName = SohUtils::GetItemName(item.id);
}
UIWidgets::SetLastItemHoverText(itemName);
} }
void DrawBottle(ItemTrackerItem item) { void DrawBottle(ItemTrackerItem item) {
@ -891,6 +943,19 @@ void UpdateVectors() {
mainWindowItems.insert(mainWindowItems.end(), gregItems.begin(), gregItems.end()); mainWindowItems.insert(mainWindowItems.end(), gregItems.begin(), gregItems.end());
} }
// If we're adding triforce pieces to the main window
if (CVarGetInteger("gItemTrackerTriforcePiecesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) {
// If Greg isn't on the main window, add empty items to place the triforce pieces on a new row.
if (CVarGetInteger("gItemTrackerGregDisplayType", SECTION_DISPLAY_EXTENDED_HIDDEN) != SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) {
while (mainWindowItems.size() % 6) {
mainWindowItems.push_back(ITEM_TRACKER_ITEM(ITEM_NONE, 0, DrawItem));
}
}
// Add triforce pieces
mainWindowItems.insert(mainWindowItems.end(), triforcePieces.begin(), triforcePieces.end());
}
shouldUpdateVectors = false; shouldUpdateVectors = false;
} }
@ -914,6 +979,7 @@ void ItemTrackerWindow::DrawElement() {
(CVarGetInteger("gItemTrackerSongsDisplayType", SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_MAIN_WINDOW) || (CVarGetInteger("gItemTrackerSongsDisplayType", SECTION_DISPLAY_MAIN_WINDOW) == SECTION_DISPLAY_MAIN_WINDOW) ||
(CVarGetInteger("gItemTrackerDungeonItemsDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) || (CVarGetInteger("gItemTrackerDungeonItemsDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) ||
(CVarGetInteger("gItemTrackerGregDisplayType", SECTION_DISPLAY_EXTENDED_HIDDEN) == SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) || (CVarGetInteger("gItemTrackerGregDisplayType", SECTION_DISPLAY_EXTENDED_HIDDEN) == SECTION_DISPLAY_EXTENDED_MAIN_WINDOW) ||
(CVarGetInteger("gItemTrackerTriforcePiecesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) ||
(CVarGetInteger("gItemTrackerNotesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) (CVarGetInteger("gItemTrackerNotesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW)
) { ) {
BeginFloatingWindows("Item Tracker##main window"); BeginFloatingWindows("Item Tracker##main window");
@ -984,6 +1050,12 @@ void ItemTrackerWindow::DrawElement() {
EndFloatingWindows(); EndFloatingWindows();
} }
if (CVarGetInteger("gItemTrackerTriforcePiecesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE) {
BeginFloatingWindows("Triforce Piece Tracker");
DrawItemsInRows(triforcePieces);
EndFloatingWindows();
}
if (CVarGetInteger("gItemTrackerNotesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE && CVarGetInteger("gItemTrackerDisplayType", TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { if (CVarGetInteger("gItemTrackerNotesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_SEPARATE && CVarGetInteger("gItemTrackerDisplayType", TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) {
ImGui::SetNextWindowSize(ImVec2(400,300), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(400,300), ImGuiCond_FirstUseEver);
BeginFloatingWindows("Personal Notes", ImGuiWindowFlags_NoFocusOnAppearing); BeginFloatingWindows("Personal Notes", ImGuiWindowFlags_NoFocusOnAppearing);
@ -995,6 +1067,7 @@ void ItemTrackerWindow::DrawElement() {
static const char* itemTrackerCapacityTrackOptions[5] = { "No Numbers", "Current Capacity", "Current Ammo", "Current Capacity / Max Capacity", "Current Ammo / Current Capacity" }; static const char* itemTrackerCapacityTrackOptions[5] = { "No Numbers", "Current Capacity", "Current Ammo", "Current Capacity / Max Capacity", "Current Ammo / Current Capacity" };
static const char* itemTrackerKeyTrackOptions[3] = { "Collected / Max", "Current / Collected / Max", "Current / Max" }; static const char* itemTrackerKeyTrackOptions[3] = { "Collected / Max", "Current / Collected / Max", "Current / Max" };
static const char* itemTrackerTriforcePieceTrackOptions[2] = { "Collected / Required", "Collected / Required / Max" };
static const char* windowTypes[2] = { "Floating", "Window" }; static const char* windowTypes[2] = { "Floating", "Window" };
static const char* displayModes[2] = { "Always", "Combo Button Hold" }; static const char* displayModes[2] = { "Always", "Combo Button Hold" };
static const char* buttons[14] = { "A", "B", "C-Up", "C-Down", "C-Left", "C-Right", "L", "Z", "R", "Start", "D-Up", "D-Down", "D-Left", "D-Right" }; static const char* buttons[14] = { "A", "B", "C-Up", "C-Down", "C-Left", "C-Right", "L", "Z", "R", "Start", "D-Up", "D-Down", "D-Left", "D-Right" };
@ -1002,7 +1075,7 @@ static const char* displayTypes[3] = { "Hidden", "Main Window", "Separate" };
static const char* extendedDisplayTypes[4] = { "Hidden", "Main Window", "Misc Window", "Separate" }; static const char* extendedDisplayTypes[4] = { "Hidden", "Main Window", "Misc Window", "Separate" };
void ItemTrackerSettingsWindow::DrawElement() { void ItemTrackerSettingsWindow::DrawElement() {
ImGui::SetNextWindowSize(ImVec2(600,375), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(733, 472), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("Item Tracker Settings", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { if (!ImGui::Begin("Item Tracker Settings", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) {
ImGui::End(); ImGui::End();
@ -1055,6 +1128,8 @@ void ItemTrackerSettingsWindow::DrawElement() {
UIWidgets::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gItemTrackerIconSize", 25, 128, "", 36); UIWidgets::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gItemTrackerIconSize", 25, 128, "", 36);
UIWidgets::EnhancementSliderInt("Icon margins : %dpx", "##ITEMTRACKERSPACING", "gItemTrackerIconSpacing", -5, 50, "", 12); UIWidgets::EnhancementSliderInt("Icon margins : %dpx", "##ITEMTRACKERSPACING", "gItemTrackerIconSpacing", -5, 50, "", 12);
UIWidgets::Spacer(0);
ImGui::Text("Ammo/Capacity Tracking"); ImGui::Text("Ammo/Capacity Tracking");
UIWidgets::EnhancementCombobox("gItemTrackerCapacityTrack", itemTrackerCapacityTrackOptions, ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY); UIWidgets::EnhancementCombobox("gItemTrackerCapacityTrack", itemTrackerCapacityTrackOptions, ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY);
UIWidgets::InsertHelpHoverText("Customize what the numbers under each item are tracking." UIWidgets::InsertHelpHoverText("Customize what the numbers under each item are tracking."
@ -1064,10 +1139,19 @@ void ItemTrackerSettingsWindow::DrawElement() {
shouldUpdateVectors = true; shouldUpdateVectors = true;
} }
} }
UIWidgets::Spacer(0);
ImGui::Text("Key Count Tracking"); ImGui::Text("Key Count Tracking");
UIWidgets::EnhancementCombobox("gItemTrackerKeyTrack", itemTrackerKeyTrackOptions, KEYS_COLLECTED_MAX); UIWidgets::EnhancementCombobox("gItemTrackerKeyTrack", itemTrackerKeyTrackOptions, KEYS_COLLECTED_MAX);
UIWidgets::InsertHelpHoverText("Customize what numbers are shown for key tracking."); UIWidgets::InsertHelpHoverText("Customize what numbers are shown for key tracking.");
UIWidgets::Spacer(0);
ImGui::Text("Triforce Piece Count Tracking");
UIWidgets::EnhancementCombobox("gItemTrackerTriforcePieceTrack", itemTrackerTriforcePieceTrackOptions, TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX);
UIWidgets::InsertHelpHoverText("Customize what numbers are shown for triforce piece tracking.");
ImGui::TableNextColumn(); ImGui::TableNextColumn();
if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Inventory", "gItemTrackerInventoryItemsDisplayType", displayTypes, SECTION_DISPLAY_MAIN_WINDOW)) { if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Inventory", "gItemTrackerInventoryItemsDisplayType", displayTypes, SECTION_DISPLAY_MAIN_WINDOW)) {
@ -1107,6 +1191,10 @@ void ItemTrackerSettingsWindow::DrawElement() {
shouldUpdateVectors = true; shouldUpdateVectors = true;
} }
if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Triforce Pieces", "gItemTrackerTriforcePiecesDisplayType", displayTypes, SECTION_DISPLAY_HIDDEN)) {
shouldUpdateVectors = true;
}
if (CVarGetInteger("gItemTrackerDisplayType", TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) { if (CVarGetInteger("gItemTrackerDisplayType", TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) {
if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Personal notes", "gItemTrackerNotesDisplayType", displayTypes, SECTION_DISPLAY_HIDDEN)) { if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Personal notes", "gItemTrackerNotesDisplayType", displayTypes, SECTION_DISPLAY_HIDDEN)) {
shouldUpdateVectors = true; shouldUpdateVectors = true;

View file

@ -436,5 +436,8 @@ extern "C" void Randomizer_InitSaveFile() {
gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth gSaveContext.itemGetInf[3] |= 0x8000; // Obtained Mask of Truth
} }
// Reset triforce pieces collected
gSaveContext.triforcePiecesCollected = 0;
SetStartingItems(); SetStartingItems();
} }

View file

@ -722,22 +722,22 @@ void RegisterOnUpdateMainMenuSelection() {
if (!CVarGetInteger("gA11yTTS", 0)) return; if (!CVarGetInteger("gA11yTTS", 0)) return;
switch (questIndex) { switch (questIndex) {
case FS_QUEST_NORMAL: { case QUEST_NORMAL: {
auto translation = GetParameritizedText("quest_sel_vanilla", TEXT_BANK_FILECHOOSE, nullptr); auto translation = GetParameritizedText("quest_sel_vanilla", TEXT_BANK_FILECHOOSE, nullptr);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
break; break;
} }
case FS_QUEST_MASTER: { case QUEST_MASTER: {
auto translation = GetParameritizedText("quest_sel_mq", TEXT_BANK_FILECHOOSE, nullptr); auto translation = GetParameritizedText("quest_sel_mq", TEXT_BANK_FILECHOOSE, nullptr);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
break; break;
} }
case FS_QUEST_RANDOMIZER: { case QUEST_RANDOMIZER: {
auto translation = GetParameritizedText("quest_sel_randomizer", TEXT_BANK_FILECHOOSE, nullptr); auto translation = GetParameritizedText("quest_sel_randomizer", TEXT_BANK_FILECHOOSE, nullptr);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
break; break;
} }
case FS_QUEST_BOSSRUSH: { case QUEST_BOSSRUSH: {
auto translation = GetParameritizedText("quest_sel_boss_rush", TEXT_BANK_FILECHOOSE, nullptr); auto translation = GetParameritizedText("quest_sel_boss_rush", TEXT_BANK_FILECHOOSE, nullptr);
SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
break; break;

View file

@ -1110,11 +1110,11 @@ uint32_t IsSceneMasterQuest(s16 sceneNum) {
if (OTRGlobals::Instance->HasMasterQuest()) { if (OTRGlobals::Instance->HasMasterQuest()) {
if (!OTRGlobals::Instance->HasOriginal()) { if (!OTRGlobals::Instance->HasOriginal()) {
value = 1; value = 1;
} else if (gSaveContext.isMasterQuest) { } else if (IS_MASTER_QUEST) {
value = 1; value = 1;
} else { } else {
value = 0; value = 0;
if (gSaveContext.n64ddFlag && if (IS_RANDO &&
!OTRGlobals::Instance->gRandomizer->masterQuestDungeons.empty() && !OTRGlobals::Instance->gRandomizer->masterQuestDungeons.empty() &&
OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(sceneNum)) { OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(sceneNum)) {
value = 1; value = 1;
@ -1966,7 +1966,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
const int maxBufferSize = sizeof(font->msgBuf); const int maxBufferSize = sizeof(font->msgBuf);
CustomMessage messageEntry; CustomMessage messageEntry;
s16 actorParams = 0; s16 actorParams = 0;
if (gSaveContext.n64ddFlag) { if (IS_RANDO) {
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) { if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) {
if (player->getItemEntry.getItemId == RG_ICE_TRAP) { if (player->getItemEntry.getItemId == RG_ICE_TRAP) {
@ -1975,6 +1975,8 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
if (CVarGetInteger("gLetItSnow", 0)) { if (CVarGetInteger("gLetItSnow", 0)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, NUM_ICE_TRAP_MESSAGES + 1); messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, NUM_ICE_TRAP_MESSAGES + 1);
} }
} else if (player->getItemEntry.getItemId == RG_TRIFORCE_PIECE) {
messageEntry = Randomizer::GetTriforcePieceMessage();
} else { } else {
messageEntry = Randomizer_GetCustomGetItemMessage(player); messageEntry = Randomizer_GetCustomGetItemMessage(player);
} }
@ -2129,14 +2131,14 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
// RANDOTODO: Implement a way to determine if an item came from a skulltula and // RANDOTODO: Implement a way to determine if an item came from a skulltula and
// inject the auto-dismiss control code if it did. // inject the auto-dismiss control code if it did.
if (CVarGetInteger("gSkulltulaFreeze", 0) != 0 && if (CVarGetInteger("gSkulltulaFreeze", 0) != 0 &&
!(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF)) { !(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_TOKENS) != RO_TOKENSANITY_OFF)) {
textId = TEXT_GS_NO_FREEZE; textId = TEXT_GS_NO_FREEZE;
} else { } else {
textId = TEXT_GS_FREEZE; textId = TEXT_GS_FREEZE;
} }
// In vanilla, GS token count is incremented prior to the text box displaying // In vanilla, GS token count is incremented prior to the text box displaying
// In rando we need to bump the token count by one to show the correct count // In rando we need to bump the token count by one to show the correct count
s16 gsCount = gSaveContext.inventory.gsTokens + (gSaveContext.n64ddFlag ? 1 : 0); s16 gsCount = gSaveContext.inventory.gsTokens + (IS_RANDO ? 1 : 0);
messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId); messageEntry = CustomMessageManager::Instance->RetrieveMessage(customMessageTableID, textId);
messageEntry.Replace("{{gsCount}}", std::to_string(gsCount)); messageEntry.Replace("{{gsCount}}", std::to_string(gsCount));
} }

View file

@ -136,6 +136,8 @@ void SaveManager::LoadRandomizerVersion1() {
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems); SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount);
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer; std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
@ -251,6 +253,8 @@ void SaveManager::LoadRandomizerVersion2() {
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems); SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount); SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount);
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer; std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
@ -282,7 +286,7 @@ void SaveManager::LoadRandomizerVersion2() {
void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool fullSave) { void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool fullSave) {
if(!saveContext->n64ddFlag) return; if(saveContext->questId != QUEST_RANDOMIZER) return;
SaveManager::Instance->SaveArray("itemLocations", RC_MAX, [&](size_t i) { SaveManager::Instance->SaveArray("itemLocations", RC_MAX, [&](size_t i) {
SaveManager::Instance->SaveStruct("", [&]() { SaveManager::Instance->SaveStruct("", [&]() {
@ -338,6 +342,8 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
SaveManager::Instance->SaveData("adultTradeItems", saveContext->adultTradeItems); SaveManager::Instance->SaveData("adultTradeItems", saveContext->adultTradeItems);
SaveManager::Instance->SaveData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->pendingIceTrapCount); SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->pendingIceTrapCount);
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer; std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
@ -450,12 +456,12 @@ void SaveManager::InitMeta(int fileNum) {
fileMetaInfo[fileNum].seedHash[i] = gSaveContext.seedIcons[i]; fileMetaInfo[fileNum].seedHash[i] = gSaveContext.seedIcons[i];
} }
fileMetaInfo[fileNum].randoSave = gSaveContext.n64ddFlag; fileMetaInfo[fileNum].randoSave = IS_RANDO;
// If the file is marked as a Master Quest file or if we're randomized and have at least one master quest dungeon, we need the mq otr. // If the file is marked as a Master Quest file or if we're randomized and have at least one master quest dungeon, we need the mq otr.
fileMetaInfo[fileNum].requiresMasterQuest = gSaveContext.isMasterQuest > 0 || (gSaveContext.n64ddFlag && gSaveContext.mqDungeonCount > 0); fileMetaInfo[fileNum].requiresMasterQuest = IS_MASTER_QUEST || (IS_RANDO && gSaveContext.mqDungeonCount > 0);
// If the file is not marked as Master Quest, it could still theoretically be a rando save with all 12 MQ dungeons, in which case // If the file is not marked as Master Quest, it could still theoretically be a rando save with all 12 MQ dungeons, in which case
// we don't actually require a vanilla OTR. // we don't actually require a vanilla OTR.
fileMetaInfo[fileNum].requiresOriginal = !gSaveContext.isMasterQuest && (!gSaveContext.n64ddFlag || gSaveContext.mqDungeonCount < 12); fileMetaInfo[fileNum].requiresOriginal = !IS_MASTER_QUEST && (!IS_RANDO || gSaveContext.mqDungeonCount < 12);
fileMetaInfo[fileNum].buildVersionMajor = gSaveContext.sohStats.buildVersionMajor; fileMetaInfo[fileNum].buildVersionMajor = gSaveContext.sohStats.buildVersionMajor;
fileMetaInfo[fileNum].buildVersionMinor = gSaveContext.sohStats.buildVersionMinor; fileMetaInfo[fileNum].buildVersionMinor = gSaveContext.sohStats.buildVersionMinor;
@ -611,7 +617,7 @@ void SaveManager::InitFileNormal() {
gSaveContext.pendingSale = ITEM_NONE; gSaveContext.pendingSale = ITEM_NONE;
gSaveContext.pendingSaleMod = MOD_NONE; gSaveContext.pendingSaleMod = MOD_NONE;
if (gSaveContext.isBossRush) { if (IS_BOSS_RUSH) {
BossRush_InitSave(); BossRush_InitSave();
} }
@ -891,8 +897,8 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se
nlohmann::json& sectionBlock = saveBlock["sections"][saveFuncInfo.name]; nlohmann::json& sectionBlock = saveBlock["sections"][saveFuncInfo.name];
sectionBlock["version"] = sectionHandlerPair.second.version; sectionBlock["version"] = sectionHandlerPair.second.version;
// If any save file is loaded for medatata, or a spoiler log is loaded (not sure which at this point), there is still data in the "randomizer" section // If any save file is loaded for medatata, or a spoiler log is loaded (not sure which at this point), there is still data in the "randomizer" section
// This clears the randomizer data block if and only if the section being called is "randomizer" and n64ddFlag is false. // This clears the randomizer data block if and only if the section being called is "randomizer" and the current save file is not a randomizer save file.
if (sectionHandlerPair.second.name == "randomizer" && !gSaveContext.n64ddFlag) { if (sectionHandlerPair.second.name == "randomizer" && !IS_RANDO) {
sectionBlock["data"] = nlohmann::json::object(); sectionBlock["data"] = nlohmann::json::object();
continue; continue;
} }
@ -1113,7 +1119,11 @@ void SaveManager::LoadBaseVersion1() {
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) { SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.playerName[i]); SaveManager::Instance->LoadData("", gSaveContext.playerName[i]);
}); });
SaveManager::Instance->LoadData("n64ddFlag", gSaveContext.n64ddFlag); int isRando = 0;
SaveManager::Instance->LoadData("n64ddFlag", isRando);
if (isRando) {
gSaveContext.questId = QUEST_RANDOMIZER;
}
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity); SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
SaveManager::Instance->LoadData("health", gSaveContext.health); SaveManager::Instance->LoadData("health", gSaveContext.health);
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel); SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
@ -1254,7 +1264,11 @@ void SaveManager::LoadBaseVersion2() {
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) { SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.playerName[i]); SaveManager::Instance->LoadData("", gSaveContext.playerName[i]);
}); });
SaveManager::Instance->LoadData("n64ddFlag", gSaveContext.n64ddFlag); int isRando = 0;
SaveManager::Instance->LoadData("n64ddFlag", isRando);
if (isRando) {
gSaveContext.questId = QUEST_RANDOMIZER;
}
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity); SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
SaveManager::Instance->LoadData("health", gSaveContext.health); SaveManager::Instance->LoadData("health", gSaveContext.health);
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel); SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
@ -1420,7 +1434,11 @@ void SaveManager::LoadBaseVersion2() {
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) { SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]); SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
}); });
SaveManager::Instance->LoadData("isMasterQuest", gSaveContext.isMasterQuest); int isMQ = 0;
SaveManager::Instance->LoadData("isMasterQuest", isMQ);
if (isMQ) {
gSaveContext.questId = QUEST_MASTER;
}
// Workaround for breaking save compatibility from 5.0.2 -> 5.1.0 in commit d7c35221421bf712b5ead56a360f81f624aca4bc // Workaround for breaking save compatibility from 5.0.2 -> 5.1.0 in commit d7c35221421bf712b5ead56a360f81f624aca4bc
if (!gSaveContext.isMagicAcquired) { if (!gSaveContext.isMagicAcquired) {
@ -1462,7 +1480,11 @@ void SaveManager::LoadBaseVersion3() {
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) { SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.playerName[i]); SaveManager::Instance->LoadData("", gSaveContext.playerName[i]);
}); });
SaveManager::Instance->LoadData("n64ddFlag", gSaveContext.n64ddFlag); int isRando = 0;
SaveManager::Instance->LoadData("n64ddFlag", isRando);
if (isRando) {
gSaveContext.questId = QUEST_RANDOMIZER;
}
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity); SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
SaveManager::Instance->LoadData("health", gSaveContext.health); SaveManager::Instance->LoadData("health", gSaveContext.health);
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel); SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
@ -1650,7 +1672,11 @@ void SaveManager::LoadBaseVersion3() {
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) { SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]); SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
}); });
SaveManager::Instance->LoadData("isMasterQuest", gSaveContext.isMasterQuest); int isMQ = 0;
SaveManager::Instance->LoadData("isMasterQuest", isMQ);
if (isMQ) {
gSaveContext.questId = QUEST_MASTER;
}
SaveManager::Instance->LoadStruct("backupFW", []() { SaveManager::Instance->LoadStruct("backupFW", []() {
SaveManager::Instance->LoadStruct("pos", []() { SaveManager::Instance->LoadStruct("pos", []() {
SaveManager::Instance->LoadData("x", gSaveContext.backupFW.pos.x); SaveManager::Instance->LoadData("x", gSaveContext.backupFW.pos.x);
@ -1680,7 +1706,11 @@ void SaveManager::LoadBaseVersion4() {
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) { SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.playerName[i]); SaveManager::Instance->LoadData("", gSaveContext.playerName[i]);
}); });
SaveManager::Instance->LoadData("n64ddFlag", gSaveContext.n64ddFlag); int isRando = 0;
SaveManager::Instance->LoadData("n64ddFlag", isRando);
if (isRando) {
gSaveContext.questId = QUEST_RANDOMIZER;
}
SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity); SaveManager::Instance->LoadData("healthCapacity", gSaveContext.healthCapacity);
SaveManager::Instance->LoadData("health", gSaveContext.health); SaveManager::Instance->LoadData("health", gSaveContext.health);
SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel); SaveManager::Instance->LoadData("magicLevel", gSaveContext.magicLevel);
@ -1823,7 +1853,11 @@ void SaveManager::LoadBaseVersion4() {
SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) { SaveManager::Instance->LoadArray("randomizerInf", ARRAY_COUNT(gSaveContext.randomizerInf), [](size_t i) {
SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]); SaveManager::Instance->LoadData("", gSaveContext.randomizerInf[i]);
}); });
SaveManager::Instance->LoadData("isMasterQuest", gSaveContext.isMasterQuest); int isMQ = 0;
SaveManager::Instance->LoadData("isMasterQuest", isMQ);
if (isMQ) {
gSaveContext.questId = QUEST_MASTER;
}
SaveManager::Instance->LoadStruct("backupFW", []() { SaveManager::Instance->LoadStruct("backupFW", []() {
SaveManager::Instance->LoadStruct("pos", []() { SaveManager::Instance->LoadStruct("pos", []() {
SaveManager::Instance->LoadData("x", gSaveContext.backupFW.pos.x); SaveManager::Instance->LoadData("x", gSaveContext.backupFW.pos.x);
@ -1853,7 +1887,7 @@ void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSav
SaveManager::Instance->SaveArray("playerName", ARRAY_COUNT(saveContext->playerName), [&](size_t i) { SaveManager::Instance->SaveArray("playerName", ARRAY_COUNT(saveContext->playerName), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->playerName[i]); SaveManager::Instance->SaveData("", saveContext->playerName[i]);
}); });
SaveManager::Instance->SaveData("n64ddFlag", saveContext->n64ddFlag); SaveManager::Instance->SaveData("n64ddFlag", saveContext->questId == QUEST_RANDOMIZER);
SaveManager::Instance->SaveData("healthCapacity", saveContext->healthCapacity); SaveManager::Instance->SaveData("healthCapacity", saveContext->healthCapacity);
SaveManager::Instance->SaveData("health", saveContext->health); SaveManager::Instance->SaveData("health", saveContext->health);
SaveManager::Instance->SaveData("magicLevel", saveContext->magicLevel); SaveManager::Instance->SaveData("magicLevel", saveContext->magicLevel);
@ -1992,7 +2026,7 @@ void SaveManager::SaveBase(SaveContext* saveContext, int sectionID, bool fullSav
SaveManager::Instance->SaveArray("randomizerInf", ARRAY_COUNT(saveContext->randomizerInf), [&](size_t i) { SaveManager::Instance->SaveArray("randomizerInf", ARRAY_COUNT(saveContext->randomizerInf), [&](size_t i) {
SaveManager::Instance->SaveData("", saveContext->randomizerInf[i]); SaveManager::Instance->SaveData("", saveContext->randomizerInf[i]);
}); });
SaveManager::Instance->SaveData("isMasterQuest", saveContext->isMasterQuest); SaveManager::Instance->SaveData("isMasterQuest", saveContext->questId == QUEST_MASTER);
SaveManager::Instance->SaveStruct("backupFW", [&]() { SaveManager::Instance->SaveStruct("backupFW", [&]() {
SaveManager::Instance->SaveStruct("pos", [&]() { SaveManager::Instance->SaveStruct("pos", [&]() {
SaveManager::Instance->SaveData("x", saveContext->backupFW.pos.x); SaveManager::Instance->SaveData("x", saveContext->backupFW.pos.x);
@ -2149,7 +2183,7 @@ void SaveManager::DeleteZeldaFile(int fileNum) {
} }
bool SaveManager::IsRandoFile() { bool SaveManager::IsRandoFile() {
return gSaveContext.n64ddFlag != 0 ? true : false; return IS_RANDO;
} }
// Functionality required to convert old saves into versioned saves // Functionality required to convert old saves into versioned saves

View file

@ -527,7 +527,7 @@ void DrawEnhancementsMenu() {
UIWidgets::PaddedEnhancementCheckbox("Better Owl", "gBetterOwl", true, false); UIWidgets::PaddedEnhancementCheckbox("Better Owl", "gBetterOwl", true, false);
UIWidgets::Tooltip("The default response to Kaepora Gaebora is always that you understood what he said"); UIWidgets::Tooltip("The default response to Kaepora Gaebora is always that you understood what he said");
UIWidgets::PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false); UIWidgets::PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false);
bool forceSkipScarecrow = gSaveContext.n64ddFlag && bool forceSkipScarecrow = IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_SCARECROWS_SONG); OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_SCARECROWS_SONG);
static const char* forceSkipScarecrowText = static const char* forceSkipScarecrowText =
"This setting is forcefully enabled because a savefile\nwith \"Skip Scarecrow Song\" is loaded"; "This setting is forcefully enabled because a savefile\nwith \"Skip Scarecrow Song\" is loaded";
@ -647,7 +647,7 @@ void DrawEnhancementsMenu() {
UIWidgets::Tooltip("Respawn with full health instead of 3 Hearts"); UIWidgets::Tooltip("Respawn with full health instead of 3 Hearts");
UIWidgets::PaddedEnhancementCheckbox("No Random Drops", "gNoRandomDrops", true, false); UIWidgets::PaddedEnhancementCheckbox("No Random Drops", "gNoRandomDrops", true, false);
UIWidgets::Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses"); UIWidgets::Tooltip("Disables random drops, except from the Goron Pot, Dampe, and bosses");
bool forceEnableBombchuDrops = gSaveContext.n64ddFlag && bool forceEnableBombchuDrops = IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1; OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1;
static const char* forceEnableBombchuDropsText = static const char* forceEnableBombchuDropsText =
"This setting is forcefully enabled because a savefile\nwith \"Enable Bombchu Drops\" is loaded."; "This setting is forcefully enabled because a savefile\nwith \"Enable Bombchu Drops\" is loaded.";
@ -851,7 +851,7 @@ void DrawEnhancementsMenu() {
UIWidgets::Tooltip("Removes the input requirement on textboxes after defeating Ganon, allowing Credits sequence to continue to progress"); UIWidgets::Tooltip("Removes the input requirement on textboxes after defeating Ganon, allowing Credits sequence to continue to progress");
// Blue Fire Arrows // Blue Fire Arrows
bool forceEnableBlueFireArrows = gSaveContext.n64ddFlag && bool forceEnableBlueFireArrows = IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BLUE_FIRE_ARROWS); OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BLUE_FIRE_ARROWS);
static const char* forceEnableBlueFireArrowsText = static const char* forceEnableBlueFireArrowsText =
"This setting is forcefully enabled because a savefile\nwith \"Blue Fire Arrows\" is loaded."; "This setting is forcefully enabled because a savefile\nwith \"Blue Fire Arrows\" is loaded.";
@ -860,7 +860,7 @@ void DrawEnhancementsMenu() {
UIWidgets::Tooltip("Allows Ice Arrows to melt red ice.\nMay require a room reload if toggled during gameplay."); UIWidgets::Tooltip("Allows Ice Arrows to melt red ice.\nMay require a room reload if toggled during gameplay.");
// Sunlight Arrows // Sunlight Arrows
bool forceEnableSunLightArrows = gSaveContext.n64ddFlag && bool forceEnableSunLightArrows = IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SUNLIGHT_ARROWS); OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SUNLIGHT_ARROWS);
static const char* forceEnableSunLightArrowsText = static const char* forceEnableSunLightArrowsText =
"This setting is forcefully enabled because a savefile\nwith \"Sunlight Arrows\" is loaded."; "This setting is forcefully enabled because a savefile\nwith \"Sunlight Arrows\" is loaded.";
@ -1520,7 +1520,7 @@ void DrawRandomizerMenu() {
(OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_VANILLA && (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_VANILLA &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_OWN_DUNGEON && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_OWN_DUNGEON &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_STARTWITH) || OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_STARTWITH) ||
!gSaveContext.n64ddFlag) { !IS_RANDO) {
disableKeyColors = false; disableKeyColors = false;
} }

View file

@ -96,6 +96,8 @@ void SkeletonFactoryV0::ParseFileBinary(std::shared_ptr<BinaryReader> reader,
} else { } else {
SPDLOG_ERROR("unknown skeleton type {}", (uint32_t)skeleton->type); SPDLOG_ERROR("unknown skeleton type {}", (uint32_t)skeleton->type);
} }
skeleton->skeletonData.skeletonHeader.skeletonType = (uint8_t)skeleton->type;
} }
void SkeletonFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource) void SkeletonFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_ptr<IResource> resource)
{ {
@ -150,6 +152,7 @@ void SkeletonFactoryV0::ParseFileXML(tinyxml2::XMLElement* reader, std::shared_p
skel->skeletonData.flexSkeletonHeader.sh.limbCount = skel->limbCount; skel->skeletonData.flexSkeletonHeader.sh.limbCount = skel->limbCount;
skel->skeletonData.flexSkeletonHeader.sh.segment = (void**)skel->skeletonHeaderSegments.data(); skel->skeletonData.flexSkeletonHeader.sh.segment = (void**)skel->skeletonHeaderSegments.data();
skel->skeletonData.flexSkeletonHeader.dListCount = skel->dListCount; skel->skeletonData.flexSkeletonHeader.dListCount = skel->dListCount;
skel->skeletonData.skeletonHeader.skeletonType = (uint8_t)skel->type;
} }
} // namespace LUS } // namespace LUS

View file

@ -66,15 +66,17 @@ void SkeletonPatcher::ClearSkeletons()
void SkeletonPatcher::UpdateSkeletons() { void SkeletonPatcher::UpdateSkeletons() {
bool isHD = CVarGetInteger("gAltAssets", 0); bool isHD = CVarGetInteger("gAltAssets", 0);
for (auto skel : skeletons) for (auto skel : skeletons) {
{
Skeleton* newSkel = Skeleton* newSkel =
(Skeleton*)LUS::Context::GetInstance()->GetResourceManager() (Skeleton*)LUS::Context::GetInstance()->GetResourceManager()
->LoadResource((isHD ? LUS::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true) ->LoadResource((isHD ? LUS::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true)
.get(); .get();
if (newSkel != nullptr) if (newSkel != nullptr) {
skel.skelAnime->skeleton = newSkel->skeletonData.skeletonHeader.segment; skel.skelAnime->skeleton = newSkel->skeletonData.skeletonHeader.segment;
uintptr_t skelPtr = (uintptr_t)newSkel->GetPointer();
memcpy(&skel.skelAnime->skeletonHeader, &skelPtr, sizeof(uintptr_t)); // Dumb thing that needs to be done because cast is not cooperating
}
} }
} }
} // namespace LUS } // namespace LUS

View file

@ -24,6 +24,7 @@ enum class SkeletonType {
typedef struct { typedef struct {
/* 0x00 */ void** segment; /* 0x00 */ void** segment;
/* 0x04 */ uint8_t limbCount; /* 0x04 */ uint8_t limbCount;
uint8_t skeletonType;
} SkeletonHeader; // size = 0x8 } SkeletonHeader; // size = 0x8
// Model has limbs with flexible meshes // Model has limbs with flexible meshes

View file

@ -76,7 +76,7 @@ void OTRPlay_InitScene(PlayState* play, s32 spawn) {
OTRScene_ExecuteCommands(play, (LUS::Scene*)play->sceneSegment); OTRScene_ExecuteCommands(play, (LUS::Scene*)play->sceneSegment);
Play_InitEnvironment(play, play->skyboxId); Play_InitEnvironment(play, play->skyboxId);
// Unpause the timer for Boss Rush when the scene loaded isn't the Chamber of Sages. // Unpause the timer for Boss Rush when the scene loaded isn't the Chamber of Sages.
if (gSaveContext.isBossRush && play->sceneNum != SCENE_CHAMBER_OF_THE_SAGES) { if (IS_BOSS_RUSH && play->sceneNum != SCENE_CHAMBER_OF_THE_SAGES) {
gSaveContext.isBossRushPaused = 0; gSaveContext.isBossRushPaused = 0;
} }
/* auto data = static_cast<LUS::Vertex*>(LUS::Context::GetInstance() /* auto data = static_cast<LUS::Vertex*>(LUS::Context::GetInstance()

View file

@ -668,6 +668,7 @@ void Flags_SetSwitch(PlayState* play, s32 flag) {
} else { } else {
play->actorCtx.flags.tempSwch |= (1 << (flag - 0x20)); play->actorCtx.flags.tempSwch |= (1 << (flag - 0x20));
} }
GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_SWITCH, flag);
} }
/** /**
@ -680,6 +681,7 @@ void Flags_UnsetSwitch(PlayState* play, s32 flag) {
} else { } else {
play->actorCtx.flags.tempSwch &= ~(1 << (flag - 0x20)); play->actorCtx.flags.tempSwch &= ~(1 << (flag - 0x20));
} }
GameInteractor_ExecuteOnSceneFlagUnset(play->sceneNum, FLAG_SCENE_SWITCH, flag);
} }
/** /**
@ -728,6 +730,7 @@ s32 Flags_GetTreasure(PlayState* play, s32 flag) {
void Flags_SetTreasure(PlayState* play, s32 flag) { void Flags_SetTreasure(PlayState* play, s32 flag) {
lusprintf(__FILE__, __LINE__, 2, "Treasure Flag Set - %#x", flag); lusprintf(__FILE__, __LINE__, 2, "Treasure Flag Set - %#x", flag);
play->actorCtx.flags.chest |= (1 << flag); play->actorCtx.flags.chest |= (1 << flag);
GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_TREASURE, flag);
} }
/** /**
@ -742,6 +745,7 @@ s32 Flags_GetClear(PlayState* play, s32 flag) {
*/ */
void Flags_SetClear(PlayState* play, s32 flag) { void Flags_SetClear(PlayState* play, s32 flag) {
play->actorCtx.flags.clear |= (1 << flag); play->actorCtx.flags.clear |= (1 << flag);
GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_CLEAR, flag);
} }
/** /**
@ -749,6 +753,7 @@ void Flags_SetClear(PlayState* play, s32 flag) {
*/ */
void Flags_UnsetClear(PlayState* play, s32 flag) { void Flags_UnsetClear(PlayState* play, s32 flag) {
play->actorCtx.flags.clear &= ~(1 << flag); play->actorCtx.flags.clear &= ~(1 << flag);
GameInteractor_ExecuteOnSceneFlagUnset(play->sceneNum, FLAG_SCENE_CLEAR, flag);
} }
/** /**
@ -795,6 +800,7 @@ void Flags_SetCollectible(PlayState* play, s32 flag) {
play->actorCtx.flags.tempCollect |= (1 << (flag - 0x20)); play->actorCtx.flags.tempCollect |= (1 << (flag - 0x20));
} }
} }
GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_COLLECTIBLE, flag);
} }
void func_8002CDE4(PlayState* play, TitleCardContext* titleCtx) { void func_8002CDE4(PlayState* play, TitleCardContext* titleCtx) {
@ -1982,7 +1988,7 @@ s32 GiveItemEntryWithoutActor(PlayState* play, GetItemEntry getItemEntry) {
if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) { if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) {
if (((player->heldActor != NULL) && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX)) || if (((player->heldActor != NULL) && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX)) ||
(gSaveContext.n64ddFlag && (getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))) || (IS_RANDO && (getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))) ||
(!(player->stateFlags1 & 0x20000800))) { (!(player->stateFlags1 & 0x20000800))) {
if ((getItemEntry.getItemId != GI_NONE)) { if ((getItemEntry.getItemId != GI_NONE)) {
player->getItemEntry = getItemEntry; player->getItemEntry = getItemEntry;
@ -2018,8 +2024,8 @@ s32 GiveItemEntryFromActor(Actor* actor, PlayState* play, GetItemEntry getItemEn
if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) { if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) {
if ((((player->heldActor != NULL) || (actor == player->targetActor)) && if ((((player->heldActor != NULL) || (actor == player->targetActor)) &&
((!gSaveContext.n64ddFlag && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX))) || ((!IS_RANDO && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX))) ||
(gSaveContext.n64ddFlag && ((getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))))) || (IS_RANDO && ((getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))))) ||
(!(player->stateFlags1 & 0x20000800))) { (!(player->stateFlags1 & 0x20000800))) {
if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) { if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) {
s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y; s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y;
@ -2060,7 +2066,7 @@ s32 func_8002F434(Actor* actor, PlayState* play, s32 getItemId, f32 xzRange, f32
if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) { if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) {
if ((((player->heldActor != NULL) || (actor == player->targetActor)) && if ((((player->heldActor != NULL) || (actor == player->targetActor)) &&
((!gSaveContext.n64ddFlag && ((getItemId > GI_NONE) && (getItemId < GI_MAX))) || (gSaveContext.n64ddFlag && ((getItemId > RG_NONE) && (getItemId < RG_MAX))))) || ((!IS_RANDO && ((getItemId > GI_NONE) && (getItemId < GI_MAX))) || (IS_RANDO && ((getItemId > RG_NONE) && (getItemId < RG_MAX))))) ||
(!(player->stateFlags1 & 0x20000800))) { (!(player->stateFlags1 & 0x20000800))) {
if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) { if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) {
s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y; s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y;
@ -4718,6 +4724,7 @@ s32 Flags_GetEventChkInf(s32 flag) {
*/ */
void Flags_SetEventChkInf(s32 flag) { void Flags_SetEventChkInf(s32 flag) {
gSaveContext.eventChkInf[flag >> 4] |= (1 << (flag & 0xF)); gSaveContext.eventChkInf[flag >> 4] |= (1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, flag);
} }
/** /**
@ -4725,6 +4732,7 @@ void Flags_SetEventChkInf(s32 flag) {
*/ */
void Flags_UnsetEventChkInf(s32 flag) { void Flags_UnsetEventChkInf(s32 flag) {
gSaveContext.eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF)); gSaveContext.eventChkInf[flag >> 4] &= ~(1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagUnset(FLAG_EVENT_CHECK_INF, flag);
} }
/** /**
@ -4739,6 +4747,7 @@ s32 Flags_GetItemGetInf(s32 flag) {
*/ */
void Flags_SetItemGetInf(s32 flag) { void Flags_SetItemGetInf(s32 flag) {
gSaveContext.itemGetInf[flag >> 4] |= (1 << (flag & 0xF)); gSaveContext.itemGetInf[flag >> 4] |= (1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagSet(FLAG_ITEM_GET_INF, flag);
} }
/** /**
@ -4746,6 +4755,7 @@ void Flags_SetItemGetInf(s32 flag) {
*/ */
void Flags_UnsetItemGetInf(s32 flag) { void Flags_UnsetItemGetInf(s32 flag) {
gSaveContext.itemGetInf[flag >> 4] &= ~(1 << (flag & 0xF)); gSaveContext.itemGetInf[flag >> 4] &= ~(1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagUnset(FLAG_ITEM_GET_INF, flag);
} }
/** /**
@ -4760,6 +4770,7 @@ s32 Flags_GetInfTable(s32 flag) {
*/ */
void Flags_SetInfTable(s32 flag) { void Flags_SetInfTable(s32 flag) {
gSaveContext.infTable[flag >> 4] |= (1 << (flag & 0xF)); gSaveContext.infTable[flag >> 4] |= (1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagSet(FLAG_INF_TABLE, flag);
} }
/** /**
@ -4767,6 +4778,7 @@ void Flags_SetInfTable(s32 flag) {
*/ */
void Flags_UnsetInfTable(s32 flag) { void Flags_UnsetInfTable(s32 flag) {
gSaveContext.infTable[flag >> 4] &= ~(1 << (flag & 0xF)); gSaveContext.infTable[flag >> 4] &= ~(1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagUnset(FLAG_INF_TABLE, flag);
} }
/** /**
@ -4781,6 +4793,7 @@ s32 Flags_GetEventInf(s32 flag) {
*/ */
void Flags_SetEventInf(s32 flag) { void Flags_SetEventInf(s32 flag) {
gSaveContext.eventInf[flag >> 4] |= (1 << (flag & 0xF)); gSaveContext.eventInf[flag >> 4] |= (1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_INF, flag);
} }
/** /**
@ -4788,6 +4801,7 @@ void Flags_SetEventInf(s32 flag) {
*/ */
void Flags_UnsetEventInf(s32 flag) { void Flags_UnsetEventInf(s32 flag) {
gSaveContext.eventInf[flag >> 4] &= ~(1 << (flag & 0xF)); gSaveContext.eventInf[flag >> 4] &= ~(1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagUnset(FLAG_EVENT_INF, flag);
} }
/** /**
@ -4802,6 +4816,7 @@ s32 Flags_GetRandomizerInf(RandomizerInf flag) {
*/ */
void Flags_SetRandomizerInf(RandomizerInf flag) { void Flags_SetRandomizerInf(RandomizerInf flag) {
gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF)); gSaveContext.randomizerInf[flag >> 4] |= (1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagSet(FLAG_RANDOMIZER_INF, flag);
} }
/** /**
@ -4809,6 +4824,7 @@ void Flags_SetRandomizerInf(RandomizerInf flag) {
*/ */
void Flags_UnsetRandomizerInf(RandomizerInf flag) { void Flags_UnsetRandomizerInf(RandomizerInf flag) {
gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF)); gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagUnset(FLAG_RANDOMIZER_INF, flag);
} }
u32 func_80035BFC(PlayState* play, s16 arg1) { u32 func_80035BFC(PlayState* play, s16 arg1) {

View file

@ -246,7 +246,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
case 3: case 3:
if (sp3F != 0) { if (sp3F != 0) {
Flags_SetEnv(play, 0); Flags_SetEnv(play, 0);
if (gSaveContext.entranceIndex == 0x0053 || (gSaveContext.n64ddFlag && gSaveContext.entranceIndex == 0x05F4)) { if (gSaveContext.entranceIndex == 0x0053 || (IS_RANDO && gSaveContext.entranceIndex == 0x05F4)) {
Flags_SetEnv(play, 2); Flags_SetEnv(play, 2);
} }
} }
@ -497,7 +497,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
// cmd->base == 8: Traveling back/forward in time cutscene // cmd->base == 8: Traveling back/forward in time cutscene
// cmd->base == 24: Dropping a fish for Jabu Jabu // cmd->base == 24: Dropping a fish for Jabu Jabu
// cmd->base == 33: Zelda escaping with impa cutscene // cmd->base == 33: Zelda escaping with impa cutscene
bool randoCsSkip = (gSaveContext.n64ddFlag && (cmd->base == 8 || cmd->base == 24 || cmd->base == 33)); bool randoCsSkip = (IS_RANDO && (cmd->base == 8 || cmd->base == 24 || cmd->base == 33));
bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) && bool debugCsSkip = (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) &&
(gSaveContext.fileNum != 0xFEDC) && CVarGetInteger("gDebugEnabled", 0)); (gSaveContext.fileNum != 0xFEDC) && CVarGetInteger("gDebugEnabled", 0));
@ -2113,7 +2113,7 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) {
u8 requiredAge; u8 requiredAge;
s16 i; s16 i;
if (gSaveContext.n64ddFlag && if (IS_RANDO &&
// don't skip epona escape cutscenes // don't skip epona escape cutscenes
gSaveContext.entranceIndex != 650 && gSaveContext.entranceIndex != 650 &&
gSaveContext.entranceIndex != 654 && gSaveContext.entranceIndex != 654 &&
@ -2151,9 +2151,9 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) { if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) {
const bool bShouldTowerRandoSkip = const bool bShouldTowerRandoSkip =
(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE)); (IS_RANDO && Randomizer_GetSettingValue(RSK_SKIP_TOWER_ESCAPE));
if ((gSaveContext.entranceIndex == 0x01E1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) { if ((gSaveContext.entranceIndex == 0x01E1) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT)) {
if (!gSaveContext.n64ddFlag) { if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT); Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT);
gSaveContext.entranceIndex = 0x0123; gSaveContext.entranceIndex = 0x0123;
gSaveContext.cutsceneIndex = 0xFFF0; gSaveContext.cutsceneIndex = 0xFFF0;
@ -2161,12 +2161,12 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
} else if ((gSaveContext.entranceIndex == 0x00DB) && LINK_IS_ADULT && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) && } else if ((gSaveContext.entranceIndex == 0x00DB) && LINK_IS_ADULT && (Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP)) &&
(Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) &&
!Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) { !Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) {
if (!gSaveContext.n64ddFlag) { if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL); Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL);
gSaveContext.cutsceneIndex = 0xFFF0; gSaveContext.cutsceneIndex = 0xFFF0;
} }
} else if ((gSaveContext.entranceIndex == 0x05E0) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) { } else if ((gSaveContext.entranceIndex == 0x05E0) && !Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE)) {
if (!gSaveContext.n64ddFlag) { if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE); Flags_SetEventChkInf(EVENTCHKINF_SPOKE_TO_SARIA_ON_BRIDGE);
Item_Give(play, ITEM_OCARINA_FAIRY); Item_Give(play, ITEM_OCARINA_FAIRY);
gSaveContext.entranceIndex = 0x011E; gSaveContext.entranceIndex = 0x011E;
@ -2175,7 +2175,7 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
} else if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) && } else if (CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) && CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) && LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)) { (gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME)) {
if (!gSaveContext.n64ddFlag) { if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS); Flags_SetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
gSaveContext.entranceIndex = 0x0053; gSaveContext.entranceIndex = 0x0053;
gSaveContext.cutsceneIndex = 0xFFF8; gSaveContext.cutsceneIndex = 0xFFF8;
@ -2187,7 +2187,7 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO); Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO);
gSaveContext.entranceIndex = 0x0517; gSaveContext.entranceIndex = 0x0517;
// In rando, skip the cutscene for the tower falling down after the escape. // In rando, skip the cutscene for the tower falling down after the escape.
if (gSaveContext.n64ddFlag) { if (IS_RANDO) {
return; return;
} }
gSaveContext.cutsceneIndex = 0xFFF0; gSaveContext.cutsceneIndex = 0xFFF0;

View file

@ -78,6 +78,8 @@
#include "objects/object_gi_sword_1/object_gi_sword_1.h" #include "objects/object_gi_sword_1/object_gi_sword_1.h"
#include "objects/object_st/object_st.h" #include "objects/object_st/object_st.h"
#include "soh_assets.h"
// "Get Item" Model Draw Functions // "Get Item" Model Draw Functions
void GetItem_DrawMaskOrBombchu(PlayState* play, s16 drawId); void GetItem_DrawMaskOrBombchu(PlayState* play, s16 drawId);
void GetItem_DrawSoldOut(PlayState* play, s16 drawId); void GetItem_DrawSoldOut(PlayState* play, s16 drawId);
@ -110,6 +112,7 @@ void GetItem_DrawJewelKokiri(PlayState* play, s16 drawId);
void GetItem_DrawJewelGoron(PlayState* play, s16 drawId); void GetItem_DrawJewelGoron(PlayState* play, s16 drawId);
void GetItem_DrawJewelZora(PlayState* play, s16 drawId); void GetItem_DrawJewelZora(PlayState* play, s16 drawId);
void GetItem_DrawGenericMusicNote(PlayState* play, s16 drawId); void GetItem_DrawGenericMusicNote(PlayState* play, s16 drawId);
void GetItem_DrawTriforcePiece(PlayState* play, s16 drawId);
typedef struct { typedef struct {
/* 0x00 */ void (*drawFunc)(PlayState*, s16); /* 0x00 */ void (*drawFunc)(PlayState*, s16);
@ -384,7 +387,8 @@ DrawItemTableEntry sDrawItemTable[] = {
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Saria's song { GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Saria's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Sun's song { GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Sun's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Song of time { GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Song of time
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } } //Song of storms { GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Song of storms
{ GetItem_DrawTriforcePiece, { gTriforcePiece0DL } } // Triforce Piece
}; };
/** /**
@ -1031,3 +1035,33 @@ void GetItem_DrawWallet(PlayState* play, s16 drawId) {
CLOSE_DISPS(play->state.gfxCtx); CLOSE_DISPS(play->state.gfxCtx);
} }
void GetItem_DrawTriforcePiece(PlayState* play, s16 drawId) {
OPEN_DISPS(play->state.gfxCtx);
Gfx_SetupDL_25Opa(play->state.gfxCtx);
Matrix_Scale(0.035f, 0.035f, 0.035f, MTXMODE_APPLY);
uint16_t index = gSaveContext.triforcePiecesCollected % 3;
Gfx* triforcePieceDL;
switch (index) {
case 1:
triforcePieceDL = (Gfx*) gTriforcePiece1DL;
break;
case 2:
triforcePieceDL = (Gfx*) gTriforcePiece2DL;
break;
default:
triforcePieceDL = (Gfx*) gTriforcePiece0DL;
break;
}
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, triforcePieceDL);
CLOSE_DISPS(play->state.gfxCtx);
}

View file

@ -381,7 +381,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
Actor_SetScale(&this->actor, 0.03f); Actor_SetScale(&this->actor, 0.03f);
this->scale = 0.03f; this->scale = 0.03f;
// Offset keys in randomizer slightly higher for their GID replacement // Offset keys in randomizer slightly higher for their GID replacement
if (!gSaveContext.n64ddFlag) { if (!IS_RANDO) {
yOffset = 350.0f; yOffset = 350.0f;
} else { } else {
yOffset = 430.0f; yOffset = 430.0f;
@ -488,7 +488,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
RandomizerCheck randoCheck = RandomizerCheck randoCheck =
Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams);
if (gSaveContext.n64ddFlag && randoCheck != RC_UNKNOWN_CHECK) { if (IS_RANDO && randoCheck != RC_UNKNOWN_CHECK) {
this->randoGiEntry = this->randoGiEntry =
Randomizer_GetItemFromKnownCheck(randoCheck, getItemId); Randomizer_GetItemFromKnownCheck(randoCheck, getItemId);
this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING; this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING;
@ -578,7 +578,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
if (!Actor_HasParent(&this->actor, play)) { if (!Actor_HasParent(&this->actor, play)) {
if (getItemId != GI_NONE) { if (getItemId != GI_NONE) {
if (!gSaveContext.n64ddFlag || this->randoGiEntry.getItemId == GI_NONE) { if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) {
func_8002F554(&this->actor, play, getItemId); func_8002F554(&this->actor, play, getItemId);
} else { } else {
GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry); GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry);
@ -731,7 +731,7 @@ void func_8001E5C8(EnItem00* this, PlayState* play) {
Player* player = GET_PLAYER(play); Player* player = GET_PLAYER(play);
if (this->getItemId != GI_NONE) { if (this->getItemId != GI_NONE) {
if (!Actor_HasParent(&this->actor, play)) { if (!Actor_HasParent(&this->actor, play)) {
if (!gSaveContext.n64ddFlag) { if (!IS_RANDO) {
func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f); func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f);
} else { } else {
GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f); GiveItemEntryFromActor(&this->actor, play, this->randoGiEntry, 50.0f, 80.0f);
@ -783,7 +783,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
this->actor.params == ITEM00_BOMBS_SPECIAL || this->actor.params == ITEM00_BOMBCHU) { this->actor.params == ITEM00_BOMBS_SPECIAL || this->actor.params == ITEM00_BOMBCHU) {
if (CVarGetInteger("gNewDrops", 0) || if (CVarGetInteger("gNewDrops", 0) ||
// Keys in randomizer need to always rotate for their GID replacement // Keys in randomizer need to always rotate for their GID replacement
(gSaveContext.n64ddFlag && this->actor.params == ITEM00_SMALL_KEY)) { (IS_RANDO && this->actor.params == ITEM00_SMALL_KEY)) {
this->actor.shape.rot.y += 960; this->actor.shape.rot.y += 960;
} else { } else {
this->actor.shape.rot.y = 0; this->actor.shape.rot.y = 0;
@ -951,7 +951,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
params = &this->actor.params; params = &this->actor.params;
if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) { if ((getItemId != GI_NONE) && !Actor_HasParent(&this->actor, play)) {
if (!gSaveContext.n64ddFlag || this->randoGiEntry.getItemId == GI_NONE) { if (!IS_RANDO || this->randoGiEntry.getItemId == GI_NONE) {
func_8002F554(&this->actor, play, getItemId); func_8002F554(&this->actor, play, getItemId);
} else { } else {
getItemId = this->randoGiEntry.getItemId; getItemId = this->randoGiEntry.getItemId;
@ -1046,7 +1046,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
} }
break; break;
case ITEM00_HEART_PIECE: case ITEM00_HEART_PIECE:
if (CVarGetInteger("gNewDrops", 0) && !gSaveContext.n64ddFlag) { if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) {
mtxScale = 21.0f; mtxScale = 21.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
GetItem_Draw(play, GID_HEART_PIECE); GetItem_Draw(play, GID_HEART_PIECE);
@ -1156,7 +1156,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
break; break;
} }
case ITEM00_SMALL_KEY: case ITEM00_SMALL_KEY:
if (CVarGetInteger("gNewDrops", 0) && !gSaveContext.n64ddFlag) { if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) {
mtxScale = 8.0f; mtxScale = 8.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY); Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
GetItem_Draw(play, GID_KEY_SMALL); GetItem_Draw(play, GID_KEY_SMALL);
@ -1362,7 +1362,7 @@ static const Vtx customDropVtx[] = {
* Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...). * Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...).
*/ */
void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) { void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) {
if (gSaveContext.n64ddFlag && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) { if (IS_RANDO && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) {
RandomizerCheck randoCheck = RandomizerCheck randoCheck =
Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams);
@ -1456,7 +1456,7 @@ void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play) {
* Draw Function used for the Piece of Heart type of En_Item00. * Draw Function used for the Piece of Heart type of En_Item00.
*/ */
void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) { void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) {
if (gSaveContext.n64ddFlag) { if (IS_RANDO) {
RandomizerCheck randoCheck = RandomizerCheck randoCheck =
Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams); Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams);
@ -1533,7 +1533,7 @@ s16 func_8001F404(s16 dropId) {
} }
if ((CVarGetInteger("gBombchuDrops", 0) || if ((CVarGetInteger("gBombchuDrops", 0) ||
(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1)) && (IS_RANDO && Randomizer_GetSettingValue(RSK_ENABLE_BOMBCHU_DROPS) == 1)) &&
(dropId == ITEM00_BOMBS_A || dropId == ITEM00_BOMBS_B || dropId == ITEM00_BOMBS_SPECIAL)) { (dropId == ITEM00_BOMBS_A || dropId == ITEM00_BOMBS_B || dropId == ITEM00_BOMBS_SPECIAL)) {
dropId = EnItem00_ConvertBombDropToBombchu(dropId); dropId = EnItem00_ConvertBombDropToBombchu(dropId);
} }

View file

@ -33,7 +33,7 @@ void GameOver_Update(PlayState* play) {
gSaveContext.eventInf[1] &= ~1; gSaveContext.eventInf[1] &= ~1;
// search inventory for spoiling items and revert if necessary // search inventory for spoiling items and revert if necessary
if (!(gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE))) { if (!(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE))) {
for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) { for (i = 0; i < ARRAY_COUNT(gSpoilingItems); i++) {
if (INV_CONTENT(ITEM_POCKET_EGG) == gSpoilingItems[i]) { if (INV_CONTENT(ITEM_POCKET_EGG) == gSpoilingItems[i]) {
INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i]; INV_CONTENT(gSpoilingItemReverts[i]) = gSpoilingItemReverts[i];

View file

@ -73,8 +73,8 @@ void func_8006D0EC(PlayState* play, Player* player) {
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -25.0f, 0.0f, -1600.0f, 0, -0x4000, 0, 1, true); Actor_Spawn(&play->actorCtx, play, ACTOR_EN_HORSE, -25.0f, 0.0f, -1600.0f, 0, -0x4000, 0, 1, true);
assert(horseActor != NULL); assert(horseActor != NULL);
} else if ((play->sceneNum == gSaveContext.horseData.scene) && } else if ((play->sceneNum == gSaveContext.horseData.scene) &&
(((Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) != 0) && (!gSaveContext.n64ddFlag || (((Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) != 0) && (!IS_RANDO ||
(gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_SONG_EPONA) && (IS_RANDO && CHECK_QUEST_ITEM(QUEST_SONG_EPONA) &&
(INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE)))) || DREG(1) != 0)) { (INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE)))) || DREG(1) != 0)) {
// "Set by existence of horse %d %d %d" // "Set by existence of horse %d %d %d"
osSyncPrintf("馬存在によるセット %d %d %d\n", gSaveContext.horseData.scene, Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED), osSyncPrintf("馬存在によるセット %d %d %d\n", gSaveContext.horseData.scene, Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED),

View file

@ -60,7 +60,7 @@ void KaleidoScopeCall_Update(PlayState* play) {
GameInteractor_ExecuteOnPauseMenu(); GameInteractor_ExecuteOnPauseMenu();
if (!gSaveContext.sohStats.gameComplete && if (!gSaveContext.sohStats.gameComplete &&
(!gSaveContext.isBossRush || !gSaveContext.isBossRushPaused)) { (!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) {
gSaveContext.sohStats.pauseTimer++; gSaveContext.sohStats.pauseTimer++;
} }

View file

@ -394,8 +394,8 @@ void Map_InitData(PlayState* play, s16 room) {
} }
} else if (play->sceneNum == SCENE_LAKE_HYLIA) { } else if (play->sceneNum == SCENE_LAKE_HYLIA) {
if ((LINK_AGE_IN_YEARS == YEARS_ADULT) && if ((LINK_AGE_IN_YEARS == YEARS_ADULT) &&
((!gSaveContext.n64ddFlag && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) || ((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
(gSaveContext.n64ddFlag && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)))) { (IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)))) {
extendedMapIndex = 0x15; extendedMapIndex = 0x15;
} }
} else if (play->sceneNum == SCENE_GERUDO_VALLEY) { } else if (play->sceneNum == SCENE_GERUDO_VALLEY) {
@ -403,8 +403,8 @@ void Map_InitData(PlayState* play, s16 room) {
extendedMapIndex = 0x16; extendedMapIndex = 0x16;
} }
} else if (play->sceneNum == SCENE_GERUDOS_FORTRESS) { } else if (play->sceneNum == SCENE_GERUDOS_FORTRESS) {
if ((!gSaveContext.n64ddFlag && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) || if ((!IS_RANDO && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) ||
(gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) { (IS_RANDO && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) {
extendedMapIndex = 0x17; extendedMapIndex = 0x17;
} }
} }

View file

@ -1617,9 +1617,9 @@ void Message_OpenText(PlayState* play, u16 textId) {
// Increments text id based on piece of heart count, assumes the piece of heart text is all // Increments text id based on piece of heart count, assumes the piece of heart text is all
// in order and that you don't have more than the intended amount of heart pieces. // in order and that you don't have more than the intended amount of heart pieces.
textId += (gSaveContext.inventory.questItems & 0xF0000000 & 0xF0000000) >> 0x1C; textId += (gSaveContext.inventory.questItems & 0xF0000000 & 0xF0000000) >> 0x1C;
} else if (!gSaveContext.n64ddFlag && (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_SWORD, 2))) { } else if (!IS_RANDO && (msgCtx->textId == 0xC && CHECK_OWNED_EQUIP(EQUIP_SWORD, 2))) {
textId = 0xB; // Traded Giant's Knife for Biggoron Sword textId = 0xB; // Traded Giant's Knife for Biggoron Sword
} else if (!gSaveContext.n64ddFlag && (msgCtx->textId == 0xB4 && (Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_CURSED_MAN_IN_SKULL_HOUSE)))) { } else if (!IS_RANDO && (msgCtx->textId == 0xB4 && (Flags_GetEventChkInf(EVENTCHKINF_SPOKE_TO_CURSED_MAN_IN_SKULL_HOUSE)))) {
textId = 0xB5; // Destroyed Gold Skulltula textId = 0xB5; // Destroyed Gold Skulltula
} }
// Ocarina Staff + Dialog // Ocarina Staff + Dialog
@ -2517,7 +2517,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
if (msgCtx->lastPlayedSong < OCARINA_SONG_SARIAS && if (msgCtx->lastPlayedSong < OCARINA_SONG_SARIAS &&
(msgCtx->ocarinaAction < OCARINA_ACTION_PLAYBACK_MINUET || (msgCtx->ocarinaAction < OCARINA_ACTION_PLAYBACK_MINUET ||
msgCtx->ocarinaAction >= OCARINA_ACTION_PLAYBACK_SARIA)) { msgCtx->ocarinaAction >= OCARINA_ACTION_PLAYBACK_SARIA)) {
if (msgCtx->disableWarpSongs || (interfaceCtx->restrictions.warpSongs == 3 && !gSaveContext.n64ddFlag)) { if (msgCtx->disableWarpSongs || (interfaceCtx->restrictions.warpSongs == 3 && !IS_RANDO)) {
Message_StartTextbox(play, 0x88C, NULL); // "You can't warp here!" Message_StartTextbox(play, 0x88C, NULL); // "You can't warp here!"
play->msgCtx.ocarinaMode = OCARINA_MODE_04; play->msgCtx.ocarinaMode = OCARINA_MODE_04;
} else if ((gSaveContext.eventInf[0] & 0xF) != 1) { } else if ((gSaveContext.eventInf[0] & 0xF) != 1) {
@ -2603,7 +2603,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
msgCtx->lastPlayedSong = msgCtx->ocarinaStaff->state; msgCtx->lastPlayedSong = msgCtx->ocarinaStaff->state;
msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_SUCCESS; msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_SUCCESS;
if (!gSaveContext.n64ddFlag) { if (!IS_RANDO) {
Item_Give(play, ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]); Item_Give(play, ITEM_SONG_MINUET + gOcarinaSongItemMap[msgCtx->ocarinaStaff->state]);
} }

View file

@ -792,7 +792,7 @@ s32 OnePointCutscene_SetInfo(PlayState* play, s16 camIdx, s16 csId, Actor* actor
case 4100: case 4100:
csInfo->keyFrames = D_801225D4; csInfo->keyFrames = D_801225D4;
// RANDO: Waterfall opening cutscene skips to the end of the cutscene data earlier by doing this // RANDO: Waterfall opening cutscene skips to the end of the cutscene data earlier by doing this
if (!(gSaveContext.n64ddFlag)) { if (!(IS_RANDO)) {
csInfo->keyFrameCnt = 5; csInfo->keyFrameCnt = 5;
} else { } else {
csInfo->keyFrameCnt = 2; csInfo->keyFrameCnt = 2;

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