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
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)
The latest release is available in the most recent post in the `#downloads` channel.
### 2. Download The Ship of Harkinian from [Releases](https://github.com/HarbourMasters/Shipwright/releases)
### 3. Launch the Game!
#### Windows

View File

@ -81,7 +81,7 @@ cd "build/x64"
```
## 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!**

View File

@ -44,6 +44,18 @@ static const ALIGN_ASSET(2) char gTitleRandomizerSubtitleTex[] = dgTitleRandomiz
#define dgTitleBossRushSubtitleTex "__OTR__objects/object_mag/gTitleBossRushSubtitleTex"
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
#define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx"
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"
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"
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,
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg,
s32 dListIndex);
void SkelAnime_DrawSkeletonOpa(PlayState* play, SkelAnime* skelAnime, OverrideLimbDrawOpa overrideLimbDraw,
PostLimbDrawOpa postLimbDraw, void* arg);
void SkelAnime_DrawOpa(PlayState* play, void** skeleton, Vec3s* jointTable,
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, void* arg);
void SkelAnime_DrawFlexOpa(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount,

View File

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

View File

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

View File

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

View File

@ -409,7 +409,8 @@ typedef enum {
FLAG_ITEM_GET_INF,
FLAG_INF_TABLE,
FLAG_EVENT_INF,
FLAG_RANDOMIZER_INF
FLAG_RANDOMIZER_INF,
FLAG_GS_TOKEN,
} FlagType;
typedef struct {
@ -620,7 +621,7 @@ typedef struct Player {
/* 0x0858 */ f32 unk_858;
/* 0x085C */ f32 unk_85C; // stick length 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;
/* 0x0868 */ f32 unk_868;
/* 0x086C */ f32 unk_86C;

View File

@ -284,8 +284,7 @@ typedef struct {
/* 0x1428 */ u16 pendingSaleMod;
// #region SOH [General]
// Upstream TODO: Move these to their own struct or name to more obviously specific to SoH
/* */ uint32_t isMasterQuest;
/* */ uint32_t isBossRush;
/* */ uint8_t questId;
/* */ uint32_t isBossRushPaused;
/* */ uint8_t bossRushOptions[BOSSRUSH_OPTIONS_AMOUNT];
/* */ u8 mqDungeonCount;
@ -324,9 +323,22 @@ typedef struct {
/* */ u8 seedIcons[5];
/* */ u16 randomizerInf[10];
/* */ u16 adultTradeItems;
/* */ u8 triforcePiecesCollected;
// #endregion
} 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 {
/* 0x00 */ BTN_ENABLED,
/* 0xFF */ BTN_DISABLED = 0xFF
@ -577,11 +589,16 @@ typedef enum {
// 0xDA-0xDE
#define EVENTCHKINF_SKULLTULA_REWARD_INDEX 13
#define EVENTCHKINF_SKULLTULA_REWARD_10_MASK (1 << 10)
#define EVENTCHKINF_SKULLTULA_REWARD_20_MASK (1 << 11)
#define EVENTCHKINF_SKULLTULA_REWARD_30_MASK (1 << 12)
#define EVENTCHKINF_SKULLTULA_REWARD_40_MASK (1 << 13)
#define EVENTCHKINF_SKULLTULA_REWARD_50_MASK (1 << 14)
#define EVENTCHKINF_SKULLTULA_REWARD_10_SHIFT 10
#define EVENTCHKINF_SKULLTULA_REWARD_20_SHIFT 11
#define EVENTCHKINF_SKULLTULA_REWARD_30_SHIFT 12
#define EVENTCHKINF_SKULLTULA_REWARD_40_SHIFT 13
#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:
return ImVec4(0.4f, 0.33f, 0.0f, 1.0f);
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:
return ImVec4(0.0f, 0.25f, 0.5f, 1.0f);
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::PushStyleColor(ImGuiCol_Header, GetSequenceTypeColor(SEQ_BGM_WORLD));

View File

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

View File

@ -10,6 +10,7 @@
#include <string>
#include <libultraship/bridge.h>
#include <libultraship/libultraship.h>
#include "soh_assets.h"
extern "C" {
#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}}
};
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
std::vector<std::string> gsMapping = {
"Deku Tree",
@ -509,6 +514,10 @@ void DrawInfoTab() {
}
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);
static std::array<const char*, 7> minigameHS = { "Horseback Archery",
@ -699,7 +708,7 @@ void DrawInventoryTab() {
ImVec2(0, 0), ImVec2(1, 1), 0)) {
gSaveContext.inventory.items[selectedIndex] = slotEntry.id;
// Set adult trade item flag if you're playing adult trade shuffle in rando
if (gSaveContext.n64ddFlag &&
if (IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) &&
selectedIndex == SLOT_TRADE_ADULT &&
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
// 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")) {
for (int i = ITEM_POCKET_EGG; i <= ITEM_CLAIM_CHECK; 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
// 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;
ImGui::Checkbox("Keep GS Count Updated", &keepGsCountUpdated);
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++) {
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;
}
@ -1281,7 +1290,7 @@ void DrawEquipmentTab() {
"Giant (500)",
};
// 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)";
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.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) {
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));

View File

@ -234,7 +234,7 @@ extern "C" uint8_t GetRandomizedEnemy(PlayState* play, int16_t *actorId, f32 *po
EnemyEntry GetRandomizedEnemyEntry(uint32_t seed) {
if (CVarGetInteger("gRandomizedEnemies", ENEMY_RANDOMIZER_OFF) == ENEMY_RANDOMIZER_RANDOM_SEEDED) {
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);
}

View File

@ -47,6 +47,55 @@ GameInteractionEffectQueryResult GameInteractionEffectBase::Remove() {
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
GameInteractionEffectQueryResult ModifyHeartContainers::CanBeApplied() {
if (!GameInteractor::IsSaveLoaded()) {

View File

@ -18,7 +18,7 @@ public:
virtual GameInteractionEffectQueryResult CanBeRemoved();
GameInteractionEffectQueryResult Apply();
GameInteractionEffectQueryResult Remove();
int32_t parameters[2];
int32_t parameters[3];
protected:
virtual void _Apply() = 0;
@ -26,6 +26,26 @@ public:
};
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 {
GameInteractionEffectQueryResult CanBeApplied() override;
void _Apply() override;

View File

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

View File

@ -30,6 +30,22 @@ void GameInteractor_ExecuteOnSceneInitHooks(int16_t 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() {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneSpawnActors>();
}

View File

@ -11,6 +11,10 @@ void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry);
void GameInteractor_ExecuteOnTransitionEndHooks(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_ExecuteOnPlayerUpdate();
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);
}
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) {
// When taking a shield, make sure it is unequipped as well.
// 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::SlipperyFloorActive = 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) {
PacifistModeActive = active;
@ -127,3 +129,13 @@ uint8_t GameInteractor_GetSlipperyFloorActive() {
uint8_t GameInteractor_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_BOSSRUSH_FINISH], "Boss Rush Finished: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_FOUND_GREG], "Greg Found: ");
strcpy(itemTimestampDisplayName[TIMESTAMP_TRIFORCE_COMPLETED], "Triforce Completed: ");
}
void SetupDisplayColors() {
@ -839,6 +840,7 @@ void SetupDisplayColors() {
case ITEM_ARROW_LIGHT:
case TIMESTAMP_DEFEAT_GANONDORF:
case TIMESTAMP_DEFEAT_GANON:
case TIMESTAMP_TRIFORCE_COMPLETED:
itemTimestampDisplayColor[i] = COLOR_YELLOW;
break;
case ITEM_SONG_STORMS:

View File

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

View File

@ -2,10 +2,12 @@
#include <libultraship/bridge.h>
#include "game-interactor/GameInteractor.h"
#include "tts/tts.h"
#include "soh/OTRGlobals.h"
#include "soh/Enhancements/boss-rush/BossRushTypes.h"
#include "soh/Enhancements/enhancementTypes.h"
#include "soh/Enhancements/randomizer/3drando/random.hpp"
#include "soh/Enhancements/cosmetics/authenticGfxPatches.h"
#include <soh/Enhancements/item-tables/ItemTableManager.h>
#include "soh/Enhancements/nametag.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 &&
!nearbyOcarinaSpot && !nearbyFrogs) {
if (gSaveContext.n64ddFlag) {
if (IS_RANDO) {
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
// Temple of Time scene where the only object present is the Door of Time
CVarSetInteger("gSwitchTimeline", 1);
@ -469,7 +471,7 @@ void RegisterHyperBosses() {
uint8_t hyperBossesActive =
CVarGetInteger("gHyperBosses", 0) ||
(gSaveContext.isBossRush &&
(IS_BOSS_RUSH &&
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.
@ -581,7 +583,7 @@ void UpdateMirrorModeState(int32_t sceneNum) {
(sceneNum == SCENE_GANON_BOSS);
if (mirroredMode == MIRRORED_WORLD_RANDOM_SEEDED || mirroredMode == MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED) {
uint32_t seed = sceneNum + (gSaveContext.n64ddFlag ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt);
uint32_t seed = sceneNum + (IS_RANDO ? gSaveContext.finalSeed : gSaveContext.sohStats.fileCreatedAt);
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
//and that are always counted
//enemies that can't be uniquely identified by their id
@ -1008,6 +1049,7 @@ void InitMods() {
RegisterBonkDamage();
RegisterMenuPathFix();
RegisterMirrorModeHandler();
RegisterTriforceHunt();
RegisterEnemyDefeatCounts();
RegisterAltTrapTypes();
RegisterRandomizerSheikSpawn();

View File

@ -503,7 +503,9 @@ static std::vector<uint32_t> CalculateBarrenRegions() {
if (Location(loc)->GetPlacedItem().IsMajorItem() || ElementInContainer(loc, wothLocations)) {
AddElementsToPool(potentiallyUsefulLocations, std::vector{loc});
} 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});
}
}
@ -723,6 +725,9 @@ static Text BuildGanonBossKeyText() {
} else if (GanonsBossKey.Is(GANONSBOSSKEY_LACS_TOKENS)) {
ganonBossKeyText = BuildCountReq(LACS_TOKENS_HINT, LACSTokenCount);
} else if (GanonsBossKey.Is(GANONSBOSSKEY_TRIFORCE_HUNT)) {
ganonBossKeyText = Hint(GANON_BK_TRIFORCE_HINT).GetText();
}
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_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[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[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++)
locationLookupTable.insert(std::make_pair(locationTable[i].GetRandomizerCheck(), static_cast<Key>(i)));
@ -1523,6 +1524,9 @@ void GenerateLocationPool() {
allLocations.clear();
AddLocation(LINKS_POCKET);
if (Settings::TriforceHunt.Is(TRIFORCE_HUNT_ON)) {
AddLocation(TRIFORCE_COMPLETED);
}
AddLocations(overworldLocations);
for (auto dungeon : Dungeon::dungeonList) {

View File

@ -662,9 +662,17 @@ void GenerateItemPool() {
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
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);
if (ShuffleKokiriSword) {
@ -1135,7 +1143,7 @@ void GenerateItemPool() {
if (GanonsBossKey.Is(GANONSBOSSKEY_FINAL_GS_REWARD)) {
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);
} else if (GanonsBossKey.Is(GANONSBOSSKEY_VANILLA)) {
PlaceItemInLocation(GANONS_TOWER_BOSS_KEY_CHEST, GANONS_CASTLE_BOSS_KEY);

View File

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

View File

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

View File

@ -150,6 +150,9 @@ namespace Logic {
uint8_t BottomOfTheWellKeys = 0;
uint8_t TreasureGameKeys = 0;
//Triforce Pieces
uint8_t TriforcePieces = 0;
//Boss Keys
bool BossKeyForestTemple = false;
bool BossKeyFireTemple = false;
@ -309,6 +312,7 @@ namespace Logic {
bool AtDay = false;
bool AtNight = false;
uint8_t Age = 0;
bool CanCompleteTriforce = false;
//Events
bool ShowedMidoSwordAndShield = false;
@ -620,7 +624,7 @@ namespace Logic {
(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_TOKENS && GoldSkulltulaTokens >= LACSTokenCount.Value<uint8_t>());
CanCompleteTriforce = TriforcePieces >= TriforceHuntRequired.Value<uint8_t>();
}
bool SmallKeys(Key dungeon, uint8_t requiredAmount) {
@ -873,7 +877,8 @@ namespace Logic {
NumBottles = 0;
NoBottles = false;
//Triforce Pieces
TriforcePieces = 0;
//Drops and Bottle Contents Access
DekuNutDrop = false;

View File

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

View File

@ -101,6 +101,9 @@ namespace Settings {
Option BombchusInLogic = Option::Bool("Bombchus in Logic", {"Off", "On"});
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 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(
"MQ Dungeon Count", { MultiVecOpts({ NumOpts(0, 12), { "Random" }, { "Selection" } }) });
uint8_t MQSet;
@ -139,6 +142,9 @@ namespace Settings {
&BombchusInLogic,
&AmmoDrops,
&HeartDropRefill,
&TriforceHunt,
&TriforceHuntTotal,
&TriforceHuntRequired,
&MQDungeonCount,
&SetDungeonTypes,
&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 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 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;
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);
@ -1685,6 +1691,13 @@ namespace Settings {
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
std::vector<uint32_t> mapChests = GetLocations(everyPossibleLocation, Category::cVanillaMap);
std::vector<uint32_t> compassChests = GetLocations(everyPossibleLocation, Category::cVanillaCompass);
@ -2365,7 +2378,11 @@ namespace Settings {
Keysanity.SetSelectedIndex(cvarSettings[RSK_KEYSANITY]);
GerudoKeys.SetSelectedIndex(cvarSettings[RSK_GERUDO_KEYS]);
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]);
LACSMedallionCount.SetSelectedIndex(cvarSettings[RSK_LACS_MEDALLION_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
for (size_t i = 0; i < dungeons.size(); i++) {
dungeons[i]->ClearKeyRing();

View File

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

View File

@ -13,7 +13,7 @@ using namespace Settings;
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
//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{"Life Heart", "Cœur de vie", "Vida Corazón"},
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

View File

@ -54,7 +54,9 @@ void GenerateStartingInventory() {
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);
}

View File

@ -3,17 +3,23 @@
#include "z64.h"
#include "macros.h"
#include "functions.h"
#include "variables.h"
#include "soh/OTRGlobals.h"
#include "randomizerTypes.h"
#include <array>
#include "objects/object_gi_key/object_gi_key.h"
#include "objects/object_gi_bosskey/object_gi_bosskey.h"
#include "objects/object_gi_hearts/object_gi_hearts.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" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry) {
s32 pad;
s8 keysCanBeOutsideDungeon = getItemEntry->getItemId == RG_GERUDO_FORTRESS_SMALL_KEY ?
Randomizer_GetSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA :
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) {
s32 pad;
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_BOSS_KEYSANITY);
@ -107,8 +112,6 @@ extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEnt
}
extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry) {
s32 pad;
s16 color_slot = getItemEntry->getItemId - RG_FOREST_TEMPLE_KEY_RING;
s16 colors[9][3] = {
{ 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) {
s32 pad;
OPEN_DISPS(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);
}
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;
extern "C" void Randomizer_DrawSmallKey(PlayState* play, GetItemEntry* getItemEntry);
extern "C" void Randomizer_DrawKeyRing(PlayState* play, GetItemEntry* getItemEntry);
extern "C" void Randomizer_DrawBossKey(PlayState* play, GetItemEntry* getItemEntry);
extern "C" void Randomizer_DrawDoubleDefense(PlayState* play, GetItemEntry getItemEntry);
extern "C" void Randomizer_DrawIceTrap(PlayState* play, GetItemEntry getItemEntry);
#ifdef __cplusplus
extern "C" {
#endif
void Randomizer_DrawSmallKey(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

View File

@ -55,6 +55,7 @@ const std::string Randomizer::getItemMessageTableID = "Randomizer";
const std::string Randomizer::hintMessageTableID = "RandomizerHints";
const std::string Randomizer::merchantMessageTableID = "RandomizerMerchants";
const std::string Randomizer::rupeeMessageTableID = "RandomizerRupees";
const std::string Randomizer::triforcePieceMessageTableID = "RandomizerTriforcePiece";
const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi";
const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap";
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 Grottos", RSK_MIX_GROTTO_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:Hint Clarity", RSK_HINT_CLARITY },
{ "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_CUCCO_COUNT:
case RSK_STARTING_SKULLTULA_TOKEN:
case RSK_TRIFORCE_HUNT_PIECES_TOTAL:
case RSK_TRIFORCE_HUNT_PIECES_REQUIRED:
numericValueString = it.value();
gSaveContext.randoSettings[index].value = std::stoi(numericValueString);
break;
@ -908,6 +914,7 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
case RSK_DECOUPLED_ENTRANCES:
case RSK_SHOPSANITY_PRICES_AFFORDABLE:
case RSK_ALL_LOCATIONS_REACHABLE:
case RSK_TRIFORCE_HUNT:
if(it.value() == "Off") {
gSaveContext.randoSettings[index].value = RO_GENERIC_OFF;
} 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;
} else if(it.value() == "100 GS Reward") {
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;
case RSK_RANDOM_MQ_DUNGEONS:
@ -1980,6 +1989,7 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe
case RG_BUY_DEKU_NUT_10:
case RG_BUY_DEKU_STICK_1:
case RG_BUY_HEART:
case RG_TRIFORCE_PIECE:
default:
return CAN_OBTAIN;
}
@ -2990,6 +3000,10 @@ void GenerateRandomizerImgui(std::string seed = "") {
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_DODONGOS_CAVERN] = CVarGetInteger("gRandomizeMqDungeonsDodongosCavern", 0);
cvarSettings[RSK_MQ_JABU_JABU] = CVarGetInteger("gRandomizeMqDungeonsJabuJabu", 0);
@ -3502,6 +3516,7 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::PaddedSeparator();
// Master Quest Dungeons
if (OTRGlobals::Instance->HasMasterQuest() && OTRGlobals::Instance->HasOriginal()) {
ImGui::PushItemWidth(-FLT_MIN);
ImGui::Text("Master Quest Dungeons");
@ -3549,8 +3564,43 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::EnhancementCheckbox("Ganon's Castle##RandomizeMqDungeons",
"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();
// COLUMN 3 - Shuffle Entrances
@ -4144,7 +4194,11 @@ void RandomizerSettingsWindow::DrawElement() {
"\n"
"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();
switch (CVarGetInteger("gRandomizeShuffleGanonBossKey", RO_GANON_BOSS_KEY_VANILLA)) {
case RO_GANON_BOSS_KEY_LACS_STONES:
@ -5461,6 +5515,70 @@ CustomMessage Randomizer::GetRupeeMessage(u16 rupeeTextId) {
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() {
CustomMessage NaviMessages[NUM_NAVI_MESSAGES] = {
@ -5988,6 +6106,7 @@ void Randomizer::CreateCustomMessages() {
}};
CreateGetItemMessages(&getItemMessages);
CreateRupeeMessages();
CreateTriforcePieceMessages();
CreateNaviRandoMessages();
CreateIceTrapRandoMessages();
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_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_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);
for (int i = 0; i < ARRAY_COUNT(extendedVanillaGetItemTable); i++) {
@ -6113,6 +6233,8 @@ void InitRandoItemTable() {
randoGetItemTable[i].drawFunc = (CustomDrawFunc)Randomizer_DrawBossKey;
} else if (randoGetItemTable[i].itemId == RG_DOUBLE_DEFENSE) {
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]);
}

View File

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

View File

@ -847,6 +847,7 @@ typedef enum {
RC_ZR_NEAR_GROTTOS_GOSSIP_STONE,
RC_ZR_OPEN_GROTTO_GOSSIP_STONE,
RC_GANONDORF_HINT,
RC_TRIFORCE_COMPLETED,
RC_MAX
} RandomizerCheck;
@ -1302,6 +1303,7 @@ typedef enum {
RG_BUY_RED_POTION_40,
RG_BUY_RED_POTION_50,
RG_TRIFORCE,
RG_TRIFORCE_PIECE,
RG_HINT,
RG_TYCOON_WALLET,
RG_MAX
@ -1453,6 +1455,9 @@ typedef enum {
RSK_ALL_LOCATIONS_REACHABLE,
RSK_SHUFFLE_BOSS_ENTRANCES,
RSK_SHUFFLE_100_GS_REWARD,
RSK_TRIFORCE_HUNT,
RSK_TRIFORCE_HUNT_PIECES_TOTAL,
RSK_TRIFORCE_HUNT_PIECES_REQUIRED,
RSK_MAX
} RandomizerSettingKey;
@ -1613,6 +1618,7 @@ typedef enum {
RO_GANON_BOSS_KEY_LACS_DUNGEONS,
RO_GANON_BOSS_KEY_LACS_TOKENS,
RO_GANON_BOSS_KEY_KAK_TOKENS,
RO_GANON_BOSS_KEY_TRIFORCE_HUNT,
} RandoOptionGanonsBossKey;
// 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_RIGHT,
} 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;
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%
showShops = gSaveContext.n64ddFlag ? (
showShops = IS_RANDO ? (
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_OFF &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHOPSANITY) != RO_SHOPSANITY_ZERO_ITEMS)
: false;
showBeans = gSaveContext.n64ddFlag ?
showBeans = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MAGIC_BEANS) == RO_GENERIC_YES
: true;
showScrubs = gSaveContext.n64ddFlag ?
showScrubs = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_SCRUBS) != RO_SCRUBS_OFF
: false;
showMerchants = gSaveContext.n64ddFlag ?
showMerchants = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_MERCHANTS) != RO_SHUFFLE_MERCHANTS_OFF
: true;
showCows = gSaveContext.n64ddFlag ?
showCows = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_COWS) == RO_GENERIC_YES
: false;
showAdultTrade = gSaveContext.n64ddFlag ?
showAdultTrade = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_ADULT_TRADE) == RO_GENERIC_YES
: true;
showKokiriSword = gSaveContext.n64ddFlag ?
showKokiriSword = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_KOKIRI_SWORD) == RO_GENERIC_YES
: true;
showWeirdEgg = gSaveContext.n64ddFlag ?
showWeirdEgg = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_WEIRD_EGG) == RO_GENERIC_YES
: true;
showGerudoCard = gSaveContext.n64ddFlag ?
showGerudoCard = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD) == RO_GENERIC_YES
: true;
showFrogSongRupees = gSaveContext.n64ddFlag ?
showFrogSongRupees = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_FROG_SONG_RUPEES) == RO_GENERIC_YES
: false;
showStartingMapsCompasses = gSaveContext.n64ddFlag ?
showStartingMapsCompasses = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_STARTING_MAPS_COMPASSES) != RO_DUNGEON_ITEM_LOC_VANILLA
: false;
showKeysanity = gSaveContext.n64ddFlag ?
showKeysanity = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA
: false;
showBossKeysanity = gSaveContext.n64ddFlag ?
showBossKeysanity = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BOSS_KEYSANITY) != RO_DUNGEON_ITEM_LOC_VANILLA
: false;
showGerudoFortressKeys = gSaveContext.n64ddFlag ?
showGerudoFortressKeys = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GERUDO_KEYS) != RO_GERUDO_KEYS_VANILLA
: false;
showGanonBossKey = gSaveContext.n64ddFlag ?
showGanonBossKey = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_VANILLA
: false;
showOcarinas = gSaveContext.n64ddFlag ?
showOcarinas = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_OCARINA) == RO_GENERIC_YES
: false;
show100SkullReward = gSaveContext.n64ddFlag ?
show100SkullReward = IS_RANDO ?
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_100_GS_REWARD) == RO_GENERIC_YES
: false;
if (gSaveContext.n64ddFlag) {
if (IS_RANDO) {
switch (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_TOKENS)) {
case RO_TOKENSANITY_ALL:
showOverworldTokens = true;
@ -747,7 +747,7 @@ bool HasItemBeenCollected(RandomizerCheckObject obj) {
case SpoilerCollectionCheckType::SPOILER_CHK_GRAVEDIGGER:
// Gravedigger has a fix in place that means one of two save locations. Check both.
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
default:
return false;
@ -831,7 +831,7 @@ void DrawLocation(RandomizerCheckObject rcObj, RandomizerCheckShow* thisCheckSta
case RCSHOW_SAVED:
case RCSHOW_CHECKED:
case RCSHOW_SCUMMED:
if (gSaveContext.n64ddFlag)
if (IS_RANDO)
txt = OTRGlobals::Instance->gRandomizer
->EnumToSpoilerfileGetName[gSaveContext.itemLocations[rcObj.rc].get.rgID][gSaveContext.language];
else if (gSaveContext.language == LANGUAGE_ENG)
@ -843,7 +843,7 @@ void DrawLocation(RandomizerCheckObject rcObj, RandomizerCheckShow* thisCheckSta
txt = "Skipped"; //TODO language
break;
case RCSHOW_SEEN:
if (gSaveContext.n64ddFlag)
if (IS_RANDO)
txt = OTRGlobals::Instance->gRandomizer
->EnumToSpoilerfileGetName[gSaveContext.itemLocations[rcObj.rc].get.fakeRgID][gSaveContext.language];
else if (gSaveContext.language == LANGUAGE_ENG)

View File

@ -80,6 +80,10 @@ std::vector<ItemTrackerItem> gregItems = {
ITEM_TRACKER_ITEM(ITEM_RUPEE_GREEN, 0, DrawItem),
};
std::vector<ItemTrackerItem> triforcePieces = {
ITEM_TRACKER_ITEM(RG_TRIFORCE_PIECE, 0, DrawItem),
};
std::vector<ItemTrackerDungeon> itemTrackerDungeonsWithMapsHorizontal = {
{ SCENE_DEKU_TREE, { ITEM_DUNGEON_MAP, ITEM_COMPASS } },
{ SCENE_DODONGOS_CAVERN, { ITEM_DUNGEON_MAP, ITEM_COMPASS } },
@ -243,6 +247,11 @@ typedef enum {
KEYS_CURRENT_MAX
} ItemTrackerKeysNumberOption;
typedef enum {
TRIFORCE_PIECE_COLLECTED_REQUIRED,
TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX
} ItemTrackerTriforcePieceNumberOption;
typedef enum {
SECTION_DISPLAY_HIDDEN,
SECTION_DISPLAY_MAIN_WINDOW,
@ -488,6 +497,37 @@ void DrawItemCount(ItemTrackerItem item) {
ImGui::PushStyleColor(ImGuiCol_Text, maxColor);
ImGui::Text("%s", maxString.c_str());
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 {
ImGui::SetCursorScreenPos(ImVec2(p.x, p.y - 14));
ImGui::Text("");
@ -520,9 +560,11 @@ void DrawQuest(ItemTrackerItem item) {
};
void DrawItem(ItemTrackerItem item) {
uint32_t actualItemId = INV_CONTENT(item.id);
int iconSize = CVarGetInteger("gItemTrackerIconSize", 36);
bool hasItem = actualItemId != ITEM_NONE;
std::string itemName = "";
if (item.id == ITEM_NONE) {
return;
@ -562,6 +604,11 @@ void DrawItem(ItemTrackerItem item) {
actualItemId = item.id;
hasItem = Flags_GetRandomizerInf(RAND_INF_GREG_FOUND);
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()) {
@ -569,13 +616,18 @@ void DrawItem(ItemTrackerItem item) {
}
ImGui::BeginGroup();
ImGui::Image(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName(hasItem && IsValidSaveFile() ? item.name : item.nameFaded),
ImVec2(iconSize, iconSize), ImVec2(0, 0), ImVec2(1, 1));
DrawItemCount(item);
ImGui::EndGroup();
UIWidgets::SetLastItemHoverText(SohUtils::GetItemName(item.id));
if (itemName == "") {
itemName = SohUtils::GetItemName(item.id);
}
UIWidgets::SetLastItemHoverText(itemName);
}
void DrawBottle(ItemTrackerItem item) {
@ -891,6 +943,19 @@ void UpdateVectors() {
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;
}
@ -914,6 +979,7 @@ void ItemTrackerWindow::DrawElement() {
(CVarGetInteger("gItemTrackerSongsDisplayType", SECTION_DISPLAY_MAIN_WINDOW) == 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("gItemTrackerTriforcePiecesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW) ||
(CVarGetInteger("gItemTrackerNotesDisplayType", SECTION_DISPLAY_HIDDEN) == SECTION_DISPLAY_MAIN_WINDOW)
) {
BeginFloatingWindows("Item Tracker##main window");
@ -984,6 +1050,12 @@ void ItemTrackerWindow::DrawElement() {
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) {
ImGui::SetNextWindowSize(ImVec2(400,300), ImGuiCond_FirstUseEver);
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* 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* 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" };
@ -1002,7 +1075,7 @@ static const char* displayTypes[3] = { "Hidden", "Main Window", "Separate" };
static const char* extendedDisplayTypes[4] = { "Hidden", "Main Window", "Misc Window", "Separate" };
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)) {
ImGui::End();
@ -1055,6 +1128,8 @@ void ItemTrackerSettingsWindow::DrawElement() {
UIWidgets::EnhancementSliderInt("Icon size : %dpx", "##ITEMTRACKERICONSIZE", "gItemTrackerIconSize", 25, 128, "", 36);
UIWidgets::EnhancementSliderInt("Icon margins : %dpx", "##ITEMTRACKERSPACING", "gItemTrackerIconSpacing", -5, 50, "", 12);
UIWidgets::Spacer(0);
ImGui::Text("Ammo/Capacity Tracking");
UIWidgets::EnhancementCombobox("gItemTrackerCapacityTrack", itemTrackerCapacityTrackOptions, ITEM_TRACKER_NUMBER_CURRENT_CAPACITY_ONLY);
UIWidgets::InsertHelpHoverText("Customize what the numbers under each item are tracking."
@ -1064,10 +1139,19 @@ void ItemTrackerSettingsWindow::DrawElement() {
shouldUpdateVectors = true;
}
}
UIWidgets::Spacer(0);
ImGui::Text("Key Count Tracking");
UIWidgets::EnhancementCombobox("gItemTrackerKeyTrack", itemTrackerKeyTrackOptions, KEYS_COLLECTED_MAX);
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();
if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Inventory", "gItemTrackerInventoryItemsDisplayType", displayTypes, SECTION_DISPLAY_MAIN_WINDOW)) {
@ -1107,6 +1191,10 @@ void ItemTrackerSettingsWindow::DrawElement() {
shouldUpdateVectors = true;
}
if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Triforce Pieces", "gItemTrackerTriforcePiecesDisplayType", displayTypes, SECTION_DISPLAY_HIDDEN)) {
shouldUpdateVectors = true;
}
if (CVarGetInteger("gItemTrackerDisplayType", TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_ALWAYS) {
if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Personal notes", "gItemTrackerNotesDisplayType", displayTypes, SECTION_DISPLAY_HIDDEN)) {
shouldUpdateVectors = true;

View File

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

View File

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

View File

@ -1110,11 +1110,11 @@ uint32_t IsSceneMasterQuest(s16 sceneNum) {
if (OTRGlobals::Instance->HasMasterQuest()) {
if (!OTRGlobals::Instance->HasOriginal()) {
value = 1;
} else if (gSaveContext.isMasterQuest) {
} else if (IS_MASTER_QUEST) {
value = 1;
} else {
value = 0;
if (gSaveContext.n64ddFlag &&
if (IS_RANDO &&
!OTRGlobals::Instance->gRandomizer->masterQuestDungeons.empty() &&
OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(sceneNum)) {
value = 1;
@ -1966,7 +1966,7 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
const int maxBufferSize = sizeof(font->msgBuf);
CustomMessage messageEntry;
s16 actorParams = 0;
if (gSaveContext.n64ddFlag) {
if (IS_RANDO) {
Player* player = GET_PLAYER(play);
if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) {
if (player->getItemEntry.getItemId == RG_ICE_TRAP) {
@ -1975,6 +1975,8 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
if (CVarGetInteger("gLetItSnow", 0)) {
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, NUM_ICE_TRAP_MESSAGES + 1);
}
} else if (player->getItemEntry.getItemId == RG_TRIFORCE_PIECE) {
messageEntry = Randomizer::GetTriforcePieceMessage();
} else {
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
// inject the auto-dismiss control code if it did.
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;
} else {
textId = TEXT_GS_FREEZE;
}
// 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
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.Replace("{{gsCount}}", std::to_string(gsCount));
}

View File

@ -136,6 +136,8 @@ void SaveManager::LoadRandomizerVersion1() {
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount);
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
@ -251,6 +253,8 @@ void SaveManager::LoadRandomizerVersion2() {
SaveManager::Instance->LoadData("adultTradeItems", gSaveContext.adultTradeItems);
SaveManager::Instance->LoadData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
SaveManager::Instance->LoadData("pendingIceTrapCount", gSaveContext.pendingIceTrapCount);
std::shared_ptr<Randomizer> randomizer = OTRGlobals::Instance->gRandomizer;
@ -282,7 +286,7 @@ void SaveManager::LoadRandomizerVersion2() {
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->SaveStruct("", [&]() {
@ -338,6 +342,8 @@ void SaveManager::SaveRandomizer(SaveContext* saveContext, int sectionID, bool f
SaveManager::Instance->SaveData("adultTradeItems", saveContext->adultTradeItems);
SaveManager::Instance->SaveData("triforcePiecesCollected", gSaveContext.triforcePiecesCollected);
SaveManager::Instance->SaveData("pendingIceTrapCount", saveContext->pendingIceTrapCount);
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].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.
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
// 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].buildVersionMinor = gSaveContext.sohStats.buildVersionMinor;
@ -611,7 +617,7 @@ void SaveManager::InitFileNormal() {
gSaveContext.pendingSale = ITEM_NONE;
gSaveContext.pendingSaleMod = MOD_NONE;
if (gSaveContext.isBossRush) {
if (IS_BOSS_RUSH) {
BossRush_InitSave();
}
@ -891,8 +897,8 @@ void SaveManager::SaveFileThreaded(int fileNum, SaveContext* saveContext, int se
nlohmann::json& sectionBlock = saveBlock["sections"][saveFuncInfo.name];
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
// This clears the randomizer data block if and only if the section being called is "randomizer" and n64ddFlag is false.
if (sectionHandlerPair.second.name == "randomizer" && !gSaveContext.n64ddFlag) {
// 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" && !IS_RANDO) {
sectionBlock["data"] = nlohmann::json::object();
continue;
}
@ -1113,7 +1119,11 @@ void SaveManager::LoadBaseVersion1() {
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t 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("health", gSaveContext.health);
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->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("health", gSaveContext.health);
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->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
if (!gSaveContext.isMagicAcquired) {
@ -1462,7 +1480,11 @@ void SaveManager::LoadBaseVersion3() {
SaveManager::Instance->LoadArray("playerName", ARRAY_COUNT(gSaveContext.playerName), [](size_t 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("health", gSaveContext.health);
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->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("pos", []() {
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->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("health", gSaveContext.health);
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->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("pos", []() {
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->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("health", saveContext->health);
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->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("pos", [&]() {
SaveManager::Instance->SaveData("x", saveContext->backupFW.pos.x);
@ -2149,7 +2183,7 @@ void SaveManager::DeleteZeldaFile(int fileNum) {
}
bool SaveManager::IsRandoFile() {
return gSaveContext.n64ddFlag != 0 ? true : false;
return IS_RANDO;
}
// 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::Tooltip("The default response to Kaepora Gaebora is always that you understood what he said");
UIWidgets::PaddedEnhancementCheckbox("Fast Ocarina Playback", "gFastOcarinaPlayback", true, false);
bool forceSkipScarecrow = gSaveContext.n64ddFlag &&
bool forceSkipScarecrow = IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SKIP_SCARECROWS_SONG);
static const char* forceSkipScarecrowText =
"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::PaddedEnhancementCheckbox("No Random Drops", "gNoRandomDrops", true, false);
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;
static const char* forceEnableBombchuDropsText =
"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");
// Blue Fire Arrows
bool forceEnableBlueFireArrows = gSaveContext.n64ddFlag &&
bool forceEnableBlueFireArrows = IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_BLUE_FIRE_ARROWS);
static const char* forceEnableBlueFireArrowsText =
"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.");
// Sunlight Arrows
bool forceEnableSunLightArrows = gSaveContext.n64ddFlag &&
bool forceEnableSunLightArrows = IS_RANDO &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SUNLIGHT_ARROWS);
static const char* forceEnableSunLightArrowsText =
"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_OWN_DUNGEON &&
OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_GANONS_BOSS_KEY) != RO_GANON_BOSS_KEY_STARTWITH) ||
!gSaveContext.n64ddFlag) {
!IS_RANDO) {
disableKeyColors = false;
}

View File

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

View File

@ -66,15 +66,17 @@ void SkeletonPatcher::ClearSkeletons()
void SkeletonPatcher::UpdateSkeletons() {
bool isHD = CVarGetInteger("gAltAssets", 0);
for (auto skel : skeletons)
{
for (auto skel : skeletons) {
Skeleton* newSkel =
(Skeleton*)LUS::Context::GetInstance()->GetResourceManager()
->LoadResource((isHD ? LUS::IResource::gAltAssetPrefix : "") + skel.vanillaSkeletonPath, true)
.get();
if (newSkel != nullptr)
if (newSkel != nullptr) {
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

View File

@ -24,6 +24,7 @@ enum class SkeletonType {
typedef struct {
/* 0x00 */ void** segment;
/* 0x04 */ uint8_t limbCount;
uint8_t skeletonType;
} SkeletonHeader; // size = 0x8
// 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);
Play_InitEnvironment(play, play->skyboxId);
// 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;
}
/* auto data = static_cast<LUS::Vertex*>(LUS::Context::GetInstance()

View File

@ -668,6 +668,7 @@ void Flags_SetSwitch(PlayState* play, s32 flag) {
} else {
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 {
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) {
lusprintf(__FILE__, __LINE__, 2, "Treasure Flag Set - %#x", 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) {
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) {
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));
}
}
GameInteractor_ExecuteOnSceneFlagSet(play->sceneNum, FLAG_SCENE_COLLECTIBLE, flag);
}
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->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))) {
if ((getItemEntry.getItemId != GI_NONE)) {
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->heldActor != NULL) || (actor == player->targetActor)) &&
((!gSaveContext.n64ddFlag && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX))) ||
(gSaveContext.n64ddFlag && ((getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))))) ||
((!IS_RANDO && ((getItemEntry.getItemId > GI_NONE) && (getItemEntry.getItemId < GI_MAX))) ||
(IS_RANDO && ((getItemEntry.getItemId > RG_NONE) && (getItemEntry.getItemId < RG_MAX))))) ||
(!(player->stateFlags1 & 0x20000800))) {
if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) {
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->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))) {
if ((actor->xzDistToPlayer < xzRange) && (fabsf(actor->yDistToPlayer) < yRange)) {
s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y;
@ -4718,6 +4724,7 @@ s32 Flags_GetEventChkInf(s32 flag) {
*/
void Flags_SetEventChkInf(s32 flag) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
gSaveContext.randomizerInf[flag >> 4] &= ~(1 << (flag & 0xF));
GameInteractor_ExecuteOnFlagUnset(FLAG_RANDOMIZER_INF, flag);
}
u32 func_80035BFC(PlayState* play, s16 arg1) {

View File

@ -246,7 +246,7 @@ void func_80064824(PlayState* play, CutsceneContext* csCtx, CsCmdBase* cmd) {
case 3:
if (sp3F != 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);
}
}
@ -497,7 +497,7 @@ void Cutscene_Command_Terminator(PlayState* play, CutsceneContext* csCtx, CsCmdB
// cmd->base == 8: Traveling back/forward in time cutscene
// cmd->base == 24: Dropping a fish for Jabu Jabu
// 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) &&
(gSaveContext.fileNum != 0xFEDC) && CVarGetInteger("gDebugEnabled", 0));
@ -2113,7 +2113,7 @@ void Cutscene_HandleEntranceTriggers(PlayState* play) {
u8 requiredAge;
s16 i;
if (gSaveContext.n64ddFlag &&
if (IS_RANDO &&
// don't skip epona escape cutscenes
gSaveContext.entranceIndex != 650 &&
gSaveContext.entranceIndex != 654 &&
@ -2151,9 +2151,9 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
if ((gSaveContext.gameMode == 0) && (gSaveContext.respawnFlag <= 0) && (gSaveContext.cutsceneIndex < 0xFFF0)) {
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.n64ddFlag) {
if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_LEARNED_REQUIEM_OF_SPIRIT);
gSaveContext.entranceIndex = 0x0123;
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)) &&
(Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP)) && (Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP)) &&
!Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL)) {
if (!gSaveContext.n64ddFlag) {
if (!IS_RANDO) {
Flags_SetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL);
gSaveContext.cutsceneIndex = 0xFFF0;
}
} 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);
Item_Give(play, ITEM_OCARINA_FAIRY);
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) &&
LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS) &&
(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);
gSaveContext.entranceIndex = 0x0053;
gSaveContext.cutsceneIndex = 0xFFF8;
@ -2187,7 +2187,7 @@ void Cutscene_HandleConditionalTriggers(PlayState* play) {
Flags_SetEventChkInf(EVENTCHKINF_WATCHED_GANONS_CASTLE_COLLAPSE_CAUGHT_BY_GERUDO);
gSaveContext.entranceIndex = 0x0517;
// In rando, skip the cutscene for the tower falling down after the escape.
if (gSaveContext.n64ddFlag) {
if (IS_RANDO) {
return;
}
gSaveContext.cutsceneIndex = 0xFFF0;

View File

@ -78,6 +78,8 @@
#include "objects/object_gi_sword_1/object_gi_sword_1.h"
#include "objects/object_st/object_st.h"
#include "soh_assets.h"
// "Get Item" Model Draw Functions
void GetItem_DrawMaskOrBombchu(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_DrawJewelZora(PlayState* play, s16 drawId);
void GetItem_DrawGenericMusicNote(PlayState* play, s16 drawId);
void GetItem_DrawTriforcePiece(PlayState* play, s16 drawId);
typedef struct {
/* 0x00 */ void (*drawFunc)(PlayState*, s16);
@ -384,7 +387,8 @@ DrawItemTableEntry sDrawItemTable[] = {
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Saria's song
{ GetItem_DrawGenericMusicNote, { gGiSongNoteDL } }, //Sun's song
{ 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);
}
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);
this->scale = 0.03f;
// Offset keys in randomizer slightly higher for their GID replacement
if (!gSaveContext.n64ddFlag) {
if (!IS_RANDO) {
yOffset = 350.0f;
} else {
yOffset = 430.0f;
@ -488,7 +488,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
RandomizerCheck randoCheck =
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 =
Randomizer_GetItemFromKnownCheck(randoCheck, getItemId);
this->randoGiEntry.getItemFrom = ITEM_FROM_FREESTANDING;
@ -578,7 +578,7 @@ void EnItem00_Init(Actor* thisx, PlayState* play) {
if (!Actor_HasParent(&this->actor, play)) {
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);
} else {
GiveItemEntryFromActorWithFixedRange(&this->actor, play, this->randoGiEntry);
@ -731,7 +731,7 @@ void func_8001E5C8(EnItem00* this, PlayState* play) {
Player* player = GET_PLAYER(play);
if (this->getItemId != GI_NONE) {
if (!Actor_HasParent(&this->actor, play)) {
if (!gSaveContext.n64ddFlag) {
if (!IS_RANDO) {
func_8002F434(&this->actor, play, this->getItemId, 50.0f, 80.0f);
} else {
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) {
if (CVarGetInteger("gNewDrops", 0) ||
// 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;
} else {
this->actor.shape.rot.y = 0;
@ -951,7 +951,7 @@ void EnItem00_Update(Actor* thisx, PlayState* play) {
params = &this->actor.params;
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);
} else {
getItemId = this->randoGiEntry.getItemId;
@ -1046,7 +1046,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
}
break;
case ITEM00_HEART_PIECE:
if (CVarGetInteger("gNewDrops", 0) && !gSaveContext.n64ddFlag) {
if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) {
mtxScale = 21.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
GetItem_Draw(play, GID_HEART_PIECE);
@ -1156,7 +1156,7 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) {
break;
}
case ITEM00_SMALL_KEY:
if (CVarGetInteger("gNewDrops", 0) && !gSaveContext.n64ddFlag) {
if (CVarGetInteger("gNewDrops", 0) && !IS_RANDO) {
mtxScale = 8.0f;
Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
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...).
*/
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 =
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.
*/
void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) {
if (gSaveContext.n64ddFlag) {
if (IS_RANDO) {
RandomizerCheck randoCheck =
Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams);
@ -1533,7 +1533,7 @@ s16 func_8001F404(s16 dropId) {
}
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 = EnItem00_ConvertBombDropToBombchu(dropId);
}

View File

@ -33,7 +33,7 @@ void GameOver_Update(PlayState* play) {
gSaveContext.eventInf[1] &= ~1;
// 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++) {
if (INV_CONTENT(ITEM_POCKET_EGG) == gSpoilingItems[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);
assert(horseActor != NULL);
} else if ((play->sceneNum == gSaveContext.horseData.scene) &&
(((Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) != 0) && (!gSaveContext.n64ddFlag ||
(gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_SONG_EPONA) &&
(((Flags_GetEventChkInf(EVENTCHKINF_EPONA_OBTAINED) != 0) && (!IS_RANDO ||
(IS_RANDO && CHECK_QUEST_ITEM(QUEST_SONG_EPONA) &&
(INV_CONTENT(ITEM_OCARINA_FAIRY) != ITEM_NONE)))) || DREG(1) != 0)) {
// "Set by existence of horse %d %d %d"
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();
if (!gSaveContext.sohStats.gameComplete &&
(!gSaveContext.isBossRush || !gSaveContext.isBossRushPaused)) {
(!IS_BOSS_RUSH || !gSaveContext.isBossRushPaused)) {
gSaveContext.sohStats.pauseTimer++;
}

View File

@ -394,8 +394,8 @@ void Map_InitData(PlayState* play, s16 room) {
}
} else if (play->sceneNum == SCENE_LAKE_HYLIA) {
if ((LINK_AGE_IN_YEARS == YEARS_ADULT) &&
((!gSaveContext.n64ddFlag && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
(gSaveContext.n64ddFlag && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)))) {
((!IS_RANDO && !CHECK_QUEST_ITEM(QUEST_MEDALLION_WATER)) ||
(IS_RANDO && !Flags_GetRandomizerInf(RAND_INF_DUNGEONS_DONE_WATER_TEMPLE)))) {
extendedMapIndex = 0x15;
}
} else if (play->sceneNum == SCENE_GERUDO_VALLEY) {
@ -403,8 +403,8 @@ void Map_InitData(PlayState* play, s16 room) {
extendedMapIndex = 0x16;
}
} else if (play->sceneNum == SCENE_GERUDOS_FORTRESS) {
if ((!gSaveContext.n64ddFlag && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) ||
(gSaveContext.n64ddFlag && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) {
if ((!IS_RANDO && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) ||
(IS_RANDO && CHECK_QUEST_ITEM(QUEST_GERUDO_CARD))) {
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
// in order and that you don't have more than the intended amount of heart pieces.
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
} 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
}
// Ocarina Staff + Dialog
@ -2517,7 +2517,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
if (msgCtx->lastPlayedSong < OCARINA_SONG_SARIAS &&
(msgCtx->ocarinaAction < OCARINA_ACTION_PLAYBACK_MINUET ||
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!"
play->msgCtx.ocarinaMode = OCARINA_MODE_04;
} else if ((gSaveContext.eventInf[0] & 0xF) != 1) {
@ -2603,7 +2603,7 @@ void Message_DrawMain(PlayState* play, Gfx** p) {
msgCtx->lastPlayedSong = msgCtx->ocarinaStaff->state;
msgCtx->msgMode = MSGMODE_SONG_PLAYBACK_SUCCESS;
if (!gSaveContext.n64ddFlag) {
if (!IS_RANDO) {
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:
csInfo->keyFrames = D_801225D4;
// 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;
} else {
csInfo->keyFrameCnt = 2;

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