diff options
| author | aMannus <mannusmenting@gmail.com> | 2026-01-10 13:59:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-10 12:59:32 +0000 |
| commit | 14a6bc1f85c2bec1a8aaff6afb7a6dcc01838dbf (patch) | |
| tree | 6ad82d3cecba75a11400362b1709a5cc840df179 | |
| parent | 5bbc32c2d1443390dc4415d62f89fab234f42a81 (diff) | |
Add Roc's Feather (custom item) to Rando Item Pool (#6035)
This adds Roc's as a fully implemented item into the randomizer pool. When both Roc's and Nayru's is found, you can swap between them on the pause menu
Many people have contributed to this over time, so huge shoutout to:
- kentonm, this item is directly inspired by their Roc's Feather from their romhack Indigo. Also provided me with their GI model, icon texture and animation to use.
- PurpleHato, for providing the images for the item name shown on the kaleidoscope.
- Dana The Elf, providing another custom animation for the item.
- Reppan, for helping to tweak the animation and exporting the GI model for me.
50 files changed, 626 insertions, 23 deletions
diff --git a/soh/assets/custom/objects/gameplay_keep/gPlayerAnim_link_rocs_feather_jump b/soh/assets/custom/objects/gameplay_keep/gPlayerAnim_link_rocs_feather_jump Binary files differnew file mode 100644 index 000000000..331911d02 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_keep/gPlayerAnim_link_rocs_feather_jump diff --git a/soh/assets/custom/objects/gameplay_keep/gPlayerAnim_link_rocs_feather_jump_Data b/soh/assets/custom/objects/gameplay_keep/gPlayerAnim_link_rocs_feather_jump_Data Binary files differnew file mode 100644 index 000000000..616c28c81 --- /dev/null +++ b/soh/assets/custom/objects/gameplay_keep/gPlayerAnim_link_rocs_feather_jump_Data diff --git a/soh/assets/custom/objects/object_rocs_feather/eff_unknown_12.i8 b/soh/assets/custom/objects/object_rocs_feather/eff_unknown_12.i8 Binary files differnew file mode 100644 index 000000000..e305f3668 --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/eff_unknown_12.i8 diff --git a/soh/assets/custom/objects/object_rocs_feather/eff_unknown_12_i8 b/soh/assets/custom/objects/object_rocs_feather/eff_unknown_12_i8 Binary files differnew file mode 100644 index 000000000..e305f3668 --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/eff_unknown_12_i8 diff --git a/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL new file mode 100644 index 000000000..2e1d14239 --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL @@ -0,0 +1,16 @@ +<DisplayList Version="0"> + <ClearGeometryMode G_LIGHTING="1" /> + <LoadVertices Path="objects/object_rocs_feather/gGiRocsFeatherDL_vtx_cull" VertexBufferIndex="0" VertexOffset="0" Count="8"/> + <CullDisplayList Start="0" End="7"/> + <CallDisplayList Path="objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_stem"/> + <CallDisplayList Path="objects/object_rocs_feather/gGiRocsFeatherDL_tri_0"/> + <CallDisplayList Path="objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_feather"/> + <CallDisplayList Path="objects/object_rocs_feather/gGiRocsFeatherDL_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> + diff --git a/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_tri_0 b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_tri_0 new file mode 100644 index 000000000..94927832f --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_tri_0 @@ -0,0 +1,21 @@ +<DisplayList Version="0"> + <LoadVertices Path="objects/object_rocs_feather/gGiRocsFeatherDL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="32"/> + <Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="4" V12="5" Flag1="0"/> + <Triangles2 V00="6" V01="7" V02="8" Flag0="0" V10="9" V11="10" V12="11" Flag1="0"/> + <Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="15" V11="16" V12="17" Flag1="0"/> + <Triangles2 V00="15" V01="17" V02="18" Flag0="0" V10="19" V11="20" V12="21" Flag1="0"/> + <Triangles2 V00="19" V01="21" V02="22" Flag0="0" V10="23" V11="24" V12="25" Flag1="0"/> + <Triangles2 V00="23" V01="25" V02="26" Flag0="0" V10="27" V11="28" V12="29" Flag1="0"/> + <Triangles2 V00="29" V01="30" V02="27" Flag0="0" V10="29" V11="31" V12="30" Flag1="0"/> + <LoadVertices Path="objects/object_rocs_feather/gGiRocsFeatherDL_vtx_0" VertexBufferIndex="0" VertexOffset="32" Count="30"/> + <Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="4" V12="5" Flag1="0"/> + <Triangles2 V00="3" V01="5" V02="6" Flag0="0" V10="7" V11="8" V12="9" Flag1="0"/> + <Triangles2 V00="7" V01="9" V02="10" Flag0="0" V10="11" V11="12" V12="13" Flag1="0"/> + <Triangles2 V00="11" V01="13" V02="14" Flag0="0" V10="15" V11="16" V12="17" Flag1="0"/> + <Triangles2 V00="15" V01="17" V02="18" Flag0="0" V10="19" V11="20" V12="21" Flag1="0"/> + <Triangles2 V00="19" V01="21" V02="22" Flag0="0" V10="23" V11="24" V12="25" Flag1="0"/> + <Triangles2 V00="23" V01="25" V02="25" Flag0="0" V10="26" V11="26" V12="28" Flag1="0"/> + <Triangle1 V00="26" V01="28" V02="29"/> + <EndDisplayList/> +</DisplayList> + diff --git a/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_tri_1 b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_tri_1 new file mode 100644 index 000000000..9ab8f972b --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_tri_1 @@ -0,0 +1,30 @@ +<DisplayList Version="0"> + <LoadVertices Path="objects/object_rocs_feather/gGiRocsFeatherDL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="30"/> + <Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="3" V11="4" V12="5" Flag1="0"/> + <Triangles2 V00="6" V01="7" V02="8" Flag0="0" V10="9" V11="10" V12="11" Flag1="0"/> + <Triangles2 V00="12" V01="13" V02="14" Flag0="0" V10="15" V11="16" V12="17" Flag1="0"/> + <Triangles2 V00="18" V01="19" V02="20" Flag0="0" V10="21" V11="22" V12="23" Flag1="0"/> + <Triangles2 V00="24" V01="25" V02="26" Flag0="0" V10="27" V11="28" V12="29" Flag1="0"/> + <LoadVertices Path="objects/object_rocs_feather/gGiRocsFeatherDL_vtx_1" VertexBufferIndex="0" VertexOffset="30" Count="32"/> + <Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/> + <Triangles2 V00="2" V01="4" V02="3" Flag0="0" V10="3" V11="5" V12="0" Flag1="0"/> + <Triangles2 V00="6" V01="7" V02="8" Flag0="0" V10="6" V11="8" V12="9" Flag1="0"/> + <Triangles2 V00="9" V01="10" V02="6" Flag0="0" V10="9" V11="11" V12="10" Flag1="0"/> + <Triangles2 V00="9" V01="12" V02="11" Flag0="0" V10="10" V11="13" V12="6" Flag1="0"/> + <Triangles2 V00="14" V01="15" V02="16" Flag0="0" V10="14" V11="16" V12="17" Flag1="0"/> + <Triangles2 V00="16" V01="18" V02="17" Flag0="0" V10="17" V11="19" V12="14" Flag1="0"/> + <Triangles2 V00="20" V01="21" V02="22" Flag0="0" V10="20" V11="22" V12="23" Flag1="0"/> + <Triangles2 V00="24" V01="20" V02="23" Flag0="0" V10="25" V11="24" V12="23" Flag1="0"/> + <Triangles2 V00="23" V01="26" V02="25" Flag0="0" V10="23" V11="27" V12="26" Flag1="0"/> + <Triangles2 V00="23" V01="28" V02="27" Flag0="0" V10="23" V11="29" V12="28" Flag1="0"/> + <Triangles2 V00="27" V01="30" V02="26" Flag0="0" V10="25" V11="31" V12="24" Flag1="0"/> + <LoadVertices Path="objects/object_rocs_feather/gGiRocsFeatherDL_vtx_1" VertexBufferIndex="0" VertexOffset="62" Count="17"/> + <Triangles2 V00="0" V01="1" V02="2" Flag0="0" V10="0" V11="2" V12="3" Flag1="0"/> + <Triangles2 V00="2" V01="4" V02="3" Flag0="0" V10="5" V11="6" V12="7" Flag1="0"/> + <Triangles2 V00="5" V01="7" V02="8" Flag0="0" V10="7" V11="9" V12="8" Flag1="0"/> + <Triangles2 V00="8" V01="10" V02="5" Flag0="0" V10="8" V11="11" V12="10" Flag1="0"/> + <Triangles2 V00="10" V01="12" V02="5" Flag0="0" V10="13" V11="14" V12="15" Flag1="0"/> + <Triangle1 V00="13" V01="15" V02="16"/> + <EndDisplayList/> +</DisplayList> + diff --git a/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_0 b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_0 new file mode 100644 index 000000000..6b1681449 --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_0 @@ -0,0 +1,64 @@ +<Vertex Version="0"> + <Vtx X="-18" Y="-17" Z="3" S="-571" T="1073" R="225" G="213" B="116" A="255"/> + <Vtx X="-15" Y="-19" Z="3" S="-490" T="1097" R="225" G="213" B="116" A="255"/> + <Vtx X="-15" Y="-14" Z="5" S="-647" T="1032" R="225" G="213" B="116" A="255"/> + <Vtx X="5" Y="25" Z="4" S="926" T="-577" R="84" G="213" B="86" A="255"/> + <Vtx X="13" Y="34" Z="2" S="1187" T="-900" R="84" G="213" B="86" A="255"/> + <Vtx X="5" Y="25" Z="5" S="917" T="-568" R="84" G="213" B="86" A="255"/> + <Vtx X="21" Y="41" Z="-4" S="1243" T="-1254" R="23" G="59" B="110" A="255"/> + <Vtx X="12" Y="34" Z="2" S="890" T="-998" R="23" G="59" B="110" A="255"/> + <Vtx X="13" Y="34" Z="2" S="929" T="-987" R="23" G="59" B="110" A="255"/> + <Vtx X="13" Y="34" Z="2" S="802" T="-678" R="17" G="34" B="121" A="255"/> + <Vtx X="12" Y="34" Z="2" S="763" T="-689" R="17" G="34" B="121" A="255"/> + <Vtx X="5" Y="25" Z="5" S="633" T="-688" R="17" G="34" B="121" A="255"/> + <Vtx X="12" Y="34" Z="2" S="1125" T="-893" R="195" G="79" B="79" A="255"/> + <Vtx X="4" Y="25" Z="4" S="839" T="-578" R="195" G="79" B="79" A="255"/> + <Vtx X="5" Y="25" Z="5" S="846" T="-568" R="195" G="79" B="79" A="255"/> + <Vtx X="-18" Y="-17" Z="3" S="-22" T="833" R="139" G="35" B="35" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-30" T="854" R="139" G="35" B="35" A="255"/> + <Vtx X="-23" Y="-31" Z="-1" S="-218" T="1342" R="139" G="35" B="35" A="255"/> + <Vtx X="-22" Y="-31" Z="0" S="-209" T="1319" R="139" G="35" B="35" A="255"/> + <Vtx X="-7" Y="0" Z="6" S="405" T="229" R="75" G="226" B="98" A="255"/> + <Vtx X="5" Y="25" Z="4" S="880" T="-644" R="75" G="226" B="98" A="255"/> + <Vtx X="5" Y="25" Z="5" S="874" T="-640" R="75" G="226" B="98" A="255"/> + <Vtx X="-9" Y="0" Z="7" S="398" T="236" R="75" G="226" B="98" A="255"/> + <Vtx X="-22" Y="-31" Z="-2" S="-303" T="1303" R="15" G="21" B="132" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-151" T="802" R="15" G="21" B="132" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="-73" T="853" R="15" G="21" B="132" A="255"/> + <Vtx X="-20" Y="-31" Z="-2" S="-246" T="1302" R="15" G="21" B="132" A="255"/> + <Vtx X="-20" Y="-31" Z="1" S="-229" T="1730" R="0" G="129" B="0" A="255"/> + <Vtx X="-22" Y="-31" Z="0" S="-287" T="1731" R="0" G="129" B="0" A="255"/> + <Vtx X="-23" Y="-31" Z="-1" S="-331" T="1738" R="0" G="129" B="0" A="255"/> + <Vtx X="-20" Y="-31" Z="-2" S="-234" T="1746" R="0" G="129" B="0" A="255"/> + <Vtx X="-22" Y="-31" Z="-2" S="-292" T="1747" R="0" G="129" B="0" A="255"/> + <Vtx X="-20" Y="-31" Z="-2" S="-234" T="1746" R="0" G="129" B="0" A="255"/> + <Vtx X="-19" Y="-31" Z="-1" S="-181" T="1739" R="0" G="129" B="0" A="255"/> + <Vtx X="-20" Y="-31" Z="1" S="-229" T="1730" R="0" G="129" B="0" A="255"/> + <Vtx X="-20" Y="-31" Z="1" S="-38" T="1351" R="113" G="212" B="39" A="255"/> + <Vtx X="-19" Y="-31" Z="-1" S="-34" T="1345" R="113" G="212" B="39" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="161" T="933" R="113" G="212" B="39" A="255"/> + <Vtx X="-15" Y="-19" Z="3" S="167" T="918" R="113" G="212" B="39" A="255"/> + <Vtx X="-15" Y="-19" Z="3" S="-16" T="1008" R="241" G="235" B="124" A="255"/> + <Vtx X="-18" Y="-17" Z="3" S="-16" T="1008" R="241" G="235" B="124" A="255"/> + <Vtx X="-22" Y="-31" Z="0" S="-16" T="1008" R="241" G="235" B="124" A="255"/> + <Vtx X="-20" Y="-31" Z="1" S="-16" T="1008" R="241" G="235" B="124" A="255"/> + <Vtx X="-10" Y="1" Z="6" S="294" T="191" R="179" G="16" B="100" A="255"/> + <Vtx X="-18" Y="-17" Z="3" S="-16" T="825" R="179" G="16" B="100" A="255"/> + <Vtx X="-15" Y="-14" Z="5" S="76" T="722" R="179" G="16" B="100" A="255"/> + <Vtx X="-9" Y="0" Z="7" S="304" T="187" R="179" G="16" B="100" A="255"/> + <Vtx X="-15" Y="-19" Z="3" S="80" T="907" R="71" G="210" B="95" A="255"/> + <Vtx X="-7" Y="0" Z="6" S="388" T="207" R="71" G="210" B="95" A="255"/> + <Vtx X="-9" Y="0" Z="7" S="382" T="201" R="71" G="210" B="95" A="255"/> + <Vtx X="-15" Y="-14" Z="5" S="123" T="745" R="71" G="210" B="95" A="255"/> + <Vtx X="4" Y="25" Z="4" S="837" T="-659" R="188" G="45" B="98" A="255"/> + <Vtx X="-10" Y="1" Z="6" S="295" T="185" R="188" G="45" B="98" A="255"/> + <Vtx X="-9" Y="0" Z="7" S="302" T="188" R="188" G="45" B="98" A="255"/> + <Vtx X="5" Y="25" Z="5" S="843" T="-654" R="188" G="45" B="98" A="255"/> + <Vtx X="-19" Y="-31" Z="-1" S="-40" T="1364" R="87" G="243" B="164" A="255"/> + <Vtx X="-20" Y="-31" Z="-2" S="-52" T="1393" R="87" G="243" B="164" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="153" T="959" R="87" G="243" B="164" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-25" T="839" R="164" G="44" B="180" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-25" T="839" R="164" G="44" B="180" A="255"/> + <Vtx X="-22" Y="-31" Z="-2" S="-212" T="1327" R="164" G="44" B="180" A="255"/> + <Vtx X="-23" Y="-31" Z="-1" S="-214" T="1330" R="164" G="44" B="180" A="255"/> +</Vertex> diff --git a/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_1 b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_1 new file mode 100644 index 000000000..44ab97157 --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_1 @@ -0,0 +1,81 @@ +<Vertex Version="0"> + <Vtx X="-4" Y="-14" Z="0" S="30868" T="-30560" R="225" G="123" B="0" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="-25435088" T="50901360" R="225" G="123" B="0" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="-25435024" T="50901232" R="225" G="123" B="0" A="255"/> + <Vtx X="-18" Y="-17" Z="3" S="-210" T="881" R="138" G="209" B="0" A="255"/> + <Vtx X="-21" Y="-8" Z="0" S="-246" T="605" R="138" G="209" B="0" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-216" T="876" R="138" G="209" B="0" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="135" T="1196" R="47" G="138" B="0" A="255"/> + <Vtx X="-4" Y="-14" Z="0" S="468" T="970" R="47" G="138" B="0" A="255"/> + <Vtx X="-15" Y="-19" Z="3" S="131" T="1187" R="47" G="138" B="0" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-26861712" T="75270256" R="225" G="133" B="0" A="255"/> + <Vtx X="-21" Y="-8" Z="0" S="31392" T="-30448" R="225" G="133" B="0" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-26861752" T="75270368" R="225" G="133" B="0" A="255"/> + <Vtx X="0" Y="-6" Z="2" S="521" T="800" R="254" G="127" B="1" A="255"/> + <Vtx X="0" Y="-6" Z="4" S="529" T="808" R="254" G="127" B="1" A="255"/> + <Vtx X="9" Y="-6" Z="2" S="813" T="804" R="254" G="127" B="1" A="255"/> + <Vtx X="0" Y="-6" Z="4" S="579" T="784" R="18" G="130" B="255" A="255"/> + <Vtx X="0" Y="-6" Z="2" S="557" T="760" R="18" G="130" B="255" A="255"/> + <Vtx X="10" Y="-4" Z="2" S="935" T="777" R="18" G="130" B="255" A="255"/> + <Vtx X="8" Y="13" Z="2" S="828" T="153" R="245" G="127" B="0" A="255"/> + <Vtx X="8" Y="13" Z="4" S="837" T="160" R="245" G="127" B="0" A="255"/> + <Vtx X="19" Y="14" Z="1" S="1232" T="86" R="245" G="127" B="0" A="255"/> + <Vtx X="8" Y="13" Z="4" S="933" T="102" R="38" G="135" B="253" A="255"/> + <Vtx X="8" Y="13" Z="2" S="921" T="97" R="38" G="135" B="253" A="255"/> + <Vtx X="20" Y="17" Z="1" S="1362" T="-39" R="38" G="135" B="253" A="255"/> + <Vtx X="1" Y="31" Z="0" S="362" T="-917" R="131" G="23" B="3" A="255"/> + <Vtx X="1" Y="31" Z="1" S="353" T="-907" R="131" G="23" B="3" A="255"/> + <Vtx X="2" Y="36" Z="-2" S="280" T="-1105" R="131" G="23" B="3" A="255"/> + <Vtx X="1" Y="31" Z="0" S="239" T="-724" R="97" G="82" B="0" A="255"/> + <Vtx X="-2" Y="34" Z="-1" S="125" T="-811" R="97" G="82" B="0" A="255"/> + <Vtx X="1" Y="31" Z="1" S="231" T="-715" R="97" G="82" B="0" A="255"/> + <Vtx X="-7" Y="0" Z="6" S="266" T="174" R="30" G="212" B="115" A="255"/> + <Vtx X="-15" Y="-19" Z="3" S="85" T="942" R="30" G="212" B="115" A="255"/> + <Vtx X="-4" Y="-14" Z="0" S="438" T="853" R="30" G="212" B="115" A="255"/> + <Vtx X="0" Y="-6" Z="4" S="536" T="385" R="30" G="212" B="115" A="255"/> + <Vtx X="9" Y="-6" Z="2" S="840" T="386" R="30" G="212" B="115" A="255"/> + <Vtx X="10" Y="-4" Z="2" S="887" T="340" R="30" G="212" B="115" A="255"/> + <Vtx X="-18" Y="11" Z="-1" S="-150" T="-279" R="211" G="50" B="108" A="255"/> + <Vtx X="-10" Y="1" Z="6" S="157" T="155" R="211" G="50" B="108" A="255"/> + <Vtx X="4" Y="25" Z="4" S="679" T="-711" R="211" G="50" B="108" A="255"/> + <Vtx X="12" Y="34" Z="2" S="986" T="-1032" R="211" G="50" B="108" A="255"/> + <Vtx X="1" Y="31" Z="1" S="588" T="-926" R="211" G="50" B="108" A="255"/> + <Vtx X="2" Y="36" Z="-2" S="618" T="-1162" R="211" G="50" B="108" A="255"/> + <Vtx X="21" Y="41" Z="-4" S="1296" T="-1320" R="211" G="50" B="108" A="255"/> + <Vtx X="-2" Y="34" Z="-1" S="486" T="-1064" R="211" G="50" B="108" A="255"/> + <Vtx X="-15" Y="-19" Z="3" S="-288" T="1192" R="185" G="150" B="0" A="255"/> + <Vtx X="-18" Y="-17" Z="3" S="-374" T="1166" R="185" G="150" B="0" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-381" T="1186" R="185" G="150" B="0" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="-295" T="1213" R="185" G="150" B="0" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-381" T="1186" R="185" G="150" B="0" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="-295" T="1213" R="185" G="150" B="0" A="255"/> + <Vtx X="2" Y="36" Z="-2" S="577" T="-1176" R="5" G="247" B="129" A="255"/> + <Vtx X="21" Y="41" Z="-4" S="1259" T="-1325" R="5" G="247" B="129" A="255"/> + <Vtx X="20" Y="17" Z="1" S="1217" T="-461" R="5" G="247" B="129" A="255"/> + <Vtx X="8" Y="13" Z="2" S="782" T="-317" R="5" G="247" B="129" A="255"/> + <Vtx X="1" Y="31" Z="0" S="539" T="-966" R="5" G="247" B="129" A="255"/> + <Vtx X="-18" Y="11" Z="-1" S="-136" T="-282" R="5" G="247" B="129" A="255"/> + <Vtx X="-4" Y="-14" Z="0" S="229" T="886" R="5" G="247" B="129" A="255"/> + <Vtx X="0" Y="-6" Z="2" S="507" T="364" R="5" G="247" B="129" A="255"/> + <Vtx X="10" Y="-4" Z="2" S="854" T="310" R="5" G="247" B="129" A="255"/> + <Vtx X="19" Y="14" Z="1" S="1194" T="-359" R="5" G="247" B="129" A="255"/> + <Vtx X="9" Y="-6" Z="2" S="807" T="356" R="5" G="247" B="129" A="255"/> + <Vtx X="-2" Y="34" Z="-1" S="449" T="-1081" R="5" G="247" B="129" A="255"/> + <Vtx X="-4" Y="-14" Z="0" S="229" T="886" R="5" G="247" B="129" A="255"/> + <Vtx X="-15" Y="-19" Z="1" S="-16" T="1008" R="5" G="247" B="129" A="255"/> + <Vtx X="-18" Y="-17" Z="1" S="-16" T="1008" R="5" G="247" B="129" A="255"/> + <Vtx X="-18" Y="11" Z="-1" S="-136" T="-282" R="5" G="247" B="129" A="255"/> + <Vtx X="-21" Y="-8" Z="0" S="-284" T="452" R="5" G="247" B="129" A="255"/> + <Vtx X="5" Y="25" Z="4" S="675" T="-722" R="33" G="1" B="123" A="255"/> + <Vtx X="-7" Y="0" Z="6" S="238" T="161" R="33" G="1" B="123" A="255"/> + <Vtx X="10" Y="-4" Z="2" S="876" T="297" R="33" G="1" B="123" A="255"/> + <Vtx X="8" Y="13" Z="4" S="784" T="-310" R="33" G="1" B="123" A="255"/> + <Vtx X="19" Y="14" Z="1" S="1192" T="-364" R="33" G="1" B="123" A="255"/> + <Vtx X="21" Y="41" Z="-4" S="1262" T="-1307" R="33" G="1" B="123" A="255"/> + <Vtx X="20" Y="17" Z="1" S="1211" T="-467" R="33" G="1" B="123" A="255"/> + <Vtx X="13" Y="34" Z="2" S="935" T="-1050" R="33" G="1" B="123" A="255"/> + <Vtx X="-18" Y="-17" Z="3" S="-110" T="803" R="185" G="15" B="104" A="255"/> + <Vtx X="-10" Y="1" Z="6" S="129" T="130" R="185" G="15" B="104" A="255"/> + <Vtx X="-18" Y="11" Z="-1" S="-217" T="-220" R="185" G="15" B="104" A="255"/> + <Vtx X="-21" Y="-8" Z="0" S="-254" T="515" R="185" G="15" B="104" A="255"/> +</Vertex> diff --git a/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_cull b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_cull new file mode 100644 index 000000000..e43cf3bda --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/gGiRocsFeatherDL_vtx_cull @@ -0,0 +1,10 @@ +<Vertex Version="0"> + <Vtx X="-23" Y="-31" Z="-4" S="-16" T="-16" R="0" G="0" B="0" A="0"/> + <Vtx X="-23" Y="-31" Z="7" S="-16" T="-16" R="0" G="0" B="0" A="0"/> + <Vtx X="-23" Y="41" Z="7" S="-16" T="-16" R="0" G="0" B="0" A="0"/> + <Vtx X="-23" Y="41" Z="-4" S="-16" T="-16" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="-31" Z="-4" S="-16" T="-16" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="-31" Z="7" S="-16" T="-16" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="41" Z="7" S="-16" T="-16" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="41" Z="-4" S="-16" T="-16" R="0" G="0" B="0" A="0"/> +</Vertex> diff --git a/soh/assets/custom/objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_feather b/soh/assets/custom/objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_feather new file mode 100644 index 000000000..e21e92ff8 --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_feather @@ -0,0 +1,22 @@ +<DisplayList Version="0"> + <PipeSync/> + <SetCombineLERP A0="G_CCMUX_PRIMITIVE" B0="G_CCMUX_ENVIRONMENT" C0="G_CCMUX_TEXEL0" D0="G_CCMUX_ENVIRONMENT" Aa0="G_ACMUX_1" Ab0="G_ACMUX_1" Ac0="G_ACMUX_PRIM_LOD_FRAC" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_SHADE" D1="G_CCMUX_0" Aa1="G_ACMUX_1" Ab1="G_ACMUX_1" Ac1="G_ACMUX_PRIM_LOD_FRAC" Ad1="G_ACMUX_1"/> + <SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_LIGHTING="1" G_SHADING_SMOOTH="1" /> + + <SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" /> + <SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_PASS="1" G_RM_AA_ZB_TEX_EDGE2="1" /> + <Texture S="65535" T="65535" Level="0" Tile="0" On="1"/> + <SetTextureLUT Mode="G_TT_NONE"/> + <TileSync/> + <SetTextureImage Path="objects/object_rocs_feather/eff_unknown_12_i8" Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_LOAD_BLOCK" Width="1"/> + <SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_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="4" MaskT="5" ShiftT="4"/> + <LoadSync/> + <LoadBlock Tile="7" Uls="0" Ult="0" Lrs="511" Dxt="512"/> + <PipeSync/> + <SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b" Line="4" TMem="0" Tile="0" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="4" MaskT="5" ShiftT="4"/> + <SetTileSize T="0" Uls="12" Ult="120" Lrs="124" Lrt="124"/> + <SetPrimColor M="0" L="0" R="101" G="34" B="255" A="255"/> + <SetEnvColor R="44" G="187" B="200" A="255"/> + <EndDisplayList/> +</DisplayList> + diff --git a/soh/assets/custom/objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_stem b/soh/assets/custom/objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_stem new file mode 100644 index 000000000..b523babf2 --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/mat_gGiRocsFeatherDL_feather_stem @@ -0,0 +1,22 @@ +<DisplayList Version="0"> + <PipeSync/> + <SetCombineLERP A0="G_CCMUX_PRIMITIVE" B0="G_CCMUX_ENVIRONMENT" C0="G_CCMUX_TEXEL0" D0="G_CCMUX_ENVIRONMENT" Aa0="G_ACMUX_1" Ab0="G_ACMUX_1" Ac0="G_ACMUX_PRIM_LOD_FRAC" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_SHADE" D1="G_CCMUX_0" Aa1="G_ACMUX_1" Ab1="G_ACMUX_1" Ac1="G_ACMUX_PRIM_LOD_FRAC" Ad1="G_ACMUX_1"/> + <SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_LIGHTING="1" G_SHADING_SMOOTH="1" /> + + <SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" /> + <SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_PASS="1" G_RM_AA_ZB_TEX_EDGE2="1" /> + <Texture S="65535" T="65535" Level="0" Tile="0" On="1"/> + <SetTextureLUT Mode="G_TT_NONE"/> + <TileSync/> + <SetTextureImage Path="objects/object_rocs_feather/eff_unknown_12_i8" Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_LOAD_BLOCK" Width="1"/> + <SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b_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="2" MaskT="5" ShiftT="2"/> + <LoadSync/> + <LoadBlock Tile="7" Uls="0" Ult="0" Lrs="511" Dxt="512"/> + <PipeSync/> + <SetTile Format="G_IM_FMT_I" Size="G_IM_SIZ_8b" Line="4" TMem="0" Tile="0" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="2" MaskT="5" ShiftT="2"/> + <SetTileSize T="0" Uls="0" Ult="0" Lrs="124" Lrt="124"/> + <SetPrimColor M="0" L="0" R="165" G="147" B="255" A="255"/> + <SetEnvColor R="107" G="68" B="230" A="255"/> + <EndDisplayList/> +</DisplayList> + diff --git a/soh/assets/custom/objects/object_rocs_feather/model.xml b/soh/assets/custom/objects/object_rocs_feather/model.xml new file mode 100644 index 000000000..5d798a1ab --- /dev/null +++ b/soh/assets/custom/objects/object_rocs_feather/model.xml @@ -0,0 +1,10 @@ +<Vertex Version="0"> + <Vtx X="-23" Y="-40" Z="-4" S="0" T="0" R="0" G="0" B="0" A="0"/> + <Vtx X="-23" Y="-40" Z="7" S="0" T="0" R="0" G="0" B="0" A="0"/> + <Vtx X="-23" Y="32" Z="7" S="0" T="0" R="0" G="0" B="0" A="0"/> + <Vtx X="-23" Y="32" Z="-4" S="0" T="0" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="-40" Z="-4" S="0" T="0" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="-40" Z="7" S="0" T="0" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="32" Z="7" S="0" T="0" R="0" G="0" B="0" A="0"/> + <Vtx X="21" Y="32" Z="-4" S="0" T="0" R="0" G="0" B="0" A="0"/> +</Vertex> diff --git a/soh/assets/custom/textures/icon_item_static/gRocsFeatherTex.rgba32.png b/soh/assets/custom/textures/icon_item_static/gRocsFeatherTex.rgba32.png Binary files differnew file mode 100644 index 000000000..b2e4f99da --- /dev/null +++ b/soh/assets/custom/textures/icon_item_static/gRocsFeatherTex.rgba32.png diff --git a/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameENGTex.ia4.png b/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameENGTex.ia4.png Binary files differnew file mode 100644 index 000000000..bc72f3ced --- /dev/null +++ b/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameENGTex.ia4.png diff --git a/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameFRATex.ia4.png b/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameFRATex.ia4.png Binary files differnew file mode 100644 index 000000000..dc42bdc07 --- /dev/null +++ b/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameFRATex.ia4.png diff --git a/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameGERTex.ia4.png b/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameGERTex.ia4.png Binary files differnew file mode 100644 index 000000000..5842acfeb --- /dev/null +++ b/soh/assets/custom/textures/item_name_static/gRocsFeatherItemNameGERTex.ia4.png diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index e1c7b810e..c0ec61420 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -354,6 +354,9 @@ static const ALIGN_ASSET(2) char gKeyringKeysGanonsCastleMQDL[] = dgKeyringKeysG #define dgHouseKeyDL "__OTR__objects/object_housekey/gHouseKeyDL" static const ALIGN_ASSET(2) char gHouseKeyDL[] = dgHouseKeyDL; +#define dgGiRocsFeatherDL "__OTR__objects/object_rocs_feather/gGiRocsFeatherDL" +static const ALIGN_ASSET(2) char gGiRocsFeatherDL[] = dgGiRocsFeatherDL; + // overlays #define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx" static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx; @@ -437,6 +440,18 @@ static const ALIGN_ASSET(2) char gFileSelLanguageFRATex[] = dgFileSelLanguageFRA #define dgFileSelLanguageGERTex "__OTR__textures/title_static/gFileSelLanguageGERTex" static const ALIGN_ASSET(2) char gFileSelLanguageGERTex[] = dgFileSelLanguageGERTex; +#define dgRocsFeatherTex "__OTR__textures/icon_item_static/gRocsFeatherTex" +static const ALIGN_ASSET(2) char gRocsFeatherTex[] = dgRocsFeatherTex; + +#define dgRocsFeatherItemNameENGTex "__OTR__textures/item_name_static/gRocsFeatherItemNameENGTex" +static const ALIGN_ASSET(2) char gRocsFeatherItemNameENGTex[] = dgRocsFeatherItemNameENGTex; + +#define dgRocsFeatherItemNameGERTex "__OTR__textures/item_name_static/gRocsFeatherItemNameGERTex" +static const ALIGN_ASSET(2) char gRocsFeatherItemNameGERTex[] = dgRocsFeatherItemNameGERTex; + +#define dgRocsFeatherItemNameFRATex "__OTR__textures/item_name_static/gRocsFeatherItemNameFRATex" +static const ALIGN_ASSET(2) char gRocsFeatherItemNameFRATex[] = dgRocsFeatherItemNameFRATex; + #define dgEmptyTexture "__OTR__textures/virtual/gEmptyTexture" static const ALIGN_ASSET(2) char gEmptyTexture[] = dgEmptyTexture; @@ -459,6 +474,10 @@ static const ALIGN_ASSET(2) char gLinkAdultGoronTunicSkel[] = dgLinkAdultGoronTu #define dgLinkAdultZoraTunicSkel "__OTR__objects/object_link_boy_zora/gLinkAdultZoraTunicSkel" static const ALIGN_ASSET(2) char gLinkAdultZoraTunicSkel[] = dgLinkAdultZoraTunicSkel; +// Animations +#define dgPlayerAnim_link_rocs_feather_jump "__OTR__objects/gameplay_keep/gPlayerAnim_link_rocs_feather_jump" +static const ALIGN_ASSET(2) char gPlayerAnim_link_rocs_feather_jump[] = dgPlayerAnim_link_rocs_feather_jump; + // LUS Logo #define dgShipLogoDL "__OTR__textures/nintendo_rogo_static/gShipLogoDL" static const ALIGN_ASSET(2) char gShipLogoDL[] = dgShipLogoDL; diff --git a/soh/include/functions.h b/soh/include/functions.h index 8d4990290..13ebb0507 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -2452,11 +2452,13 @@ void Font_LoadOrderedFontNTSC(Font* font); // #endregion // #region SOH [General] - void Interface_RandoRestoreSwordless(void); s32 Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projectedW, bool* shouldDraw, bool* shouldUpdate); +// #region SOH [Rocs Feather] +void func_80838940(Player* this, LinkAnimationHeader* anim, f32 arg2, PlayState* play, u16 sfxId); + // #endregion #ifdef __cplusplus diff --git a/soh/include/variables.h b/soh/include/variables.h index 27ad4584d..e296017aa 100644 --- a/soh/include/variables.h +++ b/soh/include/variables.h @@ -103,7 +103,7 @@ extern "C" extern u16 gUpgradeCapacities[8][4]; extern u32 gGsFlagsMasks[4]; extern u32 gGsFlagsShifts[4]; - extern void* gItemIcons[0x82]; + extern void* gItemIcons[157]; extern u8 gItemAgeReqs[]; extern u8 gSlotAgeReqs[]; extern u8 gItemSlots[56]; diff --git a/soh/include/z64item.h b/soh/include/z64item.h index b1fa897fe..9bbb8bb30 100644 --- a/soh/include/z64item.h +++ b/soh/include/z64item.h @@ -309,6 +309,7 @@ typedef enum { /* 0x99 */ ITEM_STICK_UPGRADE_30, /* 0x9A */ ITEM_NUT_UPGRADE_30, /* 0x9B */ ITEM_NUT_UPGRADE_40, + /* */ ITEM_ROCS_FEATHER, /* 0xFC */ ITEM_LAST_USED = 0xFC, /* 0xFE */ ITEM_NONE_FE = 0xFE, /* 0xFF */ ITEM_NONE = 0xFF @@ -592,6 +593,7 @@ typedef enum { /* 0x7A */ GID_SONG_TIME, /* 0x7B */ GID_SONG_STORM, /* 0x7C */ GID_TRIFORCE_PIECE, + /* 0x7C */ GID_ROCS_FEATHER, /* */ GID_FISHING_POLE, /* 0x7C */ GID_MAXIMUM diff --git a/soh/soh/Enhancements/debugconsole.cpp b/soh/soh/Enhancements/debugconsole.cpp index ff40f149a..6a1e619d4 100644 --- a/soh/soh/Enhancements/debugconsole.cpp +++ b/soh/soh/Enhancements/debugconsole.cpp @@ -394,7 +394,7 @@ static bool GiveItemHandler(std::shared_ptr<Ship::Console> Console, const std::v if (args[1].compare("vanilla") == 0) { getItemEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_NONE, std::stoi(args[2])); } else if (args[1].compare("randomizer") == 0) { - getItemEntry = ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, std::stoi(args[2])); + getItemEntry = Rando::StaticData::RetrieveItem((RandomizerGet)std::stoi(args[2])).GetGIEntry_Copy(); } else { ERROR_MESSAGE("[SOH] Invalid argument passed, must be 'vanilla' or 'randomizer'"); return 1; diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp index 4cd3b4f45..342dc34fa 100644 --- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp +++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp @@ -13,6 +13,7 @@ #include <string> #include <libultraship/bridge.h> #include <libultraship/libultraship.h> +#include <soh_assets.h> extern "C" { #include <z64.h> @@ -540,7 +541,16 @@ void DrawInventoryTab() { uint8_t item = gSaveContext.inventory.items[index]; PushStyleButton(Colors::DarkGray); - if (item != ITEM_NONE) { + if (item == ITEM_ROCS_FEATHER) { + auto ret = ImGui::ImageButton( + "ROCS_FEATHER", + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetTextureByName("ROCS_FEATHER"), + ImVec2(48.0f, 48.0f), ImVec2(0, 0), ImVec2(1, 1)); + if (ret) { + selectedIndex = index; + ImGui::OpenPopup(itemPopupPicker); + } + } else if (item != ITEM_NONE) { const ItemMapEntry& slotEntry = itemMapping.find(item)->second; auto ret = ImGui::ImageButton( slotEntry.name.c_str(), @@ -1843,4 +1853,6 @@ void SaveEditorWindow::DrawElement() { } void SaveEditorWindow::InitElement() { + Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture("ROCS_FEATHER", gRocsFeatherTex, + ImVec4(1, 1, 1, 1)); } diff --git a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h index b561985ed..ec0382661 100644 --- a/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h +++ b/soh/soh/Enhancements/game-interactor/vanilla-behavior/GIVanillaBehavior.h @@ -2482,6 +2482,14 @@ typedef enum { // true // ``` // #### `args` + // - `*int16_t` // pauseCtx->namedItem + VB_DRAW_CUSTOM_ITEM_NAME, + + // #### `result` + // ```c + // true + // ``` + // #### `args` // - `*PlayState` // - `uint16_t` (cursorSlot - promoted from `u16`) // - `uint16_t` (cursorItem - promoted from `u16`) diff --git a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp index 4962aeac2..6a0c8babe 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/hint_list/hint_list_item.cpp @@ -1964,6 +1964,12 @@ void StaticData::HintTable_Init_Item() { CustomMessage("a gold fragment", /*german*/"ein Goldfragment", /*french*/"un fragment d'or")}); // /*spanish*/un fragmento dorado + hintTextTable[RHT_ROCS_FEATHER] = HintText(CustomMessage("Roc's Feather", /*german*/"Roc's Feather", /*french*/"Roc's Feather"), + {}, { + CustomMessage("a feather", /*german*/"a feather", /*french*/"a feather"), + CustomMessage("a chicken wing", /*german*/"a chicken wing", /*french*/"a chicken wing"), + CustomMessage("a blue wing", /*german*/"a blue wing", /*french*/"a blue wing")}); + hintTextTable[RHT_BEAN_SOUL] = HintText(CustomMessage("a bean soul", /*german*/"eine bohnenseele", /*french*/"une âme de haricot")); hintTextTable[RHT_GOHMA_SOUL] = HintText(CustomMessage("the soul of Gohma", /*german*/"Gohmas Seele", /*french*/"l'Âme de Gohma"), diff --git a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp index 710869d81..26c7119fa 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_pool.cpp @@ -384,6 +384,10 @@ void GenerateItemPool() { AddFixedItemToPool(RG_SKELETON_KEY, 1); } + if (ctx->GetOption(RSK_ROCS_FEATHER)) { + AddItemToPool(RG_ROCS_FEATHER, 2, 1, 1, 1); + } + int bronzeScale = ctx->GetOption(RSK_SHUFFLE_SWIM) ? 1 : 0; AddItemToPool(RG_PROGRESSIVE_SCALE, 3 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale, 2 + bronzeScale); diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp index 970b05389..01683eec4 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp @@ -887,6 +887,11 @@ void InitTrickNames() { Text{ "Triforce Shard", "Éclat de Triforce", "Triforce-Fragment" }, // "Triforce Shard" Text{ "Shiny Rock", "Caillou Brillant", "glänzender Stein" }, // "Shiny Rock" }; + trickNameTable[RG_ROCS_FEATHER] = { + Text{ "Chicken Wing", "Chicken Wing", "Chicken Wing" }, // "Chicken Wing" + Text{ "Roc's Leg", "Roc's Leg", "Roc's Leg" }, // "Roc's Leg" + Text{ "Roc's Fapper", "Roc's Fapper", "Roc's Fapper" }, // "Roc's Fapper" + }; trickNameTable[RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL] = { // TODO_TRANSLATE Text{ "Volcano Seed Spirit" }, @@ -1539,7 +1544,7 @@ void InitTrickNames() { } // Generate a fake name for the ice trap based on the item it's displayed as -Text GetIceTrapName(int id) { +Text GetIceTrapName(uint16_t id) { // If the trick names table has not been initialized, do so if (!initTrickNames) { InitTrickNames(); diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.hpp b/soh/soh/Enhancements/randomizer/3drando/shops.hpp index 109ea6143..a5b42cf68 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.hpp @@ -27,4 +27,4 @@ extern std::vector<RandomizerGet> GetMinVanillaShopItems(int total_replaced); extern uint16_t GetRandomPrice(Rando::Location* loc, PriceSettingsStruct priceSettings); extern uint16_t GetCheapBalancedPrice(); extern int GetShopsanityReplaceAmount(); -extern Text GetIceTrapName(int id); +extern Text GetIceTrapName(uint16_t id); diff --git a/soh/soh/Enhancements/randomizer/RocsFeather.cpp b/soh/soh/Enhancements/randomizer/RocsFeather.cpp new file mode 100644 index 000000000..e90b4d3c1 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/RocsFeather.cpp @@ -0,0 +1,101 @@ +#include <soh/OTRGlobals.h> +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" +#include <soh_assets.h> + +extern "C" { +#include <z64.h> +#include "functions.h" +#include "variables.h" +#include "macros.h" +#include "objects/gameplay_keep/gameplay_keep.h" +extern PlayState* gPlayState; +} + +#define MAX_ROCS_USES 1 + +static uint8_t rocsUseCount = 0; +static uint8_t groundTimer = 0; +static f32 effectsScale = 1.0f; + +void RegisterRocsFeather() { + bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_ROCS_FEATHER); + + COND_HOOK(OnPlayerUpdate, shouldRegister, []() { + Player* player = GET_PLAYER(gPlayState); + + // Reset Rocs count when touching the ground for 3+ frames + if (player->actor.bgCheckFlags & 1) { + if (groundTimer <= 3) { + groundTimer++; + } + } else { + groundTimer = 0; + } + + if (groundTimer >= 3) { + rocsUseCount = 0; + } + }); + + COND_VB_SHOULD(VB_CHANGE_HELD_ITEM_AND_USE_ITEM, shouldRegister, { + int32_t usedItem = va_arg(args, int32_t); + + // Roc's Feather behaviour + if (usedItem == ITEM_ROCS_FEATHER) { + *should = false; + + if (rocsUseCount < MAX_ROCS_USES) { + rocsUseCount++; + + Player* player = GET_PLAYER(gPlayState); + + func_80838940(player, (LinkAnimationHeader*)&gPlayerAnim_link_rocs_feather_jump, 5.8f, gPlayState, 0); + + // Actionvar needed to prevent weird animation morph + player->av2.actionVar2 = 1; + + // Move player forward on Roc's use + player->linearVelocity = 5.0f; + player->actor.world.rot.y = player->yaw = player->actor.shape.rot.y; + + if (gSaveContext.linkAge == LINK_AGE_CHILD) { + player->actor.velocity.y = 7.0f; + effectsScale = 1.0f; + } else { + player->actor.velocity.y = 7.5f; + effectsScale = 1.5f; + } + + Vec3f effectsPos = player->actor.home.pos; + effectsPos.y += 3; + + EffectSsGRipple_Spawn(gPlayState, &effectsPos, 200 * effectsScale, 300 * effectsScale, 1); + EffectSsGSplash_Spawn(gPlayState, &effectsPos, NULL, NULL, 0, 150 * effectsScale); + + // Remove hopping state when using Roc's after sidehop/backflip to allow grabbing ledges again + player->stateFlags2 &= ~(PLAYER_STATE2_HOPPING); + + Player_PlaySfx(&player->actor, NA_SE_PL_SKIP); + } + } + }); + + COND_VB_SHOULD(VB_DRAW_CUSTOM_ITEM_NAME, shouldRegister, { + u32 namedItem = va_arg(args, u32); + if (namedItem == ITEM_ROCS_FEATHER) { + *should = true; + const char* textureName = gRocsFeatherItemNameENGTex; + + if (gSaveContext.language == LANGUAGE_GER) { + textureName = gRocsFeatherItemNameGERTex; + } else if (gSaveContext.language == LANGUAGE_FRA) { + textureName = gRocsFeatherItemNameFRATex; + } + + memcpy(gPlayState->pauseCtx.nameSegment, textureName, strlen(textureName) + 1); + } + }); +} + +static RegisterShipInitFunc registerRocsFeather(RegisterRocsFeather, { "IS_RANDO" }); diff --git a/soh/soh/Enhancements/randomizer/RocsFeatherCycle.c b/soh/soh/Enhancements/randomizer/RocsFeatherCycle.c new file mode 100644 index 000000000..31dfb9030 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/RocsFeatherCycle.c @@ -0,0 +1,25 @@ +#include "soh/Enhancements/randomizer/RocsFeatherCycle.h" +#include "functions.h" +#include "variables.h" +#include "macros.h" + +uint8_t Enhancement_GetNextNayrusItem() { + if (INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NAYRUS_LOVE && Flags_GetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER)) { + return ITEM_ROCS_FEATHER; + } + if (INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_ROCS_FEATHER && Flags_GetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE)) { + return ITEM_NAYRUS_LOVE; + } + return ITEM_NONE; +} + +uint8_t Enhancement_GetPrevNayrusItem() { + if (INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NAYRUS_LOVE && Flags_GetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER)) { + return ITEM_ROCS_FEATHER; + } + if (INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_ROCS_FEATHER && Flags_GetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE)) { + return ITEM_NAYRUS_LOVE; + } + + return ITEM_NONE; +} diff --git a/soh/soh/Enhancements/randomizer/RocsFeatherCycle.h b/soh/soh/Enhancements/randomizer/RocsFeatherCycle.h new file mode 100644 index 000000000..859cb5ab6 --- /dev/null +++ b/soh/soh/Enhancements/randomizer/RocsFeatherCycle.h @@ -0,0 +1,9 @@ +#ifndef ROCS_FEATHER_H +#define ROCS_FEATHER_H + +#include <z64.h> + +uint8_t Enhancement_GetNextNayrusItem(); +uint8_t Enhancement_GetPrevNayrusItem(); + +#endif diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp index 0334b9e1d..78295f45c 100644 --- a/soh/soh/Enhancements/randomizer/draw.cpp +++ b/soh/soh/Enhancements/randomizer/draw.cpp @@ -490,6 +490,21 @@ extern "C" void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getIte CLOSE_DISPS(play->state.gfxCtx); } +extern "C" void Randomizer_DrawRocsFeather(PlayState* play, GetItemEntry* getItemEntry) { + Color_RGB8 color = { 0, 60, 100 }; + + OPEN_DISPS(play->state.gfxCtx); + + Gfx_SetupDL_25Xlu(play->state.gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), + G_MTX_MODELVIEW | G_MTX_LOAD); + + gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gGiRocsFeatherDL); + + CLOSE_DISPS(play->state.gfxCtx); +} + Gfx* GetEmptyDlist(GraphicsContext* gfxCtx) { Gfx* dListHead; Gfx* dList; diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h index 3830fdceb..474835c53 100644 --- a/soh/soh/Enhancements/randomizer/draw.h +++ b/soh/soh/Enhancements/randomizer/draw.h @@ -28,6 +28,7 @@ void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBombchuBagInLogic(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawBombchuBag(PlayState* play, GetItemEntry* getItemEntry); void Randomizer_DrawOverworldKey(PlayState* play, GetItemEntry* getItemEntry); +void Randomizer_DrawRocsFeather(PlayState* play, GetItemEntry* getItemEntry); #define GET_ITEM_MYSTERY \ { \ diff --git a/soh/soh/Enhancements/randomizer/item_list.cpp b/soh/soh/Enhancements/randomizer/item_list.cpp index bfd487ed6..4ff3e1e04 100644 --- a/soh/soh/Enhancements/randomizer/item_list.cpp +++ b/soh/soh/Enhancements/randomizer/item_list.cpp @@ -424,6 +424,8 @@ void Rando::StaticData::InitItemTable() { itemTable[RG_MAGIC_SINGLE] = Item(RG_MAGIC_SINGLE, Text{ "Magic Meter", "Jauge de Magie", "Magische Kraft" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_SINGLE, RG_MAGIC_SINGLE, OBJECT_GI_MAGICPOT, GID_MAGIC_SMALL, 0xE4, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); itemTable[RG_MAGIC_DOUBLE] = Item(RG_MAGIC_DOUBLE, Text{ "Enhanced Magic Meter", "Jauge de Magie améliorée", "Verb. Magische Kraft" }, ITEMTYPE_ITEM, 0x8A, true, LOGIC_PROGRESSIVE_MAGIC, RHT_MAGIC_DOUBLE, RG_MAGIC_DOUBLE, OBJECT_GI_MAGICPOT, GID_MAGIC_LARGE, 0xE8, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_LESSER, MOD_RANDOMIZER); itemTable[RG_TRIFORCE_PIECE] = Item(RG_TRIFORCE_PIECE, Text{ "Triforce Piece", "Triforce Piece", "Triforce-Splitter" }, ITEMTYPE_ITEM, 0xDF, true, LOGIC_TRIFORCE_PIECES, RHT_TRIFORCE_PIECE, RG_TRIFORCE_PIECE, OBJECT_GI_BOMB_2, GID_TRIFORCE_PIECE, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ROCS_FEATHER] = Item(RG_ROCS_FEATHER, Text{ "Roc's Feather", "Roc's Feather", "Roc's Feather" }, ITEMTYPE_ITEM, 0xE0, true, LOGIC_ROCS_FEATHER, RHT_ROCS_FEATHER, RG_ROCS_FEATHER, OBJECT_GI_BOMB_2, GID_ROCS_FEATHER, TEXT_RANDOMIZER_CUSTOM_ITEM, 0x80, CHEST_ANIM_LONG, ITEM_CATEGORY_MAJOR, MOD_RANDOMIZER); + itemTable[RG_ROCS_FEATHER].SetCustomDrawFunc(Randomizer_DrawRocsFeather); // clang-format on diff --git a/soh/soh/Enhancements/randomizer/option_descriptions.cpp b/soh/soh/Enhancements/randomizer/option_descriptions.cpp index ea559f7a8..be68728a5 100644 --- a/soh/soh/Enhancements/randomizer/option_descriptions.cpp +++ b/soh/soh/Enhancements/randomizer/option_descriptions.cpp @@ -770,6 +770,9 @@ void Settings::CreateOptionDescriptions() { mOptionDescriptions[RSK_SUNLIGHT_ARROWS] = "Light Arrows can be used to light up the sun switches instead of using the Mirror Shield. " "Item placement logic will respect this option, so it might be required to use this to progress."; + mOptionDescriptions[RSK_ROCS_FEATHER] = + "Adds Roc's Feather to the item pool. Roc's Feather is a custom item granting the player a jump on demand. " + "The jump can also be used when already in mid-air. Roc's Feather is not considered by logic."; mOptionDescriptions[RSK_SLINGBOW_BREAK_BEEHIVES] = "Allows Slingshot and Bow to break beehives when Beehive Shuffle is turned on."; mOptionDescriptions[RSK_LOGIC_RULES] = diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index bca464444..c2e60dd5b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -67,6 +67,7 @@ const std::string Randomizer::triforcePieceMessageTableID = "RandomizerTriforceP const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi"; const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap"; const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints"; +const std::string Randomizer::RocsFeatherMessageTableID = "RandomizerRocsFeather"; static const char* englishRupeeNames[188] = { "[P]", @@ -982,7 +983,13 @@ ItemObtainability Randomizer::GetItemObtainabilityFromRandomizerGet(RandomizerGe case RG_FARORES_WIND: return INV_CONTENT(ITEM_FARORES_WIND) == ITEM_NONE ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; case RG_NAYRUS_LOVE: - return INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NONE ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + if (!GetRandoSettingValue(RSK_ROCS_FEATHER)) { + return INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NONE ? CAN_OBTAIN : CANT_OBTAIN_ALREADY_HAVE; + } else { + return Flags_GetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN; + } + case RG_ROCS_FEATHER: + return Flags_GetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER) ? CANT_OBTAIN_ALREADY_HAVE : CAN_OBTAIN; // Bottles case RG_EMPTY_BOTTLE: @@ -4311,6 +4318,22 @@ CustomMessage Randomizer::GetTriforcePieceMessage() { return messageEntry; } +void CreateRocsFeatherMessage() { + CustomMessage RocsFeatherMessage = { + { "You found %cRoc's Feather%w!", "You found %cRoc's Feather%w!", "You found %cRoc's Feather%w!" }, + }; + CustomMessageManager* customMessageManager = CustomMessageManager::Instance; + customMessageManager->AddCustomMessageTable(Randomizer::RocsFeatherMessageTableID); + customMessageManager->CreateMessage(Randomizer::RocsFeatherMessageTableID, 0, RocsFeatherMessage); +} + +CustomMessage Randomizer::GetRocsFeatherMessage() { + CustomMessage messageEntry = + CustomMessageManager::Instance->RetrieveMessage(Randomizer::RocsFeatherMessageTableID, 0); + messageEntry.Format(); + return messageEntry; +} + void CreateNaviRandoMessages() { CustomMessage NaviMessages[NUM_NAVI_MESSAGES] = { @@ -5310,6 +5333,7 @@ void Randomizer::CreateCustomMessages() { } }; CreateGetItemMessages(getItemMessages); CreateRupeeMessages(); + CreateRocsFeatherMessage(); CreateTriforcePieceMessages(); CreateNaviRandoMessages(); CreateFireTempleGoronMessages(); @@ -5765,6 +5789,12 @@ extern "C" u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) { INV_CONTENT(ITEM_NUT) = ITEM_NUT; AMMO(ITEM_NUT) = static_cast<int8_t>(CUR_CAPACITY(UPG_NUTS)); break; + case RG_ROCS_FEATHER: + Flags_SetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER); + if (INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NONE) { + INV_CONTENT(ITEM_NAYRUS_LOVE) = ITEM_ROCS_FEATHER; + } + break; default: LUSLOG_WARN("Randomizer_Item_Give didn't have behaviour specified for getItemId=%d", item); assert(false); diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h index 7cdc2935a..b745edd38 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.h +++ b/soh/soh/Enhancements/randomizer/randomizer.h @@ -38,6 +38,7 @@ class Randomizer { static const std::string NaviRandoMessageTableID; static const std::string IceTrapRandoMessageTableID; static const std::string randoMiscHintsTableID; + static const std::string RocsFeatherMessageTableID; static Sprite* GetSeedTexture(uint8_t index); bool SpoilerFileExists(const char* spoilerFileName); @@ -75,6 +76,7 @@ class Randomizer { static CustomMessage GetRupeeMessage(u16 rupeeTextId); static CustomMessage GetIceTrapMessage(); static CustomMessage GetTriforcePieceMessage(); + static CustomMessage GetRocsFeatherMessage(); }; #ifdef __cplusplus diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 9275dc44d..5427b5e01 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -212,6 +212,7 @@ typedef enum { LOGIC_OCARINA_C_LEFT_BUTTON, LOGIC_OCARINA_C_RIGHT_BUTTON, LOGIC_TRIFORCE_PIECES, + LOGIC_ROCS_FEATHER, LOGIC_CAN_BORROW_MASKS, LOGIC_BORROW_SKULL_MASK, LOGIC_BORROW_SPOOKY_MASK, @@ -4659,6 +4660,10 @@ typedef enum { RG_BACK_TOWER_KEY, RG_HYLIA_LAB_KEY, RG_FISHING_HOLE_KEY, + + // Custom Items + RG_ROCS_FEATHER, + // Logic Only RG_STICKS, RG_NUTS, @@ -5784,6 +5789,7 @@ typedef enum { RHT_DEKU_STICK_CAPACITY_20, RHT_DEKU_STICK_CAPACITY_30, RHT_TRIFORCE_PIECE, + RHT_ROCS_FEATHER, RHT_BEAN_SOUL, RHT_GOHMA_SOUL, RHT_KING_DODONGO_SOUL, @@ -6595,6 +6601,7 @@ typedef enum { RSK_SHUFFLE_SONG_FAIRIES, RSK_LOCK_OVERWORLD_DOORS, RSK_SHUFFLE_GRASS, + RSK_ROCS_FEATHER, RSK_MAX } RandomizerSettingKey; diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h index 7017ec738..f15f7c1d1 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_inf.h +++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h @@ -2100,3 +2100,5 @@ DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_7) DEFINE_RAND_INF(RAND_INF_DEKU_TREE_QUEEN_GOHMA_GRASS_8) // End Grass DEFINE_RAND_INF(RAND_INF_OBTAINED_RUTOS_LETTER) +DEFINE_RAND_INF(RAND_INF_OBTAINED_NAYRUS_LOVE) +DEFINE_RAND_INF(RAND_INF_OBTAINED_ROCS_FEATHER) diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 02b1860cf..7c846ec32 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -137,6 +137,10 @@ std::vector<ItemTrackerItem> triforcePieces = { ITEM_TRACKER_ITEM(RG_TRIFORCE_PIECE, 0, DrawItem), }; +std::vector<ItemTrackerItem> rocsFeather = { + ITEM_TRACKER_ITEM(RG_ROCS_FEATHER, 0, DrawItem), +}; + std::vector<ItemTrackerItem> beanSoulItems = { ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), ITEM_TRACKER_ITEM_CUSTOM(RG_DEATH_MOUNTAIN_TRAIL_BEAN_SOUL, ITEM_BEAN, ITEM_BEAN, 0, DrawItem), @@ -838,6 +842,16 @@ void DrawItem(ItemTrackerItem item) { RO_TRIFORCE_HUNT_OFF); itemName = "Triforce Piece"; break; + case ITEM_NAYRUS_LOVE: + if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_ROCS_FEATHER)) { + hasItem = Flags_GetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE); + } + break; + case RG_ROCS_FEATHER: + actualItemId = item.id; + hasItem = Flags_GetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER); + itemName = "Roc's Feather"; + break; case RG_DEATH_MOUNTAIN_CRATER_BEAN_SOUL: actualItemId = item.id; hasItem = Flags_GetRandomizerInf(RAND_INF_DEATH_MOUNTAIN_CRATER_BEAN_SOUL); @@ -1493,6 +1507,9 @@ void UpdateVectors() { SECTION_DISPLAY_MAIN_WINDOW) { mainWindowItems.insert(mainWindowItems.end(), dungeonItems.begin(), dungeonItems.end()); } + if (IS_RANDO && RAND_GET_OPTION(RSK_ROCS_FEATHER)) { + mainWindowItems.insert(mainWindowItems.end(), rocsFeather.begin(), rocsFeather.end()); + } // if we're adding greg to the misc window, // and misc isn't on the main window, @@ -2241,4 +2258,9 @@ void RegisterItemTrackerWidgets() { SohGui::mSohMenu->AddSearchWidget({ hookshotIdentWidget, "Randomizer", "Item Tracker", "General Settings" }); } +void RegisterItemTracker() { + COND_HOOK(OnLoadFile, true, [](int32_t fileNum) { shouldUpdateVectors = true; }); +} + +static RegisterShipInitFunc registerItemTracker(RegisterItemTracker); static RegisterMenuInitFunc menuInitFunc(RegisterItemTrackerWidgets); diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 6bc89940e..11fd5cf38 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -1230,6 +1230,7 @@ void Settings::CreateOptions() { // TODO: Compasses show rewards/woth, maps show dungeon mode OPT_BOOL(RSK_BLUE_FIRE_ARROWS, "Blue Fire Arrows", CVAR_RANDOMIZER_SETTING("BlueFireArrows"), mOptionDescriptions[RSK_BLUE_FIRE_ARROWS]); OPT_BOOL(RSK_SUNLIGHT_ARROWS, "Sunlight Arrows", CVAR_RANDOMIZER_SETTING("SunlightArrows"), mOptionDescriptions[RSK_SUNLIGHT_ARROWS]); + OPT_BOOL(RSK_ROCS_FEATHER, "Roc's Feather", CVAR_RANDOMIZER_SETTING("RocsFeather"), mOptionDescriptions[RSK_ROCS_FEATHER]); OPT_U8(RSK_INFINITE_UPGRADES, "Infinite Upgrades", {"Off", "Progressive", "Condensed Progressive"}, OptionCategory::Setting, CVAR_RANDOMIZER_SETTING("InfiniteUpgrades"), mOptionDescriptions[RSK_INFINITE_UPGRADES]); OPT_BOOL(RSK_SKELETON_KEY, "Skeleton Key", CVAR_RANDOMIZER_SETTING("SkeletonKey"), mOptionDescriptions[RSK_SKELETON_KEY]); OPT_BOOL(RSK_SLINGBOW_BREAK_BEEHIVES, "Slingshot/Bow Can Break Beehives", CVAR_RANDOMIZER_SETTING("SlingBowBeehives"), mOptionDescriptions[RSK_SLINGBOW_BREAK_BEEHIVES]); @@ -2379,6 +2380,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_OCARINA_BUTTONS], &mOptions[RSK_SHUFFLE_SWIM], &mOptions[RSK_SHUFFLE_BEAN_SOULS], + &mOptions[RSK_ROCS_FEATHER], &mOptions[RSK_BOMBCHU_BAG], &mOptions[RSK_ENABLE_BOMBCHU_DROPS], &mOptions[RSK_INFINITE_UPGRADES], @@ -2612,6 +2614,7 @@ void Settings::CreateOptions() { &mOptions[RSK_SHUFFLE_CHEST_MINIGAME], &mOptions[RSK_SHUFFLE_100_GS_REWARD], &mOptions[RSK_SHUFFLE_BEAN_SOULS], + &mOptions[RSK_ROCS_FEATHER], &mOptions[RSK_SHUFFLE_BOSS_SOULS], &mOptions[RSK_SHUFFLE_DEKU_STICK_BAG], &mOptions[RSK_SHUFFLE_DEKU_NUT_BAG], diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 114435e9c..0f2364ca8 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2419,6 +2419,8 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) { messageEntry = Randomizer::GetIceTrapMessage(); } else if (player->getItemEntry.getItemId == RG_TRIFORCE_PIECE) { messageEntry = Randomizer::GetTriforcePieceMessage(); + } else if (player->getItemEntry.getItemId == RG_ROCS_FEATHER) { + messageEntry = Randomizer::GetRocsFeatherMessage(); } else { messageEntry = Randomizer_GetCustomGetItemMessage(player); } diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index b6070d00c..2de2ab025 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1094,6 +1094,9 @@ void SaveManager::InitFileMaxed() { gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_PAST_BRIDGE_SPAWN; gSaveContext.sceneFlags[5].swch = 0x40000000; + + Flags_SetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE); + Flags_SetRandomizerInf(RAND_INF_OBTAINED_ROCS_FEATHER); } #if defined(__WIIU__) || defined(__SWITCH__) diff --git a/soh/soh/SohGui/ImGuiUtils.cpp b/soh/soh/SohGui/ImGuiUtils.cpp index c80293a53..69690ff53 100644 --- a/soh/soh/SohGui/ImGuiUtils.cpp +++ b/soh/soh/SohGui/ImGuiUtils.cpp @@ -133,11 +133,9 @@ 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 } } -}; - -std::map<uint32_t, ItemMapEntry> bossSoulMapping = { +std::map<uint32_t, ItemMapEntry> customItemsMapping = { + { RG_TRIFORCE_PIECE, { RG_TRIFORCE_PIECE, "RG_TRIFORCE_PIECE", "RG_TRIFORCE_PIECE_Faded", gTriforcePieceTex } }, + { RG_ROCS_FEATHER, { RG_ROCS_FEATHER, "RG_ROCS_FEATHER", "RG_ROCS_FEATHER_Faded", gRocsFeatherTex } }, { RG_GOHMA_SOUL, { RG_GOHMA_SOUL, "RG_GOHMA_SOUL", "RG_GOHMA_SOUL_Faded", gBossSoulTex } }, { RG_KING_DODONGO_SOUL, { RG_KING_DODONGO_SOUL, "RG_KING_DODONGO_SOUL", "RG_KING_DODONGO_SOUL_Faded", gBossSoulTex } }, @@ -216,14 +214,7 @@ void RegisterImGuiItemIcons() { entry.second.texturePath, gregFadedGreen); } - for (const auto& entry : triforcePieceMapping) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, - ImVec4(1, 1, 1, 1)); - Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture( - entry.second.nameFaded, entry.second.texturePath, ImVec4(1, 1, 1, 0.3f)); - } - - for (const auto& entry : bossSoulMapping) { + for (const auto& entry : customItemsMapping) { Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(entry.second.name, entry.second.texturePath, ImVec4(1, 1, 1, 1)); Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture( diff --git a/soh/soh/SohGui/ImGuiUtils.h b/soh/soh/SohGui/ImGuiUtils.h index 2206b4e48..a92a1d737 100644 --- a/soh/soh/SohGui/ImGuiUtils.h +++ b/soh/soh/SohGui/ImGuiUtils.h @@ -36,8 +36,6 @@ typedef struct { // Maps items ids to info for use in ImGui extern std::map<uint32_t, ItemMapEntry> itemMapping; -extern std::map<uint32_t, ItemMapEntry> gregMapping; - typedef struct { uint32_t id; std::string name; diff --git a/soh/src/code/z_inventory.c b/soh/src/code/z_inventory.c index 4141ffe1f..5f317672d 100644 --- a/soh/src/code/z_inventory.c +++ b/soh/src/code/z_inventory.c @@ -3,6 +3,7 @@ #include "textures/icon_item_static/icon_item_static.h" #include "textures/icon_item_24_static/icon_item_24_static.h" #include "textures/parameter_static/parameter_static.h" +#include <soh_assets.h> // Bit Flag array in which gBitFlags[n] is literally (1 << n) u32 gBitFlags[] = { @@ -168,6 +169,35 @@ void* gItemIcons[] = { gOcarinaBtnIconCLeftTex, gOcarinaBtnIconCRightTex, gOcarinaBtnIconATex, + // Push down array to reach newly added item IDs + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + // Start custom items + gRocsFeatherTex, }; // Used to map item IDs to inventory slots diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index a9dfdd01f..86a72456f 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -2464,6 +2464,12 @@ u8 Item_Give(PlayState* play, u8 item) { } return Return_Item(item, MOD_NONE, ITEM_NONE); + } else if (item == ITEM_NAYRUS_LOVE && Randomizer_GetSettingValue(RSK_ROCS_FEATHER)) { + Flags_SetRandomizerInf(RAND_INF_OBTAINED_NAYRUS_LOVE); + if (INV_CONTENT(ITEM_NAYRUS_LOVE) == ITEM_NONE) { + INV_CONTENT(ITEM_NAYRUS_LOVE) = ITEM_NAYRUS_LOVE; + } + return Return_Item(item, MOD_NONE, ITEM_NONE); } returnItem = gSaveContext.inventory.items[slot]; osSyncPrintf("Item_Register(%d)=%d %d\n", slot, item, returnItem); diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c index 4890fa2a4..aa51915c1 100644 --- a/soh/src/code/z_play.c +++ b/soh/src/code/z_play.c @@ -594,6 +594,10 @@ void Play_Init(GameState* thisx) { gSlotAgeReqs[SLOT_TRADE_CHILD] = AGE_REQ_CHILD; } + // Handle Rocs Feather requiement + gItemAgeReqs[ITEM_ROCS_FEATHER] = AGE_REQ_NONE; + gSlotAgeReqs[SLOT_NAYRUS_LOVE] = AGE_REQ_NONE; + func_800304DC(play, &play->actorCtx, play->linkActorEntry); while (!func_800973FC(play, &play->roomCtx)) { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index 28e5e3ed8..1bf210630 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -2,6 +2,7 @@ #include "textures/parameter_static/parameter_static.h" #include "textures/icon_item_static/icon_item_static.h" #include "soh/Enhancements/randomizer/ShuffleTradeItems.h" +#include "soh/Enhancements/randomizer/RocsFeatherCycle.h" #include "soh/Enhancements/randomizer/randomizerTypes.h" #include "soh/Enhancements/enhancementTypes.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" @@ -374,6 +375,10 @@ void KaleidoScope_HandleItemCycles(PlayState* play) { KaleidoScope_HandleItemCycleExtras(play, SLOT_TRADE_ADULT, IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE), Randomizer_GetPrevAdultTradeItem(), Randomizer_GetNextAdultTradeItem(), true); + + // Handle Nayru's Love/Roc's Feather + KaleidoScope_HandleItemCycleExtras(play, SLOT_NAYRUS_LOVE, Randomizer_GetSettingValue(RSK_ROCS_FEATHER), + Enhancement_GetPrevNayrusItem(), Enhancement_GetNextNayrusItem(), true); } void KaleidoScope_DrawItemCycles(PlayState* play) { @@ -393,6 +398,10 @@ void KaleidoScope_DrawItemCycles(PlayState* play) { KaleidoScope_DrawItemCycleExtras(play, SLOT_TRADE_ADULT, IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_ADULT_TRADE), Randomizer_GetPrevAdultTradeItem(), Randomizer_GetNextAdultTradeItem()); + + // Draw Nayru's Love/Roc's Feather + KaleidoScope_DrawItemCycleExtras(play, SLOT_NAYRUS_LOVE, Randomizer_GetSettingValue(RSK_ROCS_FEATHER), + Enhancement_GetPrevNayrusItem(), Enhancement_GetNextNayrusItem()); } bool IsItemCycling() { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c index 1e53d8180..b4cb2d793 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_scope_PAL.c @@ -22,6 +22,7 @@ #include "soh/ResourceManagerHelpers.h" #include "soh/SaveManager.h" #include "soh/Enhancements/kaleido.h" +#include <soh_assets.h> static void* sEquipmentFRATexs[] = { gPauseEquipment00FRATex, gPauseEquipment01Tex, gPauseEquipment02Tex, gPauseEquipment03Tex, gPauseEquipment04Tex, @@ -2493,7 +2494,10 @@ void KaleidoScope_UpdateNamePanel(PlayState* play) { osSyncPrintf("J_N=%d point=%d\n", gSaveContext.language, sp2A); const char* textureName = iconNameTextures[sp2A]; - memcpy(pauseCtx->nameSegment, textureName, strlen(textureName) + 1); + + if (!GameInteractor_Should(VB_DRAW_CUSTOM_ITEM_NAME, false, pauseCtx->namedItem)) { + memcpy(pauseCtx->nameSegment, textureName, strlen(textureName) + 1); + } } pauseCtx->nameDisplayTimer = 0; |
