diff --git a/CMakeLists.txt b/CMakeLists.txt
index fccae7f3630..597cda235be 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,8 +5,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version")
-project(Ship VERSION 8.0.1 LANGUAGES C CXX)
-set(PROJECT_BUILD_NAME "MacReady Bravo" CACHE STRING "")
+project(Ship VERSION 8.0.3 LANGUAGES C CXX)
+set(PROJECT_BUILD_NAME "Holiday 2023" CACHE STRING "")
set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "")
set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh)
diff --git a/libultraship b/libultraship
index 9509806ae3c..59427a67bf9 160000
--- a/libultraship
+++ b/libultraship
@@ -1 +1 @@
-Subproject commit 9509806ae3ca6e35882fb976de70c5bde471b8f5
+Subproject commit 59427a67bf9af060a4928bb72e3acce3b0782177
diff --git a/soh/assets/custom/objects/object_festivehats/antlers_64 b/soh/assets/custom/objects/object_festivehats/antlers_64
new file mode 100644
index 00000000000..74fe9e81977
Binary files /dev/null and b/soh/assets/custom/objects/object_festivehats/antlers_64 differ
diff --git a/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL b/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL
new file mode 100644
index 00000000000..ab8fdf45f29
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL_tri_0
new file mode 100644
index 00000000000..980452845c3
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL_tri_0
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL_vtx_0
new file mode 100644
index 00000000000..8a64cdf18f5
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gCuccoLadyHatDL_vtx_0
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL
new file mode 100644
index 00000000000..6d059179fdb
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_tri_0
new file mode 100644
index 00000000000..3e0ab2ad8f3
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_tri_0
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_tri_1 b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_tri_1
new file mode 100644
index 00000000000..99f0a799deb
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_tri_1
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_vtx_0
new file mode 100644
index 00000000000..ebb2b0eeac3
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_vtx_0
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_vtx_1 b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_vtx_1
new file mode 100644
index 00000000000..d7263bc946b
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gEponaRudolphHatDL_vtx_1
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL b/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL
new file mode 100644
index 00000000000..2b2ee6c3e6a
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL_tri_0
new file mode 100644
index 00000000000..543e90c1f4b
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL_tri_0
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL_vtx_0
new file mode 100644
index 00000000000..d7263bc946b
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gHorseAntlersDL_vtx_0
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL b/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL
new file mode 100644
index 00000000000..27bdd9211b2
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL_tri_0
new file mode 100644
index 00000000000..313f489de85
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL_tri_0
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL_vtx_0
new file mode 100644
index 00000000000..eb7d042ff69
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkAdultHatTrimDL_vtx_0
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL b/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL
new file mode 100644
index 00000000000..6f72624513b
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL_tri_0
new file mode 100644
index 00000000000..83cf6d929d6
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL_tri_0
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL_vtx_0
new file mode 100644
index 00000000000..b937dad3e38
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkAdultPompomDL_vtx_0
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL b/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL
new file mode 100644
index 00000000000..769a4192892
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL_tri_0
new file mode 100644
index 00000000000..776fb4da9e8
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL_tri_0
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL_vtx_0
new file mode 100644
index 00000000000..847f1ae8164
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkChildHatTrimDL_vtx_0
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL b/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL
new file mode 100644
index 00000000000..4093e1aa37a
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL_tri_0
new file mode 100644
index 00000000000..4f18af8bf8a
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL_tri_0
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL_vtx_0
new file mode 100644
index 00000000000..b0c371f1350
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gLinkChildPompomDL_vtx_0
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL b/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL
new file mode 100644
index 00000000000..ec6ccada7f5
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL_tri_0
new file mode 100644
index 00000000000..672602bc15c
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL_tri_0
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL_vtx_0
new file mode 100644
index 00000000000..c7a513a67fb
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gPaperCrownGenericDL_vtx_0
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL
new file mode 100644
index 00000000000..0f457397652
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_tri_0 b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_tri_0
new file mode 100644
index 00000000000..5396ff4d8a9
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_tri_0
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_tri_1 b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_tri_1
new file mode 100644
index 00000000000..bdf895c49f6
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_tri_1
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_vtx_0 b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_vtx_0
new file mode 100644
index 00000000000..145ca70f4fe
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_vtx_0
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_vtx_1 b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_vtx_1
new file mode 100644
index 00000000000..7f90daac735
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/gSantaHatGenericDL_vtx_1
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/hilite_nose b/soh/assets/custom/objects/object_festivehats/hilite_nose
new file mode 100644
index 00000000000..b2d4623c9c7
Binary files /dev/null and b/soh/assets/custom/objects/object_festivehats/hilite_nose differ
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gCuccoLadyHatDL_f3dlite_hatcolour b/soh/assets/custom/objects/object_festivehats/mat_gCuccoLadyHatDL_f3dlite_hatcolour
new file mode 100644
index 00000000000..d1d036f8961
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gCuccoLadyHatDL_f3dlite_hatcolour
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gEponaRudolphHatDL_f3dlite_antlers b/soh/assets/custom/objects/object_festivehats/mat_gEponaRudolphHatDL_f3dlite_antlers
new file mode 100644
index 00000000000..3717c72b2e3
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gEponaRudolphHatDL_f3dlite_antlers
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_shard_edge b/soh/assets/custom/objects/object_festivehats/mat_gEponaRudolphHatDL_f3dlite_rednose
similarity index 75%
rename from soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_shard_edge
rename to soh/assets/custom/objects/object_festivehats/mat_gEponaRudolphHatDL_f3dlite_rednose
index b9e61293d1e..758d8698be8 100644
--- a/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_shard_edge
+++ b/soh/assets/custom/objects/object_festivehats/mat_gEponaRudolphHatDL_f3dlite_rednose
@@ -1,21 +1,21 @@
-
-
-
+
+
+
-
+
-
+
-
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gHorseAntlersDL_f3dlite_antlers b/soh/assets/custom/objects/object_festivehats/mat_gHorseAntlersDL_f3dlite_antlers
new file mode 100644
index 00000000000..3717c72b2e3
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gHorseAntlersDL_f3dlite_antlers
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gLinkAdultHatTrimDL_f3dlite_santahat_white b/soh/assets/custom/objects/object_festivehats/mat_gLinkAdultHatTrimDL_f3dlite_santahat_white
new file mode 100644
index 00000000000..2f72783f760
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gLinkAdultHatTrimDL_f3dlite_santahat_white
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gLinkAdultPompomDL_f3dlite_santahat_white b/soh/assets/custom/objects/object_festivehats/mat_gLinkAdultPompomDL_f3dlite_santahat_white
new file mode 100644
index 00000000000..2f72783f760
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gLinkAdultPompomDL_f3dlite_santahat_white
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gLinkChildHatTrimDL_f3dlite_santahat_white b/soh/assets/custom/objects/object_festivehats/mat_gLinkChildHatTrimDL_f3dlite_santahat_white
new file mode 100644
index 00000000000..2f72783f760
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gLinkChildHatTrimDL_f3dlite_santahat_white
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gLinkChildPompomDL_f3dlite_santahat_white b/soh/assets/custom/objects/object_festivehats/mat_gLinkChildPompomDL_f3dlite_santahat_white
new file mode 100644
index 00000000000..2f72783f760
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gLinkChildPompomDL_f3dlite_santahat_white
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gPaperCrownGenericDL_f3dlite_crown b/soh/assets/custom/objects/object_festivehats/mat_gPaperCrownGenericDL_f3dlite_crown
new file mode 100644
index 00000000000..4fb4e2029cb
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gPaperCrownGenericDL_f3dlite_crown
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gSantaHatGenericDL_f3dlite_santahatred b/soh/assets/custom/objects/object_festivehats/mat_gSantaHatGenericDL_f3dlite_santahatred
new file mode 100644
index 00000000000..b42644ae815
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gSantaHatGenericDL_f3dlite_santahatred
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_festivehats/mat_gSantaHatGenericDL_f3dlite_santahatwhite b/soh/assets/custom/objects/object_festivehats/mat_gSantaHatGenericDL_f3dlite_santahatwhite
new file mode 100644
index 00000000000..2f72783f760
--- /dev/null
+++ b/soh/assets/custom/objects/object_festivehats/mat_gSantaHatGenericDL_f3dlite_santahatwhite
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/CuccoBedding_32 b/soh/assets/custom/objects/object_kakariko_decor/CuccoBedding_32
new file mode 100644
index 00000000000..68187fbf5f4
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/CuccoBedding_32 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/SnowBlanket_32 b/soh/assets/custom/objects/object_kakariko_decor/SnowBlanket_32
new file mode 100644
index 00000000000..733b3075735
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/SnowBlanket_32 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/SnowBuildup_32 b/soh/assets/custom/objects/object_kakariko_decor/SnowBuildup_32
new file mode 100644
index 00000000000..4653f07d12c
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/SnowBuildup_32 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/SnowDissolve_32 b/soh/assets/custom/objects/object_kakariko_decor/SnowDissolve_32
new file mode 100644
index 00000000000..e7c7aa14292
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/SnowDissolve_32 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/String_BYBY_32 b/soh/assets/custom/objects/object_kakariko_decor/String_BYBY_32
new file mode 100644
index 00000000000..62efcb10a36
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/String_BYBY_32 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/String_GRGR_32 b/soh/assets/custom/objects/object_kakariko_decor/String_GRGR_32
new file mode 100644
index 00000000000..b905f21a9a6
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/String_GRGR_32 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/UsagiLeaf_8 b/soh/assets/custom/objects/object_kakariko_decor/UsagiLeaf_8
new file mode 100644
index 00000000000..fc4d3ff5be3
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/UsagiLeaf_8 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/YukiUsagi_16 b/soh/assets/custom/objects/object_kakariko_decor/YukiUsagi_16
new file mode 100644
index 00000000000..2034627ff95
Binary files /dev/null and b/soh/assets/custom/objects/object_kakariko_decor/YukiUsagi_16 differ
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL
new file mode 100644
index 00000000000..13d9447f76a
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_tri_0 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_tri_0
new file mode 100644
index 00000000000..1263127aa62
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_tri_0
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_tri_1 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_tri_1
new file mode 100644
index 00000000000..2aff9496e8e
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_tri_1
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_0 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_0
new file mode 100644
index 00000000000..9f3683fed91
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_0
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_1 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_1
new file mode 100644
index 00000000000..e438e71cf2c
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_1
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_cull b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_cull
new file mode 100644
index 00000000000..c3ecddb8a81
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoAdultDecorDL_vtx_cull
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL
new file mode 100644
index 00000000000..a3972ce7a1f
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_0 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_0
new file mode 100644
index 00000000000..eb7e92fdfce
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_0
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_1 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_1
new file mode 100644
index 00000000000..77468a73821
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_1
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_2 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_2
new file mode 100644
index 00000000000..97634bb7bf9
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_tri_2
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_0 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_0
new file mode 100644
index 00000000000..24e3e3d6eea
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_0
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_1 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_1
new file mode 100644
index 00000000000..0b12310ec50
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_1
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_2 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_2
new file mode 100644
index 00000000000..f2a81069d0c
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_2
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_cull b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_cull
new file mode 100644
index 00000000000..b2e233783de
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoChildDecorDL_vtx_cull
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL
new file mode 100644
index 00000000000..f0363d242de
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_0 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_0
new file mode 100644
index 00000000000..5ee2633e5f5
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_0
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_1 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_1
new file mode 100644
index 00000000000..2b52e5ef38c
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_1
@@ -0,0 +1,221 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_2 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_2
new file mode 100644
index 00000000000..d6f5dbafe5b
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_2
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_3 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_3
new file mode 100644
index 00000000000..f66ba5914a0
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_3
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_4 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_4
new file mode 100644
index 00000000000..e0d3768970a
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_4
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_5 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_5
new file mode 100644
index 00000000000..ca52719c952
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_5
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_6 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_6
new file mode 100644
index 00000000000..75be056f591
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_6
@@ -0,0 +1,330 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_7 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_7
new file mode 100644
index 00000000000..eeedcf1ee5f
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_tri_7
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_0 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_0
new file mode 100644
index 00000000000..c0a07802c63
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_0
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_1 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_1
new file mode 100644
index 00000000000..c7615dd3be2
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_1
@@ -0,0 +1,770 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_2 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_2
new file mode 100644
index 00000000000..3ff9d2e436b
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_2
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_3 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_3
new file mode 100644
index 00000000000..b0e49797ac6
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_3
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_4 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_4
new file mode 100644
index 00000000000..0434529395c
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_4
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_5 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_5
new file mode 100644
index 00000000000..46c6ac9a192
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_5
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_6 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_6
new file mode 100644
index 00000000000..0e597050551
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_6
@@ -0,0 +1,497 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_7 b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_7
new file mode 100644
index 00000000000..1929d460ef2
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_7
@@ -0,0 +1,230 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_cull b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_cull
new file mode 100644
index 00000000000..a183da29360
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/gKakarikoDecorDL_vtx_cull
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoAdultDecorDL_f3dlite_StringGRGR b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoAdultDecorDL_f3dlite_StringGRGR
new file mode 100644
index 00000000000..b8478fa9025
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoAdultDecorDL_f3dlite_StringGRGR
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_edges b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoAdultDecorDL_f3dlite_snowlayer
similarity index 52%
rename from soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_edges
rename to soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoAdultDecorDL_f3dlite_snowlayer
index 9355e709439..5456b3893ac 100644
--- a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_edges
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoAdultDecorDL_f3dlite_snowlayer
@@ -1,21 +1,21 @@
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_SnowBuildup b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_SnowBuildup
new file mode 100644
index 00000000000..a79cca54f3b
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_SnowBuildup
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_UsagiLeaf b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_UsagiLeaf
new file mode 100644
index 00000000000..be29498efe7
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_UsagiLeaf
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_YukiUsagiBody b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_YukiUsagiBody
new file mode 100644
index 00000000000..3a2d2c88989
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoChildDecorDL_f3dlite_YukiUsagiBody
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_CuccoBedding b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_CuccoBedding
new file mode 100644
index 00000000000..52025821097
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_CuccoBedding
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_SnowBuildup b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_SnowBuildup
new file mode 100644
index 00000000000..a79cca54f3b
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_SnowBuildup
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_StringBYBY b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_StringBYBY
new file mode 100644
index 00000000000..5c85eb88f40
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_StringBYBY
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_StringGRGR b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_StringGRGR
new file mode 100644
index 00000000000..b8478fa9025
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_StringGRGR
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_UsagiLeaf b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_UsagiLeaf
new file mode 100644
index 00000000000..be29498efe7
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_UsagiLeaf
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_YukiUsagiBody b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_YukiUsagiBody
new file mode 100644
index 00000000000..3a2d2c88989
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_YukiUsagiBody
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_snowdissolve b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_snowdissolve
new file mode 100644
index 00000000000..e86142f2970
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_snowdissolve
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_snowlayer b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_snowlayer
new file mode 100644
index 00000000000..5456b3893ac
--- /dev/null
+++ b/soh/assets/custom/objects/object_kakariko_decor/mat_gKakarikoDecorDL_f3dlite_snowlayer
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/SnowBlanket_32 b/soh/assets/custom/objects/object_temple_of_time_decor/SnowBlanket_32
new file mode 100644
index 00000000000..733b3075735
Binary files /dev/null and b/soh/assets/custom/objects/object_temple_of_time_decor/SnowBlanket_32 differ
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/SnowBuildup_32 b/soh/assets/custom/objects/object_temple_of_time_decor/SnowBuildup_32
new file mode 100644
index 00000000000..4653f07d12c
Binary files /dev/null and b/soh/assets/custom/objects/object_temple_of_time_decor/SnowBuildup_32 differ
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/String_BYBY_32 b/soh/assets/custom/objects/object_temple_of_time_decor/String_BYBY_32
new file mode 100644
index 00000000000..62efcb10a36
Binary files /dev/null and b/soh/assets/custom/objects/object_temple_of_time_decor/String_BYBY_32 differ
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/String_GRGR_32 b/soh/assets/custom/objects/object_temple_of_time_decor/String_GRGR_32
new file mode 100644
index 00000000000..b905f21a9a6
Binary files /dev/null and b/soh/assets/custom/objects/object_temple_of_time_decor/String_GRGR_32 differ
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL
new file mode 100644
index 00000000000..491663279db
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_0 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_0
new file mode 100644
index 00000000000..75fc6598b2c
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_0
@@ -0,0 +1,2222 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_1 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_1
new file mode 100644
index 00000000000..bf36e26c42b
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_1
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_2 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_2
new file mode 100644
index 00000000000..4020ff3d1f0
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_2
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_3 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_3
new file mode 100644
index 00000000000..eb072a5ef74
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_3
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_4 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_4
new file mode 100644
index 00000000000..34fbdd80624
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_4
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_5 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_5
new file mode 100644
index 00000000000..e360d5739ed
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_5
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_6 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_6
new file mode 100644
index 00000000000..8dcd07878ce
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_6
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_7 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_7
new file mode 100644
index 00000000000..a276056ed75
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_7
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_8 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_8
new file mode 100644
index 00000000000..b7f90b048a6
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_tri_8
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_0 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_0
new file mode 100644
index 00000000000..772a7955d4c
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_0
@@ -0,0 +1,4468 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_1 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_1
new file mode 100644
index 00000000000..f62970ec9e0
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_1
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_2 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_2
new file mode 100644
index 00000000000..30da04c9f6e
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_2
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_3 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_3
new file mode 100644
index 00000000000..834efd769c9
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_3
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_4 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_4
new file mode 100644
index 00000000000..acfe49fc65d
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_4
@@ -0,0 +1,224 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_5 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_5
new file mode 100644
index 00000000000..13fd6d48a69
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_5
@@ -0,0 +1,284 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_6 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_6
new file mode 100644
index 00000000000..e8e4e4a528c
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_6
@@ -0,0 +1,278 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_7 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_7
new file mode 100644
index 00000000000..359d4871604
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_7
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_8 b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_8
new file mode 100644
index 00000000000..2cb6bf701cc
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_8
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_cull b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_cull
new file mode 100644
index 00000000000..6dd5d78cb9f
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/gTempleOfTimeDecorDL_vtx_cull
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/ice b/soh/assets/custom/objects/object_temple_of_time_decor/ice
new file mode 100644
index 00000000000..ff27a02466a
Binary files /dev/null and b/soh/assets/custom/objects/object_temple_of_time_decor/ice differ
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_SnowBuildup b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_SnowBuildup
new file mode 100644
index 00000000000..46d52d40d06
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_SnowBuildup
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_shard_edge b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_StringBYBY
similarity index 52%
rename from soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_shard_edge
rename to soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_StringBYBY
index c222fe68d5c..16c505a28f7 100644
--- a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_shard_edge
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_StringBYBY
@@ -1,21 +1,21 @@
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_StringGRGR b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_StringGRGR
new file mode 100644
index 00000000000..5663994ee1d
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_StringGRGR
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_blue_material b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_blue_material
new file mode 100644
index 00000000000..c0c1a4ac939
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_blue_material
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_green_material b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_green_material
new file mode 100644
index 00000000000..6fcf6e1d8ff
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_green_material
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_red_material b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_red_material
new file mode 100644
index 00000000000..a73985478ca
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_red_material
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_yellow_material b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_yellow_material
new file mode 100644
index 00000000000..9f11354bdd6
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_gift_col_yellow_material
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_surface b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_ice_material
similarity index 65%
rename from soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_surface
rename to soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_ice_material
index e863b31c5ac..2a71c2cc93b 100644
--- a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_surface
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_ice_material
@@ -1,21 +1,21 @@
-
-
-
+
+
+
-
+
-
+
-
+
diff --git a/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_snowlayer b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_snowlayer
new file mode 100644
index 00000000000..e15d18af101
--- /dev/null
+++ b/soh/assets/custom/objects/object_temple_of_time_decor/mat_gTempleOfTimeDecorDL_f3dlite_snowlayer
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_completed/GlowAlpha_64 b/soh/assets/custom/objects/object_triforce_completed/GlowAlpha_64
new file mode 100644
index 00000000000..1682d9e6f2f
Binary files /dev/null and b/soh/assets/custom/objects/object_triforce_completed/GlowAlpha_64 differ
diff --git a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL
index 966bef20600..b7c7d8af02a 100644
--- a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL
+++ b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL
@@ -1,7 +1,7 @@
-
+
-
+
diff --git a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_0 b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_0
index dea47708c1f..f9d6420cc0f 100644
--- a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_0
+++ b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_0
@@ -1,56 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_1 b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_1
index 36be4333f2b..b67adf06ef8 100644
--- a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_1
+++ b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_1
@@ -1,7 +1,390 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0 b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0
index 6ca96db3059..ca11ab1b3b6 100644
--- a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0
+++ b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0
@@ -1,54 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_1 b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_1
index 3a653966d71..cc747f74a3c 100644
--- a/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_1
+++ b/soh/assets/custom/objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_1
@@ -1,8 +1,347 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_completed/hilite_melon b/soh/assets/custom/objects/object_triforce_completed/hilite_melon
new file mode 100644
index 00000000000..df1d605b38e
Binary files /dev/null and b/soh/assets/custom/objects/object_triforce_completed/hilite_melon differ
diff --git a/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_Glow b/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_Glow
new file mode 100644
index 00000000000..6bed4d27447
--- /dev/null
+++ b/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_Glow
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_triforce_surface b/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_OrnamentGold
similarity index 75%
rename from soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_triforce_surface
rename to soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_OrnamentGold
index 5f8dc51f904..65dfd4f5601 100644
--- a/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_f3dlite_triforce_surface
+++ b/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_OrnamentGold
@@ -1,6 +1,6 @@
-
+
@@ -8,14 +8,14 @@
-
+
-
+
diff --git a/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_edges b/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_edges
deleted file mode 100644
index 52591dfc85e..00000000000
--- a/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_edges
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_surface b/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_surface
deleted file mode 100644
index 06193ae61a0..00000000000
--- a/soh/assets/custom/objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_surface
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_completed/noise_tex b/soh/assets/custom/objects/object_triforce_completed/noise_tex
deleted file mode 100644
index a6d6cf945e1..00000000000
Binary files a/soh/assets/custom/objects/object_triforce_completed/noise_tex and /dev/null differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL
index 70d08c31d21..0beb02144fe 100644
--- a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL
+++ b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL
@@ -1,10 +1,8 @@
-
+
-
+
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_0 b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_0
index 09e44f1b798..286a543842c 100644
--- a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_0
+++ b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_0
@@ -1,17 +1,67 @@
-
-
-
+
+
+
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_1 b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_1
index 48001e3c394..a3c013e4acf 100644
--- a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_1
+++ b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_1
@@ -1,18 +1,91 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_2 b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_2
deleted file mode 100644
index e35e34492a7..00000000000
--- a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_tri_2
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_0 b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_0
index a86fa98bf57..4f60b10fe4b 100644
--- a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_0
+++ b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_0
@@ -1,18 +1,72 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_1 b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_1
index 230fbb7f88c..80931181f14 100644
--- a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_1
+++ b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_1
@@ -1,22 +1,107 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_2 b/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_2
deleted file mode 100644
index 86d1238254d..00000000000
--- a/soh/assets/custom/objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_2
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/image b/soh/assets/custom/objects/object_triforce_piece_0/image
new file mode 100644
index 00000000000..2a8a62348be
Binary files /dev/null and b/soh/assets/custom/objects/object_triforce_piece_0/image differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_ball b/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_ball
new file mode 100644
index 00000000000..214ad3df66c
--- /dev/null
+++ b/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_ball
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_shard_edge b/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_shard_edge
deleted file mode 100644
index f6263179331..00000000000
--- a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_shard_edge
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_silver b/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_silver
new file mode 100644
index 00000000000..d56781ad265
--- /dev/null
+++ b/soh/assets/custom/objects/object_triforce_piece_0/mat_gTriforcePiece0DL_silver
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_0/noise_tex b/soh/assets/custom/objects/object_triforce_piece_0/noise_tex
deleted file mode 100644
index a6d6cf945e1..00000000000
Binary files a/soh/assets/custom/objects/object_triforce_piece_0/noise_tex and /dev/null differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL
index 50a9264c62c..4ffea5cf8a7 100644
--- a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL
+++ b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL
@@ -1,7 +1,7 @@
-
+
-
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_0 b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_0
index 5f33f7347ea..c9e63a8d967 100644
--- a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_0
+++ b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_0
@@ -1,20 +1,67 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_1 b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_1
index 43df6492b43..67f0ba8eb34 100644
--- a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_1
+++ b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_tri_1
@@ -1,25 +1,88 @@
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_0 b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_0
index e078b82461b..366463fd9cc 100644
--- a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_0
+++ b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_0
@@ -1,23 +1,72 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_1 b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_1
index e0460194daa..8085ae95ab8 100644
--- a/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_1
+++ b/soh/assets/custom/objects/object_triforce_piece_1/gTriforcePiece1DL_vtx_1
@@ -1,34 +1,96 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/image b/soh/assets/custom/objects/object_triforce_piece_1/image
new file mode 100644
index 00000000000..2a8a62348be
Binary files /dev/null and b/soh/assets/custom/objects/object_triforce_piece_1/image differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/image_copy b/soh/assets/custom/objects/object_triforce_piece_1/image_copy
new file mode 100644
index 00000000000..2a8a62348be
Binary files /dev/null and b/soh/assets/custom/objects/object_triforce_piece_1/image_copy differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_blue_mat b/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_blue_mat
new file mode 100644
index 00000000000..6ba4d88f9b2
--- /dev/null
+++ b/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_blue_mat
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_silver_002 b/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_silver_002
new file mode 100644
index 00000000000..26f9a0b700c
--- /dev/null
+++ b/soh/assets/custom/objects/object_triforce_piece_1/mat_gTriforcePiece1DL_silver_002
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_1/noise_tex b/soh/assets/custom/objects/object_triforce_piece_1/noise_tex
deleted file mode 100644
index a6d6cf945e1..00000000000
Binary files a/soh/assets/custom/objects/object_triforce_piece_1/noise_tex and /dev/null differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL
index 5213cd53ca7..7318e9b1c04 100644
--- a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL
+++ b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL
@@ -1,10 +1,8 @@
-
+
-
+
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_0 b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_0
index b54e182d5e9..59d81883f18 100644
--- a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_0
+++ b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_0
@@ -1,29 +1,67 @@
-
+
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
-
+
+
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_1 b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_1
index 00a32bfd88e..a15c641d7ab 100644
--- a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_1
+++ b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_1
@@ -1,11 +1,378 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_2 b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_2
deleted file mode 100644
index 0993c1c1ee3..00000000000
--- a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_tri_2
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_0 b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_0
index bf7dfcac670..90dc38784f0 100644
--- a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_0
+++ b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_0
@@ -1,36 +1,72 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_1 b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_1
index e3237ab2157..ef4ea40e42a 100644
--- a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_1
+++ b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_1
@@ -1,12 +1,410 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_2 b/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_2
deleted file mode 100644
index ec4e737005b..00000000000
--- a/soh/assets/custom/objects/object_triforce_piece_2/gTriforcePiece2DL_vtx_2
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/image b/soh/assets/custom/objects/object_triforce_piece_2/image
new file mode 100644
index 00000000000..2a8a62348be
Binary files /dev/null and b/soh/assets/custom/objects/object_triforce_piece_2/image differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/image_copy b/soh/assets/custom/objects/object_triforce_piece_2/image_copy
new file mode 100644
index 00000000000..2a8a62348be
Binary files /dev/null and b/soh/assets/custom/objects/object_triforce_piece_2/image_copy differ
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_Green_mat b/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_Green_mat
new file mode 100644
index 00000000000..94418f24fc5
--- /dev/null
+++ b/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_Green_mat
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_surface b/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_surface
deleted file mode 100644
index d903f00bbd5..00000000000
--- a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_surface
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_silver_001 b/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_silver_001
new file mode 100644
index 00000000000..6a9be7bec45
--- /dev/null
+++ b/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_silver_001
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/noise_tex b/soh/assets/custom/objects/object_triforce_piece_2/noise_tex
deleted file mode 100644
index a6d6cf945e1..00000000000
Binary files a/soh/assets/custom/objects/object_triforce_piece_2/noise_tex and /dev/null differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bark_64 b/soh/assets/custom/objects/object_xmas_tree/Bark_64
new file mode 100644
index 00000000000..8f1b837cd26
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bark_64 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_B_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_B_32
new file mode 100644
index 00000000000..5e28d8e8203
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_B_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_G_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_G_32
new file mode 100644
index 00000000000..a40393dbd4a
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_G_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_R_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_R_32
new file mode 100644
index 00000000000..c2d49ae4245
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble1Tex_R_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_B_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_B_32
new file mode 100644
index 00000000000..2596d826432
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_B_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_G_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_G_32
new file mode 100644
index 00000000000..e6889fee4b0
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_G_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_R_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_R_32
new file mode 100644
index 00000000000..aef353a27ea
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble2Tex_R_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_B_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_B_32
new file mode 100644
index 00000000000..8f9c96cb13b
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_B_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_G_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_G_32
new file mode 100644
index 00000000000..b8ce81e43fe
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_G_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_R_32 b/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_R_32
new file mode 100644
index 00000000000..40394698fcd
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Bauble3Tex_R_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/GlowAlpha_64 b/soh/assets/custom/objects/object_xmas_tree/GlowAlpha_64
new file mode 100644
index 00000000000..1682d9e6f2f
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/GlowAlpha_64 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/LeavesAlpha_64 b/soh/assets/custom/objects/object_xmas_tree/LeavesAlpha_64
new file mode 100644
index 00000000000..e33491d5af5
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/LeavesAlpha_64 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/LeavesAlpha_shaded_64 b/soh/assets/custom/objects/object_xmas_tree/LeavesAlpha_shaded_64
new file mode 100644
index 00000000000..dca2158b4b0
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/LeavesAlpha_shaded_64 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Wrapping_B_32 b/soh/assets/custom/objects/object_xmas_tree/Wrapping_B_32
new file mode 100644
index 00000000000..9d70aa720ce
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Wrapping_B_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Wrapping_B_64 b/soh/assets/custom/objects/object_xmas_tree/Wrapping_B_64
new file mode 100644
index 00000000000..071e01a2d14
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Wrapping_B_64 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Wrapping_G_32 b/soh/assets/custom/objects/object_xmas_tree/Wrapping_G_32
new file mode 100644
index 00000000000..8fac0c1c4fe
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Wrapping_G_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Wrapping_G_64 b/soh/assets/custom/objects/object_xmas_tree/Wrapping_G_64
new file mode 100644
index 00000000000..6c128dbee7b
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Wrapping_G_64 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Wrapping_R_32 b/soh/assets/custom/objects/object_xmas_tree/Wrapping_R_32
new file mode 100644
index 00000000000..a61f3d3867b
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Wrapping_R_32 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/Wrapping_R_64 b/soh/assets/custom/objects/object_xmas_tree/Wrapping_R_64
new file mode 100644
index 00000000000..d884c2ca670
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/Wrapping_R_64 differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL
new file mode 100644
index 00000000000..c354defdad6
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_0
new file mode 100644
index 00000000000..bc1589a6573
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_0
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_1
new file mode 100644
index 00000000000..ff14442dc0d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_1
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_2
new file mode 100644
index 00000000000..ea5e79a96b1
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_2
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_3
new file mode 100644
index 00000000000..4280e17a5d4
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_tri_3
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_0
new file mode 100644
index 00000000000..2d2b533a440
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_0
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_1
new file mode 100644
index 00000000000..2199d077963
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_1
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_2
new file mode 100644
index 00000000000..e0403545aa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_2
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_3
new file mode 100644
index 00000000000..ae1fba2946e
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor100DL_vtx_3
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL
new file mode 100644
index 00000000000..80f8fc81be3
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_0
new file mode 100644
index 00000000000..2a2601403ad
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_0
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_1
new file mode 100644
index 00000000000..87dc5c7caf0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_1
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_2
new file mode 100644
index 00000000000..d9d225ee153
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_2
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_3
new file mode 100644
index 00000000000..010dfe6698b
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_3
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_4
new file mode 100644
index 00000000000..34de1a10f75
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_4
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_5
new file mode 100644
index 00000000000..dbaef4a37c6
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_5
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_6
new file mode 100644
index 00000000000..4b4aaa74244
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_6
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_7
new file mode 100644
index 00000000000..a3aa6c67295
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_tri_7
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_0
new file mode 100644
index 00000000000..189a72f7836
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_0
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_1
new file mode 100644
index 00000000000..491afaa21aa
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_1
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_2
new file mode 100644
index 00000000000..1c86dfb200f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_2
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_3
new file mode 100644
index 00000000000..fef6070e2c8
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_3
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_4
new file mode 100644
index 00000000000..74ff37e831f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_4
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_5
new file mode 100644
index 00000000000..e5347a692ec
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_5
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_6
new file mode 100644
index 00000000000..57b0c83f5e3
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_6
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_7
new file mode 100644
index 00000000000..4eea9d31dc9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor10DL_vtx_7
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL
new file mode 100644
index 00000000000..cd83c25f822
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_0
new file mode 100644
index 00000000000..7410becefa0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_0
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_1
new file mode 100644
index 00000000000..782f5f9e1db
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_1
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_2
new file mode 100644
index 00000000000..46d90cfee34
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_2
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_3
new file mode 100644
index 00000000000..fcae1cb6087
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_3
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_4
new file mode 100644
index 00000000000..cea2d4b0147
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_4
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_5
new file mode 100644
index 00000000000..8e6c88ddf62
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_5
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_6
new file mode 100644
index 00000000000..0c0928683c2
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_6
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_7
new file mode 100644
index 00000000000..f564728104c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_7
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_8
new file mode 100644
index 00000000000..8464121eb12
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_8
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_9 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_9
new file mode 100644
index 00000000000..a22341bdf18
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_tri_9
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_0
new file mode 100644
index 00000000000..c8a3028f56c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_0
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_1
new file mode 100644
index 00000000000..d7bf03045fe
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_1
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_2
new file mode 100644
index 00000000000..768baea6575
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_2
@@ -0,0 +1,300 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_3
new file mode 100644
index 00000000000..87d0b13154a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_3
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_4
new file mode 100644
index 00000000000..8fb01822419
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_4
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_5
new file mode 100644
index 00000000000..76d9b788af8
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_5
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_6
new file mode 100644
index 00000000000..60cef595cc3
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_6
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_7
new file mode 100644
index 00000000000..e590fd8487c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_7
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_8
new file mode 100644
index 00000000000..505f171b0da
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_8
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_9 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_9
new file mode 100644
index 00000000000..50c131f9c9a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor20DL_vtx_9
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL
new file mode 100644
index 00000000000..4e4fd95aad2
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_0
new file mode 100644
index 00000000000..1ee54492c69
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_0
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_1
new file mode 100644
index 00000000000..0efacf68ad9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_1
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_2
new file mode 100644
index 00000000000..e05cc11fb6f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_2
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_3
new file mode 100644
index 00000000000..19917bd2e89
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_3
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_4
new file mode 100644
index 00000000000..f5f256b23e1
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_4
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_5
new file mode 100644
index 00000000000..536d06f7acf
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_5
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_6
new file mode 100644
index 00000000000..45568173a0d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_tri_6
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_0
new file mode 100644
index 00000000000..509ed65291a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_0
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_1
new file mode 100644
index 00000000000..49c0a080a23
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_1
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_2
new file mode 100644
index 00000000000..c109c19f59f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_2
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_3
new file mode 100644
index 00000000000..c7c1e10a65e
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_3
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_4
new file mode 100644
index 00000000000..a26e55df1d1
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_4
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_5
new file mode 100644
index 00000000000..d1177d63384
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_5
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_6
new file mode 100644
index 00000000000..d947223ad79
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor30DL_vtx_6
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL
new file mode 100644
index 00000000000..9da99431f10
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_0
new file mode 100644
index 00000000000..f94c732e4d9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_0
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_1
new file mode 100644
index 00000000000..34891928660
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_1
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_10 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_10
new file mode 100644
index 00000000000..959b692d481
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_10
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_11 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_11
new file mode 100644
index 00000000000..41fb8d2b9bb
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_11
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_12 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_12
new file mode 100644
index 00000000000..8062b5a562c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_12
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_2
new file mode 100644
index 00000000000..7c52dae868b
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_2
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_3
new file mode 100644
index 00000000000..af789278611
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_3
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_4
new file mode 100644
index 00000000000..e662f6ed6aa
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_4
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_5
new file mode 100644
index 00000000000..22b809b3f24
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_5
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_6
new file mode 100644
index 00000000000..1d845ad8a81
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_6
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_7
new file mode 100644
index 00000000000..12c90c20934
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_7
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_8
new file mode 100644
index 00000000000..bbd9078cede
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_8
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_9 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_9
new file mode 100644
index 00000000000..11e6780ea03
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_tri_9
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_0
new file mode 100644
index 00000000000..8579d6fee95
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_0
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_1
new file mode 100644
index 00000000000..b0dcceeec23
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_1
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_10 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_10
new file mode 100644
index 00000000000..7d59969b3d7
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_10
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_11 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_11
new file mode 100644
index 00000000000..ab7d95f641a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_11
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_12 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_12
new file mode 100644
index 00000000000..514f00f3894
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_12
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_2
new file mode 100644
index 00000000000..7135901b7a4
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_2
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_3
new file mode 100644
index 00000000000..874e86e4556
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_3
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_4
new file mode 100644
index 00000000000..8dcece79bdc
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_4
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_5
new file mode 100644
index 00000000000..030415bf5e1
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_5
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_6
new file mode 100644
index 00000000000..5758decfe91
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_6
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_7
new file mode 100644
index 00000000000..7e171bd29a8
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_7
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_8
new file mode 100644
index 00000000000..26f056a5fca
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_8
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_9 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_9
new file mode 100644
index 00000000000..878f90b20ec
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor40DL_vtx_9
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL
new file mode 100644
index 00000000000..537d98d5f8f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_0
new file mode 100644
index 00000000000..41e8cb3c97d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_0
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_1
new file mode 100644
index 00000000000..0beb4cd5f4a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_1
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_2
new file mode 100644
index 00000000000..a33dc968910
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_2
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_3
new file mode 100644
index 00000000000..8cd67cdeb7d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_3
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_4
new file mode 100644
index 00000000000..f3cb40c18fd
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_4
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_5
new file mode 100644
index 00000000000..28c1fa004f6
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_tri_5
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_0
new file mode 100644
index 00000000000..4bbea8de4d4
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_0
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_1
new file mode 100644
index 00000000000..c331cabed74
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_1
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_2
new file mode 100644
index 00000000000..62bb3dc536e
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_2
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_3
new file mode 100644
index 00000000000..135764c05a0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_3
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_4
new file mode 100644
index 00000000000..1066194fbf5
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_4
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_5
new file mode 100644
index 00000000000..afec2ee782a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor50DL_vtx_5
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL
new file mode 100644
index 00000000000..fe51b9f6b84
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_0
new file mode 100644
index 00000000000..1d746dde9cf
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_0
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_1
new file mode 100644
index 00000000000..095e5d8f1a3
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_1
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_2
new file mode 100644
index 00000000000..b1f3c81fcaf
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_2
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_3
new file mode 100644
index 00000000000..e88a5cffe72
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_3
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_4
new file mode 100644
index 00000000000..cbc9ce14a9c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_4
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_5
new file mode 100644
index 00000000000..6646786c150
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_5
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_6
new file mode 100644
index 00000000000..a2a881763ed
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_6
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_7
new file mode 100644
index 00000000000..2a5440b8677
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_7
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_8
new file mode 100644
index 00000000000..245daae2b22
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_8
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_9 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_9
new file mode 100644
index 00000000000..34a3d0b55ce
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_tri_9
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_0
new file mode 100644
index 00000000000..b33405eec8f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_0
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_1
new file mode 100644
index 00000000000..ff671566d99
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_1
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_2
new file mode 100644
index 00000000000..21358026ec7
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_2
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_3
new file mode 100644
index 00000000000..831547972d3
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_3
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_4
new file mode 100644
index 00000000000..c591133b836
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_4
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_5
new file mode 100644
index 00000000000..d111addadae
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_5
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_6
new file mode 100644
index 00000000000..2684a5759c5
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_6
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_7
new file mode 100644
index 00000000000..a2ab6b20a93
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_7
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_8
new file mode 100644
index 00000000000..fed438e57b0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_8
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_9 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_9
new file mode 100644
index 00000000000..9f8e178ed21
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor60DL_vtx_9
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL
new file mode 100644
index 00000000000..9d7a0b7491e
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_0
new file mode 100644
index 00000000000..540a5e3e395
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_0
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_1
new file mode 100644
index 00000000000..3b27e35d234
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_1
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_2
new file mode 100644
index 00000000000..29326efac0a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_2
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_3
new file mode 100644
index 00000000000..83850278e12
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_3
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_4
new file mode 100644
index 00000000000..38401ac4f3c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_4
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_5
new file mode 100644
index 00000000000..ef0b4397d75
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_5
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_6
new file mode 100644
index 00000000000..0df60862536
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_tri_6
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_0
new file mode 100644
index 00000000000..6e115c0bb30
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_0
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_1
new file mode 100644
index 00000000000..ce6941dc97c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_1
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_2
new file mode 100644
index 00000000000..56624ffb043
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_2
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_3
new file mode 100644
index 00000000000..ec758ec9199
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_3
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_4
new file mode 100644
index 00000000000..3e9cc0ff4cc
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_4
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_5
new file mode 100644
index 00000000000..ac28e8fb0d9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_5
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_6
new file mode 100644
index 00000000000..0cf3101e0f0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor70DL_vtx_6
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL
new file mode 100644
index 00000000000..ba14f553d07
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_0
new file mode 100644
index 00000000000..233c5e5b743
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_0
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_1
new file mode 100644
index 00000000000..160f85e3392
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_1
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_2
new file mode 100644
index 00000000000..712db2eadf4
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_2
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_3
new file mode 100644
index 00000000000..567f9bbfa63
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_3
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_4
new file mode 100644
index 00000000000..ed60abbb97a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_4
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_5
new file mode 100644
index 00000000000..9d012597673
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_5
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_6
new file mode 100644
index 00000000000..011391daaf4
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_6
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_7
new file mode 100644
index 00000000000..ae4be6ebdd1
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_7
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_8
new file mode 100644
index 00000000000..b7a34eb1de0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_tri_8
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_0
new file mode 100644
index 00000000000..4e538463f3a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_0
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_1
new file mode 100644
index 00000000000..1c7a6b49c92
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_1
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_2
new file mode 100644
index 00000000000..2717d84f0bc
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_2
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_3
new file mode 100644
index 00000000000..e5f479fc47c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_3
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_4
new file mode 100644
index 00000000000..5e1500678a0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_4
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_5
new file mode 100644
index 00000000000..e0036208883
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_5
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_6
new file mode 100644
index 00000000000..e67313e14f8
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_6
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_7
new file mode 100644
index 00000000000..7acc51f2a0c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_7
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_8 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_8
new file mode 100644
index 00000000000..c3ac2ef3648
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor80DL_vtx_8
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL
new file mode 100644
index 00000000000..f96deccc4d7
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_0
new file mode 100644
index 00000000000..aaf575f3edc
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_0
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_1
new file mode 100644
index 00000000000..17e2bbb1443
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_1
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_2
new file mode 100644
index 00000000000..45f70fca8ef
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_2
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_3
new file mode 100644
index 00000000000..501540e9913
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_3
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_4
new file mode 100644
index 00000000000..6aa20edebd3
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_4
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_5
new file mode 100644
index 00000000000..9f5515c3b6a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_5
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_6
new file mode 100644
index 00000000000..e8b2ebe155f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_6
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_7
new file mode 100644
index 00000000000..e8686cfeb9a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_tri_7
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_0
new file mode 100644
index 00000000000..4bf94f75a49
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_0
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_1
new file mode 100644
index 00000000000..a3e163984cf
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_1
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_2
new file mode 100644
index 00000000000..5075a97320f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_2
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_3 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_3
new file mode 100644
index 00000000000..7b0fce1b261
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_3
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_4 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_4
new file mode 100644
index 00000000000..240d7afe250
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_4
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_5 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_5
new file mode 100644
index 00000000000..adf5dfa9b04
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_5
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_6 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_6
new file mode 100644
index 00000000000..5e02e04d8d4
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_6
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_7 b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_7
new file mode 100644
index 00000000000..f92e3d98df2
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasDecor90DL_vtx_7
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL
new file mode 100644
index 00000000000..2bad08d2da6
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_tri_0
new file mode 100644
index 00000000000..79b9903f80a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_tri_0
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_tri_1
new file mode 100644
index 00000000000..0f82cf89324
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_tri_1
@@ -0,0 +1,390 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_vtx_0
new file mode 100644
index 00000000000..a990fc5af05
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_vtx_0
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_vtx_1
new file mode 100644
index 00000000000..7467705946b
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasStarDL_vtx_1
@@ -0,0 +1,347 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL
new file mode 100644
index 00000000000..c343cfe2a0c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_0
new file mode 100644
index 00000000000..38cdbe014bb
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_0
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_1
new file mode 100644
index 00000000000..ff4e066a5b1
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_1
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_2
new file mode 100644
index 00000000000..561d3ac5efb
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_tri_2
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_0 b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_0
new file mode 100644
index 00000000000..94e5e1fefc0
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_0
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_1 b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_1
new file mode 100644
index 00000000000..01ed88a1458
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_1
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_2 b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_2
new file mode 100644
index 00000000000..fd03778f89a
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/gXmasTreeDL_vtx_2
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/hilite_melon b/soh/assets/custom/objects/object_xmas_tree/hilite_melon
new file mode 100644
index 00000000000..df1d605b38e
Binary files /dev/null and b/soh/assets/custom/objects/object_xmas_tree/hilite_melon differ
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_B_64 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_B_64
new file mode 100644
index 00000000000..e2cb1c6af43
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_B_64
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_G_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_G_32
new file mode 100644
index 00000000000..5f67d4de108
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_G_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_R_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_R_32
new file mode 100644
index 00000000000..f330997c280
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_R_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_R_64 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_R_64
new file mode 100644
index 00000000000..ddba85e48a7
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor100DL_f3dlite_Wrapping_R_64
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_G
new file mode 100644
index 00000000000..424720964de
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_B
new file mode 100644
index 00000000000..a2fb866622d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_R
new file mode 100644
index 00000000000..780bee1c538
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble2_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble3_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble3_G
new file mode 100644
index 00000000000..5ec29067d2d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble3_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble3_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble3_R
new file mode 100644
index 00000000000..6bfad5f53ee
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor10DL_f3dlite_Bauble3_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_B
new file mode 100644
index 00000000000..a2fb866622d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_R
new file mode 100644
index 00000000000..780bee1c538
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble2_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble3_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble3_B
new file mode 100644
index 00000000000..7af3c0fdfa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble3_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble3_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble3_G
new file mode 100644
index 00000000000..5ec29067d2d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Bauble3_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_B_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_B_32
new file mode 100644
index 00000000000..1425245e052
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_B_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_G_64 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_G_64
new file mode 100644
index 00000000000..c3a973f3929
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_G_64
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_R_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_R_32
new file mode 100644
index 00000000000..f330997c280
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor20DL_f3dlite_Wrapping_R_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_G
new file mode 100644
index 00000000000..424720964de
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble2_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble2_B
new file mode 100644
index 00000000000..a2fb866622d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble2_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble3_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble3_B
new file mode 100644
index 00000000000..7af3c0fdfa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble3_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble3_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble3_R
new file mode 100644
index 00000000000..6bfad5f53ee
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor30DL_f3dlite_Bauble3_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_B
new file mode 100644
index 00000000000..a2fb866622d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_R
new file mode 100644
index 00000000000..780bee1c538
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble2_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_B
new file mode 100644
index 00000000000..7af3c0fdfa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_G
new file mode 100644
index 00000000000..5ec29067d2d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_R
new file mode 100644
index 00000000000..6bfad5f53ee
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Bauble3_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_B_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_B_32
new file mode 100644
index 00000000000..1425245e052
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_B_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_G_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_G_32
new file mode 100644
index 00000000000..5f67d4de108
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_G_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_G_64 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_G_64
new file mode 100644
index 00000000000..c3a973f3929
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_G_64
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_R_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_R_32
new file mode 100644
index 00000000000..f330997c280
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_R_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_R_64 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_R_64
new file mode 100644
index 00000000000..ddba85e48a7
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor40DL_f3dlite_Wrapping_R_64
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble1_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble1_G
new file mode 100644
index 00000000000..424720964de
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble1_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble2_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble2_R
new file mode 100644
index 00000000000..780bee1c538
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble2_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble3_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble3_B
new file mode 100644
index 00000000000..7af3c0fdfa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble3_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble3_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble3_R
new file mode 100644
index 00000000000..6bfad5f53ee
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor50DL_f3dlite_Bauble3_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_G
new file mode 100644
index 00000000000..424720964de
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble2_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble2_R
new file mode 100644
index 00000000000..780bee1c538
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble2_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble3_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble3_G
new file mode 100644
index 00000000000..5ec29067d2d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Bauble3_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_B_64 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_B_64
new file mode 100644
index 00000000000..e2cb1c6af43
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_B_64
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_G_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_G_32
new file mode 100644
index 00000000000..5f67d4de108
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_G_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_R_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_R_32
new file mode 100644
index 00000000000..f330997c280
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_R_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_R_64 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_R_64
new file mode 100644
index 00000000000..ddba85e48a7
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor60DL_f3dlite_Wrapping_R_64
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble1_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble1_G
new file mode 100644
index 00000000000..424720964de
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble1_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble2_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble2_R
new file mode 100644
index 00000000000..780bee1c538
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble2_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_B
new file mode 100644
index 00000000000..7af3c0fdfa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_G
new file mode 100644
index 00000000000..5ec29067d2d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_R
new file mode 100644
index 00000000000..6bfad5f53ee
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor70DL_f3dlite_Bauble3_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble2_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble2_G
new file mode 100644
index 00000000000..a3ebffce584
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble2_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_B
new file mode 100644
index 00000000000..7af3c0fdfa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_G
new file mode 100644
index 00000000000..5ec29067d2d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_R
new file mode 100644
index 00000000000..6bfad5f53ee
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Bauble3_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_B_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_B_32
new file mode 100644
index 00000000000..1425245e052
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_B_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_G_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_G_32
new file mode 100644
index 00000000000..5f67d4de108
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_G_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_R_32 b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_R_32
new file mode 100644
index 00000000000..f330997c280
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor80DL_f3dlite_Wrapping_R_32
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_B
new file mode 100644
index 00000000000..0562ad51423
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_G
new file mode 100644
index 00000000000..424720964de
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_R
new file mode 100644
index 00000000000..ed8997bac1c
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble1_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble2_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble2_B
new file mode 100644
index 00000000000..a2fb866622d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble2_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble2_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble2_R
new file mode 100644
index 00000000000..780bee1c538
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble2_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_B b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_B
new file mode 100644
index 00000000000..7af3c0fdfa9
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_B
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_G b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_G
new file mode 100644
index 00000000000..5ec29067d2d
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_G
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_R b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_R
new file mode 100644
index 00000000000..6bfad5f53ee
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasDecor90DL_f3dlite_Bauble3_R
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasStarDL_f3dlite_Glow b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasStarDL_f3dlite_Glow
new file mode 100644
index 00000000000..381668c5c49
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasStarDL_f3dlite_Glow
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_edges b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasStarDL_f3dlite_OrnamentGold
similarity index 72%
rename from soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_edges
rename to soh/assets/custom/objects/object_xmas_tree/mat_gXmasStarDL_f3dlite_OrnamentGold
index 5968068f5fb..b657da8a753 100644
--- a/soh/assets/custom/objects/object_triforce_piece_2/mat_gTriforcePiece2DL_f3dlite_triforce_edges
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasStarDL_f3dlite_OrnamentGold
@@ -1,21 +1,21 @@
-
+
-
+
-
+
-
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeBrown b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeBrown
new file mode 100644
index 00000000000..37fdb10d29f
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeBrown
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeGreen b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeGreen
new file mode 100644
index 00000000000..119341c7017
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeGreen
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeTip b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeTip
new file mode 100644
index 00000000000..9baaadbf554
--- /dev/null
+++ b/soh/assets/custom/objects/object_xmas_tree/mat_gXmasTreeDL_f3dlite_TreeTip
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/textures/parameter_static/gTriforcePiece.rgba32.png b/soh/assets/custom/textures/parameter_static/gTriforcePiece.rgba32.png
index cc67b6a133d..eace659af29 100644
Binary files a/soh/assets/custom/textures/parameter_static/gTriforcePiece.rgba32.png and b/soh/assets/custom/textures/parameter_static/gTriforcePiece.rgba32.png differ
diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h
index 2b193053c3b..fef6e221987 100644
--- a/soh/assets/soh_assets.h
+++ b/soh/assets/soh_assets.h
@@ -8,6 +8,27 @@
// On Mac, not using aligned resource names was causing crashes in release builds
// objects
+#define dgLinkAdultHatTrimDL "__OTR__objects/object_festivehats/gLinkAdultHatTrimDL"
+static const ALIGN_ASSET(2) char gLinkAdultHatTrimDL[] = dgLinkAdultHatTrimDL;
+
+#define dgLinkAdultPompomDL "__OTR__objects/object_festivehats/gLinkAdultPompomDL"
+static const ALIGN_ASSET(2) char gLinkAdultPompomDL[] = dgLinkAdultPompomDL;
+
+#define dgLinkChildHatTrimDL "__OTR__objects/object_festivehats/gLinkChildHatTrimDL"
+static const ALIGN_ASSET(2) char gLinkChildHatTrimDL[] = dgLinkChildHatTrimDL;
+
+#define dgPaperCrownGenericDL "__OTR__objects/object_festivehats/gPaperCrownGenericDL"
+static const ALIGN_ASSET(2) char gPaperCrownGenericDL[] = dgPaperCrownGenericDL;
+
+#define dgSantaHatGenericDL "__OTR__objects/object_festivehats/gSantaHatGenericDL"
+static const ALIGN_ASSET(2) char gSantaHatGenericDL[] = dgSantaHatGenericDL;
+
+#define dgHorseAntlersDL "__OTR__objects/object_festivehats/gHorseAntlersDL"
+static const ALIGN_ASSET(2) char gHorseAntlersDL[] = dgHorseAntlersDL;
+
+#define dgEponaRudolphHatDL "__OTR__objects/object_festivehats/gEponaRudolphHatDL"
+static const ALIGN_ASSET(2) char gEponaRudolphHatDL[] = dgEponaRudolphHatDL;
+
#define dgChristmasGreenTreasureChestFrontTex "__OTR__objects/object_box/gChristmasGreenTreasureChestFrontTex"
static const ALIGN_ASSET(2) char gChristmasGreenTreasureChestFrontTex[] = dgChristmasGreenTreasureChestFrontTex;
@@ -56,6 +77,54 @@ static const ALIGN_ASSET(2) char gTriforcePiece2DL[] = dgTriforcePiece2DL;
#define dgTriforcePieceCompletedDL "__OTR__objects/object_triforce_completed/gTriforcePieceCompletedDL"
static const ALIGN_ASSET(2) char gTriforcePieceCompletedDL[] = dgTriforcePieceCompletedDL;
+#define dgXmasTreeDL "__OTR__objects/object_xmas_tree/gXmasTreeDL"
+static const ALIGN_ASSET(2) char gXmasTreeDL[] = dgXmasTreeDL;
+
+#define dgXmasDecor10DL "__OTR__objects/object_xmas_tree/gXmasDecor10DL"
+static const ALIGN_ASSET(2) char gXmasDecor10DL[] = dgXmasDecor10DL;
+
+#define dgXmasDecor20DL "__OTR__objects/object_xmas_tree/gXmasDecor20DL"
+static const ALIGN_ASSET(2) char gXmasDecor20DL[] = dgXmasDecor20DL;
+
+#define dgXmasDecor30DL "__OTR__objects/object_xmas_tree/gXmasDecor30DL"
+static const ALIGN_ASSET(2) char gXmasDecor30DL[] = dgXmasDecor30DL;
+
+#define dgXmasDecor40DL "__OTR__objects/object_xmas_tree/gXmasDecor40DL"
+static const ALIGN_ASSET(2) char gXmasDecor40DL[] = dgXmasDecor40DL;
+
+#define dgXmasDecor50DL "__OTR__objects/object_xmas_tree/gXmasDecor50DL"
+static const ALIGN_ASSET(2) char gXmasDecor50DL[] = dgXmasDecor50DL;
+
+#define dgXmasDecor60DL "__OTR__objects/object_xmas_tree/gXmasDecor60DL"
+static const ALIGN_ASSET(2) char gXmasDecor60DL[] = dgXmasDecor60DL;
+
+#define dgXmasDecor70DL "__OTR__objects/object_xmas_tree/gXmasDecor70DL"
+static const ALIGN_ASSET(2) char gXmasDecor70DL[] = dgXmasDecor70DL;
+
+#define dgXmasDecor80DL "__OTR__objects/object_xmas_tree/gXmasDecor80DL"
+static const ALIGN_ASSET(2) char gXmasDecor80DL[] = dgXmasDecor80DL;
+
+#define dgXmasDecor90DL "__OTR__objects/object_xmas_tree/gXmasDecor90DL"
+static const ALIGN_ASSET(2) char gXmasDecor90DL[] = dgXmasDecor90DL;
+
+#define dgXmasDecor100DL "__OTR__objects/object_xmas_tree/gXmasDecor100DL"
+static const ALIGN_ASSET(2) char gXmasDecor100DL[] = dgXmasDecor100DL;
+
+#define dgXmasStarDL "__OTR__objects/object_xmas_tree/gXmasStarDL"
+static const ALIGN_ASSET(2) char gXmasStarDL[] = dgXmasStarDL;
+
+#define dgKakarikoDecorDL "__OTR__objects/object_kakariko_decor/gKakarikoDecorDL"
+static const ALIGN_ASSET(2) char gKakarikoDecorDL[] = dgKakarikoDecorDL;
+
+#define dgTempleOfTimeDecorDL "__OTR__objects/object_temple_of_time_decor/gTempleOfTimeDecorDL"
+static const ALIGN_ASSET(2) char gTempleOfTimeDecorDL[] = dgTempleOfTimeDecorDL;
+
+#define dgKakarikoChildDecorDL "__OTR__objects/object_kakariko_decor/gKakarikoChildDecorDL"
+static const ALIGN_ASSET(2) char gKakarikoChildDecorDL[] = dgKakarikoChildDecorDL;
+
+#define dgKakarikoAdultDecorDL "__OTR__objects/object_kakariko_decor/gKakarikoAdultDecorDL"
+static const ALIGN_ASSET(2) char gKakarikoAdultDecorDL[] = dgKakarikoAdultDecorDL;
+
// overlays
#define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx"
static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx;
diff --git a/soh/assets/sources/TempleOfTime_DL.blend b/soh/assets/sources/TempleOfTime_DL.blend
new file mode 100644
index 00000000000..38500e0d7ed
Binary files /dev/null and b/soh/assets/sources/TempleOfTime_DL.blend differ
diff --git a/soh/assets/xml/GC_MQ_D/objects/object_mo.xml b/soh/assets/xml/GC_MQ_D/objects/object_mo.xml
index f25286df87c..f31a345d6a4 100644
--- a/soh/assets/xml/GC_MQ_D/objects/object_mo.xml
+++ b/soh/assets/xml/GC_MQ_D/objects/object_mo.xml
@@ -79,7 +79,7 @@
-
+
diff --git a/soh/assets/xml/GC_MQ_D/overlays/ovl_Boss_Dodongo.xml b/soh/assets/xml/GC_MQ_D/overlays/ovl_Boss_Dodongo.xml
index f2ee5b7b8c0..0e2c84f578b 100644
--- a/soh/assets/xml/GC_MQ_D/overlays/ovl_Boss_Dodongo.xml
+++ b/soh/assets/xml/GC_MQ_D/overlays/ovl_Boss_Dodongo.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml b/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml
index 2a6247c9f5c..b4528ef3176 100644
--- a/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml
+++ b/soh/assets/xml/GC_MQ_PAL_F/objects/object_mo.xml
@@ -8,7 +8,7 @@
-
+
@@ -69,17 +69,17 @@
-
+
-
+
-
+
diff --git a/soh/assets/xml/GC_MQ_PAL_F/overlays/ovl_Boss_Dodongo.xml b/soh/assets/xml/GC_MQ_PAL_F/overlays/ovl_Boss_Dodongo.xml
index 0e1303c17d7..8a1c4ee94cc 100644
--- a/soh/assets/xml/GC_MQ_PAL_F/overlays/ovl_Boss_Dodongo.xml
+++ b/soh/assets/xml/GC_MQ_PAL_F/overlays/ovl_Boss_Dodongo.xml
@@ -1,6 +1,6 @@
-
-
+
+
diff --git a/soh/assets/xml/GC_MQ_PAL_F/text/message_data_static.xml b/soh/assets/xml/GC_MQ_PAL_F/text/message_data_static.xml
index 400a27e27d0..5241e3ef766 100644
--- a/soh/assets/xml/GC_MQ_PAL_F/text/message_data_static.xml
+++ b/soh/assets/xml/GC_MQ_PAL_F/text/message_data_static.xml
@@ -1,14 +1,14 @@
-
+
-
+
-
+
-
+
diff --git a/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml b/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml
index 2a6247c9f5c..b4528ef3176 100644
--- a/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml
+++ b/soh/assets/xml/GC_NMQ_D/objects/object_mo.xml
@@ -8,7 +8,7 @@
-
+
@@ -69,17 +69,17 @@
-
+
-
+
-
+
diff --git a/soh/assets/xml/GC_NMQ_D/overlays/ovl_Boss_Dodongo.xml b/soh/assets/xml/GC_NMQ_D/overlays/ovl_Boss_Dodongo.xml
index f6a52f04433..d31e4abcc60 100644
--- a/soh/assets/xml/GC_NMQ_D/overlays/ovl_Boss_Dodongo.xml
+++ b/soh/assets/xml/GC_NMQ_D/overlays/ovl_Boss_Dodongo.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml
index 2a6247c9f5c..b4528ef3176 100644
--- a/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml
+++ b/soh/assets/xml/GC_NMQ_PAL_F/objects/object_mo.xml
@@ -8,7 +8,7 @@
-
+
@@ -69,17 +69,17 @@
-
+
-
+
-
+
diff --git a/soh/assets/xml/GC_NMQ_PAL_F/overlays/ovl_Boss_Dodongo.xml b/soh/assets/xml/GC_NMQ_PAL_F/overlays/ovl_Boss_Dodongo.xml
index f2ee5b7b8c0..67d85d16896 100644
--- a/soh/assets/xml/GC_NMQ_PAL_F/overlays/ovl_Boss_Dodongo.xml
+++ b/soh/assets/xml/GC_NMQ_PAL_F/overlays/ovl_Boss_Dodongo.xml
@@ -1,6 +1,6 @@
-
-
-
+
+
+
diff --git a/soh/assets/xml/N64_PAL_10/objects/object_mo.xml b/soh/assets/xml/N64_PAL_10/objects/object_mo.xml
index 2a6247c9f5c..b4528ef3176 100644
--- a/soh/assets/xml/N64_PAL_10/objects/object_mo.xml
+++ b/soh/assets/xml/N64_PAL_10/objects/object_mo.xml
@@ -8,7 +8,7 @@
-
+
@@ -69,17 +69,17 @@
-
+
-
+
-
+
diff --git a/soh/assets/xml/N64_PAL_10/overlays/ovl_Boss_Dodongo.xml b/soh/assets/xml/N64_PAL_10/overlays/ovl_Boss_Dodongo.xml
index 8f0c7612c2e..5e4975bc1d4 100644
--- a/soh/assets/xml/N64_PAL_10/overlays/ovl_Boss_Dodongo.xml
+++ b/soh/assets/xml/N64_PAL_10/overlays/ovl_Boss_Dodongo.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/soh/assets/xml/N64_PAL_11/objects/object_mo.xml b/soh/assets/xml/N64_PAL_11/objects/object_mo.xml
index 2a6247c9f5c..b4528ef3176 100644
--- a/soh/assets/xml/N64_PAL_11/objects/object_mo.xml
+++ b/soh/assets/xml/N64_PAL_11/objects/object_mo.xml
@@ -8,7 +8,7 @@
-
+
@@ -69,17 +69,17 @@
-
+
-
+
-
+
diff --git a/soh/assets/xml/N64_PAL_11/overlays/ovl_Boss_Dodongo.xml b/soh/assets/xml/N64_PAL_11/overlays/ovl_Boss_Dodongo.xml
index cd9069e13f2..d6f77448d1e 100644
--- a/soh/assets/xml/N64_PAL_11/overlays/ovl_Boss_Dodongo.xml
+++ b/soh/assets/xml/N64_PAL_11/overlays/ovl_Boss_Dodongo.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/soh/soh/ActorDB.cpp b/soh/soh/ActorDB.cpp
index a66048b322f..1ffe5bf3e84 100644
--- a/soh/soh/ActorDB.cpp
+++ b/soh/soh/ActorDB.cpp
@@ -604,8 +604,59 @@ static ActorDBInit EnPartnerInit = {
};
extern "C" s16 gEnPartnerId;
+#include "src/overlays/actors/ovl_En_Snowball/z_en_snowball.h"
+static ActorDBInit EnSnowballInit = {
+ "En_Snowball",
+ "Snowball",
+ ACTORCAT_ITEMACTION,
+ (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_DRAGGED_BY_HOOKSHOT | ACTOR_FLAG_CAN_PRESS_SWITCH),
+ OBJECT_GAMEPLAY_KEEP,
+ sizeof(EnSnowball),
+ (ActorFunc)EnSnowball_Init,
+ (ActorFunc)EnSnowball_Destroy,
+ (ActorFunc)EnSnowball_Update,
+ (ActorFunc)EnSnowball_Draw,
+ nullptr,
+};
+extern "C" s16 gEnSnowballId;
+
+#include "src/overlays/actors/ovl_En_ChristmasTree/z_en_christmastree.h"
+static ActorDBInit EnChristmasTreeInit = {
+ "En_ChristmasTree",
+ "Christmas Tree",
+ ACTORCAT_PROP,
+ (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED),
+ OBJECT_GAMEPLAY_KEEP,
+ sizeof(EnChristmasTree),
+ (ActorFunc)EnChristmasTree_Init,
+ (ActorFunc)EnChristmasTree_Destroy,
+ (ActorFunc)EnChristmasTree_Update,
+ (ActorFunc)EnChristmasTree_Draw,
+ nullptr,
+};
+extern "C" s16 gEnChristmasTreeId;
+
+#include "src/overlays/actors/ovl_En_ChristmasDeco/z_en_christmasdeco.h"
+static ActorDBInit EnChristmasDecoInit = {
+ "En_ChristmasDeco",
+ "Christmas Decos",
+ ACTORCAT_PROP,
+ (ACTOR_FLAG_DRAW_WHILE_CULLED),
+ OBJECT_GAMEPLAY_KEEP,
+ sizeof(EnChristmasDeco),
+ (ActorFunc)EnChristmasDeco_Init,
+ (ActorFunc)EnChristmasDeco_Destroy,
+ (ActorFunc)EnChristmasDeco_Update,
+ (ActorFunc)EnChristmasDeco_Draw,
+ nullptr,
+};
+extern "C" s16 gEnChristmasDecoId;
+
void ActorDB::AddBuiltInCustomActors() {
gEnPartnerId = ActorDB::Instance->AddEntry(EnPartnerInit).entry.id;
+ gEnSnowballId = ActorDB::Instance->AddEntry(EnSnowballInit).entry.id;
+ gEnChristmasTreeId = ActorDB::Instance->AddEntry(EnChristmasTreeInit).entry.id;
+ gEnChristmasDecoId = ActorDB::Instance->AddEntry(EnChristmasDecoInit).entry.id;
}
extern "C" ActorDBEntry* ActorDB_Retrieve(const int id) {
diff --git a/soh/soh/Enhancements/controls/GameControlEditor.cpp b/soh/soh/Enhancements/controls/GameControlEditor.cpp
index 935935c4801..eb69f3cc852 100644
--- a/soh/soh/Enhancements/controls/GameControlEditor.cpp
+++ b/soh/soh/Enhancements/controls/GameControlEditor.cpp
@@ -312,6 +312,7 @@ namespace GameControlEditor {
DrawHelpIcon("Allows the cursor on the pause menu to be over any slot. Sometimes required in rando to select "
"certain items.");
UIWidgets::Spacer(0);
+ ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
UIWidgets::PaddedEnhancementCheckbox("Enable walk speed modifiers", "gEnableWalkModify", true, false);
DrawHelpIcon("Hold the assigned button to change the maximum walking speed\nTo change the assigned button, go into the Ports tabs above");
if (CVarGetInteger("gEnableWalkModify", 0)) {
@@ -323,6 +324,7 @@ namespace GameControlEditor {
UIWidgets::PaddedEnhancementSliderFloat("Modifier 2: %d %%", "##WalkMod2", "gWalkModifierTwo", 0.0f, 5.0f, "", 1.0f, true, true, false, true);
window->EndGroupPanelPublic(0);
}
+ ImGui::EndDisabled();
UIWidgets::Spacer(0);
UIWidgets::PaddedEnhancementCheckbox("Answer Navi Prompt with L Button", "gNaviOnL");
DrawHelpIcon("Speak to Navi with L but enter first-person camera with C-Up");
diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
index 9c56ac32ba1..14a86456366 100644
--- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
+++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
@@ -47,6 +47,13 @@ extern PlayState* gPlayState;
#include "objects/object_gjyo_objects/object_gjyo_objects.h"
#include "textures/nintendo_rogo_static/nintendo_rogo_static.h"
#include "objects/object_gi_rabit_mask/object_gi_rabit_mask.h"
+#include "objects/object_wood02/object_wood02.h"
+#include "scenes/overworld/spot00/spot00_room_0.h"
+#include "scenes/overworld/spot04/spot04_room_0.h"
+#include "scenes/overworld/spot04/spot04_room_1.h"
+#include "scenes/overworld/spot20/spot20_room_0.h"
+#include "scenes/overworld/spot03/spot03_room_0.h"
+#include "scenes/overworld/spot15/spot15_room_0.h"
void ResourceMgr_PatchGfxByName(const char* path, const char* patchName, int index, Gfx instruction);
void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const char* patchName, int destinationIndex, int sourceIndex);
void ResourceMgr_UnpatchGfxByName(const char* path, const char* patchName);
@@ -190,9 +197,9 @@ typedef struct {
colors were darker than the gDPSetPrimColor. You will see many more examples of this below in the `ApplyOrResetCustomGfxPatches` method
*/
static std::map cosmeticOptions = {
- COSMETIC_OPTION("Link_KokiriTunic", "Kokiri Tunic", GROUP_LINK, ImVec4( 30, 105, 27, 255), false, true, false),
- COSMETIC_OPTION("Link_GoronTunic", "Goron Tunic", GROUP_LINK, ImVec4(100, 20, 0, 255), false, true, false),
- COSMETIC_OPTION("Link_ZoraTunic", "Zora Tunic", GROUP_LINK, ImVec4( 0, 60, 100, 255), false, true, false),
+ COSMETIC_OPTION("Link_KokiriTunic", "Kokiri Tunic", GROUP_LINK, ImVec4(255, 0, 0, 255), false, true, false),
+ COSMETIC_OPTION("Link_GoronTunic", "Goron Tunic", GROUP_LINK, ImVec4(255, 0, 0, 255), false, true, false),
+ COSMETIC_OPTION("Link_ZoraTunic", "Zora Tunic", GROUP_LINK, ImVec4(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("Link_Hair", "Hair", GROUP_LINK, ImVec4(255, 173, 27, 255), false, true, true),
COSMETIC_OPTION("Link_Linen", "Linen", GROUP_LINK, ImVec4(255, 255, 255, 255), false, true, true),
COSMETIC_OPTION("Link_Boots", "Boots", GROUP_LINK, ImVec4( 93, 44, 18, 255), false, true, true),
@@ -325,7 +332,7 @@ static std::map cosmeticOptions = {
COSMETIC_OPTION("NPC_Dog1", "Dog 1", GROUP_NPC, ImVec4(255, 255, 200, 255), false, true, true),
COSMETIC_OPTION("NPC_Dog2", "Dog 2", GROUP_NPC, ImVec4(150, 100, 50, 255), false, true, true),
COSMETIC_OPTION("NPC_GoldenSkulltula", "Golden Skulltula", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, false),
- COSMETIC_OPTION("NPC_Kokiri", "Kokiri", GROUP_NPC, ImVec4( 0, 130, 70, 255), false, true, false),
+ COSMETIC_OPTION("NPC_Kokiri", "Kokiri", GROUP_NPC, ImVec4(255, 0, 0, 255), false, true, false),
COSMETIC_OPTION("NPC_Gerudo", "Gerudo", GROUP_NPC, ImVec4( 90, 0, 140, 255), false, true, false),
COSMETIC_OPTION("NPC_MetalTrap", "Metal Trap", GROUP_NPC, ImVec4(255, 255, 255, 255), false, true, true),
COSMETIC_OPTION("NPC_IronKnuckles", "Iron Knuckles", GROUP_NPC, ImVec4(245, 255, 205, 255), false, true, false),
@@ -441,6 +448,24 @@ void CosmeticsUpdateTick() {
5. GFX Command: The GFX command you want to insert
*/
void ApplyOrResetCustomGfxPatches(bool manualChange) {
+ if (manualChange) {
+ PATCH_GFX(object_wood02_DL_007968, "Tree1", "gLetItSnow", 17, gsDPSetPrimColor(0, 0, 255, 255, 255, 255));
+ PATCH_GFX(object_wood02_DL_000090, "Tree2", "gLetItSnow", 17, gsDPSetPrimColor(0, 0, 200, 255, 255, 255));
+ PATCH_GFX(object_wood02_DL_000340, "Tree3", "gLetItSnow", 17, gsDPSetPrimColor(0, 0, 255, 255, 255, 255));
+ PATCH_GFX(object_wood02_DL_000340, "Tree4", "gLetItSnow", 24, gsDPSetPrimColor(0, 0, 255, 255, 255, 255));
+ PATCH_GFX(spot00_room_0DL_0139A8, "Path1", "gLetItSnow", 23, gsDPSetPrimColor(0, 0, 100, 150, 255, 60));
+ PATCH_GFX(spot00_room_0DL_013250, "Path2", "gLetItSnow", 23, gsDPSetPrimColor(0, 0, 100, 150, 255, 60));
+ PATCH_GFX(spot00_room_0DL_0143C8, "Path3", "gLetItSnow", 23, gsDPSetPrimColor(0, 0, 100, 150, 255, 60));
+ PATCH_GFX(spot04_room_0DL_018048, "Path4", "gLetItSnow", 24, gsDPSetPrimColor(0, 0, 100, 150, 255, 60));
+ PATCH_GFX(spot04_room_1DL_007810, "Path5", "gLetItSnow", 24, gsDPSetPrimColor(0, 0, 100, 150, 255, 60));
+ PATCH_GFX(spot20_room_0DL_0062D0, "Path6", "gLetItSnow", 23, gsDPSetPrimColor(0, 0, 200, 230, 255, 30));
+ PATCH_GFX(spot20_room_0DL_004460, "Path8", "gLetItSnow", 31, gsDPSetPrimColor(0, 0, 200, 230, 255, 30));
+ PATCH_GFX(spot20_room_0DL_004460, "Path9", "gLetItSnow", 118, gsDPSetPrimColor(0, 0, 200, 230, 255, 30));
+ PATCH_GFX(spot20_room_0DL_0065E8, "Path10", "gLetItSnow", 24, gsDPSetPrimColor(0, 0, 200, 230, 255, 30));
+ PATCH_GFX(spot03_room_0DL_00C4B0, "Path11", "gLetItSnow", 23, gsDPSetPrimColor(0, 0, 200, 230, 255, 30));
+ PATCH_GFX(spot15_room_0DL_00C748, "Path12", "gLetItSnow", 23, gsDPSetPrimColor(0, 0, 200, 230, 255, 30));
+ }
+
static CosmeticOption& linkGoronTunic = cosmeticOptions.at("Link_GoronTunic");
if (manualChange || CVarGetInteger(linkGoronTunic.rainbowCvar, 0)) {
static Color_RGBA8 defaultColor = {linkGoronTunic.defaultColor.x, linkGoronTunic.defaultColor.y, linkGoronTunic.defaultColor.z, linkGoronTunic.defaultColor.w};
@@ -1485,6 +1510,7 @@ void Draw_Placements(){
}
void DrawSillyTab() {
+ ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
if (CVarGetInteger("gLetItSnow", 0)) {
if (UIWidgets::EnhancementCheckbox("Let It Snow", "gLetItSnow")) {
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
@@ -1569,6 +1595,7 @@ void DrawSillyTab() {
CVarClear("gCosmetics.Kak_Windmill_Speed.Changed");
LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
}
+ ImGui::EndDisabled();
}
// Copies the RGB values from one cosmetic option to another, multiplied by the passed in amount, this
diff --git a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp
index a9f3b1f198e..d2e8e03b123 100644
--- a/soh/soh/Enhancements/crowd-control/CrowdControl.cpp
+++ b/soh/soh/Enhancements/crowd-control/CrowdControl.cpp
@@ -380,13 +380,13 @@ CrowdControl::Effect* CrowdControl::ParseMessage(char payload[512]) {
effect->category = kEffectCatBoots;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
- effect->giEffect->parameters[0] = PLAYER_BOOTS_IRON;
+ effect->giEffect->parameters[0] = EQUIP_VALUE_BOOTS_IRON;
break;
case kEffectForceHoverBoots:
effect->category = kEffectCatBoots;
effect->timeRemaining = 30000;
effect->giEffect = new GameInteractionEffect::ForceEquipBoots();
- effect->giEffect->parameters[0] = PLAYER_BOOTS_HOVER;
+ effect->giEffect->parameters[0] = EQUIP_VALUE_BOOTS_HOVER;
break;
case kEffectSlipperyFloor:
effect->category = kEffectCatSlipperyFloor;
diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp
index 9af4eadb7e9..b357363ac97 100644
--- a/soh/soh/Enhancements/debugger/debugSaveEditor.cpp
+++ b/soh/soh/Enhancements/debugger/debugSaveEditor.cpp
@@ -515,7 +515,7 @@ void DrawInfoTab() {
UIWidgets::InsertHelpHoverText("Z-Targeting behavior");
if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT)) {
- ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U16, &gSaveContext.triforcePiecesCollected);
+ ImGui::InputScalar("Triforce Pieces", ImGuiDataType_U8, &gSaveContext.triforcePiecesCollected);
UIWidgets::InsertHelpHoverText("Currently obtained Triforce Pieces. For Triforce Hunt.");
}
diff --git a/soh/soh/Enhancements/debugger/debugSaveEditor.h b/soh/soh/Enhancements/debugger/debugSaveEditor.h
index 42c9c91c0f5..01557efefe0 100644
--- a/soh/soh/Enhancements/debugger/debugSaveEditor.h
+++ b/soh/soh/Enhancements/debugger/debugSaveEditor.h
@@ -505,6 +505,7 @@ const std::vector flagTables = {
{ RAND_INF_CHILD_FISHING, "RAND_INF_CHILD_FISHING" },
{ RAND_INF_ADULT_FISHING, "RAND_INF_ADULT_FISHING" },
{ RAND_INF_10_BIG_POES, "RAND_INF_10_BIG_POES" },
+ { RAND_INF_GRANT_GANONS_BOSSKEY, "RAND_INF_GRANT_GANONS_BOSSKEY" },
} },
};
diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h
index 529ebed81ed..c8461bbf1a3 100644
--- a/soh/soh/Enhancements/enhancementTypes.h
+++ b/soh/soh/Enhancements/enhancementTypes.h
@@ -1,3 +1,6 @@
+#ifndef _ENHANCEMENT_TYPES_H_
+#define _ENHANCEMENT_TYPES_H_
+
typedef enum {
WARP_MODE_OVERRIDE_OFF,
WARP_MODE_OVERRIDE_MQ_AS_VANILLA,
@@ -74,3 +77,5 @@ typedef enum {
DEKU_STICK_UNBREAKABLE,
DEKU_STICK_UNBREAKABLE_AND_ALWAYS_ON_FIRE,
} DekuStickType;
+
+#endif
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h
index ae711c0932d..514fe787f10 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h
@@ -65,6 +65,7 @@ typedef enum {
extern "C" {
#endif
uint8_t GameInteractor_NoUIActive();
+void GameInteractor_SetNoUIActive(uint8_t state);
GILinkSize GameInteractor_GetLinkSize();
void GameInteractor_SetLinkSize(GILinkSize size);
uint8_t GameInteractor_InvisibleLinkActive();
@@ -193,6 +194,8 @@ class GameInteractor {
DEFINE_HOOK(OnSetGameLanguage, void());
+ DEFINE_HOOK(OnAssetAltChange, void());
+
// Helpers
static bool IsSaveLoaded();
static bool IsGameplayPaused();
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
index 13df133a0d9..4bd5354a67a 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
@@ -181,3 +181,9 @@ void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode) {
void GameInteractor_ExecuteOnSetGameLanguage() {
GameInteractor::Instance->ExecuteHooks();
}
+
+// MARK: - System
+
+void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void)) {
+ GameInteractor::Instance->RegisterGameHook(fn);
+}
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
index 47114a300a0..7b7b226faf2 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
@@ -56,6 +56,10 @@ void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode);
// MARK: - Game
void GameInteractor_ExecuteOnSetGameLanguage();
+
+// MARK: - System
+void GameInteractor_RegisterOnAssetAltChange(void (*fn)(void));
+
#ifdef __cplusplus
}
#endif
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_State.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_State.cpp
index 21642ddedce..38d125786e6 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_State.cpp
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_State.cpp
@@ -36,6 +36,10 @@ uint8_t GameInteractor_NoUIActive() {
return GameInteractor::State::NoUIActive;
}
+void GameInteractor_SetNoUIActive(uint8_t state) {
+ GameInteractor::State::NoUIActive = state;
+}
+
// MARK: - GameInteractor::State::LinkSize
GILinkSize GameInteractor_GetLinkSize() {
return GameInteractor::State::LinkSize;
diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp
index 0bbeff8ca0f..cb97d32f466 100644
--- a/soh/soh/Enhancements/mods.cpp
+++ b/soh/soh/Enhancements/mods.cpp
@@ -32,6 +32,7 @@ extern "C" {
#include "functions.h"
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
+extern "C" s16 gEnSnowballId;
extern void Overlay_DisplayText(float duration, const char* text);
uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
}
@@ -47,6 +48,7 @@ void ReloadSceneTogglingLinkAge() {
void RegisterInfiniteMoney() {
GameInteractor::Instance->RegisterGameHook([]() {
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gInfiniteMoney", 0) != 0) {
if (gSaveContext.rupees < CUR_CAPACITY(UPG_WALLET)) {
gSaveContext.rupees = CUR_CAPACITY(UPG_WALLET);
@@ -57,6 +59,7 @@ void RegisterInfiniteMoney() {
void RegisterInfiniteHealth() {
GameInteractor::Instance->RegisterGameHook([]() {
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gInfiniteHealth", 0) != 0) {
if (gSaveContext.health < gSaveContext.healthCapacity) {
gSaveContext.health = gSaveContext.healthCapacity;
@@ -67,6 +70,7 @@ void RegisterInfiniteHealth() {
void RegisterInfiniteAmmo() {
GameInteractor::Instance->RegisterGameHook([]() {
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gInfiniteAmmo", 0) != 0) {
// Deku Sticks
if (AMMO(ITEM_STICK) < CUR_CAPACITY(UPG_STICKS)) {
@@ -103,6 +107,7 @@ void RegisterInfiniteAmmo() {
void RegisterInfiniteMagic() {
GameInteractor::Instance->RegisterGameHook([]() {
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gInfiniteMagic", 0) != 0) {
if (gSaveContext.isMagicAcquired && gSaveContext.magic != (gSaveContext.isDoubleMagicAcquired + 1) * 0x30) {
gSaveContext.magic = (gSaveContext.isDoubleMagicAcquired + 1) * 0x30;
@@ -113,6 +118,7 @@ void RegisterInfiniteMagic() {
void RegisterInfiniteNayrusLove() {
GameInteractor::Instance->RegisterGameHook([]() {
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gInfiniteNayru", 0) != 0) {
gSaveContext.nayrusLoveTimer = 0x44B;
}
@@ -121,7 +127,7 @@ void RegisterInfiniteNayrusLove() {
void RegisterMoonJumpOnL() {
GameInteractor::Instance->RegisterGameHook([]() {
- if (!gPlayState) return;
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gMoonJumpOnL", 0) != 0) {
Player* player = GET_PLAYER(gPlayState);
@@ -136,7 +142,7 @@ void RegisterMoonJumpOnL() {
void RegisterInfiniteISG() {
GameInteractor::Instance->RegisterGameHook([]() {
- if (!gPlayState) return;
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gEzISG", 0) != 0) {
Player* player = GET_PLAYER(gPlayState);
@@ -148,7 +154,7 @@ void RegisterInfiniteISG() {
//Permanent quick put away (QPA) glitched damage value
void RegisterEzQPA() {
GameInteractor::Instance->RegisterGameHook([]() {
- if (!gPlayState) return;
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gEzQPA", 0) != 0) {
Player* player = GET_PLAYER(gPlayState);
@@ -160,7 +166,7 @@ void RegisterEzQPA() {
void RegisterUnrestrictedItems() {
GameInteractor::Instance->RegisterGameHook([]() {
- if (!gPlayState) return;
+ if (!GameInteractor::IsSaveLoaded()) return;
if (CVarGetInteger("gNoRestrictItems", 0) != 0) {
u8 sunsBackup = gPlayState->interfaceCtx.restrictions.sunsSong;
@@ -188,14 +194,16 @@ void RegisterFreezeTime() {
/// Switches Link's age and respawns him at the last entrance he entered.
void RegisterSwitchAge() {
GameInteractor::Instance->RegisterGameHook([]() {
+ if (!GameInteractor::IsSaveLoaded()) {
+ CVarClear("gSwitchAge");
+ return;
+ }
static bool warped = false;
static Vec3f playerPos;
static int16_t playerYaw;
static RoomContext* roomCtx;
static s32 roomNum;
- if (!gPlayState) return;
-
if (CVarGetInteger("gSwitchAge", 0) && !warped) {
playerPos = GET_PLAYER(gPlayState)->actor.world.pos;
playerYaw = GET_PLAYER(gPlayState)->actor.shape.rot.y;
@@ -215,7 +223,7 @@ void RegisterSwitchAge() {
func_80097534(gPlayState, roomCtx); // load map for new room (unloading the previous room)
}
warped = false;
- CVarSetInteger("gSwitchAge", 0);
+ CVarClear("gSwitchAge");
}
});
}
@@ -224,7 +232,8 @@ void RegisterSwitchAge() {
void RegisterOcarinaTimeTravel() {
GameInteractor::Instance->RegisterGameHook([]() {
- if (!gPlayState) {
+ if (!GameInteractor::IsSaveLoaded()) {
+ CVarClear("gTimeTravel");
return;
}
@@ -623,15 +632,15 @@ f32 triforcePieceScale;
void RegisterTriforceHunt() {
GameInteractor::Instance->RegisterGameHook([]() {
+ Player* player = GET_PLAYER(gPlayState);
+ uint8_t currentPieces = gSaveContext.triforcePiecesCollected;
+ uint8_t requiredPieces = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
+
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;
}
@@ -644,16 +653,23 @@ void RegisterTriforceHunt() {
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);
- }
+
+}
+
+void RegisterGrantGanonsBossKey() {
+ GameInteractor::Instance->RegisterGameHook([]() {
+ Player* player = GET_PLAYER(gPlayState);
+ // Triforce Hunt needs the check if the player isn't being teleported to the credits scene.
+ if (!GameInteractor::IsGameplayPaused() && IS_RANDO && Flags_GetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY) &&
+ gPlayState->sceneLoadFlag != 0x14 &&
+ (1 << 0 & gSaveContext.inventory.dungeonItems[SCENE_GANONS_TOWER]) == 0 && player->stateFlags1 !=
+ PLAYER_STATE1_INPUT_DISABLED) {
+ GetItemEntry getItemEntry =
+ ItemTableManager::Instance->RetrieveItemEntry(MOD_RANDOMIZER, RG_GANONS_CASTLE_BOSS_KEY);
+ GiveItemEntryWithoutActor(gPlayState, getItemEntry);
}
});
}
@@ -1025,8 +1041,16 @@ void RegisterRandomizedEnemySizes() {
Player* player = GET_PLAYER(gPlayState);
Actor* actor = static_cast(refActor);
- // Only apply to enemies and bosses. Exclude the wobbly platforms in Jabu because they need to act like platforms.
- if (!CVarGetInteger("gRandomizedEnemySizes", 0) || (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || actor->id == ACTOR_EN_BROB) {
+ // Exclude wobbly platforms in Jabu because they need to act like platforms.
+ // Exclude Dead Hand hands and Bongo Bongo main body because they make the fights (near) impossible.
+ uint8_t excludedEnemy = actor->id == ACTOR_EN_BROB || actor->id == ACTOR_EN_DHA || (actor->id == ACTOR_BOSS_SST && actor->params == -1);
+
+ // Dodongo, Volvagia and Dead Hand are always smaller because they're impossible when bigger.
+ uint8_t smallOnlyEnemy =
+ actor->id == ACTOR_BOSS_DODONGO || actor->id == ACTOR_BOSS_FD || actor->id == ACTOR_BOSS_FD2 || ACTOR_EN_DH;
+
+ // Only apply to enemies and bosses.
+ if (!CVarGetInteger("gRandomizedEnemySizes", 0) || (actor->category != ACTORCAT_ENEMY && actor->category != ACTORCAT_BOSS) || excludedEnemy) {
return;
}
@@ -1035,9 +1059,8 @@ void RegisterRandomizedEnemySizes() {
uint8_t bigActor = rand() % 2;
- // Big actor. Dodongo and Volvagia are always smaller because they're impossible when bigger.
- if (bigActor && actor->id != ACTOR_BOSS_DODONGO && actor->id != ACTOR_BOSS_FD &&
- actor->id != ACTOR_BOSS_FD2) {
+ // Big actor
+ if (bigActor && !smallOnlyEnemy) {
randomNumber = rand() % 200;
// Between 100% and 300% size.
randomScale = 1.0f + (randomNumber / 100);
@@ -1052,6 +1075,99 @@ void RegisterRandomizedEnemySizes() {
});
}
+static CollisionPoly snowballPoly;
+static Vec3f snowballPos;
+static f32 raycastResult;
+
+static u32 iceBlockParams[] = {
+ 0x214,
+ 0x1,
+ 0x11,
+ 0x10,
+ 0x20,
+};
+
+void RegisterSnowballs() {
+ GameInteractor::Instance->RegisterGameHook([]() {
+ if (gPlayState->sceneNum != SCENE_HYRULE_FIELD && gPlayState->sceneNum != SCENE_KAKARIKO_VILLAGE) {
+ return;
+ }
+
+ int actorsSpawned = 0;
+
+ while (actorsSpawned < 30) {
+ snowballPos.x = (float)(Random(
+ (gPlayState->sceneNum == SCENE_HYRULE_FIELD ? -10000 : -2700) + 10000,
+ (gPlayState->sceneNum == SCENE_HYRULE_FIELD ? 5000 : 2000) + 10000
+ ) - (float)10000.0f);
+ snowballPos.y = 5000;
+ snowballPos.z = (float)(Random(
+ (gPlayState->sceneNum == SCENE_HYRULE_FIELD ? -1000 : -2000) + 10000,
+ (gPlayState->sceneNum == SCENE_HYRULE_FIELD ? 15000 : 2000) + 10000
+ ) - (float)10000.0f);
+
+ raycastResult = BgCheck_AnyRaycastFloor1(&gPlayState->colCtx, &snowballPoly, &snowballPos);
+
+ if (raycastResult > BGCHECK_Y_MIN) {
+ Actor_Spawn(&gPlayState->actorCtx, gPlayState, gEnSnowballId, snowballPos.x, raycastResult,
+ snowballPos.z, 0, 0, 0, gPlayState->sceneNum == SCENE_HYRULE_FIELD, 0);
+ actorsSpawned++;
+ }
+ }
+ });
+
+ GameInteractor::Instance->RegisterGameHook([]() {
+ if (gPlayState->sceneNum != SCENE_LAKE_HYLIA) {
+ return;
+ }
+
+ int actorsSpawned = 0;
+
+ Vec3f spawnedIceBlockPos[15];
+
+ while (actorsSpawned < 15) {
+ Vec3f iceBlockPos;
+ iceBlockPos.x = (float)(Random(
+ (-4200) + 10000,
+ (3000) + 10000
+ ) - (float)10000.0f);
+ iceBlockPos.y = -1713.0f;
+ iceBlockPos.z = (float)(Random(
+ (2600) + 10000,
+ (9000) + 10000
+ ) - (float)10000.0f);
+
+ raycastResult = BgCheck_AnyRaycastFloor1(&gPlayState->colCtx, &snowballPoly, &iceBlockPos);
+
+ if (raycastResult > BGCHECK_Y_MIN) {
+
+ bool overlaps = false;
+ for (int i = 0; i < actorsSpawned; i++) {
+ if (Math_Vec3f_DistXZ(&spawnedIceBlockPos[i], &iceBlockPos) < 500.0f) {
+ overlaps = true;
+ break;
+ }
+ }
+
+ if (overlaps) {
+ continue;
+ }
+
+ if (LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER)) {
+ iceBlockPos.y = raycastResult;
+ } else {
+ iceBlockPos.y = -1310.0f;
+ }
+
+ Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_BG_SPOT08_ICEBLOCK, iceBlockPos.x, iceBlockPos.y,
+ iceBlockPos.z, 0, (s16)Random(0, 0xFFFF), 0, RandomElement(iceBlockParams), 0);
+ spawnedIceBlockPos[actorsSpawned] = iceBlockPos;
+ actorsSpawned++;
+ }
+ }
+ });
+}
+
void InitMods() {
RegisterTTS();
RegisterInfiniteMoney();
@@ -1076,9 +1192,11 @@ void InitMods() {
RegisterMenuPathFix();
RegisterMirrorModeHandler();
RegisterTriforceHunt();
+ RegisterGrantGanonsBossKey();
RegisterEnemyDefeatCounts();
RegisterAltTrapTypes();
RegisterRandomizerSheikSpawn();
RegisterRandomizedEnemySizes();
+ RegisterSnowballs();
NameTag_RegisterHooks();
}
diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h
index f0f586e0031..22c9dd7db3d 100644
--- a/soh/soh/Enhancements/presets.h
+++ b/soh/soh/Enhancements/presets.h
@@ -217,6 +217,31 @@ const std::vector enhancementsCvars = {
"gFixTexturesOOB",
"gIvanCoopModeEnabled",
"gEnemySpawnsOverWaterboxes",
+ "gTreeStickDrops",
+ "gShadowTag",
+ "gRandomizedEnemySizes",
+ "gRandomizedEnemies",
+ "gMirroredWorldMode",
+ "gMirroredWorld",
+ "gHyperEnemies",
+ "gHookshotableReticle",
+ "gHideBunnyHood",
+ "gFixVineFall",
+ "gFileSelectMoreInfo",
+ "gEnemyHealthBar",
+ "gBushDropFix",
+ "gAllDogsRichard",
+ "gAddTraps.enabled",
+ "gAddTraps.Ammo",
+ "gAddTraps.Bomb",
+ "gAddTraps.Burn",
+ "gAddTraps.Ice",
+ "gAddTraps.Kill",
+ "gAddTraps.Knock",
+ "gAddTraps.Shock",
+ "gAddTraps.Speed",
+ "gAddTraps.Tele",
+ "gAddTraps.Void",
};
const std::vector cheatCvars = {
@@ -269,7 +294,23 @@ const std::vector cheatCvars = {
"gNoRedeadFreeze",
"gBombTimerMultiplier",
"gNoFishDespawn",
- "gNoBugsDespawn"
+ "gNoBugsDespawn",
+ "gWalkModifierDoesntChangeJump",
+ "gStatsEnabled",
+ "gSaveStatesEnabled",
+ "gSaveStatePromise",
+ "gRegEditEnabled",
+ "gPreset0",
+ "gPreset1",
+ "gDekuStickCheat",
+ "gDebugWarpScreenTranslation",
+ "gDebugSaveFileMode",
+ "gCosmetics.Link_BodyScale.Changed",
+ "gCosmetics.Link_BodyScale.Value",
+ "gCosmetics.Link_HeadScale.Changed",
+ "gCosmetics.Link_HeadScale.Value",
+ "gCosmetics.Link_SwordScale.Changed",
+ "gCosmetics.Link_SwordScale.Value",
};
const std::vector randomizerCvars = {
@@ -399,6 +440,15 @@ const std::vector randomizerCvars = {
"gRandomizeGregHint",
"gRandoManualSeedEntry",
"gRandomizerSettingsEnabled",
+ "gRandomizeTriforceHuntTotalPieces",
+ "gRandomizeTriforceHuntRequiredPieces",
+ "gRandomizeTriforceHunt",
+ "gRandomizeShuffleMasterSword",
+ "gRandomizeSariaHint",
+ "gRandomizeRupeeNames",
+ "gRandomizeFrogsHint",
+ "gRandoRelevantNavi",
+ "gRandoQuestItemFanfares",
};
const std::vector vanillaPlusPresetEntries = {
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 9b9913c8c4a..7d7a3cf428a 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
@@ -1931,12 +1931,12 @@ void HintTable_Init_Item() {
hintTable[TRIFORCE_PIECE] = HintText::Item({
//obscure text
- Text{"a triumph fork", /*french*/"la Tribosse", /*spanish*/"un trígono del triunfo"},
- Text{"cheese", /*french*/"du fromage", /*spanish*/"un porción de queso"},
- Text{"a gold fragment", /*french*/"un fragment d'or", /*spanish*/"un fragmento dorado"},
+ Text{"a Christmas Ornament", /*french*/"la Tribosse", /*spanish*/"un trígono del triunfo"},
+ Text{"a Christmas Ornament", /*french*/"du fromage", /*spanish*/"un porción de queso"},
+ Text{"a Christmas Ornament", /*french*/"un fragment d'or", /*spanish*/"un fragmento dorado"},
}, {},
//clear text
- Text{"a Piece of the Triforce", /*french*/"un fragment de la Triforce", /*spanish*/"un fragmento de la Trifuerza"}
+ Text{"a Christmas Ornament", /*french*/"un fragment de la Triforce", /*spanish*/"un fragmento de la Trifuerza"}
);
hintTable[EPONA] = HintText::Item({
diff --git a/soh/soh/Enhancements/randomizer/3drando/item_list.cpp b/soh/soh/Enhancements/randomizer/3drando/item_list.cpp
index 34e9c779f7b..6f61b9e1269 100644
--- a/soh/soh/Enhancements/randomizer/3drando/item_list.cpp
+++ b/soh/soh/Enhancements/randomizer/3drando/item_list.cpp
@@ -242,7 +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_PIECE] = Item(RG_TRIFORCE_PIECE, Text{"Christmas Ornament", "Christmas Ornament", "Christmas Ornament"}, 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);
diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp
index 577de1c1958..0ab29d8692d 100644
--- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp
+++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp
@@ -24,11 +24,11 @@ void LocationTable_Init() {
//Lost Woods
locationTable[LW_NEAR_SHORTCUTS_GROTTO_CHEST] = ItemLocation::Chest (RC_LW_NEAR_SHORTCUTS_GROTTO_CHEST, 0x3E, 0x14, "LW Near Shortcuts Grotto Chest", LW_NEAR_SHORTCUTS_GROTTO_CHEST, BLUE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
- locationTable[LW_SKULL_KID] = ItemLocation::Base (RC_LW_SKULL_KID, 0x5B, "LW Skull Kid", LW_SKULL_KID, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(30), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
+ locationTable[LW_SKULL_KID] = ItemLocation::Base (RC_LW_SKULL_KID, 0x5B, "LW Skull Kid", LW_SKULL_KID, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(22), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
locationTable[LW_TRADE_COJIRO] = ItemLocation::Base (RC_LW_TRADE_COJIRO, 0x5B, "LW Trade Cojiro", LW_TRADE_COJIRO, ODD_MUSHROOM, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
- locationTable[LW_TRADE_ODD_POTION] = ItemLocation::Base (RC_LW_TRADE_ODD_POTION, 0x5B, "LW Trade Odd Potion", LW_TRADE_ODD_POTION, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(57), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
- locationTable[LW_OCARINA_MEMORY_GAME] = ItemLocation::Base (RC_LW_OCARINA_MEMORY_GAME, 0x5B, "LW Ocarina Memory Game", LW_OCARINA_MEMORY_GAME, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(31), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
- locationTable[LW_TARGET_IN_WOODS] = ItemLocation::Base (RC_LW_TARGET_IN_WOODS, 0x5B, "LW Target in Woods", LW_TARGET_IN_WOODS, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
+ locationTable[LW_TRADE_ODD_POTION] = ItemLocation::Base (RC_LW_TRADE_ODD_POTION, 0x5B, "LW Trade Odd Potion", LW_TRADE_ODD_POTION, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(49), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
+ locationTable[LW_OCARINA_MEMORY_GAME] = ItemLocation::Base (RC_LW_OCARINA_MEMORY_GAME, 0x5B, "LW Ocarina Memory Game", LW_OCARINA_MEMORY_GAME, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(23), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
+ locationTable[LW_TARGET_IN_WOODS] = ItemLocation::Base (RC_LW_TARGET_IN_WOODS, 0x5B, "LW Target in Woods", LW_TARGET_IN_WOODS, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
locationTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, 0x5B, "LW Deku Scrub Near Deku Theater Right",LW_DEKU_SCRUB_NEAR_DEKU_THEATER_RIGHT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
locationTable[LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, 0x5B, "LW Deku Scrub Near Deku Theater Left", LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, BUY_DEKU_STICK_1, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
locationTable[LW_DEKU_SCRUB_NEAR_BRIDGE] = ItemLocation::Base (RC_LW_DEKU_SCRUB_NEAR_BRIDGE, 0x5B, "LW Deku Scrub Near Bridge", LW_DEKU_SCRUB_NEAR_BRIDGE, PROGRESSIVE_STICK_UPGRADE, {Category::cDekuScrub, Category::cDekuScrubUpgrades}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LOST_WOODS);
@@ -53,7 +53,7 @@ void LocationTable_Init() {
//Lake Hylia
locationTable[LH_CHILD_FISHING] = ItemLocation::Base (RC_LH_CHILD_FISHING, 0x49, "LH Child Fishing", LH_CHILD_FISHING, PIECE_OF_HEART, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA);
locationTable[LH_ADULT_FISHING] = ItemLocation::Base (RC_LH_ADULT_FISHING, 0x49, "LH Adult Fishing", LH_ADULT_FISHING, PROGRESSIVE_SCALE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA);
- locationTable[LH_LAB_DIVE] = ItemLocation::Base (RC_LH_LAB_DIVE, 0x38, "LH Lab Dive", LH_LAB_DIVE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(24), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA);
+ locationTable[LH_LAB_DIVE] = ItemLocation::Base (RC_LH_LAB_DIVE, 0x38, "LH Lab Dive", LH_LAB_DIVE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(16), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA);
locationTable[LH_TRADE_FROG] = ItemLocation::Base (RC_LH_TRADE_FROG, 0x38, "LH Lab Trade Eyeball Frog", LH_TRADE_FROG, EYEDROPS, {Category::cAdultTrade}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA);
locationTable[LH_UNDERWATER_ITEM] = ItemLocation::Base (RC_LH_UNDERWATER_ITEM, 0x57, "LH Underwater Item", LH_UNDERWATER_ITEM, RUTOS_LETTER, {}, SpoilerCollectionCheck::EventChkInf(0x31), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA);
locationTable[LH_SUN] = ItemLocation::Base (RC_LH_SUN, 0x57, "LH Sun", LH_SUN, FIRE_ARROWS, {}, SpoilerCollectionCheck::Chest(0x57, 0x1F), SpoilerCollectionCheckGroup::GROUP_LAKE_HYLIA);
@@ -73,7 +73,7 @@ void LocationTable_Init() {
//Gerudo Fortress
locationTable[GF_CHEST] = ItemLocation::Chest (RC_GF_CHEST, 0x5D, 0x00, "GF Chest", GF_CHEST, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
locationTable[GF_HBA_1000_POINTS] = ItemLocation::Base (RC_GF_HBA_1000_POINTS, 0x5D, "GF HBA 1000 Points", GF_HBA_1000_POINTS, PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x08), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
- locationTable[GF_HBA_1500_POINTS] = ItemLocation::Base (RC_GF_HBA_1500_POINTS, 0x5D, "GF HBA 1500 Points", GF_HBA_1500_POINTS, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(7), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
+ locationTable[GF_HBA_1500_POINTS] = ItemLocation::Base (RC_GF_HBA_1500_POINTS, 0x5D, "GF HBA 1500 Points", GF_HBA_1500_POINTS, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::ItemGetInf(15), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
locationTable[GF_GERUDO_MEMBERSHIP_CARD] = ItemLocation::Base (RC_GF_GERUDO_MEMBERSHIP_CARD, 0x0C, "GF Gerudo Membership Card", GF_GERUDO_MEMBERSHIP_CARD, GERUDO_MEMBERSHIP_CARD, {}, SpoilerCollectionCheck::GerudoToken(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
locationTable[GF_NORTH_F1_CARPENTER] = ItemLocation::Collectable(RC_GF_NORTH_F1_CARPENTER, 0x0C, 0x0C, "GF North F1 Carpenter", GF_NORTH_F1_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
locationTable[GF_NORTH_F2_CARPENTER] = ItemLocation::Collectable(RC_GF_NORTH_F2_CARPENTER, 0x0C, 0x0A, "GF North F2 Carpenter", GF_NORTH_F2_CARPENTER, GERUDO_FORTRESS_SMALL_KEY, {Category::cVanillaGFSmallKey}, SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
@@ -90,12 +90,12 @@ void LocationTable_Init() {
locationTable[COLOSSUS_DEKU_SCRUB_GROTTO_FRONT] = ItemLocation::GrottoScrub(RC_COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, 0xFD, "Colossus Deku Scrub Grotto Front", COLOSSUS_DEKU_SCRUB_GROTTO_FRONT, BUY_GREEN_POTION, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_GERUDO_VALLEY);
//Market
- locationTable[MARKET_TREASURE_CHEST_GAME_REWARD] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_REWARD, 0x10, "MK Treasure Chest Game Reward", MARKET_TREASURE_CHEST_GAME_REWARD, TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(19), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
- locationTable[MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, 0x4B, "MK Bombchu Bowling First Prize", MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(25), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
- locationTable[MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, 0x4B, "MK Bombchu Bowling Second Prize", MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(26), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
+ locationTable[MARKET_TREASURE_CHEST_GAME_REWARD] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_REWARD, 0x10, "MK Treasure Chest Game Reward", MARKET_TREASURE_CHEST_GAME_REWARD, TREASURE_GAME_HEART, {}, SpoilerCollectionCheck::ItemGetInf(27), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
+ locationTable[MARKET_BOMBCHU_BOWLING_FIRST_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, 0x4B, "MK Bombchu Bowling First Prize", MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, PROGRESSIVE_BOMB_BAG, {}, SpoilerCollectionCheck::ItemGetInf(17), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
+ locationTable[MARKET_BOMBCHU_BOWLING_SECOND_PRIZE] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, 0x4B, "MK Bombchu Bowling Second Prize", MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(18), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[MARKET_BOMBCHU_BOWLING_BOMBCHUS] = ItemLocation::Base (RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, 0x4B, "MK Bombchu Bowling Bombchus", NONE, BOMBCHU_DROP, {}, SpoilerCollectionCheck::None(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[MARKET_LOST_DOG] = ItemLocation::Base (RC_MARKET_LOST_DOG, 0x35, "MK Lost Dog", MARKET_LOST_DOG, PIECE_OF_HEART, {}, SpoilerCollectionCheck::InfTable(0x19, 0x09), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
- locationTable[MARKET_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_MARKET_SHOOTING_GALLERY_REWARD, 0x42, "MK Shooting Gallery", MARKET_SHOOTING_GALLERY_REWARD, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(5), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
+ locationTable[MARKET_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_MARKET_SHOOTING_GALLERY_REWARD, 0x42, "MK Shooting Gallery", MARKET_SHOOTING_GALLERY_REWARD, PROGRESSIVE_SLINGSHOT, {}, SpoilerCollectionCheck::ItemGetInf(13), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[MARKET_10_BIG_POES] = ItemLocation::Base (RC_MARKET_10_BIG_POES, 0x4D, "MK 10 Big Poes", MARKET_10_BIG_POES, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_1] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_1, 0x10, 0x01, "MK Chest Game First Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_1, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
locationTable[MARKET_TREASURE_CHEST_GAME_ITEM_2] = ItemLocation::Chest (RC_MARKET_TREASURE_CHEST_GAME_ITEM_2, 0x10, 0x03, "MK Chest Game Second Room Chest", MARKET_TREASURE_CHEST_GAME_ITEM_2, TREASURE_GAME_SMALL_KEY, {Category::cChestMinigame}, SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE);
@@ -115,14 +115,14 @@ void LocationTable_Init() {
locationTable[KAK_30_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_30_GOLD_SKULLTULA_REWARD, 0x50, "Kak 30 Gold Skulltula Reward", KAK_30_GOLD_SKULLTULA_REWARD, PROGRESSIVE_WALLET, {}, SpoilerCollectionCheck::EventChkInf(0xDC), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_40_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_40_GOLD_SKULLTULA_REWARD, 0x50, "Kak 40 Gold Skulltula Reward", KAK_40_GOLD_SKULLTULA_REWARD, BOMBCHU_10, {}, SpoilerCollectionCheck::EventChkInf(0xDD), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_50_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_50_GOLD_SKULLTULA_REWARD, 0x50, "Kak 50 Gold Skulltula Reward", KAK_50_GOLD_SKULLTULA_REWARD, PIECE_OF_HEART, {}, SpoilerCollectionCheck::EventChkInf(0xDE), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
- locationTable[KAK_100_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_100_GOLD_SKULLTULA_REWARD, 0x50, "Kak 100 Gold Skulltula Reward", KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, {}, SpoilerCollectionCheck::EventChkInf(0xDF), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
- locationTable[KAK_MAN_ON_ROOF] = ItemLocation::Base (RC_KAK_MAN_ON_ROOF, 0x52, "Kak Man on Roof", KAK_MAN_ON_ROOF, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(29), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
+ locationTable[KAK_100_GOLD_SKULLTULA_REWARD] = ItemLocation::Base (RC_KAK_100_GOLD_SKULLTULA_REWARD, 0x50, "Kak 100 Gold Skulltula Reward", KAK_100_GOLD_SKULLTULA_REWARD, HUGE_RUPEE, {}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
+ locationTable[KAK_MAN_ON_ROOF] = ItemLocation::Base (RC_KAK_MAN_ON_ROOF, 0x52, "Kak Man on Roof", KAK_MAN_ON_ROOF, PIECE_OF_HEART, {}, SpoilerCollectionCheck::ItemGetInf(21), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_SHOOTING_GALLERY_REWARD] = ItemLocation::Base (RC_KAK_SHOOTING_GALLERY_REWARD, 0x42, "Kak Shooting Gallery Reward", KAK_SHOOTING_GALLERY_REWARD, PROGRESSIVE_BOW, {}, SpoilerCollectionCheck::Chest(0x42, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
- locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(56), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
+ locationTable[KAK_TRADE_ODD_MUSHROOM] = ItemLocation::Base (RC_KAK_TRADE_ODD_MUSHROOM, 0x4E, "Kak Trade Odd Mushroom", KAK_TRADE_ODD_MUSHROOM, ODD_POTION, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(48), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_GRANNYS_SHOP] = ItemLocation::Base (RC_KAK_GRANNYS_SHOP, 0x4E, "Kak Granny's Shop", KAK_GRANNYS_SHOP, BLUE_POTION_REFILL, {Category::cMerchant}, SpoilerCollectionCheck::RandomizerInf(), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
- locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(36), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
- locationTable[KAK_ANJU_AS_CHILD] = ItemLocation::Base (RC_KAK_ANJU_AS_CHILD, 0x52, "Kak Anju as Child", KAK_ANJU_AS_CHILD, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
- locationTable[KAK_TRADE_POCKET_CUCCO] = ItemLocation::Base (RC_KAK_TRADE_POCKET_CUCCO, 0x52, "Kak Trade Pocket Cucco", KAK_TRADE_POCKET_CUCCO, COJIRO, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(38), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
+ locationTable[KAK_ANJU_AS_ADULT] = ItemLocation::Base (RC_KAK_ANJU_AS_ADULT, 0x52, "Kak Anju as Adult", KAK_ANJU_AS_ADULT, CLAIM_CHECK, {}, SpoilerCollectionCheck::ItemGetInf(44), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
+ locationTable[KAK_ANJU_AS_CHILD] = ItemLocation::Base (RC_KAK_ANJU_AS_CHILD, 0x52, "Kak Anju as Child", KAK_ANJU_AS_CHILD, EMPTY_BOTTLE, {}, SpoilerCollectionCheck::ItemGetInf(12), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
+ locationTable[KAK_TRADE_POCKET_CUCCO] = ItemLocation::Base (RC_KAK_TRADE_POCKET_CUCCO, 0x52, "Kak Trade Pocket Cucco", KAK_TRADE_POCKET_CUCCO, COJIRO, {Category::cAdultTrade}, SpoilerCollectionCheck::ItemGetInf(46), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_IMPAS_HOUSE_FREESTANDING_POH] = ItemLocation::Collectable(RC_KAK_IMPAS_HOUSE_FREESTANDING_POH, 0x37, 0x01, "Kak Impas House Freestanding PoH", KAK_IMPAS_HOUSE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[KAK_WINDMILL_FREESTANDING_POH] = ItemLocation::Collectable(RC_KAK_WINDMILL_FREESTANDING_POH, 0x48, 0x01, "Kak Windmill Freestanding PoH", KAK_WINDMILL_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
@@ -133,7 +133,7 @@ void LocationTable_Init() {
locationTable[GRAVEYARD_HOOKSHOT_CHEST] = ItemLocation::Chest (RC_GRAVEYARD_HOOKSHOT_CHEST, 0x48, 0x00, "GY Hookshot Chest", GRAVEYARD_HOOKSHOT_CHEST, PROGRESSIVE_HOOKSHOT, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[GRAVEYARD_DAMPE_RACE_FREESTANDING_POH] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, 0x48, 0x07, "GY Dampe Race Freestanding PoH", GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
locationTable[GRAVEYARD_FREESTANDING_POH] = ItemLocation::Collectable(RC_GRAVEYARD_FREESTANDING_POH, 0x53, 0x04, "GY Freestanding PoH", GRAVEYARD_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
- locationTable[GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, 0x53, "GY Dampe Gravedigging Tour", GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, PIECE_OF_HEART, {}, SpoilerCollectionCheck::Gravedigger(0x53, 0x1F), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
+ locationTable[GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR] = ItemLocation::Collectable(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, 0x53, "GY Dampe Gravedigging Tour", GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, PIECE_OF_HEART, {}, SpoilerCollectionCheck::Gravedigger(0x53, 0x19), SpoilerCollectionCheckGroup::GROUP_KAKARIKO);
//Death Mountain
locationTable[DMT_CHEST] = ItemLocation::Chest (RC_DMT_CHEST, 0x60, 0x01, "DMT Chest", DMT_CHEST, PURPLE_RUPEE, {}, SpoilerCollectionCheckGroup::GROUP_DEATH_MOUNTAIN);
@@ -191,7 +191,7 @@ void LocationTable_Init() {
locationTable[ZF_BOTTOM_FREESTANDING_POH] = ItemLocation::Collectable(RC_ZF_BOTTOM_FREESTANDING_POH, 0x59, 0x14, "ZF Bottom Freestanding PoH", ZF_BOTTOM_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_ZORAS_DOMAIN);
//Lon Lon Ranch
- locationTable[LLR_TALONS_CHICKENS] = ItemLocation::Base (RC_LLR_TALONS_CHICKENS, 0x4C, "LLR Talons Chickens", LLR_TALONS_CHICKENS, BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(10), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH);
+ locationTable[LLR_TALONS_CHICKENS] = ItemLocation::Base (RC_LLR_TALONS_CHICKENS, 0x4C, "LLR Talons Chickens", LLR_TALONS_CHICKENS, BOTTLE_WITH_MILK, {}, SpoilerCollectionCheck::ItemGetInf(2), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH);
locationTable[LLR_FREESTANDING_POH] = ItemLocation::Collectable(RC_LLR_FREESTANDING_POH, 0x4C, 0x01, "LLR Freestanding PoH", LLR_FREESTANDING_POH, PIECE_OF_HEART, {}, SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH);
locationTable[LLR_DEKU_SCRUB_GROTTO_LEFT] = ItemLocation::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_LEFT, 0xFC, "LLR Deku Scrub Grotto Left", LLR_DEKU_SCRUB_GROTTO_LEFT, BUY_DEKU_NUT_5, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH);
locationTable[LLR_DEKU_SCRUB_GROTTO_RIGHT] = ItemLocation::GrottoScrub(RC_LLR_DEKU_SCRUB_GROTTO_RIGHT, 0xFC, "LLR Deku Scrub Grotto Right", LLR_DEKU_SCRUB_GROTTO_RIGHT, BUY_BOMBS_535, {Category::cDekuScrub}, SpoilerCollectionCheck::Scrub(), SpoilerCollectionCheckGroup::GROUP_LON_LON_RANCH);
diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp
index 088ba506756..62042246c36 100644
--- a/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp
+++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.cpp
@@ -1,5 +1,6 @@
#include "playthrough.hpp"
+#include
#include
#include "custom_messages.hpp"
#include "fill.hpp"
@@ -8,6 +9,7 @@
#include "random.hpp"
#include "spoiler_log.hpp"
#include "soh/Enhancements/randomizer/randomizerTypes.h"
+#include "variables.h"
namespace Playthrough {
@@ -39,6 +41,10 @@ int Playthrough_Init(uint32_t seed, std::unordered_map{}(std::to_string(Settings::seed) + settingsStr);
Random_Init(finalHash);
Settings::hash = std::to_string(finalHash);
diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.cpp b/soh/soh/Enhancements/randomizer/3drando/shops.cpp
index 85fb22c22dd..7e94b8066d8 100644
--- a/soh/soh/Enhancements/randomizer/3drando/shops.cpp
+++ b/soh/soh/Enhancements/randomizer/3drando/shops.cpp
@@ -699,9 +699,9 @@ void InitTrickNames() {
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"}};
+ Text{"Glass Ball", "Morceau de Fromage", "Piece of Cheese"},
+ Text{"Coal", "Éclat de Triforce", "Triforce Shard"},
+ Text{"Ornamento", "Caiiloux Brillant", "Shiny Rock"}};
/*
//Names for individual upgrades, in case progressive names are replaced
diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp
index eacc62725b8..570ac5801ce 100644
--- a/soh/soh/Enhancements/randomizer/draw.cpp
+++ b/soh/soh/Enhancements/randomizer/draw.cpp
@@ -214,7 +214,7 @@ extern "C" void Randomizer_DrawTriforcePiece(PlayState* play, GetItemEntry getIt
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
- uint16_t current = gSaveContext.triforcePiecesCollected;
+ uint8_t current = gSaveContext.triforcePiecesCollected;
Matrix_Scale(0.035f, 0.035f, 0.035f, MTXMODE_APPLY);
@@ -238,8 +238,8 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
- uint16_t current = gSaveContext.triforcePiecesCollected;
- uint16_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
+ uint8_t current = gSaveContext.triforcePiecesCollected;
+ uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
Matrix_Scale(triforcePieceScale, triforcePieceScale, triforcePieceScale, MTXMODE_APPLY);
diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp
index 8f88a729940..d9342e92ae9 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer.cpp
@@ -60,6 +60,7 @@ 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::christmasTreeMessageTableID = "RandomizerChristmasTree";
const std::string Randomizer::NaviRandoMessageTableID = "RandomizerNavi";
const std::string Randomizer::IceTrapRandoMessageTableID = "RandomizerIceTrap";
const std::string Randomizer::randoMiscHintsTableID = "RandomizerMiscHints";
@@ -360,37 +361,35 @@ std::unordered_map SpoilerfileSettingNameToEn
{ "Shuffle Dungeon Quest:Ganon's Castle", RSK_MQ_GANONS_CASTLE },
};
-std::string sanitize(std::string stringValue) {
- // Add backslashes.
- for (auto i = stringValue.begin();;) {
- auto const pos = std::find_if(i, stringValue.end(), [](char const c) { return '\\' == c || '\'' == c || '"' == c; });
- if (pos == stringValue.end()) {
- break;
- }
- i = std::next(stringValue.insert(pos, '\\'), 2);
- }
-
- // Removes others.
- stringValue.erase(std::remove_if(stringValue.begin(), stringValue.end(), [](char const c) {
- return '\n' == c || '\r' == c || '\0' == c || '\x1A' == c; }), stringValue.end());
-
- return stringValue;
-}
-
#pragma optimize("", off)
#pragma GCC push_options
#pragma GCC optimize ("O0")
bool Randomizer::SpoilerFileExists(const char* spoilerFileName) {
- if (strcmp(spoilerFileName, "") != 0) {
- std::ifstream spoilerFileStream(sanitize(spoilerFileName));
- if (!spoilerFileStream) {
- return false;
- } else {
+ try {
+ if (strcmp(spoilerFileName, "") != 0) {
+ std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
+ if (!spoilerFileStream) {
+ return false;
+ }
+
+ json spoilerFileJson;
+ spoilerFileStream >> spoilerFileJson;
+
+ if (!spoilerFileJson.contains("version") || !spoilerFileJson.contains("finalSeed")) {
+ return false;
+ }
+
return true;
}
- }
- return false;
+ return false;
+ } catch (std::exception& e) {
+ SPDLOG_ERROR("Error checking if spoiler file exists: {}", e.what());
+ return false;
+ } catch (...) {
+ SPDLOG_ERROR("Error checking if spoiler file exists");
+ return false;
+ }
}
#pragma GCC pop_options
#pragma optimize("", on)
@@ -659,7 +658,7 @@ void Randomizer::LoadMasterQuestDungeons(const char* spoilerFileName) {
}
void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) {
- std::ifstream spoilerFileStream(sanitize(spoilerFileName));
+ std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
if (!spoilerFileStream)
return;
@@ -1293,7 +1292,7 @@ std::string FormatJsonHintText(std::string jsonHint) {
}
void Randomizer::ParseHintLocationsFile(const char* spoilerFileName) {
- std::ifstream spoilerFileStream(sanitize(spoilerFileName));
+ std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
if (!spoilerFileStream)
return;
@@ -1394,7 +1393,7 @@ void Randomizer::ParseHintLocationsFile(const char* spoilerFileName) {
}
void Randomizer::ParseRequiredTrialsFile(const char* spoilerFileName) {
- std::ifstream spoilerFileStream(sanitize(spoilerFileName));
+ std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
if (!spoilerFileStream) {
return;
}
@@ -1415,7 +1414,7 @@ void Randomizer::ParseRequiredTrialsFile(const char* spoilerFileName) {
}
void Randomizer::ParseMasterQuestDungeonsFile(const char* spoilerFileName) {
- std::ifstream spoilerFileStream(sanitize(spoilerFileName));
+ std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
if (!spoilerFileStream) {
return;
}
@@ -1495,7 +1494,7 @@ int16_t Randomizer::GetVanillaMerchantPrice(RandomizerCheck check) {
}
void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent) {
- std::ifstream spoilerFileStream(sanitize(spoilerFileName));
+ std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
if (!spoilerFileStream)
return;
@@ -1558,7 +1557,7 @@ void Randomizer::ParseItemLocationsFile(const char* spoilerFileName, bool silent
}
void Randomizer::ParseEntranceDataFile(const char* spoilerFileName, bool silent) {
- std::ifstream spoilerFileStream(sanitize(spoilerFileName));
+ std::ifstream spoilerFileStream(SohUtils::Sanitize(spoilerFileName));
if (!spoilerFileStream) {
return;
}
@@ -2547,6 +2546,7 @@ std::map rcToRandomizerInf = {
{ RC_LH_CHILD_FISHING, RAND_INF_CHILD_FISHING },
{ RC_LH_ADULT_FISHING, RAND_INF_ADULT_FISHING },
{ RC_MARKET_10_BIG_POES, RAND_INF_10_BIG_POES },
+ { RC_KAK_100_GOLD_SKULLTULA_REWARD, RAND_INF_KAK_100_GOLD_SKULLTULA_REWARD },
};
RandomizerCheckObject Randomizer::GetCheckObjectFromActor(s16 actorId, s16 sceneNum, s32 actorParams = 0x00) {
@@ -3143,7 +3143,9 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f);
}
+ ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
DrawPresetSelector(PRESET_TYPE_RANDOMIZER);
+ ImGui::EndDisabled();
UIWidgets::Spacer(0);
UIWidgets::EnhancementCheckbox("Manual seed entry", "gRandoManualSeedEntry", false, "");
@@ -3166,13 +3168,17 @@ void RandomizerSettingsWindow::DrawElement() {
}
UIWidgets::Spacer(0);
+ ImGui::BeginDisabled(CVarGetInteger("gRandomizerDontGenerateSpoiler", 0) && gSaveContext.gameMode != GAMEMODE_FILE_SELECT);
if (ImGui::Button("Generate Randomizer")) {
GenerateRandomizer(CVarGetInteger("gRandoManualSeedEntry", 0) ? seedString : "");
}
+ ImGui::EndDisabled();
UIWidgets::Spacer(0);
- std::string spoilerfilepath = CVarGetString("gSpoilerLog", "");
- ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str());
+ if (!CVarGetInteger("gRandomizerDontGenerateSpoiler", 0)) {
+ std::string spoilerfilepath = CVarGetString("gSpoilerLog", "");
+ ImGui::Text("Spoiler File: %s", spoilerfilepath.c_str());
+ }
// RANDOTODO settings presets
// std::string presetfilepath = CVarGetString("gLoadedPreset", "");
@@ -3180,6 +3186,8 @@ void RandomizerSettingsWindow::DrawElement() {
UIWidgets::PaddedSeparator();
+ ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
+
ImGuiWindow* window = ImGui::GetCurrentWindow();
static ImVec2 cellPadding(8.0f, 8.0f);
@@ -3542,21 +3550,20 @@ void RandomizerSettingsWindow::DrawElement() {
}
// Triforce Hunt
- UIWidgets::EnhancementCheckbox("Triforce Hunt", "gRandomizeTriforceHunt");
+ UIWidgets::EnhancementCheckbox("Christmas Ornaments 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."
+ "The Christmas ornnaments went missing from the tree in Kakariko Village! Find them back and restore the Christmas "
+ "magic. The tree will get more and more decorated as you find more of the ornaments. Interact with the completed tree "
+ "to finish the game! Your game will be saved and Ganon's Boss key will be granted once you load back into the save."
);
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);
+ ImGui::Text("Ornaments in the world: %d", totalPieces);
UIWidgets::InsertHelpHoverText(
- "The amount of Triforce pieces that will be placed in the world. "
+ "The amount of Christmas ornaments 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();
@@ -3564,9 +3571,9 @@ void RandomizerSettingsWindow::DrawElement() {
// Triforce Hunt (required pieces)
int requiredPieces = CVarGetInteger("gRandomizeTriforceHuntRequiredPieces", 20);
- ImGui::Text("Triforce Pieces to win: %d", requiredPieces);
+ ImGui::Text("Ornaments to win: %d", requiredPieces);
UIWidgets::InsertHelpHoverText(
- "The amount of Triforce pieces required to win the game."
+ "The amount of Christmas ornaments required to win the game."
);
ImGui::SameLine();
UIWidgets::EnhancementSliderInt("", "##TriforceHuntRequiredPieces", "gRandomizeTriforceHuntRequiredPieces", 1, totalPieces, "", 20);
@@ -5224,6 +5231,8 @@ void RandomizerSettingsWindow::DrawElement() {
ImGui::EndTabBar();
}
+
+ ImGui::EndDisabled();
if (disableEditingRandoSettings) {
UIWidgets::ReEnableComponent("");
@@ -5515,27 +5524,27 @@ CustomMessage Randomizer::GetRupeeMessage(u16 rupeeTextId) {
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!",
+ { "You found a %yChristmas Ornament%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!",
+ { "You found a %yChristmas Ornament%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!",
+ { "You found a %yChristmas Ornament%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!",
+ { "You found a %yChristmas Ornament%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!",
+ { "You found all of the %yChristmas&Ornaments%w! Visit the %gChristmas&tree%w in Kakariko Village!",
"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!",
+ { "You found a spare %yChristmas Ornament%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!" },
};
@@ -5548,9 +5557,9 @@ void CreateTriforcePieceMessages() {
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;
+ uint8_t current = gSaveContext.triforcePiecesCollected + 1;
+ uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
+ uint8_t remaining = required - current;
float percentageCollected = (float)current / (float)required;
uint8_t messageIndex;
@@ -5575,6 +5584,39 @@ CustomMessage Randomizer::GetTriforcePieceMessage() {
messageEntry.Replace("{{required}}", std::to_string(required), std::to_string(required), std::to_string(required));
return messageEntry;
}
+void CreateChristmasTreeMessages() {
+ CustomMessage ChristmasTreeMessages[2] = {
+
+ { "The %yChristmas tree%w seems to be&missing some of %gits magic%w... Find all&ornaments to save %rChristmas%w!",
+ "The %yChristmas tree%w seems to be&missing some of %gits magic%w... Find all&ornaments to save %rChristmas%w!",
+ "The %yChristmas tree%w seems to be&missing some of %gits magic%w... Find all&ornaments to save %rChristmas%w!" },
+
+ { "The tree's magic has been fully&restored. %gMerry %rChristmas%w!",
+ "The tree's magic has been fully&restored. %gMerry %rChristmas%w!",
+ "The tree's magic has been fully&restored. %gMerry %rChristmas%w!" }
+ };
+ CustomMessageManager* customMessageManager = CustomMessageManager::Instance;
+ customMessageManager->AddCustomMessageTable(Randomizer::christmasTreeMessageTableID);
+ for (unsigned int i = 0; i <= 1; i++) {
+ customMessageManager->CreateMessage(Randomizer::christmasTreeMessageTableID, i, ChristmasTreeMessages[i]);
+ }
+}
+
+CustomMessage Randomizer::GetChristmasTreeMessage() {
+ // Item is only given after the textbox, so reflect that inside the textbox.
+ uint8_t current = gSaveContext.triforcePiecesCollected;
+ uint8_t required = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
+ uint8_t messageIndex;
+
+ if (current < required) {
+ messageIndex = 0;
+ } else {
+ messageIndex = 1;
+ }
+
+ CustomMessage messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::christmasTreeMessageTableID, messageIndex);
+ return messageEntry;
+}
void CreateNaviRandoMessages() {
CustomMessage NaviMessages[NUM_NAVI_MESSAGES] = {
@@ -6108,6 +6150,7 @@ void Randomizer::CreateCustomMessages() {
CreateGetItemMessages(&getItemMessages);
CreateRupeeMessages();
CreateTriforcePieceMessages();
+ CreateChristmasTreeMessages();
CreateNaviRandoMessages();
CreateIceTrapRandoMessages();
CreateFireTempleGoronMessages();
diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h
index a726cecdeee..3ad363d2a97 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.h
+++ b/soh/soh/Enhancements/randomizer/randomizer.h
@@ -49,6 +49,7 @@ class Randomizer {
static const std::string merchantMessageTableID;
static const std::string rupeeMessageTableID;
static const std::string triforcePieceMessageTableID;
+ static const std::string christmasTreeMessageTableID;
static const std::string NaviRandoMessageTableID;
static const std::string IceTrapRandoMessageTableID;
static const std::string randoMiscHintsTableID;
@@ -105,6 +106,7 @@ class Randomizer {
static void CreateCustomMessages();
static CustomMessage GetRupeeMessage(u16 rupeeTextId);
static CustomMessage GetTriforcePieceMessage();
+ static CustomMessage GetChristmasTreeMessage();
bool CheckContainsVanillaItem(RandomizerCheck randoCheck);
};
diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp
index d7f99edfb9c..d551108615b 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_check_objects.cpp
@@ -39,7 +39,7 @@ std::map rcObjects = {
RC_OBJECT(RC_LW_DEKU_SCRUB_NEAR_DEKU_THEATER_LEFT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x01, GI_STICKS_1, "Deku Scrub Near Deku Theater Left", "LW Deku Scrub Near Deku Theater Left", false),
RC_OBJECT(RC_LW_DEKU_SCRUB_NEAR_BRIDGE, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_LOST_WOODS, 0x09, GI_STICK_UPGRADE_20, "Deku Scrub Near Bridge", "LW Deku Scrub Near Bridge", true),
RC_OBJECT(RC_LW_DEKU_SCRUB_GROTTO_REAR, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x03,0xF5), GI_SEEDS_30, "Deku Scrub Grotto Rear", "LW Deku Scrub Grotto Rear", false),
- RC_OBJECT(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A,0xF5), GI_NUT_UPGRADE_30, "Deku Scrub Grotto Front", "LW Deku Scrub Grotto Front", false),
+ RC_OBJECT(RC_LW_DEKU_SCRUB_GROTTO_FRONT, RCVORMQ_BOTH, RCTYPE_SCRUB, RCAREA_LOST_WOODS, ACTOR_EN_DNS, SCENE_GROTTOS, TWO_ACTOR_PARAMS(0x0A,0xF5), GI_NUT_UPGRADE_30, "Deku Scrub Grotto Front", "LW Deku Scrub Grotto Front", true),
RC_OBJECT(RC_DEKU_THEATER_SKULL_MASK, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, GI_NONE, "Deku Theater Skull Mask", "Deku Theater Skull Mask", true),
RC_OBJECT(RC_DEKU_THEATER_MASK_OF_TRUTH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_LOST_WOODS, ACTOR_ID_MAX, SCENE_GROTTOS, 0x00, GI_NONE, "Deku Theater Mask of Truth", "Deku Theater Mask of Truth", true),
RC_OBJECT(RC_LW_GS_BEAN_PATCH_NEAR_BRIDGE, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_LOST_WOODS, ACTOR_EN_SI, SCENE_LOST_WOODS, 27905, GI_SKULL_TOKEN, "GS Bean Patch Near Bridge", "LW GS Bean Patch Near Bridge", true),
@@ -238,7 +238,7 @@ std::map rcObjects = {
RC_OBJECT(RC_GRAVEYARD_HOOKSHOT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_BOX, SCENE_WINDMILL_AND_DAMPES_GRAVE, 4352, GI_HOOKSHOT, "Hookshot Chest", "GY Hookshot Chest", true),
RC_OBJECT(RC_GRAVEYARD_DAMPE_RACE_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_WINDMILL_AND_DAMPES_GRAVE, 1798, GI_HEART_PIECE, "Dampe Race Freestanding PoH", "GY Dampe Race Freestanding PoH", true),
RC_OBJECT(RC_GRAVEYARD_FREESTANDING_POH, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 1030, GI_HEART_PIECE, "Freestanding PoH", "GY Freestanding PoH", true),
- RC_OBJECT(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 7942, GI_HEART_PIECE, "Dampe Gravedigging Tour", "GY Dampe Gravedigging Tour", true),
+ RC_OBJECT(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_GRAVEYARD, ACTOR_EN_ITEM00, SCENE_GRAVEYARD, 6406, GI_HEART_PIECE, "Dampe Gravedigging Tour", "GY Dampe Gravedigging Tour", true),
RC_OBJECT(RC_GRAVEYARD_GS_WALL, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_GRAVEYARD, ACTOR_EN_SI, SCENE_GRAVEYARD, 20608, GI_SKULL_TOKEN, "GS Wall", "Graveyard GS Wall", true),
RC_OBJECT(RC_GRAVEYARD_GS_BEAN_PATCH, RCVORMQ_BOTH, RCTYPE_SKULL_TOKEN, RCAREA_GRAVEYARD, ACTOR_EN_SI, SCENE_GRAVEYARD, 28673, GI_SKULL_TOKEN, "GS Bean Patch", "Graveyard GS Bean Patch", true),
RC_OBJECT(RC_SONG_FROM_ROYAL_FAMILYS_TOMB, RCVORMQ_BOTH, RCTYPE_SONG_LOCATION, RCAREA_GRAVEYARD, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "Song from Composers Grave", "Song from Composers Grave", true),
diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
index 6123c1a2797..003c8c135a9 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
@@ -73,21 +73,12 @@ bool showLinksPocket;
bool fortressFast;
bool fortressNormal;
-bool bypassRandoCheck = true;
// persistent during gameplay
bool initialized;
bool doAreaScroll;
bool previousShowHidden = false;
bool hideShopRightChecks = true;
-bool checkCollected = false;
-int checkLoops = 0;
-int checkCounter = 0;
-u16 savedFrames = 0;
-bool messageCloseCheck = false;
-bool pendingSaleCheck = false;
-bool transitionCheck = false;
-
std::map startingShopItem = { { SCENE_KOKIRI_SHOP, RC_KF_SHOP_ITEM_1 },
{ SCENE_BAZAAR, RC_MARKET_BAZAAR_ITEM_1 },
{ SCENE_POTION_SHOP_MARKET, RC_MARKET_POTION_SHOP_ITEM_1 },
@@ -118,12 +109,9 @@ bool showVOrMQ;
s8 areaChecksGotten[32]; //| "Kokiri Forest (4/9)"
bool optCollapseAll; // A bool that will collapse all checks once
bool optExpandAll; // A bool that will expand all checks once
-RandomizerCheck lastItemGetCheck = RC_UNKNOWN_CHECK;
RandomizerCheck lastLocationChecked = RC_UNKNOWN_CHECK;
RandomizerCheckArea previousArea = RCAREA_INVALID;
RandomizerCheckArea currentArea = RCAREA_INVALID;
-std::vector checkAreas;
-std::vector itemsReceived;
OSContPad* trackerButtonsPressed;
void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags = 0);
@@ -194,10 +182,6 @@ Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green
std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L,
BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT };
-void SetLastItemGetRC(RandomizerCheck rc) {
- lastItemGetCheck = rc;
-}
-
void DefaultCheckData(RandomizerCheck rc) {
gSaveContext.checkTrackerData[rc].status = RCSHOW_UNCHECKED;
gSaveContext.checkTrackerData[rc].skipped = 0;
@@ -253,9 +237,6 @@ void SetCheckCollected(RandomizerCheck rc) {
} else {
gSaveContext.checkTrackerData[rc].skipped = false;
}
- if (!checkAreas.empty()) {
- checkAreas.erase(checkAreas.begin());
- }
SaveManager::Instance->SaveSection(gSaveContext.fileNum, sectionId, true);
doAreaScroll = true;
@@ -360,32 +341,18 @@ bool vector_contains_scene(std::vector vec, const int16_t scene) {
std::vector skipScenes = {SCENE_GANON_BOSS, SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR, SCENE_GANON_BOSS, SCENE_INSIDE_GANONS_CASTLE_COLLAPSE, SCENE_GANONS_TOWER_COLLAPSE_INTERIOR};
-bool EvaluateCheck(RandomizerCheckObject rco) {
- if (HasItemBeenCollected(rco.rc) && gSaveContext.checkTrackerData[rco.rc].status != RCSHOW_COLLECTED &&
- gSaveContext.checkTrackerData[rco.rc].status != RCSHOW_SAVED) {
- SetCheckCollected(rco.rc);
- return true;
- }
- return false;
-}
-
-bool CheckByArea(RandomizerCheckArea area = RCAREA_INVALID) {
- if (area == RCAREA_INVALID) {
- area = checkAreas.front();
- }
- if (area != RCAREA_INVALID) {
- auto areaChecks = checksByArea.find(area)->second;
- if (checkCounter >= areaChecks.size()) {
- checkCounter = 0;
- checkLoops++;
- }
- auto rco = areaChecks.at(checkCounter);
- return EvaluateCheck(rco);
+void ClearAreaChecksAndTotals() {
+ for (auto& [rcArea, vec] : checksByArea) {
+ vec.clear();
+ areaChecksGotten[rcArea] = 0;
}
}
void SetShopSeen(uint32_t sceneNum, bool prices) {
RandomizerCheck start = startingShopItem.find(sceneNum)->second;
+ if (sceneNum == SCENE_POTION_SHOP_KAKARIKO && !LINK_IS_ADULT) {
+ return;
+ }
if (GetCheckArea() == RCAREA_KAKARIKO_VILLAGE && sceneNum == SCENE_BAZAAR) {
start = RC_KAK_BAZAAR_ITEM_1;
}
@@ -509,12 +476,6 @@ void CheckTrackerLoadGame(int32_t fileNum) {
UpdateInventoryChecks();
}
-void CheckTrackerDialogClosed() {
- if (messageCloseCheck) {
- messageCloseCheck = false;
- }
-}
-
void CheckTrackerShopSlotChange(uint8_t cursorSlot, int16_t basePrice) {
if (gPlayState->sceneNum == SCENE_HAPPY_MASK_SHOP) { // Happy Mask Shop is not used in rando, so is not tracked
return;
@@ -536,10 +497,6 @@ void CheckTrackerTransition(uint32_t sceneNum) {
if (!GameInteractor::IsSaveLoaded()) {
return;
}
- gSaveContext;
- if (transitionCheck) {
- transitionCheck = false;
- }
doAreaScroll = true;
previousArea = currentArea;
currentArea = GetCheckArea();
@@ -560,29 +517,13 @@ void CheckTrackerFrame() {
if (!GameInteractor::IsSaveLoaded()) {
return;
}
- if (!checkAreas.empty() && !transitionCheck && !messageCloseCheck && !pendingSaleCheck) {
- for (int i = 0; i < 10; i++) {
- if (CheckByArea()) {
- checkCounter = 0;
- break;
- } else {
- checkCounter++;
- }
- }
- if (checkLoops > 15) {
- checkAreas.erase(checkAreas.begin());
- checkLoops = 0;
+ // TODO: Move to OnAmmoChange hook once it gets added.
+ if (gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_COLLECTED &&
+ gSaveContext.checkTrackerData[RC_ZR_MAGIC_BEAN_SALESMAN].status != RCSHOW_SAVED) {
+ if (BEANS_BOUGHT >= 10) {
+ SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN);
}
}
- if (savedFrames > 0 && !pendingSaleCheck && !messageCloseCheck) {
- savedFrames--;
- }
-}
-
-void CheckTrackerSaleEnd(GetItemEntry giEntry) {
- if (pendingSaleCheck) {
- pendingSaleCheck = false;
- }
}
void CheckTrackerItemReceive(GetItemEntry giEntry) {
@@ -593,7 +534,7 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) {
// Vanilla special item checks
if (!IS_RANDO) {
if (giEntry.itemId == ITEM_SHIELD_DEKU) {
- SetCheckCollected(RC_KF_SHOP_ITEM_3);
+ SetCheckCollected(RC_KF_SHOP_ITEM_1);
return;
}else if (giEntry.itemId == ITEM_KOKIRI_EMERALD) {
SetCheckCollected(RC_QUEEN_GOHMA);
@@ -622,16 +563,19 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) {
} else if (giEntry.itemId == ITEM_MEDALLION_LIGHT) {
SetCheckCollected(RC_GIFT_FROM_SAGES);
return;
- } else if (giEntry.itemId == ITEM_SONG_LULLABY) {
- SetCheckCollected(RC_SONG_FROM_IMPA);
- return;
} else if (giEntry.itemId == ITEM_SONG_EPONA) {
SetCheckCollected(RC_SONG_FROM_MALON);
return;
} else if (giEntry.itemId == ITEM_SONG_SARIA) {
SetCheckCollected(RC_SONG_FROM_SARIA);
return;
- } else if (giEntry.itemId == ITEM_SONG_SUN) {
+ } else if (giEntry.itemId == ITEM_BEAN) {
+ SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN);
+ return;
+ } else if (giEntry.itemId == ITEM_BRACELET) {
+ SetCheckCollected(RC_GC_DARUNIAS_JOY);
+ return;
+ }/* else if (giEntry.itemId == ITEM_SONG_SUN) {
SetCheckCollected(RC_SONG_FROM_ROYAL_FAMILYS_TOMB);
return;
} else if (giEntry.itemId == ITEM_SONG_TIME) {
@@ -658,42 +602,127 @@ void CheckTrackerItemReceive(GetItemEntry giEntry) {
} else if (giEntry.itemId == ITEM_SONG_PRELUDE) {
SetCheckCollected(RC_SHEIK_AT_TEMPLE);
return;
- } else if (giEntry.itemId == ITEM_BRACELET) {
- SetCheckCollected(RC_GC_DARUNIAS_JOY);
- return;
- } else if (giEntry.itemId == ITEM_LETTER_ZELDA) {
- SetCheckCollected(RC_HC_ZELDAS_LETTER);
- return;
- } else if (giEntry.itemId == ITEM_WEIRD_EGG) {
- SetCheckCollected(RC_HC_MALON_EGG);
- return;
- } else if (giEntry.itemId == ITEM_BEAN) {
- SetCheckCollected(RC_ZR_MAGIC_BEAN_SALESMAN);
- return;
- }
+ }*/
}
- auto checkArea = GetCheckArea();
- if (gSaveContext.pendingSale != ITEM_NONE) {
- pendingSaleCheck = true;
- checkAreas.push_back(checkArea);
+}
+
+void CheckTrackerSceneFlagSet(int16_t sceneNum, int16_t flagType, int32_t flag) {
+ if (flagType != FLAG_SCENE_TREASURE && flagType != FLAG_SCENE_COLLECTIBLE) {
return;
}
- if (scene == SCENE_DESERT_COLOSSUS && (gSaveContext.entranceIndex == 485 || gSaveContext.entranceIndex == 489)) {
- checkAreas.push_back(RCAREA_SPIRIT_TEMPLE);
+ if (sceneNum == SCENE_GRAVEYARD && flag == 0x19 && flagType == FLAG_SCENE_COLLECTIBLE) { // Gravedigging tour special case
+ SetCheckCollected(RC_GRAVEYARD_DAMPE_GRAVEDIGGING_TOUR);
return;
}
- if (GET_PLAYER(gPlayState) == nullptr) {
- transitionCheck = true;
- return;
+ for (auto [rc, rcObj] : RandomizerCheckObjects::GetAllRCObjects()) {
+ if (!IsVisibleInCheckTracker(rcObj)) {
+ continue;
+ }
+ SpoilerCollectionCheckType checkMatchType = flagType == FLAG_SCENE_TREASURE ? SpoilerCollectionCheckType::SPOILER_CHK_CHEST : SpoilerCollectionCheckType::SPOILER_CHK_COLLECTABLE;
+ SpoilerCollectionCheck scCheck = Location(rc)->GetCollectionCheck();
+ if (scCheck.scene == sceneNum && scCheck.flag == flag && scCheck.type == checkMatchType) {
+ SetCheckCollected(rc);
+ return;
+ }
+ }
+}
+
+void CheckTrackerFlagSet(int16_t flagType, int32_t flag) {
+ SpoilerCollectionCheckType checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_NONE;
+ switch (flagType) {
+ case FLAG_GS_TOKEN:
+ checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA;
+ break;
+ case FLAG_EVENT_CHECK_INF:
+ if ((flag == EVENTCHKINF_CARPENTERS_FREE(0) || flag == EVENTCHKINF_CARPENTERS_FREE(1) ||
+ flag == EVENTCHKINF_CARPENTERS_FREE(2) || flag == EVENTCHKINF_CARPENTERS_FREE(3))
+ && GET_EVENTCHKINF_CARPENTERS_FREE_ALL()) {
+ SetCheckCollected(RC_GF_GERUDO_MEMBERSHIP_CARD);
+ return;
+ }
+ checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_EVENT_CHK_INF;
+ break;
+ case FLAG_INF_TABLE:
+ if (flag == INFTABLE_190) {
+ SetCheckCollected(RC_GF_HBA_1000_POINTS);
+ return;
+ } else if (flag == INFTABLE_11E) {
+ SetCheckCollected(RC_GC_ROLLING_GORON_AS_CHILD);
+ return;
+ } else if (flag == INFTABLE_GORON_CITY_DOORS_UNLOCKED) {
+ SetCheckCollected(RC_GC_ROLLING_GORON_AS_ADULT);
+ return;
+ } else if (flag == INFTABLE_139) {
+ SetCheckCollected(RC_ZD_KING_ZORA_THAWED);
+ return;
+ } else if (flag == INFTABLE_191) {
+ SetCheckCollected(RC_MARKET_LOST_DOG);
+ return;
+ }
+ if (!IS_RANDO) {
+ if (flag == INFTABLE_192) {
+ SetCheckCollected(RC_LW_DEKU_SCRUB_NEAR_BRIDGE);
+ return;
+ } else if (flag == INFTABLE_193) {
+ SetCheckCollected(RC_LW_DEKU_SCRUB_GROTTO_FRONT);
+ return;
+ }
+ }
+ break;
+ case FLAG_ITEM_GET_INF:
+ if (!IS_RANDO) {
+ if (flag == ITEMGETINF_OBTAINED_STICK_UPGRADE_FROM_STAGE) {
+ SetCheckCollected(RC_DEKU_THEATER_SKULL_MASK);
+ return;
+ } else if (flag == ITEMGETINF_OBTAINED_NUT_UPGRADE_FROM_STAGE) {
+ SetCheckCollected(RC_DEKU_THEATER_MASK_OF_TRUTH);
+ return;
+ } else if (flag == ITEMGETINF_0B) {
+ SetCheckCollected(RC_HF_DEKU_SCRUB_GROTTO);
+ return;
+ }
+ }
+ checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_ITEM_GET_INF;
+ break;
+ case FLAG_RANDOMIZER_INF:
+ checkMatchType = SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF;
+ break;
}
- if (gPlayState->msgCtx.msgMode != MSGMODE_NONE) {
- checkAreas.push_back(checkArea);
- messageCloseCheck = true;
+ if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_NONE) {
return;
}
- if (IS_RANDO || (!IS_RANDO && giEntry.getItemCategory != ITEM_CATEGORY_JUNK)) {
- checkAreas.push_back(checkArea);
- checkCollected = true;
+ for (auto [rc, rcObj] : RandomizerCheckObjects::GetAllRCObjects()) {
+ if ((!IS_RANDO && ((rcObj.vOrMQ == RCVORMQ_MQ && !IS_MASTER_QUEST) ||
+ (rcObj.vOrMQ == RCVORMQ_VANILLA && IS_MASTER_QUEST))) ||
+ (IS_RANDO && ((OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) &&
+ rcObj.vOrMQ == RCVORMQ_VANILLA) ||
+ !OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) &&
+ rcObj.vOrMQ == RCVORMQ_MQ))) {
+ continue;
+ }
+ SpoilerCollectionCheck scCheck = Location(rc)->GetCollectionCheck();
+ SpoilerCollectionCheckType scCheckType = scCheck.type;
+ if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF &&
+ (scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MERCHANT ||
+ scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SHOP_ITEM ||
+ scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_COW ||
+ scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_SCRUB ||
+ scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_MASTER_SWORD ||
+ scCheckType == SpoilerCollectionCheckType::SPOILER_CHK_RANDOMIZER_INF)) {
+ if (flag == OTRGlobals::Instance->gRandomizer->GetRandomizerInfFromCheck(rc)) {
+ SetCheckCollected(rc);
+ return;
+ }
+ continue;
+ }
+ int16_t checkFlag = scCheck.flag;
+ if (checkMatchType == SpoilerCollectionCheckType::SPOILER_CHK_GOLD_SKULLTULA) {
+ checkFlag = rcObj.actorParams;
+ }
+ if (checkFlag == flag && scCheck.type == checkMatchType) {
+ SetCheckCollected(rc);
+ return;
+ }
}
}
@@ -711,7 +740,7 @@ void InitTrackerData(bool isDebug) {
void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) {
SaveManager::Instance->SaveArray("checks", ARRAY_COUNT(saveContext->checkTrackerData), [&](size_t i) {
if (saveContext->checkTrackerData[i].status == RCSHOW_COLLECTED) {
- if (gameSave || savedFrames > 0) {
+ if (gameSave) {
gSaveContext.checkTrackerData[i].status = saveContext->checkTrackerData[i].status = RCSHOW_SAVED;
UpdateAllOrdering();
UpdateInventoryChecks();
@@ -730,9 +759,6 @@ void SaveTrackerData(SaveContext* saveContext, int sectionID, bool gameSave) {
void SaveFile(SaveContext* saveContext, int sectionID, bool fullSave) {
SaveTrackerData(saveContext, sectionID, fullSave);
- if (fullSave) {
- savedFrames = 40;
- }
}
void LoadFile() {
@@ -748,14 +774,9 @@ void LoadFile() {
void Teardown() {
initialized = false;
- for (auto& [rcArea, vec] : checksByArea) {
- vec.clear();
- areaChecksGotten[rcArea] = 0;
- }
+ ClearAreaChecksAndTotals();
checksByArea.clear();
areasSpoiled = 0;
- checkCollected = false;
- checkLoops = 0;
lastLocationChecked = RC_UNKNOWN_CHECK;
}
@@ -925,7 +946,11 @@ void CheckTrackerWindow::DrawElement() {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f,
extraColor.b / 255.0f, extraColor.a / 255.0f));
- isThisAreaSpoiled = areasSpoiled & areaMask || CVarGetInteger("gCheckTrackerOptionMQSpoilers", 0);
+ isThisAreaSpoiled = areasSpoiled & areaMask || CVarGetInteger("gCheckTrackerOptionMQSpoilers", 0) || !IS_RANDO ||
+ OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_RANDOM_MQ_DUNGEONS) == RO_MQ_DUNGEONS_NONE ||
+ OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_RANDOM_MQ_DUNGEONS) == RO_MQ_DUNGEONS_SELECTION ||
+ (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_RANDOM_MQ_DUNGEONS) == RO_MQ_DUNGEONS_SET_NUMBER &&
+ OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_MQ_DUNGEON_COUNT) == 12);
if (isThisAreaSpoiled) {
if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) {
@@ -1151,8 +1176,8 @@ bool IsVisibleInCheckTracker(RandomizerCheckObject rcObj) {
}
else if (rcObj.vanillaCompletion) {
return (rcObj.vOrMQ == RCVORMQ_BOTH ||
- rcObj.vOrMQ == RCVORMQ_MQ && OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) ||
- rcObj.vOrMQ == RCVORMQ_VANILLA && !OTRGlobals::Instance->gRandomizer->masterQuestDungeons.contains(rcObj.sceneId) ||
+ (rcObj.vOrMQ == RCVORMQ_MQ && IS_MASTER_QUEST) ||
+ (rcObj.vOrMQ == RCVORMQ_VANILLA && !IS_MASTER_QUEST) ||
rcObj.rc == RC_GIFT_FROM_SAGES) && rcObj.rc != RC_LINKS_POCKET;
}
return false;
@@ -1541,10 +1566,11 @@ void CheckTrackerWindow::InitElement() {
Teardown();
});
GameInteractor::Instance->RegisterGameHook(CheckTrackerItemReceive);
- GameInteractor::Instance->RegisterGameHook(CheckTrackerSaleEnd);
GameInteractor::Instance->RegisterGameHook(CheckTrackerFrame);
GameInteractor::Instance->RegisterGameHook(CheckTrackerTransition);
GameInteractor::Instance->RegisterGameHook(CheckTrackerShopSlotChange);
+ GameInteractor::Instance->RegisterGameHook(CheckTrackerSceneFlagSet);
+ GameInteractor::Instance->RegisterGameHook(CheckTrackerFlagSet);
LocationTable_Init();
}
diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
index b2193f696e0..a8928cca3e4 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
@@ -48,10 +48,7 @@ void Teardown();
void UpdateAllOrdering();
bool IsVisibleInCheckTracker(RandomizerCheckObject rcObj);
void InitTrackerData(bool isDebug);
-void SetLastItemGetRC(RandomizerCheck rc);
RandomizerCheckArea GetCheckArea();
-void CheckTrackerDialogClosed();
-void ToggleShopRightChecks();
void UpdateCheck(uint32_t, RandomizerCheckTrackerData);
} // namespace CheckTracker
diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.c b/soh/soh/Enhancements/randomizer/randomizer_entrance.c
index f2f1a8a3f35..e6ec3fef3fa 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_entrance.c
+++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.c
@@ -76,7 +76,7 @@ static s16 newIceCavernEntrance = ICE_CAVERN_ENTRANCE;
static s8 hasCopiedEntranceTable = 0;
static s8 hasModifiedEntranceTable = 0;
-void Entrance_SetEntranceDiscovered(u16 entranceIndex);
+void Entrance_SetEntranceDiscovered(u16 entranceIndex, u8 isReversedEntrance);
u8 Entrance_EntranceIsNull(EntranceOverride* entranceOverride) {
return entranceOverride->index == 0 && entranceOverride->destination == 0 && entranceOverride->blueWarp == 0
@@ -276,13 +276,13 @@ s16 Entrance_OverrideNextIndex(s16 nextEntranceIndex) {
return nextEntranceIndex;
}
- Entrance_SetEntranceDiscovered(nextEntranceIndex);
+ Entrance_SetEntranceDiscovered(nextEntranceIndex, false);
EntranceTracker_SetLastEntranceOverride(nextEntranceIndex);
return Grotto_OverrideSpecialEntrance(Entrance_GetOverride(nextEntranceIndex));
}
s16 Entrance_OverrideDynamicExit(s16 dynamicExitIndex) {
- Entrance_SetEntranceDiscovered(dynamicExitList[dynamicExitIndex]);
+ Entrance_SetEntranceDiscovered(dynamicExitList[dynamicExitIndex], false);
EntranceTracker_SetLastEntranceOverride(dynamicExitList[dynamicExitIndex]);
return Grotto_OverrideSpecialEntrance(Entrance_GetOverride(dynamicExitList[dynamicExitIndex]));
}
@@ -784,7 +784,7 @@ u8 Entrance_GetIsEntranceDiscovered(u16 entranceIndex) {
return 0;
}
-void Entrance_SetEntranceDiscovered(u16 entranceIndex) {
+void Entrance_SetEntranceDiscovered(u16 entranceIndex, u8 isReversedEntrance) {
// Skip if already set to save time from setting the connected entrance or
// if this entrance is outside of the randomized entrance range (i.e. is a dynamic entrance)
if (entranceIndex > MAX_ENTRANCE_RANDO_USED_INDEX || Entrance_GetIsEntranceDiscovered(entranceIndex)) {
@@ -796,14 +796,20 @@ void Entrance_SetEntranceDiscovered(u16 entranceIndex) {
if (idx < SAVEFILE_ENTRANCES_DISCOVERED_IDX_COUNT) {
u32 entranceBit = 1 << (entranceIndex - (idx * bitsPerIndex));
gSaveContext.sohStats.entrancesDiscovered[idx] |= entranceBit;
- // Set connected
- for (size_t i = 0; i < ENTRANCE_OVERRIDES_MAX_COUNT; i++) {
- if (entranceIndex == gSaveContext.entranceOverrides[i].index) {
- Entrance_SetEntranceDiscovered(gSaveContext.entranceOverrides[i].overrideDestination);
- break;
+
+ // Set reverse entrance when not decoupled
+ if (!Randomizer_GetSettingValue(RSK_DECOUPLED_ENTRANCES) && !isReversedEntrance) {
+ for (size_t i = 0; i < ENTRANCE_OVERRIDES_MAX_COUNT; i++) {
+ if (entranceIndex == gSaveContext.entranceOverrides[i].index) {
+ Entrance_SetEntranceDiscovered(gSaveContext.entranceOverrides[i].overrideDestination, true);
+ break;
+ }
}
}
}
- // Save entrancesDiscovered
- Save_SaveSection(SECTION_ID_ENTRANCES);
+
+ // Save entrancesDiscovered when it is not the reversed entrance
+ if (!isReversedEntrance) {
+ Save_SaveSection(SECTION_ID_ENTRANCES);
+ }
}
diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance.h b/soh/soh/Enhancements/randomizer/randomizer_entrance.h
index c00f29701b5..c71b2493ab6 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_entrance.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_entrance.h
@@ -63,7 +63,7 @@ void Entrance_OverrideSpawnScene(int32_t sceneNum, int32_t spawn);
int32_t Entrance_OverrideSpawnSceneRoom(int32_t sceneNum, int32_t spawn, int32_t room);
void Entrance_EnableFW(void);
uint8_t Entrance_GetIsEntranceDiscovered(uint16_t entranceIndex);
-void Entrance_SetEntranceDiscovered(uint16_t entranceIndex);
+void Entrance_SetEntranceDiscovered(uint16_t entranceIndex, uint8_t isReversedEntrance);
#ifdef __cplusplus
}
#endif
diff --git a/soh/soh/Enhancements/randomizer/randomizer_grotto.c b/soh/soh/Enhancements/randomizer/randomizer_grotto.c
index 408dc01601e..78e429fb229 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_grotto.c
+++ b/soh/soh/Enhancements/randomizer/randomizer_grotto.c
@@ -140,7 +140,7 @@ s16 Grotto_OverrideSpecialEntrance(s16 nextEntranceIndex) {
// If Link hits a grotto exit, load the entrance index from the grotto exit list
// based on the current grotto ID
if (nextEntranceIndex == 0x7FFF) {
- Entrance_SetEntranceDiscovered(ENTRANCE_RANDO_GROTTO_EXIT_START + grottoId);
+ Entrance_SetEntranceDiscovered(ENTRANCE_RANDO_GROTTO_EXIT_START + grottoId, false);
EntranceTracker_SetLastEntranceOverride(ENTRANCE_RANDO_GROTTO_EXIT_START + grottoId);
nextEntranceIndex = grottoExitList[grottoId];
}
@@ -211,7 +211,7 @@ void Grotto_OverrideActorEntrance(Actor* thisx) {
if (grottoContent == grottoLoadTable[index].content && gPlayState->sceneNum == grottoLoadTable[index].scene) {
// Find the override for the matching index from the grotto Load List
- Entrance_SetEntranceDiscovered(ENTRANCE_RANDO_GROTTO_LOAD_START + index);
+ Entrance_SetEntranceDiscovered(ENTRANCE_RANDO_GROTTO_LOAD_START + index, false);
EntranceTracker_SetLastEntranceOverride(ENTRANCE_RANDO_GROTTO_LOAD_START + index);
index = grottoLoadList[index];
diff --git a/soh/soh/Enhancements/randomizer/randomizer_inf.h b/soh/soh/Enhancements/randomizer/randomizer_inf.h
index 33c206b4700..8d4ec98012f 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_inf.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_inf.h
@@ -159,6 +159,7 @@ typedef enum {
RAND_INF_CHILD_FISHING,
RAND_INF_ADULT_FISHING,
RAND_INF_10_BIG_POES,
+ RAND_INF_GRANT_GANONS_BOSSKEY,
// If you add anything to this list, you need to update the size of randomizerInf in z64save.h to be ceil(RAND_INF_MAX / 16)
diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
index f24ab818b9d..4f27a5d36bb 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp
@@ -506,7 +506,7 @@ void DrawItemCount(ItemTrackerItem item) {
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);
+ int32_t trackerTriforcePieceNumberDisplayMode = CVarGetInteger("gItemTrackerTriforcePieceTrack", TRIFORCE_PIECE_COLLECTED_REQUIRED);
currentString += std::to_string(gSaveContext.triforcePiecesCollected);
currentString += "/";
@@ -607,7 +607,7 @@ void DrawItem(ItemTrackerItem item) {
case RG_TRIFORCE_PIECE:
actualItemId = item.id;
hasItem = IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_TRIFORCE_HUNT);
- itemName = "Triforce Piece";
+ itemName = "Christmas Ornament";
break;
}
@@ -1148,9 +1148,9 @@ void ItemTrackerSettingsWindow::DrawElement() {
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::Text("Christmas ornament Count Tracking");
+ UIWidgets::EnhancementCombobox("gItemTrackerTriforcePieceTrack", itemTrackerTriforcePieceTrackOptions, TRIFORCE_PIECE_COLLECTED_REQUIRED);
+ UIWidgets::InsertHelpHoverText("Customize what numbers are shown for ornament tracking.");
ImGui::TableNextColumn();
@@ -1191,7 +1191,7 @@ void ItemTrackerSettingsWindow::DrawElement() {
shouldUpdateVectors = true;
}
- if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Triforce Pieces", "gItemTrackerTriforcePiecesDisplayType", displayTypes, SECTION_DISPLAY_HIDDEN)) {
+ if (UIWidgets::LabeledRightAlignedEnhancementCombobox("Christmas Ornaments", "gItemTrackerTriforcePiecesDisplayType", displayTypes, SECTION_DISPLAY_HIDDEN)) {
shouldUpdateVectors = true;
}
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index ad57d1ca5d2..bb58b2c618b 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -49,6 +49,9 @@
#include "Fonts.h"
#include
#include "Enhancements/custom-message/CustomMessageManager.h"
+#include "Enhancements/presets.h"
+#include "util.h"
+#include
#if not defined (__SWITCH__) && not defined(__WIIU__)
#include "Extractor/Extract.h"
@@ -253,15 +256,26 @@ OTRGlobals::OTRGlobals() {
OTRFiles.push_back(sohOtrPath);
}
std::string patchesPath = LUS::Context::LocateFileAcrossAppDirs("mods", appShortName);
+ std::vector patchOTRs = {};
if (patchesPath.length() > 0 && std::filesystem::exists(patchesPath)) {
if (std::filesystem::is_directory(patchesPath)) {
- for (const auto& p : std::filesystem::recursive_directory_iterator(patchesPath)) {
+ for (const auto& p : std::filesystem::recursive_directory_iterator(patchesPath, std::filesystem::directory_options::follow_directory_symlink)) {
if (StringHelper::IEquals(p.path().extension().string(), ".otr")) {
- OTRFiles.push_back(p.path().generic_string());
+ patchOTRs.push_back(p.path().generic_string());
}
}
}
}
+ std::sort(patchOTRs.begin(), patchOTRs.end(), [](const std::string& a, const std::string& b) {
+ return std::lexicographical_compare(
+ a.begin(), a.end(),
+ b.begin(), b.end(),
+ [](char c1, char c2) {
+ return std::tolower(c1) < std::tolower(c2);
+ }
+ );
+ });
+ OTRFiles.insert(OTRFiles.end(), patchOTRs.begin(), patchOTRs.end());
std::unordered_set ValidHashes = {
OOT_PAL_MQ,
OOT_NTSC_JP_MQ,
@@ -1046,11 +1060,19 @@ extern "C" void InitOTR() {
time_t now = time(NULL);
tm *tm_now = localtime(&now);
- if (tm_now->tm_mon == 11 && tm_now->tm_mday >= 24 && tm_now->tm_mday <= 25) {
- CVarRegisterInteger("gLetItSnow", 1);
- } else {
- CVarClear("gLetItSnow");
- }
+
+ CVarRegisterInteger("gLetItSnow", 1);
+ CVarRegisterInteger("gAltAssets", 1);
+ CVarRegisterInteger("gCosmetics.Hud_AButton.Changed", 1);
+ CVarRegisterColor("gCosmetics.Hud_AButton.Value", Color_RGBA8{ 255, 255, 255, 255 });
+ CVarRegisterInteger("gCosmetics.Hud_BButton.Changed", 1);
+ CVarRegisterColor("gCosmetics.Hud_BButton.Value", Color_RGBA8{ 255, 255, 255, 255 });
+ CVarRegisterInteger("gCosmetics.Hud_CButtons.Changed", 1);
+ CVarRegisterColor("gCosmetics.Hud_CButtons.Value", Color_RGBA8{ 255, 255, 255, 255 });
+ CVarRegisterInteger("gCosmetics.Consumable_Hearts.Changed", 1);
+ CVarRegisterColor("gCosmetics.Consumable_Hearts.Value", Color_RGBA8{ 255, 158, 0, 255 });
+ CVarRegisterInteger("gCosmetics.Consumable_Magic.Changed", 1);
+ CVarRegisterColor("gCosmetics.Consumable_Magic.Value", Color_RGBA8{ 255, 0, 0, 255 });
srand(now);
#ifdef ENABLE_CROWD_CONTROL
@@ -1216,6 +1238,7 @@ extern "C" void Graph_StartFrame() {
case KbScancode::LUS_KB_TAB: {
// Toggle HD Assets
CVarSetInteger("gAltAssets", !CVarGetInteger("gAltAssets", 0));
+ GameInteractor::Instance->ExecuteHooks();
ShouldClearTextureCacheAtEndOfFrame = true;
break;
}
@@ -1415,6 +1438,14 @@ extern "C" void ResourceMgr_DirtyDirectory(const char* resName) {
LUS::Context::GetInstance()->GetResourceManager()->DirtyDirectory(resName);
}
+extern "C" void ResourceMgr_UnloadResource(const char* resName) {
+ std::string path = resName;
+ if (path.substr(0, 7) == "__OTR__") {
+ path = path.substr(7);
+ }
+ auto res = LUS::Context::GetInstance()->GetResourceManager()->UnloadResource(path);
+}
+
// OTRTODO: There is probably a more elegant way to go about this...
// Kenix: This is definitely leaking memory when it's called.
extern "C" char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize) {
@@ -1441,6 +1472,27 @@ extern "C" uint8_t ResourceMgr_FileExists(const char* filePath) {
return ExtensionCache.contains(path);
}
+extern "C" uint8_t ResourceMgr_FileAltExists(const char* filePath) {
+ std::string path = filePath;
+ if (path.substr(0, 7) == "__OTR__") {
+ path = path.substr(7);
+ }
+
+ if (path.substr(0, 4) != "alt/") {
+ path = "alt/" + path;
+ }
+
+ return ExtensionCache.contains(path);
+}
+
+// Unloads a resource if an alternate version exists when alt assets are enabled
+// The resource is only removed from the internal cache to prevent it from used in the next resource lookup
+extern "C" void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName) {
+ if (CVarGetInteger("gAltAssets", 0) && ResourceMgr_FileAltExists((char*) resName)) {
+ ResourceMgr_UnloadResource((char*) resName);
+ }
+}
+
extern "C" void ResourceMgr_LoadFile(const char* resName) {
LUS::Context::GetInstance()->GetResourceManager()->LoadResource(resName);
}
@@ -1480,6 +1532,11 @@ extern "C" char* ResourceMgr_LoadFileFromDisk(const char* filePath) {
return data;
}
+extern "C" uint8_t ResourceMgr_TexIsRaw(const char* texPath) {
+ auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(texPath));
+ return res->Flags & TEX_FLAG_LOAD_AS_RAW;
+}
+
extern "C" uint8_t ResourceMgr_ResourceIsBackground(char* texPath) {
auto res = GetResourceByNameHandlingMQ(texPath);
return res->GetInitData()->Type == LUS::ResourceType::SOH_Background;
@@ -1565,6 +1622,11 @@ extern "C" void ResourceMgr_PushCurrentDirectory(char* path)
extern "C" Gfx* ResourceMgr_LoadGfxByName(const char* path)
{
+ // When an alt resource exists for the DL, we need to unload the original asset
+ // to clear the cache so the alt asset will be loaded instead
+ // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed
+ ResourceMgr_UnloadOriginalWhenAltExists(path);
+
auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path));
return (Gfx*)&res->Instructions[0];
}
@@ -2292,7 +2354,9 @@ extern "C" int CustomMessage_RetrieveIfExists(PlayState* play) {
s16 actorParams = 0;
if (IS_RANDO) {
Player* player = GET_PLAYER(play);
- if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) {
+ if (textId == 0x406B && play->sceneNum == SCENE_KAKARIKO_VILLAGE) {
+ messageEntry = Randomizer::GetChristmasTreeMessage();
+ } else if (textId == TEXT_RANDOMIZER_CUSTOM_ITEM) {
if (player->getItemEntry.getItemId == RG_ICE_TRAP) {
u16 iceTrapTextId = Random(0, NUM_ICE_TRAP_MESSAGES);
messageEntry = CustomMessageManager::Instance->RetrieveMessage(Randomizer::IceTrapRandoMessageTableID, iceTrapTextId);
@@ -2523,6 +2587,70 @@ extern "C" void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* repla
gfx_register_blended_texture(name, mask, replacement);
}
-extern "C" void CheckTracker_OnMessageClose() {
- CheckTracker::CheckTrackerDialogClosed();
+// #region SOH [TODO] Ideally this should move to being event based, it's currently run every frame on the file select screen
+extern "C" void SoH_ProcessDroppedFiles() {
+ const char* droppedFile = CVarGetString("gDroppedFile", "");
+ if (CVarGetInteger("gNewFileDropped", 0) && strcmp(droppedFile, "") != 0) {
+ try {
+ std::ifstream configStream(SohUtils::Sanitize(droppedFile));
+ if (!configStream) {
+ return;
+ }
+
+ nlohmann::json configJson;
+ configStream >> configJson;
+
+ if (!configJson.contains("CVars")) {
+ return;
+ }
+
+ clearCvars(enhancementsCvars);
+ clearCvars(cheatCvars);
+ clearCvars(randomizerCvars);
+
+ // Flatten everything under CVars into a single array
+ auto cvars = configJson["CVars"].flatten();
+
+ for (auto& [key, value] : cvars.items()) {
+ // Replace slashes with dots in key, and remove leading dot
+ std::string path = key;
+ std::replace(path.begin(), path.end(), '/', '.');
+ if (path[0] == '.') {
+ path.erase(0, 1);
+ }
+ if (value.is_string()) {
+ CVarSetString(path.c_str(), value.get().c_str());
+ } else if (value.is_number_integer()) {
+ CVarSetInteger(path.c_str(), value.get());
+ } else if (value.is_number_float()) {
+ CVarSetFloat(path.c_str(), value.get());
+ }
+ }
+
+ auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
+ gui->GetGuiWindow("Console")->Hide();
+ gui->GetGuiWindow("Actor Viewer")->Hide();
+ gui->GetGuiWindow("Collision Viewer")->Hide();
+ gui->GetGuiWindow("Save Editor")->Hide();
+ gui->GetGuiWindow("Display List Viewer")->Hide();
+ gui->GetGuiWindow("Stats")->Hide();
+ std::dynamic_pointer_cast(LUS::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Console"))->ClearBindings();
+
+ gui->SaveConsoleVariablesOnNextTick();
+
+ uint32_t finalHash = boost::hash_32{}(configJson.dump());
+ gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Configuration Loaded. Hash: %d", finalHash);
+ } catch (std::exception& e) {
+ SPDLOG_ERROR("Failed to load config file: {}", e.what());
+ auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
+ gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load config file");
+ return;
+ } catch (...) {
+ SPDLOG_ERROR("Failed to load config file");
+ auto gui = LUS::Context::GetInstance()->GetWindow()->GetGui();
+ gui->GetGameOverlay()->TextDrawNotification(30.0f, true, "Failed to load config file");
+ return;
+ }
+ }
}
+// #endregion
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index e00cfecd508..88c57ced336 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -86,11 +86,15 @@ uint32_t ResourceMgr_GetGameVersion(int index);
uint32_t ResourceMgr_GetGamePlatform(int index);
uint32_t ResourceMgr_GetGameRegion(int index);
void ResourceMgr_LoadDirectory(const char* resName);
+void ResourceMgr_UnloadResource(const char* resName);
char** ResourceMgr_ListFiles(const char* searchMask, int* resultSize);
uint8_t ResourceMgr_FileExists(const char* resName);
+uint8_t ResourceMgr_FileAltExists(const char* resName);
+void ResourceMgr_UnloadOriginalWhenAltExists(const char* resName);
char* GetResourceDataByNameHandlingMQ(const char* path);
void ResourceMgr_LoadFile(const char* resName);
char* ResourceMgr_LoadFileFromDisk(const char* filePath);
+uint8_t ResourceMgr_TexIsRaw(const char* texPath);
uint8_t ResourceMgr_ResourceIsBackground(char* texPath);
char* ResourceMgr_LoadJPEG(char* data, size_t dataSize);
uint16_t ResourceMgr_LoadTexWidthByName(char* texPath);
@@ -171,6 +175,7 @@ void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex);
void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement);
void SaveManager_ThreadPoolWait();
void CheckTracker_OnMessageClose();
+void SoH_ProcessDroppedFiles();
int32_t GetGIID(uint32_t itemID);
#endif
diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp
index 598ec343de9..6cb37092868 100644
--- a/soh/soh/SohMenuBar.cpp
+++ b/soh/soh/SohMenuBar.cpp
@@ -492,6 +492,8 @@ extern std::shared_ptr mGameplayStatsWindow;
void DrawEnhancementsMenu() {
if (ImGui::BeginMenu("Enhancements"))
{
+ ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
+
DrawPresetSelector(PRESET_TYPE_ENHANCEMENTS);
UIWidgets::PaddedSeparator();
@@ -605,7 +607,7 @@ void DrawEnhancementsMenu() {
UIWidgets::PaddedEnhancementCheckbox("Nuts explode bombs", "gNutsExplodeBombs", true, false);
UIWidgets::Tooltip("Makes nuts explode bombs, similar to how they interact with bombchus. This does not affect bombflowers.");
UIWidgets::PaddedEnhancementCheckbox("Equip Multiple Arrows at Once", "gSeparateArrows", true, false);
- UIWidgets::Tooltip("Allow the bow and magic arrows to be equipped at the same time on different slots");
+ UIWidgets::Tooltip("Allow the bow and magic arrows to be equipped at the same time on different slots. (Note this will disable the behaviour of the 'Equip Dupe' glitch)");
UIWidgets::PaddedEnhancementCheckbox("Bow as Child/Slingshot as Adult", "gBowSlingShotAmmoFix", true, false);
UIWidgets::Tooltip("Allows child to use bow with arrows.\nAllows adult to use slingshot with seeds.\n\nRequires glitches or 'Timeless Equipment' cheat to equip.");
UIWidgets::PaddedEnhancementCheckbox("Better Farore's Wind", "gBetterFW", true, false);
@@ -907,6 +909,7 @@ void DrawEnhancementsMenu() {
if (ImGui::BeginMenu("Mods")) {
if (UIWidgets::PaddedEnhancementCheckbox("Use Alternate Assets", "gAltAssets", false, false)) {
ShouldClearTextureCacheAtEndOfFrame = true;
+ GameInteractor::Instance->ExecuteHooks();
}
UIWidgets::Tooltip("Toggle between standard assets and alternate assets. Usually mods will indicate if this setting has to be used or not.");
UIWidgets::PaddedEnhancementCheckbox("Disable Bomb Billboarding", "gDisableBombBillboarding", true, false);
@@ -1065,6 +1068,9 @@ void DrawEnhancementsMenu() {
UIWidgets::Tooltip("Prevents immediately falling off climbable surfaces if climbing on the edges.");
UIWidgets::PaddedEnhancementCheckbox("Fix Link's eyes open while sleeping", "gFixEyesOpenWhileSleeping", true, false);
UIWidgets::Tooltip("Fixes Link's eyes being open in the opening cutscene when he is supposed to be sleeping.");
+ UIWidgets::PaddedEnhancementCheckbox("Fix Darunia dancing too fast", "gEnhancements.FixDaruniaDanceSpeed",
+ true, false, false, "", UIWidgets::CheckboxGraphics::Cross, true);
+ UIWidgets::Tooltip("Fixes Darunia's dancing speed so he dances to the beat of Saria's Song, like in vanilla.");
ImGui::EndMenu();
}
@@ -1200,6 +1206,8 @@ void DrawEnhancementsMenu() {
UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f);
+ ImGui::EndDisabled();
+
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f));
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f);
@@ -1241,6 +1249,8 @@ void DrawEnhancementsMenu() {
void DrawCheatsMenu() {
if (ImGui::BeginMenu("Cheats"))
{
+ ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
+
if (ImGui::BeginMenu("Infinite...")) {
UIWidgets::EnhancementCheckbox("Money", "gInfiniteMoney");
UIWidgets::PaddedEnhancementCheckbox("Health", "gInfiniteHealth", true, false);
@@ -1395,6 +1405,8 @@ void DrawCheatsMenu() {
}
UIWidgets::Tooltip("Clears the cutscene pointer to a value safe for wrong warps.");
+ ImGui::EndDisabled();
+
ImGui::EndMenu();
}
}
@@ -1408,6 +1420,8 @@ extern std::shared_ptr mDLViewerWindow;
void DrawDeveloperToolsMenu() {
if (ImGui::BeginMenu("Developer Tools")) {
+ ImGui::BeginDisabled(CVarGetInteger("gDisableChangingSettings", 0));
+
UIWidgets::EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");
UIWidgets::Tooltip("Enables Debug Mode, allowing you to select maps with L + R + Z, noclip with L + D-pad Right, and open the debug menu with L on the pause screen");
if (CVarGetInteger("gDebugEnabled", 0)) {
@@ -1480,6 +1494,8 @@ void DrawDeveloperToolsMenu() {
ImGui::PopStyleVar(3);
ImGui::PopStyleColor(1);
+ ImGui::EndDisabled();
+
ImGui::EndMenu();
}
}
@@ -1628,4 +1644,4 @@ void SohMenuBar::DrawElement() {
ImGui::EndMenuBar();
}
}
-} // namespace SohGui
\ No newline at end of file
+} // namespace SohGui
diff --git a/soh/soh/stubs.c b/soh/soh/stubs.c
index 9afd934680a..a162a7ac55a 100644
--- a/soh/soh/stubs.c
+++ b/soh/soh/stubs.c
@@ -260,7 +260,7 @@ void Audio_osWritebackDCache(void* mem, s32 size)
s32 osAiSetFrequency(u32 freq)
{
-
+ return 1;
}
s32 osEPiStartDma(OSPiHandle* handle, OSIoMesg* mb, s32 direction)
diff --git a/soh/soh/util.cpp b/soh/soh/util.cpp
index 62e1d2dce23..856432cbbd2 100644
--- a/soh/soh/util.cpp
+++ b/soh/soh/util.cpp
@@ -2,6 +2,7 @@
#include
#include
+#include
std::vector sceneNames = {
"Inside the Deku Tree",
@@ -318,3 +319,20 @@ void SohUtils::CopyStringToCharArray(char* destination, std::string source, size
strncpy(destination, source.c_str(), size - 1);
destination[size - 1] = '\0';
}
+
+std::string SohUtils::Sanitize(std::string stringValue) {
+ // Add backslashes.
+ for (auto i = stringValue.begin();;) {
+ auto const pos = std::find_if(i, stringValue.end(), [](char const c) { return '\\' == c || '\'' == c || '"' == c; });
+ if (pos == stringValue.end()) {
+ break;
+ }
+ i = std::next(stringValue.insert(pos, '\\'), 2);
+ }
+
+ // Removes others.
+ stringValue.erase(std::remove_if(stringValue.begin(), stringValue.end(), [](char const c) {
+ return '\n' == c || '\r' == c || '\0' == c || '\x1A' == c; }), stringValue.end());
+
+ return stringValue;
+}
diff --git a/soh/soh/util.h b/soh/soh/util.h
index bdbfcd777fb..db5af8636a3 100644
--- a/soh/soh/util.h
+++ b/soh/soh/util.h
@@ -12,4 +12,6 @@ namespace SohUtils {
// Copies a string and ensures the destination is null terminated if the source string is larger than size
// Only up to size-1 characters are copied from the source string
void CopyStringToCharArray(char* destination, std::string source, size_t size);
+
+ std::string Sanitize(std::string stringValue);
} // namespace SohUtils
diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp
index f90e8bb9370..6bbd1eca9bd 100644
--- a/soh/soh/z_message_OTR.cpp
+++ b/soh/soh/z_message_OTR.cpp
@@ -72,6 +72,9 @@ MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) {
_message_0xFFFC_nes = (char*)file->messages[i].msg.c_str();
}
+ // Assert that the first message starts at the first text ID
+ assert(table[0].textId == 0x0001);
+
return table;
}
@@ -104,6 +107,9 @@ extern "C" void OTRMessage_Init()
sStaffMessageEntryTablePtr[i].segment = file2->messages[i].msg.c_str();
sStaffMessageEntryTablePtr[i].msgSize = file2->messages[i].msg.size();
}
+
+ // Assert staff credits start at the first credits ID
+ assert(sStaffMessageEntryTablePtr[0].textId == 0x0500);
}
CustomMessageManager::Instance->AddCustomMessageTable(customMessageTableID);
diff --git a/soh/src/code/z_kankyo.c b/soh/src/code/z_kankyo.c
index 4474c2d8b02..0147c0af1fe 100644
--- a/soh/src/code/z_kankyo.c
+++ b/soh/src/code/z_kankyo.c
@@ -2289,17 +2289,17 @@ void Environment_FillScreen(GraphicsContext* gfxCtx, u8 red, u8 green, u8 blue,
}
Color_RGB8 sSandstormPrimColors[] = {
- { 210, 156, 85 },
- { 255, 200, 100 },
- { 225, 160, 50 },
- { 105, 90, 40 },
+ { 210, 210, 210 },
+ { 255, 255, 255 },
+ { 225, 225, 225 },
+ { 105, 105, 105 },
};
Color_RGB8 sSandstormEnvColors[] = {
- { 155, 106, 35 },
- { 200, 150, 50 },
- { 170, 110, 0 },
- { 50, 40, 0 },
+ { 155, 155, 155 },
+ { 200, 200, 200 },
+ { 170, 170, 170 },
+ { 50, 50, 50 },
};
u16 previousPatchedSandstormScreenSize = 0;
diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c
index da0f5f55fe2..7bb3803fcc6 100644
--- a/soh/src/code/z_message_PAL.c
+++ b/soh/src/code/z_message_PAL.c
@@ -3384,7 +3384,7 @@ void Message_Update(PlayState* play) {
}
sLastPlayedSong = 0xFF;
osSyncPrintf("OCARINA_MODE=%d chk_ocarina_no=%d\n", play->msgCtx.ocarinaMode, msgCtx->unk_E3F2);
- CheckTracker_OnMessageClose();
+ // TODO: OnMessageClose hook
break;
case MSGMODE_PAUSED:
break;
diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c
index bbaa8d90bd5..a69681f04e0 100644
--- a/soh/src/code/z_parameter.c
+++ b/soh/src/code/z_parameter.c
@@ -1526,13 +1526,13 @@ void Inventory_SwapAgeEquipment(void) {
} else {
// When becoming child, set swordless flag if player doesn't have kokiri sword
// Only in rando to keep swordless link bugs in vanilla
- if (IS_RANDO && (EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment) == 0) {
+ if (IS_RANDO && CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_KOKIRI) == 0) {
Flags_SetInfTable(INFTABLE_SWORDLESS);
}
// When using enhancements, set swordless flag if player doesn't have kokiri sword or hasn't equipped a sword yet.
// Then set the child equips button items to item none to ensure kokiri sword is not equipped
- if ((CVarGetInteger("gSwitchAge", 0) || CVarGetInteger("gSwitchTimeline", 0)) && ((EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment) == 0 || Flags_GetInfTable(INFTABLE_SWORDLESS))) {
+ if ((CVarGetInteger("gSwitchAge", 0) || CVarGetInteger("gSwitchTimeline", 0)) && (CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_KOKIRI) == 0 || Flags_GetInfTable(INFTABLE_SWORDLESS))) {
Flags_SetInfTable(INFTABLE_SWORDLESS);
gSaveContext.childEquips.buttonItems[0] = ITEM_NONE;
}
@@ -1568,7 +1568,7 @@ void Inventory_SwapAgeEquipment(void) {
gSaveContext.equips.equipment = gSaveContext.childEquips.equipment;
gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4));
// Equips kokiri sword in the inventory screen only if kokiri sword exists in inventory and a sword has been equipped already
- if (!((EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment) == 0) && !Flags_GetInfTable(INFTABLE_SWORDLESS)) {
+ if (!(CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_KOKIRI) == 0) && !Flags_GetInfTable(INFTABLE_SWORDLESS)) {
gSaveContext.equips.equipment |= EQUIP_VALUE_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4);
}
} else if (gSaveContext.childEquips.buttonItems[0] != ITEM_NONE) {
@@ -1598,7 +1598,7 @@ void Inventory_SwapAgeEquipment(void) {
(only kokiri tunic/boots equipped, no sword, no C-button items, no D-Pad items).
When becoming child, set swordless flag if player doesn't have kokiri sword
Only in rando to keep swordless link bugs in vanilla*/
- if (EQUIP_INV_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4) & gSaveContext.inventory.equipment == 0) {
+ if (CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_KOKIRI) == 0) {
Flags_SetInfTable(INFTABLE_SWORDLESS);
}
@@ -2601,14 +2601,6 @@ u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
gSaveContext.triforcePiecesCollected++;
GameInteractor_SetTriforceHuntPieceGiven(true);
- // Teleport to credits when goal is reached.
- if (gSaveContext.triforcePiecesCollected == Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED)) {
- gSaveContext.sohStats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME;
- gSaveContext.sohStats.gameComplete = 1;
- Play_PerformSave(play);
- GameInteractor_SetTriforceHuntCreditsWarpActive(true);
- }
-
return Return_Item_Entry(giEntry, RG_NONE);
}
diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c
index 59a5d0619c1..05071483621 100644
--- a/soh/src/code/z_play.c
+++ b/soh/src/code/z_play.c
@@ -36,6 +36,9 @@ PlayState* gPlayState;
s16 firstInit = 0;
s16 gEnPartnerId;
+s16 gEnSnowballId;
+s16 gEnChristmasTreeId;
+s16 gEnChristmasDecoId;
void OTRPlay_SpawnScene(PlayState* play, s32 sceneNum, s32 spawn);
@@ -766,6 +769,12 @@ void Play_Init(GameState* thisx) {
GET_PLAYER(play)->actor.world.pos.y + Player_GetHeight(GET_PLAYER(play)) + 5.0f,
GET_PLAYER(play)->actor.world.pos.z, 0, 0, 0, 1, true);
}
+
+ if (play->sceneNum == SCENE_KAKARIKO_VILLAGE) {
+ Actor_Spawn(&play->actorCtx, play, gEnChristmasTreeId, -734, 0, 420, 0, 0, 0, 0, true);
+ }
+
+ Actor_Spawn(&play->actorCtx, play, gEnChristmasDecoId, 0, 0, 0, 0, 0, 0, 0, true);
}
void Play_Update(PlayState* play) {
diff --git a/soh/src/code/z_player_lib.c b/soh/src/code/z_player_lib.c
index 820f2c67267..934b7d1065d 100644
--- a/soh/src/code/z_player_lib.c
+++ b/soh/src/code/z_player_lib.c
@@ -10,6 +10,7 @@
#include "soh/Enhancements/randomizer/draw.h"
#include
+#include
typedef struct {
/* 0x00 */ u8 flag;
@@ -966,10 +967,18 @@ void* sMouthTextures[] = {
};
#endif
+// Original colors
+//Color_RGB8 sTunicColors[] = {
+// { 30, 105, 27 },
+// { 100, 20, 0 },
+// { 0, 60, 100 },
+//};
+
+// Overwrite to red tunic as default for Holidays in Hyrule build
Color_RGB8 sTunicColors[] = {
- { 30, 105, 27 },
- { 100, 20, 0 },
- { 0, 60, 100 },
+ { 255, 0, 0 },
+ { 255, 0, 0 },
+ { 255, 0, 0 },
};
Color_RGB8 sGauntletColors[] = {
@@ -1672,6 +1681,52 @@ void Player_PostLimbDrawGameplay(PlayState* play, s32 limbIndex, Gfx** dList, Ve
Matrix_MultVec3f(&sZeroVec, D_80160000);
}
+ if (CVarGetInteger("gLetItSnow", 0) && !(this->stateFlags1 & PLAYER_STATE1_FIRST_PERSON) && !(this->stateFlags2 & PLAYER_STATE2_CRAWLING)) {
+ if (limbIndex == PLAYER_LIMB_HEAD) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Matrix_Push();
+ if (LINK_IS_ADULT) {
+ Matrix_RotateZYX(24000, -16000, -7000, MTXMODE_APPLY);
+ Matrix_Translate(32.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gLinkAdultHatTrimDL);
+ } else {
+ Matrix_RotateZYX(24000, -16000, -7000, MTXMODE_APPLY);
+ Matrix_Translate(32.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gLinkChildHatTrimDL);
+ }
+
+ Matrix_Pop();
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+
+ if (limbIndex == PLAYER_LIMB_HAT) {
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Matrix_Push();
+ if (LINK_IS_ADULT) {
+ Matrix_RotateZYX(0, 0, 17500, MTXMODE_APPLY);
+ Matrix_Translate(-195.0f, 1500.0f, -95.0f, MTXMODE_APPLY);
+ Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY);
+ } else {
+ Matrix_RotateZYX(0, 0, 27000, MTXMODE_APPLY);
+ Matrix_Translate(-950.0f, 2600.0f, -75.0f, MTXMODE_APPLY);
+ Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY);
+ }
+
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gLinkAdultPompomDL);
+ Matrix_Pop();
+
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
if (limbIndex == PLAYER_LIMB_L_HAND) {
MtxF sp14C;
Actor* hookedActor;
diff --git a/soh/src/code/z_room.c b/soh/src/code/z_room.c
index ccbc93d0ded..772978f0988 100644
--- a/soh/src/code/z_room.c
+++ b/soh/src/code/z_room.c
@@ -277,6 +277,11 @@ void func_8009638C(Gfx** displayList, void* source, void* tlut, u16 width, u16 h
bg->b.imagePal = 0;
bg->b.imageFlip = CVarGetInteger("gMirroredWorld", 0) ? G_BG_FLAG_FLIPS : 0;
+ // When an alt resource exists for the background, we need to unload the original asset
+ // to clear the cache so the alt asset will be loaded instead
+ // OTRTODO: If Alt loading over original cache is fixed, this line can most likely be removed
+ ResourceMgr_UnloadOriginalWhenAltExists((char*) source);
+
if (ResourceMgr_ResourceIsBackground((char*) source)) {
char* blob = (char*) ResourceGetDataByName((char *) source);
swapAndConvertJPEG(blob);
diff --git a/soh/src/code/z_vr_box.c b/soh/src/code/z_vr_box.c
index b77c3d86953..ff262218744 100644
--- a/soh/src/code/z_vr_box.c
+++ b/soh/src/code/z_vr_box.c
@@ -417,7 +417,12 @@ void func_800AEFC8(SkyboxContext* skyboxCtx, s16 skyboxId) {
s32 j;
s32 phi_s3 = 0;
- if (skyboxId == SKYBOX_BAZAAR || (skyboxId > SKYBOX_HOUSE_KAKARIKO && skyboxId <= SKYBOX_BOMBCHU_SHOP)) {
+ //! @bug All shops only provide 2 faces for their sky box. Mask shop is missing from the condition
+ // meaning that the Mask shop will calculate 4 faces
+ // This effect is not noticed as the faces are behind the camera, but will cause a crash in SoH.
+ // SOH General: We have added the Mask shop to this check so only the 2 expected faces are calculated.
+ if (skyboxId == SKYBOX_BAZAAR || skyboxId == SKYBOX_HAPPY_MASK_SHOP ||
+ (skyboxId >= SKYBOX_KOKIRI_SHOP && skyboxId <= SKYBOX_BOMBCHU_SHOP)) {
for (j = 0, i = 0; i < 2; i++, j += 2) {
phi_s3 = func_800ADBB0(skyboxCtx, skyboxCtx->roomVtx, phi_s3, D_8012AEBC[i].unk_0, D_8012AEBC[i].unk_4,
D_8012AEBC[i].unk_8, D_8012AEBC[i].unk_C, D_8012AEBC[i].unk_10, i, j);
diff --git a/soh/src/code/z_vr_box_draw.c b/soh/src/code/z_vr_box_draw.c
index 8eb97573e40..5b4867121bf 100644
--- a/soh/src/code/z_vr_box_draw.c
+++ b/soh/src/code/z_vr_box_draw.c
@@ -59,8 +59,14 @@ void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyb
gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[2]);
gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[3]);
- if (skyboxId != SKYBOX_BAZAAR) {
- if (skyboxId <= SKYBOX_HOUSE_KAKARIKO || skyboxId > SKYBOX_BOMBCHU_SHOP) {
+ //! @bug All shops only provide 2 faces for their sky box. Mask shop is missing from the condition
+ // meaning that the Mask shop will render the previously loaded sky box values, or uninitialized data.
+ // This effect is not noticed as the faces are behind the camera, but will cause a crash in SoH.
+ // SOH General: We have added the Mask shop to this check so only the 2 expected faces are rendered.
+ if (skyboxId != SKYBOX_BAZAAR && skyboxId != SKYBOX_HAPPY_MASK_SHOP) {
+ if (skyboxId < SKYBOX_KOKIRI_SHOP || skyboxId > SKYBOX_BOMBCHU_SHOP) {
+ // Skip remaining faces for most shop skyboxes
+
gDPPipeSync(POLY_OPA_DISP++);
gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->palettes[2]);
gSPDisplayList(POLY_OPA_DISP++, skyboxCtx->dListBuf[4]);
diff --git a/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c b/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c
index d7b45c9b617..545dbdac186 100644
--- a/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c
+++ b/soh/src/overlays/actors/ovl_Bg_Spot08_Iceblock/z_bg_spot08_iceblock.c
@@ -308,7 +308,7 @@ void BgSpot08Iceblock_Init(Actor* thisx, PlayState* play) {
break;
}
- if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
+ if (LINK_AGE_IN_YEARS == YEARS_CHILD && play->sceneNum == SCENE_ZORAS_FOUNTAIN) {
Actor_Kill(&this->dyna.actor);
return;
}
@@ -332,6 +332,11 @@ void BgSpot08Iceblock_Init(Actor* thisx, PlayState* play) {
this->surfaceNormal.y = 1.0f;
this->rotationAxis.x = 1.0f;
+ if (LINK_IS_ADULT && !Flags_GetEventChkInf(EVENTCHKINF_RAISED_LAKE_HYLIA_WATER) && play->sceneNum == SCENE_LAKE_HYLIA) {
+ BgSpot08Iceblock_SetupNoAction(this);
+ return;
+ }
+
switch (this->dyna.actor.params & 0xF) {
case 0:
case 1:
diff --git a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
index e90e36e8098..43381c7d69a 100644
--- a/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
+++ b/soh/src/overlays/actors/ovl_Boss_Dodongo/z_boss_dodongo.c
@@ -5,9 +5,22 @@
#include "scenes/dungeons/ddan_boss/ddan_boss_room_1.h"
#include "soh/frame_interpolation.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
+#include "soh_assets.h"
+#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+
+#include // malloc
+#include // memcpy
+
+// OTRTODO: Replace usage of this method when we can clear the cache
+// for a single texture without the need of a DL opcode in the render code
+void gfx_texture_cache_clear();
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
+#define LAVA_TEX_WIDTH 32
+#define LAVA_TEX_HEIGHT 64
+#define LAVA_TEX_SIZE 2048
+
void BossDodongo_Init(Actor* thisx, PlayState* play);
void BossDodongo_Destroy(Actor* thisx, PlayState* play);
void BossDodongo_Update(Actor* thisx, PlayState* play);
@@ -59,6 +72,13 @@ static u8 sMaskTex8x8[8 * 8] = { { 0 } };
static u8 sMaskTex8x32[8 * 32] = { { 0 } };
static u8 sMaskTexLava[32 * 64] = { { 0 } };
+static u32* sLavaFloorModifiedTexRaw = NULL;
+static u32* sLavaWavyTexRaw = NULL;
+static u16 sLavaFloorModifiedTex[LAVA_TEX_SIZE];
+static u16 sLavaWavyTex[LAVA_TEX_SIZE];
+
+static u8 hasRegisteredBlendedHook = 0;
+
static InitChainEntry sInitChain[] = {
ICHAIN_U8(targetMode, 5, ICHAIN_CONTINUE),
ICHAIN_S8(naviEnemyId, 0x0C, ICHAIN_CONTINUE),
@@ -66,6 +86,69 @@ static InitChainEntry sInitChain[] = {
ICHAIN_F32(targetArrowOffset, 8200.0f, ICHAIN_STOP),
};
+void BossDodongo_RegisterBlendedLavaTextureUpdate() {
+ // Not in scene so there is nothing to do
+ if (gPlayState == NULL || gPlayState->sceneNum != SCENE_DODONGOS_CAVERN_BOSS) {
+ return;
+ }
+
+ // Free old textures
+ if (sLavaFloorModifiedTexRaw != NULL) {
+ free(sLavaFloorModifiedTexRaw);
+ sLavaFloorModifiedTexRaw = NULL;
+ }
+ if (sLavaWavyTexRaw != NULL) {
+ free(sLavaWavyTexRaw);
+ sLavaWavyTexRaw = NULL;
+ }
+
+ // Unload original textures to bypass cache result for lookups
+ ResourceMgr_UnloadOriginalWhenAltExists(sLavaFloorLavaTex);
+ ResourceMgr_UnloadOriginalWhenAltExists(sLavaFloorRockTex);
+ ResourceMgr_UnloadOriginalWhenAltExists(gDodongosCavernBossLavaFloorTex);
+
+ // When the texture is HD (raw) we need to work with u32 values for RGBA32
+ // Otherwise the original asset is u16 for RGBA16
+ if (ResourceMgr_TexIsRaw(gDodongosCavernBossLavaFloorTex)) {
+ u32* lavaTex = ResourceGetDataByName(sLavaFloorLavaTex);
+ size_t lavaSize = ResourceGetSizeByName(sLavaFloorLavaTex);
+ size_t floorSize = ResourceGetSizeByName(gDodongosCavernBossLavaFloorTex);
+
+ sLavaFloorModifiedTexRaw = malloc(lavaSize);
+ sLavaWavyTexRaw = malloc(floorSize);
+
+ memcpy(sLavaFloorModifiedTexRaw, lavaTex, lavaSize);
+
+ // When KD is dead, just immediately copy the rock texture
+ if (Flags_GetClear(gPlayState, gPlayState->roomCtx.curRoom.num)) {
+ u32* rockTex = ResourceGetDataByName(sLavaFloorRockTex);
+ size_t rockSize = ResourceGetSizeByName(sLavaFloorRockTex);
+ memcpy(sLavaFloorModifiedTexRaw, rockTex, rockSize);
+ }
+
+ memcpy(sLavaWavyTexRaw, sLavaFloorModifiedTexRaw, floorSize);
+
+ // Register the blended effect for the raw texture
+ Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, sLavaWavyTexRaw);
+ } else {
+ // When KD is dead, just immediately copy the rock texture
+ if (Flags_GetClear(gPlayState, gPlayState->roomCtx.curRoom.num)) {
+ u16* rockTex = ResourceGetDataByName(sLavaFloorRockTex);
+ memcpy(sLavaFloorModifiedTex, rockTex, sizeof(sLavaFloorModifiedTex));
+ } else {
+ u16* lavaTex = ResourceGetDataByName(sLavaFloorLavaTex);
+ memcpy(sLavaFloorModifiedTex, lavaTex, sizeof(sLavaFloorModifiedTex));
+ }
+
+ // Register the blended effect for the non-raw texture
+ memcpy(sLavaWavyTex, sLavaFloorModifiedTex, sizeof(sLavaWavyTex));
+
+ Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, sLavaWavyTex);
+ }
+
+ gfx_texture_cache_clear();
+}
+
void func_808C12C4(u8* arg1, s16 arg2) {
if (arg2[arg1] != 0) {
sMaskTex8x16[arg2 / 2] = 1;
@@ -86,12 +169,51 @@ void func_808C12C4(u8* arg1, s16 arg2) {
}
}
-void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
- arg0 = GetResourceDataByNameHandlingMQ(arg0);
- floorTex = ResourceGetDataByName(floorTex);
+// Same as func_808C1554 but works with u32 values for RGBA32 raw textures
+void func_808C1554_Raw(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
+ u16 width = ResourceGetTexWidthByName(arg0);
+ s32 size = ResourceGetTexHeightByName(arg0) * width;
+
+ u32* temp_s3 = sLavaWavyTexRaw;
+ u32* temp_s1 = sLavaFloorModifiedTexRaw;
+ s32 i;
+ s32 i2;
+ u32* sp54 = malloc(size * sizeof(u32)); // Match the size for lava floor tex
+ s32 temp;
+ s32 temp2;
+
+ // Multiplier is used to try to scale the wavy effect to match the scale of the HD texture
+ // Applying sqrt(multiplier) to arg3 is to control how many pixels move left/right for the selected row
+ // Applying to arg2 and M_PI help to space out the wave effect
+ // It's not perfect but close enough
+ u16 multiplier = width / LAVA_TEX_WIDTH;
+
+ for (i = 0; i < size; i += width) {
+ temp = sinf((((i / width) + (s32)(((arg2 * multiplier) * 50.0f) / 100.0f)) & (width - 1)) * (M_PI / (16 * multiplier))) * (arg3 * sqrt(multiplier));
+ for (i2 = 0; i2 < width; i2++) {
+ sp54[i + ((temp + i2) & (width - 1))] = temp_s1[i + i2];
+ }
+ }
+ for (i = 0; i < width; i++) {
+ temp = sinf(((i + (s32)(((arg2 * multiplier) * 80.0f) / 100.0f)) & (width - 1)) * (M_PI / (16 * multiplier))) * (arg3 * sqrt(multiplier));
+ temp *= width;
+ for (i2 = 0; i2 < size; i2 += width) {
+ temp2 = (temp + i2) & (size - 1);
+ temp_s3[i + temp2] = sp54[i + i2];
+ }
+ }
+
+ free(sp54);
- u16* temp_s3 = SEGMENTED_TO_VIRTUAL(arg0);
- u16* temp_s1 = SEGMENTED_TO_VIRTUAL(floorTex);
+ // Need to clear the cache after updating sLavaWavyTexRaw
+ gfx_texture_cache_clear();
+}
+
+// Modified to support CPU modified texture with the resource system
+// Used for the original non-raw asset working with u16 values
+void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
+ u16* temp_s3 = sLavaWavyTex;
+ u16* temp_s1 = sLavaFloorModifiedTex;
s16 i;
s16 i2;
u16 sp54[2048];
@@ -112,6 +234,9 @@ void func_808C1554(void* arg0, void* floorTex, s32 arg2, f32 arg3) {
temp_s3[i + temp2] = sp54[i + i2];
}
}
+
+ // Need to clear the cache after updating sLavaWavyTex
+ gfx_texture_cache_clear();
}
void func_808C17C8(PlayState* play, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, s16 arg5) {
@@ -187,27 +312,21 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->items);
if (Flags_GetClear(play, play->roomCtx.curRoom.num)) { // KD is dead
- u16* LavaFloorTex = ResourceGetDataByName(gDodongosCavernBossLavaFloorTex);
- u16* LavaFloorRockTex = ResourceGetDataByName(sLavaFloorRockTex);
- temp_s1_3 = SEGMENTED_TO_VIRTUAL(LavaFloorTex);
- temp_s2 = SEGMENTED_TO_VIRTUAL(LavaFloorRockTex);
+ // SOH [General]
+ // Applying the "cooled off" lava rock CPU modified texture for re-visiting the scene
+ // is now handled by BossDodongo_RegisterBlendedLavaTextureUpdate below
+
Actor_Kill(&this->actor);
Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, -890.0f, -1523.76f,
-3304.0f, 0, 0, 0, WARP_DUNGEON_CHILD);
Actor_Spawn(&play->actorCtx, play, ACTOR_BG_BREAKWALL, -890.0f, -1523.76f, -3304.0f, 0, 0, 0, 0x6000, true);
Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, -690.0f, -1523.76f, -3304.0f, 0, 0, 0, 0, true);
-
- for (int i = 0; i < ARRAY_COUNT(sMaskTexLava); i++) {
- sMaskTexLava[i] = 1;
- }
- } else {
- for (int i = 0; i < ARRAY_COUNT(sMaskTexLava); i++) {
- sMaskTexLava[i] = 0;
- }
}
this->actor.flags &= ~ACTOR_FLAG_TARGETABLE;
+ // #region SOH [General]
+ // Init mask values for all blended textures
for (int i = 0; i < ARRAY_COUNT(sMaskTex8x16); i++) {
sMaskTex8x16[i] = 0;
}
@@ -223,6 +342,12 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
for (int i = 0; i < ARRAY_COUNT(sMaskTex32x16); i++) {
sMaskTex32x16[i] = 0;
}
+ // Set all true for the lava as it will always replace the scene texture
+ for (int i = 0; i < ARRAY_COUNT(sMaskTexLava); i++) {
+ sMaskTexLava[i] = 1;
+ }
+
+ // Register all blended textures
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_015890, sMaskTex8x16, NULL);
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_017210, sMaskTex8x32, NULL);
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_015D90, sMaskTex16x16, NULL);
@@ -234,10 +359,14 @@ void BossDodongo_Init(Actor* thisx, PlayState* play) {
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016990, sMaskTex32x16, NULL);
Gfx_RegisterBlendedTexture(object_kingdodongo_Tex_016E10, sMaskTex32x16, NULL);
- // OTRTODO: This is causing OOB memory reads with HD assets
- // commenting this out means the lava will stay lava even after beating king d
- //
- // Gfx_RegisterBlendedTexture(gDodongosCavernBossLavaFloorTex, sMaskTexLava, sLavaFloorRockTex);
+ BossDodongo_RegisterBlendedLavaTextureUpdate();
+
+ // Register alt listener to update the blended lava for the replacement texture based on alt path
+ if (!hasRegisteredBlendedHook) {
+ GameInteractor_RegisterOnAssetAltChange(BossDodongo_RegisterBlendedLavaTextureUpdate);
+ hasRegisteredBlendedHook = 1;
+ }
+ // #endregion
}
void BossDodongo_Destroy(Actor* thisx, PlayState* play) {
@@ -1014,21 +1143,64 @@ void BossDodongo_Update(Actor* thisx, PlayState* play2) {
}
}
- // TODO The lave floor bubbles with an effect that modifies the texture. This needs to be recreated shader-side.
- //func_808C1554(gDodongosCavernBossLavaFloorTex, sLavaFloorLavaTex, this->unk_19E, this->unk_224);
+ // The lava bubbles with a wavy effect as a CPU modified texture
+ // This has been done by maintaining copied/modified texture values in the actor code
+ // The "cooling off" effect for the lava is pre-applied to the lava texture before applying
+ // the wavy effect. Since this is two effects and closely related to the actor, I've opted
+ // to handle them here rather than as a shader effect.
+ //
+ // Apply the corresponding wavy effect based on the texture being raw or not
+ if (ResourceMgr_TexIsRaw(gDodongosCavernBossLavaFloorTex)) {
+ func_808C1554_Raw(gDodongosCavernBossLavaFloorTex, sLavaFloorLavaTex, this->unk_19E, this->unk_224);
+ } else {
+ func_808C1554(gDodongosCavernBossLavaFloorTex, sLavaFloorLavaTex, this->unk_19E, this->unk_224);
+ }
}
+ // Apply the "cooling off" effect for the lava
if (this->unk_1C6 != 0) {
- u16* ptr1 = ResourceGetDataByName(sLavaFloorLavaTex);
- u16* ptr2 = ResourceGetDataByName(sLavaFloorRockTex);
- s16 i2;
+ // Similar to above, the cooling off effect is a CPU modified texture effect
+ // Apply corresponding to the texture being raw or not
+ if (ResourceMgr_TexIsRaw(sLavaFloorRockTex)) {
+ u32* ptr1 = sLavaFloorModifiedTexRaw;
+ u32* ptr2 = ResourceGetDataByName(sLavaFloorRockTex);
+ u16 width = ResourceGetTexWidthByName(sLavaFloorRockTex);
+ u16 height = ResourceGetTexHeightByName(sLavaFloorRockTex);
+ s16 i2;
+
+ // Get the scale based on the original texture size
+ u16 widthScale = width / LAVA_TEX_WIDTH;
+ u16 heightScale = height / LAVA_TEX_HEIGHT;
+ u32 size = width * height;
+
+ for (i2 = 0; i2 < 20; i2++) {
+ s16 new_var = this->unk_1C2 & (LAVA_TEX_SIZE - 1);
+ // Compute the index to a scaled position (scaling pseudo x,y as a 1D value)
+ s32 indexStart = ((new_var % LAVA_TEX_WIDTH) * widthScale) + ((new_var / LAVA_TEX_WIDTH) * width * heightScale);
+
+ // From the starting index, apply extra pixels right/down based on the scale
+ for (size_t j = 0; j < heightScale; j++) {
+ for (size_t i3 = 0; i3 < widthScale; i3++) {
+ s32 scaledIndex = (indexStart + i3 + (j * width)) & (size - 1);
+ ptr1[scaledIndex] = ptr2[scaledIndex];
+ }
+ }
+
+ this->unk_1C2 += 37;
+ }
+ } else {
+ u16* ptr1 = sLavaFloorModifiedTex;
+ u16* ptr2 = ResourceGetDataByName(sLavaFloorRockTex);
+ s16 i2;
- for (i2 = 0; i2 < 20; i2++) {
- s16 new_var = this->unk_1C2 & 0x7FF;
+ for (i2 = 0; i2 < 20; i2++) {
+ s16 new_var = this->unk_1C2 & 0x7FF;
- sMaskTexLava[new_var] = 1;
- this->unk_1C2 += 37;
+ ptr1[new_var] = ptr2[new_var];
+ this->unk_1C2 += 37;
+ }
}
+
Math_SmoothStepToF(&this->unk_224, 0.0f, 1.0f, 0.01f, 0.0f);
}
@@ -1134,6 +1306,21 @@ void BossDodongo_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s
Matrix_MultVec3f(&D_808CA48C, &this->unk_404);
}
Collider_UpdateSpheres(limbIndex, &this->collider);
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 7) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-6643, 1771, -14834, MTXMODE_APPLY);
+ Matrix_Translate(2000.0f, 5000.0f, 4000.0f, MTXMODE_APPLY);
+ Matrix_Scale(6.114f, 6.114f, 6.114f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void BossDodongo_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c
index 6b8d2df5c8c..e25eb1a9c6b 100644
--- a/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c
+++ b/soh/src/overlays/actors/ovl_Boss_Ganon/z_boss_ganon.c
@@ -9,6 +9,7 @@
#include "assets/objects/object_ganon_anime1/object_ganon_anime1.h"
#include "assets/objects/object_ganon_anime2/object_ganon_anime2.h"
#include "assets/scenes/dungeons/ganon_boss/ganon_boss_scene.h"
+#include "soh_assets.h"
#include "soh/frame_interpolation.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
@@ -3388,6 +3389,21 @@ void BossGanon_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
Matrix_MultVec3f(&sp1C, &this->unk_214);
}
+
+ if (limbIndex == 14) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(7749, 0, -11956, MTXMODE_APPLY);
+ Matrix_Translate(675.676f, -229.730f, 148.649f, MTXMODE_APPLY);
+ Matrix_Scale(1.014f, 1.014f, 1.014f, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ Color_RGBA8 color = { 255, 0, 0, 255 };
+ gDPSetEnvColor(POLY_OPA_DISP++, color.r, color.g, color.b, color.a);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
}
void BossGanon_InitRand(s32 seedInit0, s32 seedInit1, s32 seedInit2) {
diff --git a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c
index cb00dbee83d..80d771976ad 100644
--- a/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c
+++ b/soh/src/overlays/actors/ovl_Boss_Ganon2/z_boss_ganon2.c
@@ -8,6 +8,7 @@
#include "objects/object_geff/object_geff.h"
#include "soh/frame_interpolation.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
+#include "soh_assets.h"
#include
@@ -2658,6 +2659,18 @@ void BossGanon2_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
}
}
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 16) {
+ Matrix_Push();
+ Matrix_RotateZYX(5977, 4649, 18154, MTXMODE_APPLY);
+ Matrix_Translate(364.865f, 67.568f, 378.378f, MTXMODE_APPLY);
+ Matrix_Scale(4.595f, 4.595f, 4.595f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ }
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
}
@@ -2782,6 +2795,21 @@ void BossGanon2_PostLimbDraw2(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s
} else if (limbIndex == 10) {
Matrix_MultVec3f(&D_80907164, &this->unk_1B8);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 11) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -15056, MTXMODE_APPLY);
+ Matrix_Translate(824.324f, 472.973f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.845f, 0.845f, 0.845f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 100, 100, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void func_80905674(BossGanon2* this, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c
index 111380f0b11..2761043a736 100644
--- a/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c
+++ b/soh/src/overlays/actors/ovl_Boss_Ganondrof/z_boss_ganondrof.c
@@ -12,6 +12,7 @@
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h"
#include "soh/Enhancements/boss-rush/BossRush.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
@@ -1451,6 +1452,20 @@ void BossGanondrof_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec
if (((this->flyMode != GND_FLY_PAINTING) || (this->actionFunc == BossGanondrof_Intro)) && (limbIndex <= 25)) {
Matrix_MultVec3f(&zeroVec, &this->bodyPartsPos[limbIndex - 1]);
}
+ if (CVarGetInteger("gLetItSnow", 0) && this->deathState == NOT_DEAD) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(11955, 0, -15499, MTXMODE_APPLY);
+ Matrix_Translate(459.460f, 256.757f, -567.568f, MTXMODE_APPLY);
+ Matrix_Scale(0.877f, 0.877f, 0.877f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 100, 100, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
Gfx* BossGanondrof_GetClearPixelDList(GraphicsContext* gfxCtx) {
diff --git a/soh/src/overlays/actors/ovl_En_Am/z_en_am.c b/soh/src/overlays/actors/ovl_En_Am/z_en_am.c
index c5ca6686ae3..d528f5403d3 100644
--- a/soh/src/overlays/actors/ovl_En_Am/z_en_am.c
+++ b/soh/src/overlays/actors/ovl_En_Am/z_en_am.c
@@ -8,6 +8,7 @@
#include "objects/object_am/object_am.h"
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_CAN_PRESS_SWITCH)
@@ -944,6 +945,21 @@ void EnAm_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if ((limbIndex == 1) && (this->unk_264 != 0)) {
EnAm_TransformSwordHitbox(&this->dyna.actor, play);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 4) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -2657, MTXMODE_APPLY);
+ Matrix_Translate(4000.0f, 1148.649f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.655f, 1.655f, 1.655f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
static Vec3f sIcePosOffsets[] = {
diff --git a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c
index 15ebd759c25..099ef503d47 100644
--- a/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c
+++ b/soh/src/overlays/actors/ovl_En_Ani/z_en_ani.c
@@ -6,6 +6,7 @@
#include "z_en_ani.h"
#include "objects/object_ani/object_ani.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -321,6 +322,21 @@ void EnAni_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if (limbIndex == 15) {
Matrix_MultVec3f(&sMultVec, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(1992, 0, 2656, MTXMODE_APPLY);
+ Matrix_Translate(972.973f, 40.541f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.965f, 0.965f, 0.965f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnAni_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c b/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c
index 39c0e54e952..8024c09e3fe 100644
--- a/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c
+++ b/soh/src/overlays/actors/ovl_En_Bb/z_en_bb.c
@@ -8,6 +8,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_Bb/object_Bb.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_PLAY_HIT_SFX)
@@ -1269,6 +1270,20 @@ void EnBb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
EnBb* this = (EnBb*)thisx;
BodyBreak_SetInfo(&this->bodyBreak, limbIndex, 4, 15, 15, dList, BODYBREAK_OBJECT_DEFAULT);
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-13063, 0, -27454, MTXMODE_APPLY);
+ Matrix_Translate(418.919f, -81.081f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.757f, 1.757f, 1.757f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
static Vec3f sFireIceOffsets[] = {
diff --git a/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c b/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c
index 02ff9140d3e..68bfd8e3a07 100644
--- a/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c
+++ b/soh/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c
@@ -1,6 +1,7 @@
#include "z_en_bom_chu.h"
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "objects/gameplay_keep/gameplay_keep.h"
+#include "soh_assets.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@@ -529,5 +530,15 @@ void EnBomChu_Draw(Actor* thisx, PlayState* play) {
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, gBombchuDL);
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ Matrix_Push();
+ Matrix_RotateZYX(0, -3100, 17047, MTXMODE_APPLY);
+ Matrix_Translate(445.946f, -27.027f, 608.108f, MTXMODE_APPLY);
+ Matrix_Scale(0.541f, 0.541f, 0.541f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_ChristmasDeco/z_en_christmasdeco.c b/soh/src/overlays/actors/ovl_En_ChristmasDeco/z_en_christmasdeco.c
new file mode 100644
index 00000000000..2a4e02be99e
--- /dev/null
+++ b/soh/src/overlays/actors/ovl_En_ChristmasDeco/z_en_christmasdeco.c
@@ -0,0 +1,61 @@
+/*
+ * File: z_en_christmasdeco.c
+ * Overlay: ovl_En_ChristmasDeco
+ * Description: Custom Christmas Decorations
+ */
+
+#include "z_en_christmasdeco.h"
+#include "soh_assets.h"
+
+void EnChristmasDeco_Init(Actor* thisx, PlayState* play);
+void EnChristmasDeco_Destroy(Actor* thisx, PlayState* play);
+void EnChristmasDeco_Update(Actor* thisx, PlayState* play);
+void EnChristmasDeco_Draw(Actor* thisx, PlayState* play);
+
+void EnChristmasDeco_Init(Actor* thisx, PlayState* play) {
+ if (play->sceneNum == SCENE_TEMPLE_OF_TIME) {
+ EnChristmasDeco* this = (EnChristmasDeco*)thisx;
+ this->actor.room = -1;
+ }
+}
+
+void EnChristmasDeco_Destroy(Actor* thisx, PlayState* play) {
+
+}
+
+void EnChristmasDeco_Update(Actor* thisx, PlayState* play) {
+
+}
+
+void EnChristmasDeco_Draw(Actor* thisx, PlayState* play) {
+ float decoSize = 10.0f;
+
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL_25Opa(play->state.gfxCtx);
+
+ Matrix_Scale(decoSize, decoSize, decoSize, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
+
+ // Assertion Halt in Debug mode, switch to Release when testing.
+ if (play->sceneNum == SCENE_KAKARIKO_VILLAGE) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gKakarikoDecorDL);
+ if (LINK_IS_CHILD) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gKakarikoChildDecorDL);
+ } else {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gKakarikoAdultDecorDL);
+ }
+ }
+
+ if (play->sceneNum == SCENE_TEMPLE_OF_TIME) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gTempleOfTimeDecorDL);
+ if (LINK_IS_CHILD) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gTempleOfTimeDecorDL);
+ } else {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gTempleOfTimeDecorDL);
+ }
+ }
+
+ CLOSE_DISPS(play->state.gfxCtx);
+}
diff --git a/soh/src/overlays/actors/ovl_En_ChristmasDeco/z_en_christmasdeco.h b/soh/src/overlays/actors/ovl_En_ChristmasDeco/z_en_christmasdeco.h
new file mode 100644
index 00000000000..f2a317648c2
--- /dev/null
+++ b/soh/src/overlays/actors/ovl_En_ChristmasDeco/z_en_christmasdeco.h
@@ -0,0 +1,27 @@
+#ifndef Z_EN_CHRISTMASDECO_H
+#define Z_EN_CHRISTMASDECO_H
+
+#include
+#include "global.h"
+
+struct EnChristmasDeco;
+
+typedef void (*EnChristmasDecoActionFunc)(struct EnChristmasDeco*, PlayState*);
+
+typedef struct EnChristmasDeco {
+ Actor actor;
+ EnChristmasDecoActionFunc actionFunc;
+} EnChristmasDeco;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void EnChristmasDeco_Init(Actor* thisx, PlayState* play);
+void EnChristmasDeco_Destroy(Actor* thisx, PlayState* play);
+void EnChristmasDeco_Update(Actor* thisx, PlayState* play);
+void EnChristmasDeco_Draw(Actor* thisx, PlayState* play);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/soh/src/overlays/actors/ovl_En_ChristmasTree/z_en_christmastree.c b/soh/src/overlays/actors/ovl_En_ChristmasTree/z_en_christmastree.c
new file mode 100644
index 00000000000..32a2cf81f50
--- /dev/null
+++ b/soh/src/overlays/actors/ovl_En_ChristmasTree/z_en_christmastree.c
@@ -0,0 +1,212 @@
+/*
+ * File: z_en_christmastree.c
+ * Overlay: ovl_En_ChristmasTree
+ * Description: Custom Christmas Tree for Ornament Hunt
+ */
+
+#include "z_en_christmastree.h"
+#include "soh_assets.h"
+#include "soh/Enhancements/game-interactor/GameInteractor.h"
+
+void EnChristmasTree_Init(Actor* thisx, PlayState* play);
+void EnChristmasTree_Destroy(Actor* thisx, PlayState* play);
+void EnChristmasTree_Update(Actor* thisx, PlayState* play);
+void EnChristmasTree_Draw(Actor* thisx, PlayState* play);
+
+void EnChristmasTree_Wait(EnChristmasTree* this, PlayState* play);
+void EnChristmasTree_Talk(EnChristmasTree* this, PlayState* play);
+void EnChristmasTree_SetupEndTitle(EnChristmasTree* this, PlayState* play);
+void EnChristmasTree_HandleEndTitle(EnChristmasTree* this, PlayState* play);
+
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_NONE,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
+ { 100, 330, 0, { 0, 0, 0 } },
+};
+
+static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE };
+
+void EnChristmasTree_Init(Actor* thisx, PlayState* play) {
+ EnChristmasTree* this = (EnChristmasTree*)thisx;
+
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 160.0f);
+ Collider_InitCylinder(play, &this->collider);
+ Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
+ CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
+ Actor_UpdateBgCheckInfo(play, &this->actor, 0.0f, 0.0f, 0.0f, 4);
+
+ this->actor.targetMode = 1;
+ this->actor.textId = 0x406B; // Hijacking bean seller text ID so I'm sure it doesn't clash
+
+ this->actor.shape.rot.y = -14784;
+
+ this->actionFunc = EnChristmasTree_Wait;
+}
+
+void EnChristmasTree_Destroy(Actor* thisx, PlayState* play) {
+ EnChristmasTree* this = (EnChristmasTree*)thisx;
+
+ Collider_DestroyCylinder(play, &this->collider);
+}
+
+void EnChristmasTree_Wait(EnChristmasTree* this, PlayState* play) {
+ if (Actor_ProcessTalkRequest(&this->actor, play)) { // if talk is initiated
+ this->actionFunc = EnChristmasTree_Talk;
+ } else if ((this->actor.xzDistToPlayer < 170.0f) && Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT)) { // talk range
+ func_8002F2CC(&this->actor, play, 170.0f);
+ }
+}
+
+void EnChristmasTree_Talk(EnChristmasTree* this, PlayState* play) {
+ u8 dialogState = Message_GetState(&play->msgCtx);
+ if (dialogState != TEXT_STATE_CHOICE) {
+ if ((dialogState == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { // advanced final textbox
+ // Teleport to credits when goal is reached.
+ if (gSaveContext.triforcePiecesCollected >= Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED)) {
+ gSaveContext.sohStats.itemTimestamp[TIMESTAMP_TRIFORCE_COMPLETED] = GAMEPLAYSTAT_TOTAL_TIME;
+ gSaveContext.sohStats.gameComplete = 1;
+ Play_PerformSave(play);
+ GameInteractor_SetTriforceHuntCreditsWarpActive(true);
+ this->actionFunc = EnChristmasTree_SetupEndTitle;
+ } else {
+ this->actionFunc = EnChristmasTree_Wait;
+ }
+ }
+ }
+}
+
+void EnChristmasTree_SetupEndTitle(EnChristmasTree* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ Actor_Spawn(&play->actorCtx, play, ACTOR_END_TITLE, 0, 0, 0, 0, 0, 0, 2, false);
+
+ player->stateFlags1 = PLAYER_STATE1_INPUT_DISABLED;
+
+ Flags_SetRandomizerInf(RAND_INF_GRANT_GANONS_BOSSKEY);
+
+ Play_PerformSave(play);
+
+ this->actionFunc = EnChristmasTree_HandleEndTitle;
+}
+
+void EnChristmasTree_HandleEndTitle(EnChristmasTree* this, PlayState* play) {
+ Camera* camera = Play_GetCamera(play, play->mainCamera.thisIdx);
+ Player* player = GET_PLAYER(play);
+ Vec3f camAt;
+ Vec3f camEye;
+
+ // Not forcing camera mode makes the camera jitter for a bit after setting position.
+ // Also forces letterbox bars.
+ Camera_ChangeMode(camera, CAM_MODE_STILL);
+
+ // Christmas Tree's position
+ camAt.x = -734.0f;
+ camAt.y = 130.0f;
+ camAt.z = 420.0f;
+
+ // Camera's position
+ camEye.x = -1237.0f;
+ camEye.y = 218.0f;
+ camEye.z = 408.0f;
+
+ // Not setting fov manually makes camera zoom in after setting the above for a little bit.
+ camera->fov = 60.0f;
+
+ // Set camera
+ Play_CameraSetAtEye(play, play->mainCamera.thisIdx, &camAt, &camEye);
+
+ // Hide player so he's not visible in the final screen. Also move him so target arrow on tree dissapears.
+ player->actor.scale.x = player->actor.scale.y = player->actor.scale.z = 0.00001f;
+ player->actor.world.pos.z = 500.0f;
+
+ // Hide HUD
+ Interface_ChangeAlpha(1);
+}
+
+void EnChristmasTree_Update(Actor* thisx, PlayState* play) {
+ EnChristmasTree* this = (EnChristmasTree*)thisx;
+ ColliderCylinder* collider = &this->collider;
+
+ Collider_UpdateCylinder(thisx, collider);
+ CollisionCheck_SetOC(play, &play->colChkCtx, (Collider*)collider);
+
+ Actor_SetFocus(&this->actor, 80.0f);
+
+ uint8_t triforceHuntActive = Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT);
+ float percentageCompleted = (float)gSaveContext.triforcePiecesCollected /
+ (float)Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
+
+ if ((percentageCompleted >= 1.0f || !triforceHuntActive) && !this->spawnedRupee) {
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_WONDER_ITEM, this->actor.world.pos.x, this->actor.world.pos.y + 280,
+ this->actor.world.pos.z, 0, 0, LINK_IS_ADULT ? 1 : 4, 0x1ABF, false);
+ this->spawnedRupee = 1;
+ }
+
+ this->actionFunc(this, play);
+}
+
+void EnChristmasTree_Draw(Actor* thisx, PlayState* play) {
+ EnChristmasTree* this = (EnChristmasTree*)thisx;
+
+ float treeSize = 55.0f;
+ uint8_t triforceHuntActive = Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT);
+ float percentageCompleted = (float)gSaveContext.triforcePiecesCollected /
+ (float)Randomizer_GetSettingValue(RSK_TRIFORCE_HUNT_PIECES_REQUIRED);
+
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL_25Opa(play->state.gfxCtx);
+
+ Matrix_Scale(treeSize, treeSize, treeSize, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
+
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasTreeDL);
+
+ if (percentageCompleted >= 0.1f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor10DL);
+ }
+ if (percentageCompleted >= 0.2f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor20DL);
+ }
+ if (percentageCompleted >= 0.3f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor30DL);
+ }
+ if (percentageCompleted >= 0.4f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor40DL);
+ }
+ if (percentageCompleted >= 0.5f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor50DL);
+ }
+ if (percentageCompleted >= 0.6f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor60DL);
+ }
+ if (percentageCompleted >= 0.7f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor70DL);
+ }
+ if (percentageCompleted >= 0.8f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor80DL);
+ }
+ if (percentageCompleted >= 0.9f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor90DL);
+ }
+ if (percentageCompleted >= 1.0f || !triforceHuntActive) {
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasDecor100DL);
+ gSPDisplayList(POLY_OPA_DISP++, (Gfx*)gXmasStarDL);
+ }
+
+ CLOSE_DISPS(play->state.gfxCtx);
+}
diff --git a/soh/src/overlays/actors/ovl_En_ChristmasTree/z_en_christmastree.h b/soh/src/overlays/actors/ovl_En_ChristmasTree/z_en_christmastree.h
new file mode 100644
index 00000000000..fd580ac7167
--- /dev/null
+++ b/soh/src/overlays/actors/ovl_En_ChristmasTree/z_en_christmastree.h
@@ -0,0 +1,29 @@
+#ifndef Z_EN_CHRISTMASTREE_H
+#define Z_EN_CHRISTMASTREE_H
+
+#include
+#include "global.h"
+
+struct EnChristmasTree;
+
+typedef void (*EnChristmasTreeActionFunc)(struct EnChristmasTree*, PlayState*);
+
+typedef struct EnChristmasTree {
+ Actor actor;
+ ColliderCylinder collider;
+ EnChristmasTreeActionFunc actionFunc;
+ u8 spawnedRupee;
+} EnChristmasTree;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void EnChristmasTree_Init(Actor* thisx, PlayState* play);
+void EnChristmasTree_Destroy(Actor* thisx, PlayState* play);
+void EnChristmasTree_Update(Actor* thisx, PlayState* play);
+void EnChristmasTree_Draw(Actor* thisx, PlayState* play);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c
index d1659d21c48..be4e96dcc35 100644
--- a/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c
+++ b/soh/src/overlays/actors/ovl_En_Cs/z_en_cs.c
@@ -1,6 +1,7 @@
#include "z_en_cs.h"
#include "objects/object_cs/object_cs.h"
#include "objects/object_link_child/object_link_child.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -521,4 +522,19 @@ void EnCs_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
Matrix_RotateZ(5.0 * M_PI / 9.0, MTXMODE_APPLY);
Matrix_Get(&this->spookyMaskMtx);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(8191, -5757, -24133, MTXMODE_APPLY);
+ Matrix_Translate(270.27f, 297.297f, -513.514f, MTXMODE_APPLY);
+ Matrix_Scale(1.135f, 1.135f, 1.135f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
diff --git a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c
index 6cc91e0c725..ea01c116a6e 100644
--- a/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c
+++ b/soh/src/overlays/actors/ovl_En_Daiku_Kakariko/z_en_daiku_kakariko.c
@@ -6,6 +6,7 @@
#include "z_en_daiku_kakariko.h"
#include "objects/object_daiku/object_daiku.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -539,6 +540,51 @@ void EnDaikuKakariko_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, V
gSPDisplayList(POLY_OPA_DISP++, carpenterHeadDLists[this->actor.params & 3]);
}
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ Matrix_Push();
+ switch(this->actor.params) {
+ case 259: {
+ Matrix_RotateZYX(4649, 0, -3543, MTXMODE_APPLY);
+ Matrix_Translate(824.324f, 324.324f, -175.676f, MTXMODE_APPLY);
+ Matrix_Scale(0.966f, 0.966f, 0.966f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ case 513: {
+ Matrix_RotateZYX(0, 0, -6200, MTXMODE_APPLY);
+ Matrix_Translate(770.27f, 567.568f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.899f, 0.899f, 0.899f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 255, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ case 2: {
+ Matrix_RotateZYX(0, 0, 7970, MTXMODE_APPLY);
+ Matrix_Translate(1270.27f, -878.378f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 255, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ case -256:
+ default: {
+ Matrix_RotateZYX(0, 0, -8635, MTXMODE_APPLY);
+ Matrix_Translate(675.676f, 716.216f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.899f, 0.899f, 0.899f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ }
+ }
+ Matrix_Pop();
+ }
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c b/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c
index 2b4344f68ce..524579aa9e9 100644
--- a/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c
+++ b/soh/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c
@@ -3,6 +3,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE)
@@ -1279,6 +1280,20 @@ void EnDekubaba_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
if (limbIndex == 1) {
Collider_UpdateSpheres(limbIndex, &this->collider);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 4) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(16485, -1425, -20964, MTXMODE_APPLY);
+ Matrix_Translate(-149.0f, 92.0f, -587.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.534f, 1.534f, 1.534f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnDekubaba_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c
index 0dd33a8ac99..a70587070f7 100644
--- a/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c
+++ b/soh/src/overlays/actors/ovl_En_Dns/z_en_dns.c
@@ -8,6 +8,7 @@
#include "objects/object_shopnuts/object_shopnuts.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -550,9 +551,27 @@ void EnDns_Update(Actor* thisx, PlayState* play) {
}
}
+void EnDns_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnDns* this = (EnDns*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 17) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, 17490, MTXMODE_APPLY);
+ Matrix_Translate(4200.0f, -472.973f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(4.932f, 4.932f, 4.932f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+}
+
void EnDns_Draw(Actor* thisx, PlayState* play) {
EnDns* this = (EnDns*)thisx;
Gfx_SetupDL_25Opa(play->state.gfxCtx);
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, NULL, &this->actor);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, EnDns_PostLimbDraw, &this->actor);
}
diff --git a/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c b/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c
index 359477614b7..a342e941207 100644
--- a/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c
+++ b/soh/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c
@@ -3,6 +3,7 @@
#include "overlays/actors/ovl_En_Bombf/z_en_bombf.h"
#include "objects/object_dodongo/object_dodongo.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -915,6 +916,21 @@ void EnDodongo_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
Matrix_MultVec3f(&baseOffset, &this->icePos[i]);
}
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 7) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -13063, MTXMODE_APPLY);
+ Matrix_Translate(864.865f, 756.757f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.662f, 0.662f, 0.662f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnDodongo_Draw(Actor* thisx, PlayState* play2) {
diff --git a/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c b/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c
index 38a1cf95b56..a849b43278c 100644
--- a/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c
+++ b/soh/src/overlays/actors/ovl_En_Dog/z_en_dog.c
@@ -6,6 +6,7 @@
#include "z_en_dog.h"
#include "objects/object_dog/object_dog.h"
+#include "soh_assets.h"
#define FLAGS 0
@@ -494,6 +495,19 @@ s32 EnDog_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p
}
void EnDog_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 4) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(20811, -32768, 3985, MTXMODE_APPLY);
+ Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.25f, 1.25f, 1.25f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnDog_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c
index 6da75b1e783..c699fa2866f 100644
--- a/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c
+++ b/soh/src/overlays/actors/ovl_En_Ds/z_en_ds.c
@@ -7,6 +7,7 @@
#include "z_en_ds.h"
#include "objects/object_ds/object_ds.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -322,6 +323,21 @@ void EnDs_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if (limbIndex == 5) {
Matrix_MultVec3f(&sMultVec, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 5) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-1329, -3100, 0, MTXMODE_APPLY);
+ Matrix_Translate(1270.27f, 351.351f, -310.811f, MTXMODE_APPLY);
+ Matrix_Scale(0.797f, 0.797f, 0.797f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnDs_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c
index acd64e308fc..40454811e17 100644
--- a/soh/src/overlays/actors/ovl_En_Du/z_en_du.c
+++ b/soh/src/overlays/actors/ovl_En_Du/z_en_du.c
@@ -1,6 +1,7 @@
#include "z_en_du.h"
#include "objects/object_du/object_du.h"
#include "scenes/overworld/spot18/spot18_scene.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_NO_FREEZE_OCARINA)
@@ -95,6 +96,26 @@ static AnimationInfo sAnimationInfo[] = {
{ &gDaruniaDancingEndAnim, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, -6.0f },
};
+// #region SOH [Enhancement] Only animations too fast need to be slowed down, otherwise not touched
+static AnimationInfo sAnimationInfoFix[] = {
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { &gDaruniaDancingLoop1Anim, 0.78f, 0.0f, -1.0f, ANIMMODE_ONCE, -10.0f }, //
+ { &gDaruniaDancingLoop1Anim, 0.77f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, // hop
+ { &gDaruniaDancingLoop2Anim, 0.78f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, // from hop to spin
+ { &gDaruniaDancingLoop3Anim, 0.77f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, // spin
+ { NULL },
+ { NULL },
+ { &gDaruniaDancingLoop4Anim, 0.78f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, // from spin to hop
+ { NULL },
+};
+// #endregion
+
void EnDu_SetupAction(EnDu* this, EnDuActionFunc actionFunc) {
this->actionFunc = actionFunc;
}
@@ -255,7 +276,13 @@ void func_809FE040(EnDu* this) {
if (this->unk_1E6 >= 8) {
this->unk_1E6 = 0;
}
- Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, animationIndices[this->unk_1E6]);
+ // #region SOH[Enhancement]
+ if (CVarGetInteger("gEnhancements.FixDaruniaDanceSpeed", 1)) {
+ Animation_ChangeByInfo(&this->skelAnime, sAnimationInfoFix, animationIndices[this->unk_1E6]);
+ // #endregion
+ } else {
+ Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, animationIndices[this->unk_1E6]);
+ }
}
}
@@ -271,7 +298,13 @@ void func_809FE104(EnDu* this) {
if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) {
this->unk_1E6++;
if (this->unk_1E6 < 4) {
- Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, animationIndices[this->unk_1E6]);
+ // #region SOH[Enhancement]
+ if (CVarGetInteger("gEnhancements.FixDaruniaDanceSpeed", 1) && this->unk_1E6 <= 1) {
+ Animation_ChangeByInfo(&this->skelAnime, sAnimationInfoFix, animationIndices[this->unk_1E6]);
+ // #endregion
+ } else {
+ Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, animationIndices[this->unk_1E6]);
+ }
}
}
}
@@ -465,7 +498,13 @@ void func_809FE890(EnDu* this, PlayState* play) {
}
if (csAction->action == 7 || csAction->action == 8) {
this->unk_1E6 = 0;
- Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENDU_ANIM_7);
+ // #region SOH[Enhancement]
+ if (CVarGetInteger("gEnhancements.FixDaruniaDanceSpeed", 1)) {
+ Animation_ChangeByInfo(&this->skelAnime, sAnimationInfoFix, ENDU_ANIM_7);
+ // #endregion
+ } else {
+ Animation_ChangeByInfo(&this->skelAnime, sAnimationInfo, ENDU_ANIM_7);
+ }
}
this->unk_1EA = csAction->action;
if (this->unk_1EA == 7) {
@@ -624,6 +663,20 @@ void EnDu_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if (limbIndex == 16) {
Matrix_MultVec3f(&D_809FF40C, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 17) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(13062, -1329, -15499, MTXMODE_APPLY);
+ Matrix_Translate(945.946f, -297.297f, 608.108f, MTXMODE_APPLY);
+ Matrix_Scale(1.217f, 1.217f, 1.217f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnDu_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c
index 2191daeab25..d809d283ee1 100644
--- a/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c
+++ b/soh/src/overlays/actors/ovl_En_Elf/z_en_elf.c
@@ -7,6 +7,7 @@
#include "z_en_elf.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA)
@@ -1504,6 +1505,26 @@ s32 EnElf_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p
return false;
}
+s32 EnElf_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnElf* this = (EnElf*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 2) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, 17047, MTXMODE_APPLY);
+ Matrix_Translate(202.0f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.595f, 0.595f, 0.595f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
+ return false;
+}
+
void EnElf_Draw(Actor* thisx, PlayState* play) {
s32 pad;
f32 alphaScale;
@@ -1541,7 +1562,7 @@ void EnElf_Draw(Actor* thisx, PlayState* play) {
gDPSetEnvColor(POLY_XLU_DISP++, (u8)this->outerColor.r, (u8)this->outerColor.g, (u8)this->outerColor.b,
(u8)(envAlpha * alphaScale));
POLY_XLU_DISP = SkelAnime_Draw(play, this->skelAnime.skeleton, this->skelAnime.jointTable,
- EnElf_OverrideLimbDraw, NULL, this, POLY_XLU_DISP);
+ EnElf_OverrideLimbDraw, EnElf_PostLimbDraw, this, POLY_XLU_DISP);
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c
index 278fb18e2b1..7cc516f487f 100644
--- a/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c
+++ b/soh/src/overlays/actors/ovl_En_Fu/z_en_fu.c
@@ -7,6 +7,7 @@
#include "z_en_fu.h"
#include "objects/object_fu/object_fu.h"
#include "scenes/indoors/hakasitarelay/hakasitarelay_scene.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA)
@@ -319,6 +320,20 @@ void EnFu_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if (limbIndex == FU_LIMB_HEAD) {
Matrix_MultVec3f(&sMtxSrc, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 14) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-27454, 0, 1992, MTXMODE_APPLY);
+ Matrix_Translate(878.378f, -108.108f, 67.568f, MTXMODE_APPLY);
+ Matrix_Scale(1.135f, 1.135f, 1.135f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnFu_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c
index bab56427de6..d2e8036398b 100644
--- a/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c
+++ b/soh/src/overlays/actors/ovl_En_Heishi4/z_en_heishi4.c
@@ -1,6 +1,7 @@
#include "z_en_heishi4.h"
#include "objects/object_sd/object_sd.h"
#include "vt.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -414,9 +415,29 @@ s32 EnHeishi_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f
return false;
}
+s32 EnHeishi4_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnHeishi4* this = (EnHeishi4*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 16) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, 442, MTXMODE_APPLY);
+ Matrix_Translate(256.757f, 121.621f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.337f, 1.337f, 1.337f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
+ return false;
+}
+
void EnHeishi4_Draw(Actor* thisx, PlayState* play) {
EnHeishi4* this = (EnHeishi4*)thisx;
Gfx_SetupDL_25Opa(play->state.gfxCtx);
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnHeishi_OverrideLimbDraw, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnHeishi_OverrideLimbDraw, EnHeishi4_PostLimbDraw, this);
}
diff --git a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c
index 3f8e61481a0..84eb63d5823 100644
--- a/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c
+++ b/soh/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c
@@ -7,6 +7,7 @@
#include "z_en_hs2.h"
#include "vt.h"
#include "objects/object_hs/object_hs.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -65,6 +66,14 @@ void EnHs2_Init(Actor* thisx, PlayState* play) {
this->actionFunc = func_80A6F1A4;
this->unk_2A8 = 0;
this->actor.targetMode = 6;
+
+ if (play->sceneNum == SCENE_KAKARIKO_VILLAGE) {
+ this->actor.world.pos.x = 756.0;
+ this->actor.world.pos.y = 80.0;
+ this->actor.world.pos.z = 1378.0;
+ this->actor.shape.rot.y = 32534;
+ }
+
}
void EnHs2_Destroy(Actor* thisx, PlayState* play) {
@@ -160,6 +169,21 @@ void EnHs2_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if (limbIndex == 9) {
Matrix_MultVec3f(&D_80A6F4CC, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 9) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -6421, MTXMODE_APPLY);
+ Matrix_Translate(621.622f, 378.378f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.763f, 0.763f, 0.763f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 255, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnHs2_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c
index e0ff7470d10..9473755445c 100644
--- a/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c
+++ b/soh/src/overlays/actors/ovl_En_Hy/z_en_hy.c
@@ -14,6 +14,7 @@
#include "objects/object_cne/object_cne.h"
#include "objects/object_cob/object_cob.h"
#include "objects/object_os_anime/object_os_anime.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -898,6 +899,21 @@ void EnHy_Init(Actor* thisx, PlayState* play) {
Actor_Kill(&this->actor);
}
+ if (play->sceneNum == SCENE_KAKARIKO_VILLAGE) {
+ if (this->actor.params == 1929) {
+ this->actor.world.pos.x = 261.826;
+ this->actor.world.pos.y = 240.0;
+ this->actor.world.pos.z = 1669.660;
+ this->actor.shape.rot.y = 23784;
+ }
+ if (this->actor.params == 1930) {
+ this->actor.world.pos.x = 262.224;
+ this->actor.world.pos.y = 240.0;
+ this->actor.world.pos.z = 1594.390;
+ this->actor.shape.rot.y = 7728;
+ }
+ }
+
this->getItemEntry = (GetItemEntry)GET_ITEM_NONE;
this->actionFunc = EnHy_InitImpl;
}
@@ -1189,6 +1205,101 @@ void EnHy_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
Matrix_MultVec3f(&sp3C, &this->actor.focus.pos);
}
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ Matrix_Push();
+ switch(this->actor.params) {
+ case 1938: {
+ Matrix_RotateZYX(5313, 0, -1550, MTXMODE_APPLY);
+ Matrix_Translate(1108.108f, 54.054f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ break;
+ }
+ case 135:
+ case 7: {
+ Matrix_RotateZYX(1328, 0, 885, MTXMODE_APPLY);
+ Matrix_Translate(864.865f, 229.73f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.25f, 1.25f, 1.25f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ break;
+ }
+ case 1922: {
+ Matrix_RotateZYX(4206, 221, -3543, MTXMODE_APPLY);
+ Matrix_Translate(662.162f, 162.162f, -27.027f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ break;
+ }
+ case 1925: {
+ Matrix_RotateZYX(-9521, 442, -5536, MTXMODE_APPLY);
+ Matrix_Translate(351.351f, 256.757f, 283.784f, MTXMODE_APPLY);
+ Matrix_Scale(1.217f, 1.217f, 1.217f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ break;
+ }
+ case 1920: {
+ Matrix_RotateZYX(0, 0, 3321, MTXMODE_APPLY);
+ Matrix_Translate(1148.649f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.73f, 0.73f, 0.73f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ case 1930: {
+ Matrix_RotateZYX(3542, 0, 0, MTXMODE_APPLY);
+ Matrix_Translate(972.973f, -13.514f, 54.054f, MTXMODE_APPLY);
+ Matrix_Scale(0.831f, 0.831f, 0.831f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ case 1929: {
+ Matrix_RotateZYX(3542, 0, 0, MTXMODE_APPLY);
+ Matrix_Translate(972.973f, -13.514f, 54.054f, MTXMODE_APPLY);
+ Matrix_Scale(0.831f, 0.831f, 0.831f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ case 1921: {
+ Matrix_RotateZYX(0, 0, 664, MTXMODE_APPLY);
+ Matrix_Translate(1256.757f, -297.297f, -40.541f, MTXMODE_APPLY);
+ Matrix_Scale(1.135f, 1.135f, 1.135f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 255, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ case 1939: {
+ Matrix_RotateZYX(2656, 1328, 1992, MTXMODE_APPLY);
+ Matrix_Translate(1094.594f, 94.594f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.351f, 1.351f, 1.351f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ break;
+ }
+ default: {
+ Matrix_RotateZYX(0, 0, 664, MTXMODE_APPLY);
+ Matrix_Translate(783.784f, 94.594f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.662f, 0.662f, 0.662f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ break;
+ }
+ }
+ Matrix_Pop();
+ }
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c
index aaf0e0342fc..d29b1decbb3 100644
--- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c
+++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c
@@ -9,6 +9,7 @@
#include "objects/object_ik/object_ik.h"
#include "vt.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
@@ -942,6 +943,19 @@ void EnIk_PostLimbDraw3(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
break;
}
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 11) {
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -15056, MTXMODE_APPLY);
+ Matrix_Translate(824.324f, 472.973f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.845f, 0.845f, 0.845f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 100, 100, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ }
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
}
@@ -1223,6 +1237,20 @@ void EnIk_PostLimbDraw2(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
}
} break;
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 11) {
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -15056, MTXMODE_APPLY);
+ Matrix_Translate(824.324f, 472.973f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.845f, 0.845f, 0.845f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 100, 100, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ }
+ }
+
CLOSE_DISPS(gfxCtx);
}
@@ -1373,6 +1401,19 @@ void EnIk_PostLimbDraw1(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
break;
}
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 11) {
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -15056, MTXMODE_APPLY);
+ Matrix_Translate(824.324f, 472.973f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.845f, 0.845f, 0.845f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 100, 100, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ }
+ }
+
CLOSE_DISPS(gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_In/z_en_in.c b/soh/src/overlays/actors/ovl_En_In/z_en_in.c
index 13014352ae9..2897f417b54 100644
--- a/soh/src/overlays/actors/ovl_En_In/z_en_in.c
+++ b/soh/src/overlays/actors/ovl_En_In/z_en_in.c
@@ -1,6 +1,7 @@
#include "z_en_in.h"
#include "overlays/actors/ovl_En_Horse/z_en_horse.h"
#include "objects/object_in/object_in.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -987,6 +988,18 @@ void EnIn_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
gSPDisplayList(POLY_OPA_DISP++, gIngoChildEraPitchForkDL);
}
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 16) {
+ Matrix_Push();
+ Matrix_RotateZYX(-8192, -222, -11513, MTXMODE_APPLY);
+ Matrix_Translate(770.0f, 837.0f, 878.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.068f, 1.068f, 1.068f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ }
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c
index f1dff358a61..393e10a918b 100644
--- a/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c
+++ b/soh/src/overlays/actors/ovl_En_Insect/z_en_insect.c
@@ -211,6 +211,13 @@ void EnInsect_Init(Actor* thisx, PlayState* play2) {
func_80A7D39C(this);
+ // For bugs that aren't linked to a soil patch, we remove the "short lived" flag to prevent them from despawning
+ // And exit early to not increment the "bugs dropped count"
+ if (CVarGetInteger("gNoBugsDespawn", 0) && this->soilActor == NULL) {
+ this->unk_314 &= ~4;
+ return;
+ }
+
D_80A7DEB8++;
} else {
rand = Rand_ZeroOne();
@@ -394,9 +401,6 @@ void func_80A7CAD0(EnInsect* this, PlayState* play) {
}
void func_80A7CBC8(EnInsect* this) {
- if (CVarGetInteger("gNoBugsDespawn", 0) != 0) {
- return;
- }
this->unk_31A = 60;
func_80A7BF58(this);
this->skelAnime.playSpeed = 1.9f;
diff --git a/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c b/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c
index 28d8967c24e..9a80b75ad6f 100644
--- a/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c
+++ b/soh/src/overlays/actors/ovl_En_Jj/z_en_jj.c
@@ -7,6 +7,7 @@
#include "z_en_jj.h"
#include "objects/object_jj/object_jj.h"
#include "overlays/actors/ovl_Eff_Dust/z_eff_dust.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED)
@@ -307,6 +308,26 @@ void EnJj_Update(Actor* thisx, PlayState* play) {
this->skelAnime.jointTable[10].z = this->mouthOpenAngle;
}
+s32 EnJj_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnJj* this = (EnJj*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 13) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(4649, -8635, 15276, MTXMODE_APPLY);
+ Matrix_Translate(27.027f, 135.135f, -81.081f, MTXMODE_APPLY);
+ Matrix_Scale(0.304f, 0.304f, 0.304f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
+ return false;
+}
+
void EnJj_Draw(Actor* thisx, PlayState* play2) {
static void* eyeTextures[] = { gJabuJabuEyeOpenTex, gJabuJabuEyeHalfTex, gJabuJabuEyeClosedTex };
PlayState* play = play2;
@@ -318,7 +339,7 @@ void EnJj_Draw(Actor* thisx, PlayState* play2) {
Matrix_Translate(0.0f, (cosf(this->skelAnime.curFrame * (M_PI / 41.0f)) * 10.0f) - 10.0f, 0.0f, MTXMODE_APPLY);
Matrix_Scale(10.0f, 10.0f, 10.0f, MTXMODE_APPLY);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeIndex]));
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, EnJj_PostLimbDraw, this);
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c
index 25299f5b06b..9acf7f85766 100644
--- a/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c
+++ b/soh/src/overlays/actors/ovl_En_Ko/z_en_ko.c
@@ -1377,6 +1377,12 @@ Gfx* EnKo_SetEnvColor(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b, u8 a) {
void EnKo_Draw(Actor* thisx, PlayState* play) {
EnKo* this = (EnKo*)thisx;
Color_RGBA8 tunicColor = sModelInfo[ENKO_TYPE].tunicColor;
+
+ // Overwrite to red tunic as default for Holidays in Hyrule build
+ tunicColor.r = 255;
+ tunicColor.g = 0;
+ tunicColor.b = 0;
+
Color_RGBA8 bootsColor = sModelInfo[ENKO_TYPE].bootsColor;
if (CVarGetInteger("gCosmetics.NPC_Kokiri.Changed", 0)) {
diff --git a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c
index 75e54c140a5..5b743c7e13e 100644
--- a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c
+++ b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c
@@ -266,6 +266,12 @@ void EnKusa_Init(Actor* thisx, PlayState* play) {
return;
}
+ if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.world.pos.z < 600.0) {
+ this->actor.world.pos.x += 1620.672;
+ this->actor.world.pos.y += 80;
+ this->actor.world.pos.z += 900.884;
+ }
+
EnKusa_SetupWaitObject(this);
}
diff --git a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c
index f388d49896d..20eff8f18dc 100644
--- a/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c
+++ b/soh/src/overlays/actors/ovl_En_Ma1/z_en_ma1.c
@@ -6,6 +6,7 @@
#include "z_en_ma1.h"
#include "objects/object_ma1/object_ma1.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_DRAW_WHILE_CULLED | ACTOR_FLAG_NO_FREEZE_OCARINA)
@@ -555,6 +556,21 @@ void EnMa1_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if (limbIndex == 15) {
Matrix_MultVec3f(&vec, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, 0, MTXMODE_APPLY);
+ Matrix_Translate(756.757f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.73f, 0.73f, 0.73f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnMa1_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c
index ddc9aea652d..997e37e5f06 100644
--- a/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c
+++ b/soh/src/overlays/actors/ovl_En_Niw/z_en_niw.c
@@ -9,6 +9,7 @@
#include "overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h"
#include "vt.h"
#include "soh/frame_interpolation.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_ALWAYS_THROWN)
@@ -1132,13 +1133,33 @@ s32 EnNiw_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* p
return false;
}
+s32 EnNiw_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnNiw* this = (EnNiw*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -19705, MTXMODE_APPLY);
+ Matrix_Translate(297.297f, -81.082f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
+ return false;
+}
+
void EnNiw_Draw(Actor* thisx, PlayState* play) {
EnNiw* this = (EnNiw*)thisx;
Vec3f scale = { 0.15f, 0.15f, 0.15f };
GraphicsContext* gfxCtx = play->state.gfxCtx;
Gfx_SetupDL_25Opa(play->state.gfxCtx);
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnNiw_OverrideLimbDraw, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnNiw_OverrideLimbDraw, EnNiw_PostLimbDraw, this);
if (this->actionFunc == func_80AB6450) {
func_80033C30(&this->actor.world.pos, &scale, 255, play);
diff --git a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c
index 5113b8a6894..e67a751619b 100644
--- a/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c
+++ b/soh/src/overlays/actors/ovl_En_Niw_Girl/z_en_niw_girl.c
@@ -7,6 +7,7 @@
#include "z_en_niw_girl.h"
#include "objects/object_gr/object_gr.h"
#include "vt.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -248,6 +249,27 @@ s32 EnNiwGirlOverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f
static Vec3f sConstVec3f = { 0.2f, 0.2f, 0.2f };
+s32 EnNiwGirl_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnNiwGirl* this = (EnNiwGirl*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 4) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, 0, MTXMODE_APPLY);
+ Matrix_Translate(945.945f, 0.0f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.676f, 0.676f, 0.676f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
+ return false;
+}
+
void EnNiwGirl_Draw(Actor* thisx, PlayState* play) {
static void* eyeTextures[] = { gNiwGirlEyeOpenTex, gNiwGirlEyeHalfTex, gNiwGirlEyeClosedTex };
EnNiwGirl* this = (EnNiwGirl*)thisx;
@@ -258,7 +280,7 @@ void EnNiwGirl_Draw(Actor* thisx, PlayState* play) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeIndex]));
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnNiwGirlOverrideLimbDraw, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnNiwGirlOverrideLimbDraw, EnNiwGirl_PostLimbDraw, this);
func_80033C30(&this->actor.world.pos, &sp4C, 255, play);
CLOSE_DISPS(play->state.gfxCtx);
diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c
index 8ddf52fad9b..645cc6c68df 100644
--- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c
+++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c
@@ -4,6 +4,7 @@
#include "overlays/actors/ovl_En_Niw/z_en_niw.h"
#include "vt.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
+#include
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -601,6 +602,27 @@ s32 EnNiwLady_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3
return false;
}
+s32 EnNiwLady_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnNiwLady* this = (EnNiwLady*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-886, -3322, -5093, MTXMODE_APPLY);
+ Matrix_Translate(824.324f, 283.782f, -202.703f, MTXMODE_APPLY);
+ Matrix_Scale(0.762f, 0.762f, 0.762f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
+ return false;
+}
+
void EnNiwLady_Draw(Actor* thisx, PlayState* play) {
static void* sEyeTextures[] = { gCuccoLadyEyeOpenTex, gCuccoLadyEyeHalfTex, gCuccoLadyEyeClosedTex };
EnNiwLady* this = (EnNiwLady*)thisx;
@@ -612,7 +634,7 @@ void EnNiwLady_Draw(Actor* thisx, PlayState* play) {
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyeTextures[this->faceState]));
gSPSegment(POLY_OPA_DISP++, 0x0C, func_80ABB0A0(play->state.gfxCtx));
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnNiwLady_OverrideLimbDraw, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnNiwLady_OverrideLimbDraw, EnNiwLady_PostLimbDraw, this);
}
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c b/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c
index d2500afaf82..29f2a1c0bef 100644
--- a/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c
+++ b/soh/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c
@@ -10,6 +10,7 @@
#include "objects/object_dekunuts/object_dekunuts.h"
#include "objects/object_hintnuts/object_hintnuts.h"
#include "objects/object_shopnuts/object_shopnuts.h"
+#include "assets/objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_dns/object_dns.h"
#include "objects/object_dnk/object_dnk.h"
@@ -47,7 +48,7 @@ static ColliderCylinderInit sCylinderInit = {
},
{
ELEMTYPE_UNK0,
- { 0xFFCFFFFF, 0x00, 0x08 },
+ { 0xFFCFFFFF, 0x02, 0x08 },
{ 0xFFCFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_WOOD,
BUMP_ON,
@@ -72,6 +73,8 @@ void EnNutsball_Init(Actor* thisx, PlayState* play) {
EnNutsball* this = (EnNutsball*)thisx;
s32 pad;
+ this->collider.info.toucher.effect = 2;
+
ActorShape_Init(&this->actor.shape, 400.0f, ActorShadow_DrawCircle, 13.0f);
Collider_InitCylinder(play, &this->collider);
Collider_SetCylinder(play, &this->collider, &this->actor, &sCylinderInit);
@@ -141,8 +144,8 @@ void func_80ABBBA8(EnNutsball* this, PlayState* play) {
sp40.y = this->actor.world.pos.y + 4;
sp40.z = this->actor.world.pos.z;
- EffectSsHahen_SpawnBurst(play, &sp40, 6.0f, 0, 7, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL);
- SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_EN_OCTAROCK_ROCK);
+ EffectSsIcePiece_SpawnBurst(play, &this->actor.world.pos, this->actor.scale.x / 10);
+ SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_PL_ICE_BROKEN);
Actor_Kill(&this->actor);
} else {
if (this->timer == -300) {
@@ -176,17 +179,19 @@ void EnNutsball_Draw(Actor* thisx, PlayState* play) {
OPEN_DISPS(play->state.gfxCtx);
- if (CVarGetInteger("gNewDrops", 0) != 0) {
+ if (CVarGetInteger("gNewDrops", 0) || CVarGetInteger("gLetItSnow", 0)) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 1 * (play->state.frames * 6),
- 1 * (play->state.frames * 6), 32, 32, 1, 1 * (play->state.frames * 6),
- 1 * (play->state.frames * 6), 32, 32));
- Matrix_Scale(25.0f,25.0f,25.0f,MTXMODE_APPLY);
+ f32 scale = 12.0f;
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, (0 - 1) % 128, 32, 32, 1, 0, (1 * -2) % 128, 32, 32));
+
Matrix_RotateX(thisx->home.rot.z * 9.58738e-05f, MTXMODE_APPLY);
- gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
- G_MTX_MODELVIEW | G_MTX_LOAD);
- gSPDisplayList(POLY_OPA_DISP++, sDListsNew[thisx->params]);
+ Matrix_Translate(0.0f, -445.946f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 50, 100, 255);
+ gSPDisplayList(POLY_OPA_DISP++, gEffIceFragment3DL);
} else {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY);
diff --git a/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c b/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c
index 017d1e9aea1..fd46ca603be 100644
--- a/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c
+++ b/soh/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c
@@ -2,6 +2,7 @@
#include "objects/object_okuta/object_okuta.h"
#include "objects/gameplay_field_keep/gameplay_field_keep.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "assets/objects/gameplay_keep/gameplay_keep.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE)
@@ -45,7 +46,7 @@ static ColliderCylinderInit sProjectileColliderInit = {
},
{
ELEMTYPE_UNK0,
- { 0xFFCFFFFF, 0x00, 0x08 },
+ { 0xFFCFFFFF, 0x02, 0x08 },
{ 0xFFCFFFFF, 0x00, 0x00 },
TOUCH_ON | TOUCH_SFX_HARD,
BUMP_ON,
@@ -519,38 +520,12 @@ void EnOkuta_ProjectileFly(EnOkuta* this, PlayState* play) {
f32 temp_f20;
f32 temp_f22;
s32 i;
- for (s16 i = 0; i < ARRAY_COUNT(sEffectScales); i++) {
- phi_s0 += 10000;
-
- temp_f20 = Rand_ZeroOne() * 5.0f;
- pos.x = (Math_SinS(phi_s0) * temp_f20) + this->actor.world.pos.x;
- pos.y = (Rand_ZeroOne() * 40.0f) + this->actor.world.pos.y + 5.0f;
- pos.z = (Math_CosS(phi_s0) * temp_f20) + this->actor.world.pos.z;
-
- temp_f20 = (Rand_ZeroOne() * 5.0f) + 2.0f;
- velocity.x = Math_SinS(phi_s0) * temp_f20;
- temp_f22 = Rand_ZeroOne();
- velocity.y = (Rand_ZeroOne() * i * 2.5f) + (temp_f22 * 5.0f);
- velocity.z = Math_CosS(phi_s0) * temp_f20;
-
- if (i == 0) {
- phi_v0 = 41;
- gravity = -450;
- } else if (i < 4) {
- phi_v0 = 37;
- gravity = -380;
- } else {
- phi_v0 = 69;
- gravity = -320;
- }
- EffectSsKakera_Spawn(play, &pos, &velocity, &this->actor.world.pos, gravity, phi_v0, 30, 5, 0,
- sEffectScales[i]/5, 3, 0, 70, 1, OBJECT_GAMEPLAY_FIELD_KEEP, gSilverRockFragmentsDL);
- }
+ EffectSsIcePiece_SpawnBurst(play, &this->actor.world.pos, this->actor.scale.x / 10);
} else {
EffectSsHahen_SpawnBurst(play, &pos, 6.0f, 0, 1, 2, 15, 7, 10, gOctorokProjectileDL);
}
- SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_EN_OCTAROCK_ROCK);
+ SoundSource_PlaySfxAtFixedWorldPos(play, &this->actor.world.pos, 20, NA_SE_PL_ICE_BROKEN);
Actor_Kill(&this->actor);
}
} else if (this->timer == -300) {
@@ -763,17 +738,19 @@ void EnOkuta_Draw(Actor* thisx, PlayState* play) {
} else {
OPEN_DISPS(play->state.gfxCtx);
- if (CVarGetInteger("gNewDrops", 0) != 0) {
+ if (CVarGetInteger("gNewDrops", 0) || CVarGetInteger("gLetItSnow", 0)) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 0x08,
- Gfx_TwoTexScroll(play->state.gfxCtx, 0, 1 * (play->state.frames * 6),
- 1 * (play->state.frames * 6), 32, 32, 1, 1 * (play->state.frames * 6),
- 1 * (play->state.frames * 6), 32, 32));
- Matrix_Scale(7.0f,7.0f,7.0f,MTXMODE_APPLY);
- Matrix_RotateX(thisx->home.rot.z * (M_PI / 0x8000), MTXMODE_APPLY);
- gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
- G_MTX_MODELVIEW | G_MTX_LOAD);
- gSPDisplayList(POLY_OPA_DISP++, gSilverRockDL);
+ f32 scale = 12.0f;
+
+ gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, (0 - 1) % 128, 32, 32, 1, 0, (1 * -2) % 128, 32, 32));
+
+ Matrix_RotateX(thisx->home.rot.z * 9.58738e-05f, MTXMODE_APPLY);
+ Matrix_Translate(0.0f, -445.946f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
+
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 50, 100, 255);
+ gSPDisplayList(POLY_OPA_DISP++, gEffIceFragment3DL);
} else {
Matrix_Mult(&play->billboardMtxF, MTXMODE_APPLY);
Matrix_RotateZ(this->actor.home.rot.z * (M_PI / 0x8000), MTXMODE_APPLY);
diff --git a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c
index 460c788b289..1d51de69511 100644
--- a/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c
+++ b/soh/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c
@@ -16,6 +16,7 @@
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
#include "soh/Enhancements/cosmetics/cosmeticsTypes.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#include
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -2457,6 +2458,69 @@ void EnOssan_DrawStickDirectionPrompts(PlayState* play, EnOssan* this) {
CLOSE_DISPS(play->state.gfxCtx);
}
+s32 EnOssan_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnOssan* this = (EnOssan*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 8) {
+ switch(this->actor.params) {
+ case 4: {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-11071, -443, -3986, MTXMODE_APPLY);
+ Matrix_Translate(878.378f, 351.351f, 540.541f, MTXMODE_APPLY);
+ Matrix_Scale(1.352f, 1.352f, 1.352f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ break;
+ }
+ case 1:
+ case 3: {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-6643, 1992, -1772, MTXMODE_APPLY);
+ Matrix_Translate(918.919f, 121.622f, 256.757f, MTXMODE_APPLY);
+ Matrix_Scale(0.73f, 0.73f, 0.73f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 255, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ break;
+ }
+ case 2: {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-16163, 0, 2878, MTXMODE_APPLY);
+ Matrix_Translate(905.406f, 0.0f, -27.027f, MTXMODE_APPLY);
+ Matrix_Scale(1.318f, 1.318f, 1.318f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ break;
+ }
+ default: {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-11071, -443, -3986, MTXMODE_APPLY);
+ Matrix_Translate(878.378f, 351.351f, 540.541f, MTXMODE_APPLY);
+ Matrix_Scale(1.352f, 1.352f, 1.352f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ break;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
void EnOssan_DrawBazaarShopkeeper(Actor* thisx, PlayState* play) {
static void* sBazaarShopkeeperEyeTextures[] = { gOssanEyeOpenTex, gOssanEyeHalfTex, gOssanEyeClosedTex };
EnOssan* this = (EnOssan*)thisx;
@@ -2466,7 +2530,7 @@ void EnOssan_DrawBazaarShopkeeper(Actor* thisx, PlayState* play) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sBazaarShopkeeperEyeTextures[this->eyeTextureIdx]));
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnOssan_OverrideLimbDrawDefaultShopkeeper, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnOssan_OverrideLimbDrawDefaultShopkeeper, EnOssan_PostLimbDraw, this);
EnOssan_DrawCursor(play, this, this->cursorX, this->cursorY, this->cursorZ, this->drawCursor);
EnOssan_DrawStickDirectionPrompts(play, this);
@@ -2492,6 +2556,16 @@ s32 EnOssan_OverrideLimbDrawKokiriShopkeeper(PlayState* play, s32 limbIndex, Gfx
gSPSegment(POLY_OPA_DISP++, 0x0A, SEGMENTED_TO_VIRTUAL(sKokiriShopkeeperEyeTextures[this->eyeTextureIdx]));
}
+ if (limbIndex == 15) {
+ Matrix_Push();
+ Matrix_RotateZYX(14169, -2215, 0, MTXMODE_APPLY);
+ Matrix_Translate(1810.811f, -351.351f, -94.595f, MTXMODE_APPLY);
+ Matrix_Scale(1.068f, 1.068f, 1.068f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
return 0;
@@ -2520,8 +2594,8 @@ void EnOssan_DrawKokiriShopkeeper(Actor* thisx, PlayState* play) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
- gSPSegment(POLY_OPA_DISP++, 0x08, EnOssan_SetEnvColor(play->state.gfxCtx, 0, 130, 70, 255));
- gSPSegment(POLY_OPA_DISP++, 0x09, EnOssan_SetEnvColor(play->state.gfxCtx, 110, 170, 20, 255));
+ gSPSegment(POLY_OPA_DISP++, 0x08, EnOssan_SetEnvColor(play->state.gfxCtx, 255, 0, 0, 255));
+ gSPSegment(POLY_OPA_DISP++, 0x09, EnOssan_SetEnvColor(play->state.gfxCtx, 255, 0, 0, 255));
gSPSegment(POLY_OPA_DISP++, 0x0C, EnOssan_EndDList(play->state.gfxCtx));
SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnOssan_OverrideLimbDrawKokiriShopkeeper, NULL, this);
@@ -2596,7 +2670,7 @@ void EnOssan_DrawPotionShopkeeper(Actor* thisx, PlayState* play) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sPotionShopkeeperEyeTextures[this->eyeTextureIdx]));
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, EnOssan_PostLimbDraw, this);
EnOssan_DrawCursor(play, this, this->cursorX, this->cursorY, this->cursorZ, this->drawCursor);
EnOssan_DrawStickDirectionPrompts(play, this);
@@ -2632,7 +2706,7 @@ void EnOssan_DrawBombchuShopkeeper(Actor* thisx, PlayState* play) {
Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sBombchuShopkeeperEyeTextures[this->eyeTextureIdx]));
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, NULL, EnOssan_PostLimbDraw, this);
EnOssan_DrawCursor(play, this, this->cursorX, this->cursorY, this->cursorZ, this->drawCursor);
EnOssan_DrawStickDirectionPrompts(play, this);
diff --git a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
index 8489b10326f..ba6a1e85c2f 100644
--- a/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
+++ b/soh/src/overlays/actors/ovl_En_Po_Relay/z_en_po_relay.c
@@ -7,6 +7,7 @@
#include "z_en_po_relay.h"
#include "overlays/actors/ovl_En_Honotrap/z_en_honotrap.h"
#include "objects/object_tk/object_tk.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_IGNORE_QUAKE | ACTOR_FLAG_WILL_TALK)
@@ -425,6 +426,20 @@ void EnPoRelay_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
gSPDisplayList(POLY_OPA_DISP++, gDampeHaloDL);
CLOSE_DISPS(play->state.gfxCtx);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 16) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(10627, 3321, -13727, MTXMODE_APPLY);
+ Matrix_Translate(418.919f, 40.54f, -256.757f, MTXMODE_APPLY);
+ Matrix_Scale(1.068f, 1.068f, 1.068f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnPoRelay_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c
index 6f48314ff69..001a2dda655 100644
--- a/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c
+++ b/soh/src/overlays/actors/ovl_En_Shopnuts/z_en_shopnuts.c
@@ -1,5 +1,6 @@
#include "z_en_shopnuts.h"
#include "objects/object_shopnuts/object_shopnuts.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE)
@@ -308,6 +309,20 @@ void EnShopnuts_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s*
gSPDisplayList(POLY_OPA_DISP++, gBusinessScrubNoseDL);
CLOSE_DISPS(play->state.gfxCtx);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 17) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, 17490, MTXMODE_APPLY);
+ Matrix_Translate(4200.0f, -472.973f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(4.932f, 4.932f, 4.932f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnShopnuts_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c
index 6a5862747c3..32584b826f3 100644
--- a/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c
+++ b/soh/src/overlays/actors/ovl_En_Skb/z_en_skb.c
@@ -2,6 +2,7 @@
#include "overlays/actors/ovl_En_Encount1/z_en_encount1.h"
#include "objects/object_skb/object_skb.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -551,6 +552,21 @@ void EnSkb_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
} else if ((this->unk_283 ^ (this->unk_283 | 4)) == 0) {
BodyBreak_SetInfo(&this->bodyBreak, limbIndex, 0, 18, 18, dList, BODYBREAK_OBJECT_DEFAULT);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 11) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -2215, MTXMODE_APPLY);
+ Matrix_Translate(1324.324f, 662.162f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnSkb_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Snowball/z_en_snowball.c b/soh/src/overlays/actors/ovl_En_Snowball/z_en_snowball.c
new file mode 100644
index 00000000000..a6c07a245ce
--- /dev/null
+++ b/soh/src/overlays/actors/ovl_En_Snowball/z_en_snowball.c
@@ -0,0 +1,229 @@
+/*
+ * File: z_en_snowball.c
+ * Overlay: ovl_En_Snowball
+ * Description: Rollable Snowball
+ */
+
+#include "z_en_snowball.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
+#include "objects/object_goroiwa/object_goroiwa.h"
+#include "soh_assets.h"
+
+#define FLAGS ACTOR_FLAG_UPDATE_WHILE_CULLED
+
+void EnSnowball_Init(Actor* thisx, PlayState* play);
+void EnSnowball_Destroy(Actor* thisx, PlayState* play);
+void EnSnowball_Update(Actor* thisx, PlayState* play);
+void EnSnowball_Draw(Actor* thisx, PlayState* play);
+
+static ColliderJntSphElementInit sJntSphElementsInit[] = {
+ {
+ {
+ ELEMTYPE_UNK0,
+ { 0x20000000, 0x00, 0x04 },
+ { 0x00000000, 0x00, 0x00 },
+ TOUCH_ON | TOUCH_SFX_NORMAL,
+ BUMP_NONE,
+ OCELEM_ON,
+ },
+ { 0, { { 0, 0, 0 }, 14 }, 100 },
+ },
+};
+
+static ColliderJntSphInit sJntSphInit = {
+ {
+ COLTYPE_NONE,
+ AT_ON | AT_TYPE_ENEMY,
+ AC_NONE,
+ OC1_ON | OC1_TYPE_ALL,
+ OC2_TYPE_2,
+ COLSHAPE_JNTSPH,
+ },
+ 1,
+ sJntSphElementsInit,
+};
+
+static CollisionCheckInfoInit sColChkInfoInit = { 0, 3, 15, MASS_HEAVY };
+
+void EnSnowball_UpdateCollider(EnSnowball* this) {
+ Sphere16* worldSphere = &this->collider.elements[0].dim.worldSphere;
+
+ worldSphere->center.x = this->actor.world.pos.x;
+ worldSphere->center.y = this->actor.world.pos.y + (this->actor.scale.x * 500.0f);
+ worldSphere->center.z = this->actor.world.pos.z;
+ worldSphere->radius = (this->actor.scale.x * 500.0f);
+}
+
+void EnSnowball_InitCollider(EnSnowball* this, PlayState* play) {
+ Collider_InitJntSph(play, &this->collider);
+ Collider_SetJntSph(play, &this->collider, &this->actor, &sJntSphInit, this->colliderItems);
+ EnSnowball_UpdateCollider(this);
+ this->collider.elements[0].dim.worldSphere.radius = (this->actor.scale.x * 500.0f);
+}
+
+static InitChainEntry sInitChain[] = {
+ ICHAIN_F32_DIV1000(gravity, -860, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -15000, ICHAIN_CONTINUE),
+ ICHAIN_VEC3F_DIV1000(scale, 5, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1500, ICHAIN_CONTINUE),
+ ICHAIN_F32(uncullZoneScale, 150, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1500, ICHAIN_STOP),
+};
+
+void EnSnowball_Init(Actor* thisx, PlayState* play) {
+ EnSnowball* this = (EnSnowball*)thisx;
+
+ Actor_ProcessInitChain(&this->actor, sInitChain);
+ EnSnowball_InitCollider(this, play);
+ CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit);
+ ActorShape_Init(&this->actor.shape, 595.0f, ActorShadow_DrawCircle, 9.4f);
+ this->actor.shape.shadowAlpha = 200;
+
+ if (thisx->params == 1) {
+ this->actor.speedXZ += 5.0f;
+ this->actor.world.rot.y = Rand_ZeroFloat(65536.0f);
+ }
+}
+
+void EnSnowball_Destroy(Actor* thisx, PlayState* play) {
+ EnSnowball* this = (EnSnowball*)thisx;
+
+ Collider_DestroyJntSph(play, &this->collider);
+}
+
+void EnSnowball_Update(Actor* thisx, PlayState* play) {
+ EnSnowball* this = (EnSnowball*)thisx;
+ Actor* player = GET_PLAYER(play);
+
+ // Kill the actor if it falls too far
+ if (thisx->world.pos.y < -10000.0f) {
+ Actor_Kill(thisx);
+ return;
+ }
+
+ u8 meanBoulder = thisx->params == 1 && this->actor.scale.x > 0.1f;
+
+ // Check if the player is close enough to start rolling
+ if (this->actor.xzDistToPlayer < MAX(20.0f, this->actor.scale.x * 600.0f) && !meanBoulder) {
+ /// Flip the actor's rotation away from the player
+ thisx->world.rot.y = thisx->yawTowardsPlayer + 0x8000;
+ this->actor.speedXZ = MAX(5.0f, this->actor.speedXZ);
+ }
+
+ if (this->collider.base.atFlags & AT_HIT) {
+ this->collider.base.atFlags &= ~AT_HIT;
+ // Flip the actor's rotation away from the player
+ thisx->world.rot.y = thisx->yawTowardsPlayer + 0x8000;
+
+ func_8002F6D4(play, &this->actor, 2.0f, this->actor.yawTowardsPlayer, 0.0f, 0);
+ Player_PlaySfx(&GET_PLAYER(play)->actor, NA_SE_PL_BODY_HIT);
+ }
+
+ // Slow down the actor and increase it's scale
+ if (this->actor.speedXZ > 0.0f) {
+ CollisionPoly snowballPoly;
+ u8 goingUp = this->actor.world.pos.y - this->prevY > 0.001f;
+ u8 goingDown = this->actor.world.pos.y - this->prevY < -0.001f;
+
+ // friction
+ if (thisx->params != 1) {
+ this->actor.speedXZ -= 0.1f;
+ }
+
+ if (goingDown) {
+ // Increase the speed if going down hill
+ f32 speed = (this->prevY - this->actor.world.pos.y) * 0.15f;
+ this->actor.speedXZ += MIN(speed, 0.5f);
+ } else if (goingUp) {
+ // Reduce the speed if going up hill
+ this->actor.speedXZ -= (this->actor.world.pos.y - this->prevY) * 0.1f;
+ }
+
+ if (goingUp || goingDown) {
+ // Check if going straight, one degree right, or one degree left will result in steeper slope
+ // Check straight
+ Vec3f snowballPos = this->actor.world.pos;
+ snowballPos.y += 100.0f;
+ snowballPos.x += Math_SinS(this->actor.world.rot.y) * 1.0f;
+ snowballPos.z += Math_CosS(this->actor.world.rot.y) * 1.0f;
+ float straightSlope = BgCheck_AnyRaycastFloor1(&gPlayState->colCtx, &snowballPoly, &snowballPos);
+
+ // Check one degree right
+ snowballPos = this->actor.world.pos;
+ snowballPos.y += 100.0f;
+ snowballPos.x += Math_SinS(this->actor.world.rot.y + 0x100) * 1.0f;
+ snowballPos.z += Math_CosS(this->actor.world.rot.y + 0x100) * 1.0f;
+ float rightSlope = BgCheck_AnyRaycastFloor1(&gPlayState->colCtx, &snowballPoly, &snowballPos);
+
+ // Check one degree left
+ snowballPos = this->actor.world.pos;
+ snowballPos.y += 100.0f;
+ snowballPos.x += Math_SinS(this->actor.world.rot.y - 0x100) * 1.0f;
+ snowballPos.z += Math_CosS(this->actor.world.rot.y - 0x100) * 1.0f;
+ float leftSlope = BgCheck_AnyRaycastFloor1(&gPlayState->colCtx, &snowballPoly, &snowballPos);
+
+ if (straightSlope > rightSlope || straightSlope > leftSlope) {
+ if (rightSlope < leftSlope) {
+ this->actor.world.rot.y += 0x100;
+ } else {
+ this->actor.world.rot.y -= 0x100;
+ }
+ }
+ }
+
+ // Check if the actor is colliding with a wall and bounce off
+ if (thisx->bgCheckFlags & 8) {
+ if (ABS((s16)(thisx->wallYaw - thisx->world.rot.y)) > 0x4000) {
+ thisx->world.rot.y = ((thisx->wallYaw - thisx->world.rot.y) + thisx->wallYaw) - 0x8000;
+ }
+ if (thisx->params != 1) {
+ thisx->speedXZ *= 0.7f;
+ }
+ thisx->bgCheckFlags &= ~8;
+ if (this->actor.speedXZ > 5.0f) {
+ Audio_PlayActorSound2(thisx, NA_SE_EV_BOMB_BOUND);
+ }
+ }
+
+ Actor_SetScale(&this->actor, MIN(0.15f, this->actor.scale.x + (this->actor.speedXZ * 0.00001f)));
+ }
+
+ if (this->actor.speedXZ < 0.0f) {
+ this->actor.speedXZ = 0.0f;
+ }
+
+ // Based on speed and scale, rotate the snowball
+ // The larger the snowball, the slower it rotates
+ this->sRot += (this->actor.speedXZ * 15.0f) / this->actor.scale.x;
+
+ // record the actor's position
+ this->prevY = this->actor.world.pos.y;
+
+ // Process movement (moves foward based on speed and rotation)
+ Actor_MoveForward(thisx);
+
+ // Prevent actor from going through the ground or walls
+ Actor_UpdateBgCheckInfo(play, &this->actor, MAX(10.0f, this->actor.scale.x * 250.0f), MAX(10.0f, this->actor.scale.x * 500.0f), 0.0f, 0xFF);
+
+ EnSnowball_UpdateCollider(this);
+ // Add collision checks if the actor is a mean boulder
+ if (meanBoulder) {
+ CollisionCheck_SetAT(play, &play->colChkCtx, &this->collider.base);
+ CollisionCheck_SetOC(play, &play->colChkCtx, &this->collider.base);
+ }
+}
+
+void EnSnowball_Draw(Actor* thisx, PlayState* play) {
+ EnSnowball* this = (EnSnowball*)thisx;
+
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL_25Opa(play->state.gfxCtx);
+
+ Matrix_RotateZYX(this->sRot, thisx->world.rot.y, 0, MTXMODE_APPLY);
+
+ Matrix_Translate(0.0f, 7600.0f, -148.649f, MTXMODE_APPLY);
+ Matrix_Scale(4.844f, 4.844f, 4.844f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ gSPDisplayList(POLY_OPA_DISP++, gLinkAdultPompomDL);
+
+ CLOSE_DISPS(play->state.gfxCtx);
+}
diff --git a/soh/src/overlays/actors/ovl_En_Snowball/z_en_snowball.h b/soh/src/overlays/actors/ovl_En_Snowball/z_en_snowball.h
new file mode 100644
index 00000000000..fa8c0779cfb
--- /dev/null
+++ b/soh/src/overlays/actors/ovl_En_Snowball/z_en_snowball.h
@@ -0,0 +1,31 @@
+#ifndef Z_EN_SNOWBALL_H
+#define Z_EN_SNOWBALL_H
+
+#include
+#include "global.h"
+
+struct EnSnowball;
+
+typedef void (*EnSnowballActionFunc)(struct EnSnowball*, PlayState*);
+
+typedef struct EnSnowball {
+ Actor actor;
+
+ ColliderJntSph collider;
+ ColliderJntSphElement colliderItems[1];
+ s16 sRot;
+ f32 prevY;
+} EnSnowball;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void EnSnowball_Init(Actor* thisx, PlayState* play);
+void EnSnowball_Destroy(Actor* thisx, PlayState* play);
+void EnSnowball_Update(Actor* thisx, PlayState* play);
+void EnSnowball_Draw(Actor* thisx, PlayState* play);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c
index 81242aa77de..a7f96df2be5 100644
--- a/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c
+++ b/soh/src/overlays/actors/ovl_En_Sth/z_en_sth.c
@@ -10,6 +10,7 @@
#include "objects/object_boj/object_boj.h"
#include
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -313,7 +314,9 @@ void EnSth_GiveReward(EnSth* this, PlayState* play) {
this->actor.parent = NULL;
EnSth_SetupAction(this, EnSth_RewardObtainedTalk);
gSaveContext.eventChkInf[EVENTCHKINF_SKULLTULA_REWARD_INDEX] |= this->eventFlag;
- GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SKULLTULA_REWARD_INDEX << 4) + sEventFlagsShift[this->actor.params]);
+ if (this->eventFlag != 0) {
+ GameInteractor_ExecuteOnFlagSet(FLAG_EVENT_CHECK_INF, (EVENTCHKINF_SKULLTULA_REWARD_INDEX << 4) + sEventFlagsShift[this->actor.params]);
+ }
} else {
EnSth_GivePlayerItem(this, play);
}
@@ -427,6 +430,21 @@ void EnSth_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
CLOSE_DISPS(play->state.gfxCtx);
}
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-4207, -665, -4650, MTXMODE_APPLY);
+ Matrix_Translate(932.432f, 162.163f, 81.082f, MTXMODE_APPLY);
+ Matrix_Scale(0.73f, 0.73f, 0.73f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
Gfx* EnSth_AllocColorDList(GraphicsContext* play, u8 envR, u8 envG, u8 envB, u8 envA) {
diff --git a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c
index 888b0ef3454..6d91875f3cd 100644
--- a/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c
+++ b/soh/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c
@@ -3,6 +3,7 @@
#include "overlays/actors/ovl_En_Syateki_Itm/z_en_syateki_itm.h"
#include "objects/object_ossan/object_ossan.h"
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_WHILE_CULLED | ACTOR_FLAG_NO_LOCKON)
@@ -535,12 +536,33 @@ s32 EnSyatekiMan_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, V
return 0;
}
+s32 EnSyatekiMan_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, void* thisx) {
+ EnSyatekiMan* this = (EnSyatekiMan*)thisx;
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 8) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(2214, 3985, -7750, MTXMODE_APPLY);
+ Matrix_Translate(1094.594f, 1162.162f, -40.541f, MTXMODE_APPLY);
+ Matrix_Scale(0.864f, 0.864f, 0.864f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 255, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
+
+ return false;
+}
+
void EnSyatekiMan_Draw(Actor* thisx, PlayState* play) {
s32 pad;
EnSyatekiMan* this = (EnSyatekiMan*)thisx;
Gfx_SetupDL_25Opa(play->state.gfxCtx);
- SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnSyatekiMan_OverrideLimbDraw, NULL, this);
+ SkelAnime_DrawSkeletonOpa(play, &this->skelAnime, EnSyatekiMan_OverrideLimbDraw, EnSyatekiMan_PostLimbDraw, this);
}
void EnSyatekiMan_SetBgm(void) {
diff --git a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c
index 9b0dc07e2a4..8ee8fb73396 100644
--- a/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c
+++ b/soh/src/overlays/actors/ovl_En_Ta/z_en_ta.c
@@ -7,6 +7,7 @@
#include "z_en_ta.h"
#include "vt.h"
#include "objects/object_ta/object_ta.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -1218,6 +1219,20 @@ void EnTa_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
if (limbIndex == 15) {
Matrix_MultVec3f(&D_80B16E7C, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(11955, -1993, 221, MTXMODE_APPLY);
+ Matrix_Translate(1081.081f, -108.108f, -270.270f, MTXMODE_APPLY);
+ Matrix_Scale(1.554f, 1.554f, 1.554f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnTa_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Test/z_en_test.c b/soh/src/overlays/actors/ovl_En_Test/z_en_test.c
index 46e9edc9e71..9026b433dd9 100644
--- a/soh/src/overlays/actors/ovl_En_Test/z_en_test.c
+++ b/soh/src/overlays/actors/ovl_En_Test/z_en_test.c
@@ -7,6 +7,7 @@
#include "z_en_test.h"
#include "objects/object_sk2/object_sk2.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -1949,6 +1950,20 @@ void EnTest_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot
this->bodyPartsPos[bodyPart].z = sp50.z;
}
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 11) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-10849, 0, -5314, MTXMODE_APPLY);
+ Matrix_Translate(513.514f, 283.784f, 554.054f, MTXMODE_APPLY);
+ Matrix_Scale(1.203f, 1.203f, 1.203f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnTest_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c b/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c
index 247db92f305..12f7fa18909 100644
--- a/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c
+++ b/soh/src/overlays/actors/ovl_En_Tg/z_en_tg.c
@@ -6,6 +6,7 @@
#include "z_en_tg.h"
#include "objects/object_mu/object_mu.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -168,6 +169,34 @@ void EnTg_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
// Place the target point at the guy's head instead of the center of the actor
Matrix_MultVec3f(&targetOffset, &this->actor.focus.pos);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 20) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-2657, -1550, 1549, MTXMODE_APPLY);
+ Matrix_Translate(594.594f, -135.135f, -54.054f, MTXMODE_APPLY);
+ Matrix_Scale(0.966f, 0.966f, 0.966f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+
+ if (limbIndex == 9) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-3100, 1992, 2435, MTXMODE_APPLY);
+ Matrix_Translate(864.865f, -121.622f, 175.676f, MTXMODE_APPLY);
+ Matrix_Scale(0.865f, 0.865f, 0.865f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 255, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
Gfx* EnTg_SetColor(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b, u8 a) {
diff --git a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c
index 738db714d0b..bf737cc47f1 100644
--- a/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c
+++ b/soh/src/overlays/actors/ovl_En_Tk/z_en_tk.c
@@ -8,6 +8,7 @@
#include "objects/gameplay_keep/gameplay_keep.h"
#include "objects/object_tk/object_tk.h"
#include "soh/frame_interpolation.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
#define COLLECTFLAG_GRAVEDIGGING_HEART_PIECE 0x19
@@ -408,7 +409,7 @@ s32 EnTk_ChooseReward(EnTk* this) {
f32 luck;
s32 reward;
- if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, 0x1F) && this->heartPieceSpawned == 0) {
+ if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) {
return 3;
}
@@ -624,10 +625,8 @@ void EnTk_Dig(EnTk* this, PlayState* play) {
this->currentReward = EnTk_ChooseReward(this);
- // merging in dampe tour fix seems messy, so i'm just wrapping this whole thing
- // in an n64dd check for now
- if (IS_RANDO || CVarGetInteger("gDampeWin", 0)) {
- if (this->currentReward == 3) {
+ if (this->currentReward == 3) {
+ if (IS_RANDO || CVarGetInteger("gDampeWin", 0)) {
/*
* Upgrade the purple rupee reward to the heart piece if this
* is the first grand prize dig.
@@ -635,37 +634,31 @@ void EnTk_Dig(EnTk* this, PlayState* play) {
if (!Flags_GetItemGetInf(ITEMGETINF_1C) && !(IS_RANDO || CVarGetInteger("gDampeWin", 0))) {
Flags_SetItemGetInf(ITEMGETINF_1C);
this->currentReward = 4;
- } else if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, 0x1F) && this->heartPieceSpawned == 0) {
+ } else if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && !Flags_GetCollectible(gPlayState, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE) && this->heartPieceSpawned == 0) {
this->currentReward = 4;
}
}
-
- if ((IS_RANDO || CVarGetInteger("gDampeWin", 0)) && this->currentReward == 4) {
- Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, rewardPos.x, rewardPos.y, rewardPos.z, 0,
- 0, 0, 0x1F06, true);
- this->heartPieceSpawned = 1;
- } else {
- Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]);
- }
- } else {
- if (this->currentReward == 3) {
- /*
- * Upgrade the purple rupee reward to the heart piece if this
- * is the first grand prize dig.
- */
- // If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true.
- // Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true.
- // If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag.
- if (!heartPieceSpawned &&
- (!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) ||
- CVarGetInteger("gGravediggingTourFix", 0) &&
- !Flags_GetCollectible(play, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) {
- this->currentReward = 4;
- gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE;
- heartPieceSpawned = true;
- }
+ /*
+ * Upgrade the purple rupee reward to the heart piece if this
+ * is the first grand prize dig.
+ */
+ // If vanilla itemGetInf flag is not set, it's impossible for the new flag to be set, so return true.
+ // Otherwise if the gGravediggingTourFix is enabled and the new flag hasn't been set, return true.
+ // If true, spawn the heart piece and set the vanilla itemGetInf flag and new temp clear flag.
+ if (!heartPieceSpawned &&
+ (!(gSaveContext.itemGetInf[1] & ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE) ||
+ CVarGetInteger("gGravediggingTourFix", 0) &&
+ !Flags_GetCollectible(play, COLLECTFLAG_GRAVEDIGGING_HEART_PIECE))) {
+ this->currentReward = 4;
+ gSaveContext.itemGetInf[1] |= ITEMGETINFFLAG_GRAVEDIGGING_HEART_PIECE;
+ heartPieceSpawned = true;
}
+ }
+ if (IS_RANDO && this->currentReward == 4) {
+ Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, rewardPos.x, rewardPos.y, rewardPos.z, 0, 0, 0, 0x1906, true);
+ this->heartPieceSpawned = 1;
+ } else {
EnItem00* reward = Item_DropCollectible(play, &rewardPos, rewardParams[this->currentReward]);
if (this->currentReward == 4) {
reward->collectibleFlag = COLLECTFLAG_GRAVEDIGGING_HEART_PIECE;
@@ -766,6 +759,20 @@ void EnTk_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
Matrix_MultVec3f(&sp28, &this->v3f_304);
func_80B1D200(play);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 16) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(10627, 3321, -13727, MTXMODE_APPLY);
+ Matrix_Translate(418.919f, 40.54f, -256.757f, MTXMODE_APPLY);
+ Matrix_Scale(1.068f, 1.068f, 1.068f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnTk_Draw(Actor* thisx, PlayState* play) {
diff --git a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c
index d52b82d8df6..dff5f74f01a 100644
--- a/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c
+++ b/soh/src/overlays/actors/ovl_En_Toryo/z_en_toryo.c
@@ -7,6 +7,7 @@
#include "z_en_toryo.h"
#include "objects/object_toryo/object_toryo.h"
#include "soh/Enhancements/randomizer/adult_trade_shuffle.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY)
@@ -105,6 +106,11 @@ void EnToryo_Init(Actor* thisx, PlayState* play) {
break;
case SCENE_KAKARIKO_VILLAGE:
if ((LINK_AGE_IN_YEARS == YEARS_CHILD) && IS_DAY) {
+ this->actor.world.pos.x = 756.0;
+ this->actor.world.pos.y = 80.0;
+ this->actor.world.pos.z = 1378.0;
+ this->actor.shape.rot.y = 32534;
+
this->stateFlags |= 2;
}
break;
@@ -425,4 +431,18 @@ void EnToryo_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* ro
Matrix_MultVec3f(&sMultVec, &this->actor.focus.pos);
break;
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 15) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(-23691, 664, -2879, MTXMODE_APPLY);
+ Matrix_Translate(810.811f, -243.243f, 270.27f, MTXMODE_APPLY);
+ Matrix_Scale(1.216f, 1.216f, 1.216f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
diff --git a/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c b/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c
index ba0a7561341..bff8380cdee 100644
--- a/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c
+++ b/soh/src/overlays/actors/ovl_En_Vm/z_en_vm.c
@@ -9,6 +9,7 @@
#include "overlays/actors/ovl_En_Bom/z_en_bom.h"
#include "objects/gameplay_keep/gameplay_keep.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -517,6 +518,20 @@ void EnVm_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
&this->colliderQuad2.dim.quad[1], &this->colliderQuad2.dim.quad[2],
&this->colliderQuad2.dim.quad[3]);
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 6) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(19704, -1329, 11734, MTXMODE_APPLY);
+ Matrix_Translate(310.811f, -108.108f, -81.081f, MTXMODE_APPLY);
+ Matrix_Scale(2.297f, 2.297f, 2.297f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gSantaHatGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
void EnVm_Draw(Actor* thisx, PlayState* play2) {
diff --git a/soh/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c b/soh/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
index f8b1cfd10d7..d57a1833ba1 100644
--- a/soh/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
+++ b/soh/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c
@@ -134,6 +134,10 @@ u8 WeatherTag_CheckEnableWeatherEffect(EnWeatherTag* this, PlayState* play, u8 a
u8 ret = false;
Player* player = GET_PLAYER(play);
+ if (LINK_IS_ADULT && gPlayState != NULL && gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE) {
+ return ret;
+ }
+
if (Actor_WorldDistXZToActor(&player->actor, &this->actor) < WEATHER_TAG_RANGE100(this->actor.params)) {
if ((play->envCtx.indoors != 0) || !gSkyboxBlendingEnabled ||
(play->skyboxId != SKYBOX_NORMAL_SKY && play->envCtx.unk_1F == play->envCtx.unk_20)) {
diff --git a/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c b/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c
index 41a485bbcc4..432450bf8ca 100644
--- a/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c
+++ b/soh/src/overlays/actors/ovl_En_Wf/z_en_wf.c
@@ -9,6 +9,7 @@
#include "overlays/actors/ovl_En_Encount1/z_en_encount1.h"
#include "objects/object_wf/object_wf.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED)
@@ -1426,6 +1427,21 @@ void EnWf_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
this->bodyPartsPos[bodyPartIndex].z = bodyPartPos.z;
}
}
+
+ if (CVarGetInteger("gLetItSnow", 0)) {
+ if (limbIndex == 17) {
+ OPEN_DISPS(play->state.gfxCtx);
+ Matrix_Push();
+ Matrix_RotateZYX(0, 0, -18377, MTXMODE_APPLY);
+ Matrix_Translate(729.73f, 1243.243f, 0.0f, MTXMODE_APPLY);
+ Matrix_Scale(0.743f, 0.743f, 0.743f, MTXMODE_APPLY);
+ gDPSetEnvColor(POLY_OPA_DISP++, 255, 0, 0, 255);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gPaperCrownGenericDL);
+ Matrix_Pop();
+ CLOSE_DISPS(play->state.gfxCtx);
+ }
+ }
}
static void* sWolfosNormalEyeTextures[] = { gWolfosNormalEyeOpenTex, gWolfosNormalEyeHalfTex, gWolfosNormalEyeNarrowTex,
diff --git a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c
index 4adb7afe761..0374725861c 100644
--- a/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c
+++ b/soh/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c
@@ -173,6 +173,16 @@ void EnWood02_Init(Actor* thisx, PlayState* play2) {
f32 floorY;
s16 extraRot;
+ if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.params <= WOOD_TREE_KAKARIKO_ADULT) {
+ Actor_Kill(this);
+ }
+
+ if (gPlayState->sceneNum == SCENE_KAKARIKO_VILLAGE && this->actor.params >= 0) {
+ this->actor.world.pos.x = 754.051;
+ this->actor.world.pos.y = 80.0;
+ this->actor.world.pos.z = 1429.908;
+ }
+
// The tree in Kakariko's day scene does not have the same params to spawn the GS
// as the night scene, For the always spawn GS enhancement we apply the needed
// params to have the GS drop when bonking
@@ -446,14 +456,14 @@ void EnWood02_Draw(Actor* thisx, PlayState* play) {
if ((type == WOOD_TREE_OVAL_GREEN_SPAWNER) || (type == WOOD_TREE_OVAL_GREEN_SPAWNED) ||
(type == WOOD_TREE_OVAL_GREEN) || (type == WOOD_LEAF_GREEN)) {
- red = 50;
- green = 170;
- blue = 70;
+ red = 255;
+ green = 255;
+ blue = 255;
} else if ((type == WOOD_TREE_OVAL_YELLOW_SPAWNER) || (type == WOOD_TREE_OVAL_YELLOW_SPAWNED) ||
(type == WOOD_LEAF_YELLOW)) {
- red = 180;
- green = 155;
- blue = 0;
+ red = 255;
+ green = 255;
+ blue = 255;
} else {
red = green = blue = 255;
}
diff --git a/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c b/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c
index 9aa8204dd9d..02afe7c9bce 100644
--- a/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c
+++ b/soh/src/overlays/actors/ovl_En_Zf/z_en_zf.c
@@ -7,6 +7,7 @@
#include "z_en_zf.h"
#include "objects/object_zf/object_zf.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
+#include "soh_assets.h"
#define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_WHILE_CULLED)
diff --git a/soh/src/overlays/actors/ovl_End_Title/z_end_title.c b/soh/src/overlays/actors/ovl_End_Title/z_end_title.c
index af13255a8b9..ec49dd05825 100644
--- a/soh/src/overlays/actors/ovl_End_Title/z_end_title.c
+++ b/soh/src/overlays/actors/ovl_End_Title/z_end_title.c
@@ -72,46 +72,78 @@ void EndTitle_DrawFull(Actor* thisx, PlayState* play) {
OPEN_DISPS(play->state.gfxCtx);
+ uint8_t isKak = play->sceneNum == SCENE_KAKARIKO_VILLAGE;
+
// Draw title cards on the screen
- if ((frameCount > 890) && (this->endAlpha < 200)) {
+ if ((frameCount > 890 || isKak) && (this->endAlpha < 200)) {
this->endAlpha += 7;
}
- if ((frameCount > 810) && (this->tlozAlpha < 200)) {
+ if ((frameCount > 810 || isKak) && (this->tlozAlpha < 200)) {
this->tlozAlpha += 15;
}
- if ((frameCount > 850) && (this->ootAlpha < 200)) {
+ if ((frameCount > 850 || isKak) && (this->ootAlpha < 200)) {
this->ootAlpha += 15;
}
-
+
OVERLAY_DISP = Gfx_SetupDL_64(OVERLAY_DISP);
- if (D_801614B0.a > 0)
+
+ if (this->actor.params == 2) {
gSPGrayscale(OVERLAY_DISP++, false);
- gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE);
- gDPSetEnvColor(OVERLAY_DISP++, 255, 120, 30, 0);
- gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2);
- gSPClearGeometryMode(OVERLAY_DISP++,
- G_TEXTURE_ENABLE | G_CULL_BACK | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR);
- gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0,
- COMBINED, 0, 0, 0, COMBINED);
- gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->endAlpha);
- gDPLoadTextureTile(OVERLAY_DISP++, sTheEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 80, 24, 0, 0, 80 - 1, 24 - 1, 0,
- G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
- gSPTextureRectangle(OVERLAY_DISP++, 120 << 2, 90 << 2, 200 << 2, 113 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
- gDPPipeSync(OVERLAY_DISP++);
- gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->tlozAlpha);
- gDPLoadTextureTile(OVERLAY_DISP++, sTheLegendOfZeldaTex, G_IM_FMT_IA, G_IM_SIZ_8b, 120, 24, 0, 0, 120 - 1, 24 - 1, 0,
- G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
- gSPTextureRectangle(OVERLAY_DISP++, 100 << 2, 160 << 2, 220 << 2, 183 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
- 1 << 10);
- gDPPipeSync(OVERLAY_DISP++);
- gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->ootAlpha);
- gDPLoadTextureTile(OVERLAY_DISP++, sOcarinaOfTimeTex, G_IM_FMT_IA, G_IM_SIZ_8b, 112, 16, 0,
- 0, 112 - 1, 16 - 1, 0,
- G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
- gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
- 1 << 10);
- if (D_801614B0.a > 0)
- gSPGrayscale(OVERLAY_DISP++, true);
+ gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE);
+ gDPSetEnvColor(OVERLAY_DISP++, 0, 255, 0, 0);
+ gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2);
+ gSPClearGeometryMode(OVERLAY_DISP++, G_TEXTURE_ENABLE | G_CULL_BACK | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR);
+ gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0, 0, COMBINED);
+ gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->endAlpha);
+ gDPLoadTextureTile(OVERLAY_DISP++, sTheEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 80, 24, 0, 0, 80 - 1, 24 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
+ gSPTextureRectangle(OVERLAY_DISP++, 120 << 2, 90 << 2, 200 << 2, 113 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
+ gDPPipeSync(OVERLAY_DISP++);
+ gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->tlozAlpha);
+ gDPLoadTextureTile(OVERLAY_DISP++, sTheLegendOfZeldaTex, G_IM_FMT_IA, G_IM_SIZ_8b, 120, 24, 0, 0, 120 - 1, 24 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
+ gSPTextureRectangle(OVERLAY_DISP++, 100 << 2, 160 << 2, 220 << 2, 183 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
+ gDPPipeSync(OVERLAY_DISP++);
+ gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->ootAlpha);
+ gDPLoadTextureTile(OVERLAY_DISP++, sOcarinaOfTimeTex, G_IM_FMT_IA, G_IM_SIZ_8b, 112, 16, 0, 0, 112 - 1, 16 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
+ gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10);
+
+ D_801614B0.a = 0;
+ //D_801614B0.r = 205;
+ //D_801614B0.g = 168;
+ //D_801614B0.b = 130;
+
+ //gSPGrayscale(OVERLAY_DISP++, true);
+ } else {
+ if (D_801614B0.a > 0)
+
+ gSPGrayscale(OVERLAY_DISP++, false);
+ gDPSetTextureLUT(OVERLAY_DISP++, G_TT_NONE);
+ gDPSetEnvColor(OVERLAY_DISP++, 255, 120, 30, 0);
+ gDPSetRenderMode(OVERLAY_DISP++, G_RM_PASS, G_RM_XLU_SURF2);
+ gSPClearGeometryMode(OVERLAY_DISP++, G_TEXTURE_ENABLE | G_CULL_BACK | G_FOG | G_LIGHTING | G_TEXTURE_GEN |
+ G_TEXTURE_GEN_LINEAR);
+ gDPSetCombineLERP(OVERLAY_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0,
+ COMBINED, 0, 0, 0, COMBINED);
+ gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->endAlpha);
+ gDPLoadTextureTile(OVERLAY_DISP++, sTheEndTex, G_IM_FMT_IA, G_IM_SIZ_8b, 80, 24, 0, 0, 80 - 1, 24 - 1, 0,
+ G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
+ gSPTextureRectangle(OVERLAY_DISP++, 120 << 2, 90 << 2, 200 << 2, 113 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
+ 1 << 10);
+ gDPPipeSync(OVERLAY_DISP++);
+ gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->tlozAlpha);
+ gDPLoadTextureTile(OVERLAY_DISP++, sTheLegendOfZeldaTex, G_IM_FMT_IA, G_IM_SIZ_8b, 120, 24, 0, 0, 120 - 1,
+ 24 - 1, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
+ gSPTextureRectangle(OVERLAY_DISP++, 100 << 2, 160 << 2, 220 << 2, 183 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
+ 1 << 10);
+ gDPPipeSync(OVERLAY_DISP++);
+ gDPSetPrimColor(OVERLAY_DISP++, 0x00, 0x80, 0, 0, 0, this->ootAlpha);
+ gDPLoadTextureTile(OVERLAY_DISP++, sOcarinaOfTimeTex, G_IM_FMT_IA, G_IM_SIZ_8b, 112, 16, 0, 0, 112 - 1, 16 - 1,
+ 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, 0, 0);
+ gSPTextureRectangle(OVERLAY_DISP++, 104 << 2, 177 << 2, 216 << 2, 192 << 2, G_TX_RENDERTILE, 0, 0, 1 << 10,
+ 1 << 10);
+ if (D_801614B0.a > 0)
+ gSPGrayscale(OVERLAY_DISP++, true);
+ }
+
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/src/overlays/actors/ovl_player_actor/z_player.c b/soh/src/overlays/actors/ovl_player_actor/z_player.c
index 497935a6958..52dc2a3e448 100644
--- a/soh/src/overlays/actors/ovl_player_actor/z_player.c
+++ b/soh/src/overlays/actors/ovl_player_actor/z_player.c
@@ -10101,7 +10101,8 @@ void func_80847BA0(PlayState* play, Player* this) {
D_808535F0 = func_80041DB8(&play->colCtx, this->actor.wallPoly, this->actor.wallBgId);
- if (CVarGetInteger("gFixVineFall", 0)) {
+ // conflicts arise from these two being enabled at once, and with ClimbEverything on, FixVineFall is redundant anyway
+ if (CVarGetInteger("gFixVineFall", 0) && !CVarGetInteger("gClimbEverything", 0)) {
/* This fixes the "started climbing a wall and then immediately fell off" bug.
* The main idea is if a climbing wall is detected, double-check that it will
* still be valid once climbing begins by doing a second raycast with a small
diff --git a/soh/src/overlays/effects/ovl_Effect_Ss_Bomb2/z_eff_ss_bomb2.c b/soh/src/overlays/effects/ovl_Effect_Ss_Bomb2/z_eff_ss_bomb2.c
index 12d5c38cc93..cceafe7ed27 100644
--- a/soh/src/overlays/effects/ovl_Effect_Ss_Bomb2/z_eff_ss_bomb2.c
+++ b/soh/src/overlays/effects/ovl_Effect_Ss_Bomb2/z_eff_ss_bomb2.c
@@ -178,19 +178,19 @@ void EffectSsBomb2_Update(PlayState* play, u32 index, EffectSs* this) {
divisor = this->life - 13;
this->rPrimColorR = func_80027DD4(this->rPrimColorR, 255, divisor);
this->rPrimColorG = func_80027DD4(this->rPrimColorG, 255, divisor);
- this->rPrimColorB = func_80027DD4(this->rPrimColorB, 150, divisor);
+ this->rPrimColorB = func_80027DD4(this->rPrimColorB, 255, divisor);
this->rPrimColorA = func_80027DD4(this->rPrimColorA, 255, divisor);
- this->rEnvColorR = func_80027DD4(this->rEnvColorR, 150, divisor);
- this->rEnvColorG = func_80027DD4(this->rEnvColorG, 0, divisor);
- this->rEnvColorB = func_80027DD4(this->rEnvColorB, 0, divisor);
+ this->rEnvColorR = func_80027DD4(this->rEnvColorR, 255, divisor);
+ this->rEnvColorG = func_80027DD4(this->rEnvColorG, 255, divisor);
+ this->rEnvColorB = func_80027DD4(this->rEnvColorB, 255, divisor);
} else if ((this->life < 14) && (this->life > -1)) {
divisor = this->life + 1;
- this->rPrimColorR = func_80027DD4(this->rPrimColorR, 50, divisor);
- this->rPrimColorG = func_80027DD4(this->rPrimColorG, 50, divisor);
- this->rPrimColorB = func_80027DD4(this->rPrimColorB, 50, divisor);
- this->rPrimColorA = func_80027DD4(this->rPrimColorA, 150, divisor);
- this->rEnvColorR = func_80027DD4(this->rEnvColorR, 10, divisor);
- this->rEnvColorG = func_80027DD4(this->rEnvColorG, 10, divisor);
- this->rEnvColorB = func_80027DD4(this->rEnvColorB, 10, divisor);
+ this->rPrimColorR = func_80027DD4(this->rPrimColorR, 255, divisor);
+ this->rPrimColorG = func_80027DD4(this->rPrimColorG, 255, divisor);
+ this->rPrimColorB = func_80027DD4(this->rPrimColorB, 255, divisor);
+ this->rPrimColorA = func_80027DD4(this->rPrimColorA, 255, divisor);
+ this->rEnvColorR = func_80027DD4(this->rEnvColorR, 255, divisor);
+ this->rEnvColorG = func_80027DD4(this->rEnvColorG, 255, divisor);
+ this->rEnvColorB = func_80027DD4(this->rEnvColorB, 255, divisor);
}
}
diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
index 9c83f9322cd..9e6150593d2 100644
--- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
+++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c
@@ -1,6 +1,7 @@
#include "file_choose.h"
#include
+#include
#include "textures/title_static/title_static.h"
#include "textures/parameter_static/parameter_static.h"
@@ -1024,7 +1025,7 @@ void FileChoose_UpdateRandomizer() {
return;
}
- if (!SpoilerFileExists(CVarGetString("gSpoilerLog", ""))) {
+ if (!SpoilerFileExists(CVarGetString("gSpoilerLog", "")) && !CVarGetInteger("gRandomizerDontGenerateSpoiler", 0)) {
CVarSetString("gSpoilerLog", "");
fileSelectSpoilerFileLoaded = false;
}
@@ -1051,6 +1052,10 @@ void FileChoose_UpdateRandomizer() {
Randomizer_LoadMasterQuestDungeons(fileLoc);
Randomizer_LoadEntranceOverrides(fileLoc, silent);
fileSelectSpoilerFileLoaded = true;
+
+ if (SpoilerFileExists(CVarGetString("gSpoilerLog", "")) && CVarGetInteger("gRandomizerDontGenerateSpoiler", 0)) {
+ remove(fileLoc);
+ }
}
}
@@ -1071,6 +1076,7 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
Input* input = &this->state.input[0];
bool dpad = CVarGetInteger("gDpadText", 0);
+ SoH_ProcessDroppedFiles();
FileChoose_UpdateRandomizer();
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_A)) {
@@ -1261,6 +1267,7 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
s8 i = 0;
bool dpad = CVarGetInteger("gDpadText", 0);
+ SoH_ProcessDroppedFiles();
FileChoose_UpdateRandomizer();
if (ABS(this->stickRelX) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) {
@@ -3686,4 +3693,7 @@ void FileChoose_Init(GameState* thisx) {
Font_LoadOrderedFont(&this->font);
Audio_QueueSeqCmd(0xF << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xA);
func_800F5E18(SEQ_PLAYER_BGM_MAIN, NA_BGM_FILE_SELECT, 0, 7, 1);
+
+ // Originally this was only set when transitioning from the title screen, but gSkipLogoTitle skips that process so we're ensuring it's set here
+ gSaveContext.gameMode = GAMEMODE_FILE_SELECT;
}
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 74460691056..665c95b81af 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
@@ -1054,8 +1054,9 @@ void KaleidoScope_UpdateItemEquip(PlayState* play) {
//Fix for Equip Dupe
if (pauseCtx->equipTargetItem == ITEM_BOW) {
- if ((gSaveContext.equips.buttonItems[otherButtonIndex] >= ITEM_BOW_ARROW_FIRE) &&
- (gSaveContext.equips.buttonItems[otherButtonIndex] <= ITEM_BOW_ARROW_LIGHT)) {
+ if (gSaveContext.equips.buttonItems[otherButtonIndex] >= ITEM_BOW_ARROW_FIRE &&
+ gSaveContext.equips.buttonItems[otherButtonIndex] <= ITEM_BOW_ARROW_LIGHT &&
+ !CVarGetInteger("gSeparateArrows", 0)) {
gSaveContext.equips.buttonItems[otherButtonIndex] = gSaveContext.equips.buttonItems[targetButtonIndex];
gSaveContext.equips.cButtonSlots[otherSlotIndex] = gSaveContext.equips.cButtonSlots[pauseCtx->equipTargetCBtn];
Interface_LoadItemIcon2(play, otherButtonIndex);