diff --git a/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL
new file mode 100644
index 000000000..939042daa
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_tri_0 b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_tri_0
new file mode 100644
index 000000000..8c320d243
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_tri_0
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_tri_1 b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_tri_1
new file mode 100644
index 000000000..0990859d5
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_tri_1
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_0 b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_0
new file mode 100644
index 000000000..37e6186e9
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_0
@@ -0,0 +1,119 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_1 b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_1
new file mode 100644
index 000000000..4360eedc5
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_1
@@ -0,0 +1,416 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_cull b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_cull
new file mode 100644
index 000000000..cedf6351d
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/gMysteryItemDL_vtx_cull
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_light_material b/soh/assets/custom/objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_light_material
new file mode 100644
index 000000000..4dc39e811
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_light_material
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_material b/soh/assets/custom/objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_material
new file mode 100644
index 000000000..6941bb55f
--- /dev/null
+++ b/soh/assets/custom/objects/object_mystery_item/mat_gMysteryItemDL_f3dlite_mysteryItem_material
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/assets/custom/objects/object_mystery_item/noise_tex b/soh/assets/custom/objects/object_mystery_item/noise_tex
new file mode 100644
index 000000000..aaf4e331f
Binary files /dev/null and b/soh/assets/custom/objects/object_mystery_item/noise_tex differ
diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h
index 58fed005f..e8c947d0e 100644
--- a/soh/assets/soh_assets.h
+++ b/soh/assets/soh_assets.h
@@ -77,6 +77,9 @@ static const ALIGN_ASSET(2) char gBossSoulSkullDL[] = dgBossSoulSkullDL;
#define dgFishingPoleGiDL "__OTR__objects/object_gi_fishing_pole/gFishingPoleGiDL"
static const ALIGN_ASSET(2) char gFishingPoleGiDL[] = dgFishingPoleGiDL;
+#define dgMysteryItemDL "__OTR__objects/object_mystery_item/gMysteryItemDL"
+static const ALIGN_ASSET(2) char gMysteryItemDL[] = dgMysteryItemDL;
+
// overlays
#define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx"
static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx;
diff --git a/soh/include/boost_custom/container_hash/detail/hash_range_32.hpp b/soh/include/boost_custom/container_hash/detail/hash_range_32.hpp
index 7430152ab..cfa0a2a2d 100644
--- a/soh/include/boost_custom/container_hash/detail/hash_range_32.hpp
+++ b/soh/include/boost_custom/container_hash/detail/hash_range_32.hpp
@@ -46,10 +46,18 @@ template<> struct is_char_type: public boost::true_type {};
#endif // #if !BOOST_VERSION_HAS_HASH_RANGE
+#if BOOST_USE_STD_TYPES
+#define BOOST_ENABLE_IF std::enable_if
+#define BOOST_IS_SAME std::is_same
+#else
+#define BOOST_ENABLE_IF boost::enable_if_
+#define BOOST_IS_SAME is_same
+#endif
+
template
-inline typename boost::enable_if_<
+inline typename BOOST_ENABLE_IF<
is_char_type::value_type>::value &&
- is_same::iterator_category, std::random_access_iterator_tag>::value,
+ BOOST_IS_SAME::iterator_category, std::random_access_iterator_tag>::value,
std::size_t>::type
hash_range_32( uint32_t seed, It first, It last )
{
@@ -114,4 +122,7 @@ std::size_t>::type
} // namespace hash_detail
} // namespace boost
+#undef BOOST_ENABLE_IF
+#undef BOOST_IS_SAME
+
#endif // #ifndef BOOST_HASH_DETAIL_HASH_RANGE_32_HPP
diff --git a/soh/include/boost_custom/container_hash/hash_32.hpp b/soh/include/boost_custom/container_hash/hash_32.hpp
index 4b955c43a..eaf459a34 100644
--- a/soh/include/boost_custom/container_hash/hash_32.hpp
+++ b/soh/include/boost_custom/container_hash/hash_32.hpp
@@ -23,6 +23,18 @@
#endif // #if !BOOST_VERSION_HAS_HASH_RANGE
+#if BOOST_USE_STD_TYPES
+#define BOOST_ENABLE_IF std::enable_if
+#define BOOST_IS_INTEGRAL hash_detail::is_integral
+#define BOOST_IS_UNSIGNED is_unsigned
+#define BOOST_MAKE_UNSIGNED make_unsigned
+#else
+#define BOOST_ENABLE_IF boost::enable_if_
+#define BOOST_IS_INTEGRAL boost::is_integral
+#define BOOST_IS_UNSIGNED boost::is_unsigned
+#define BOOST_MAKE_UNSIGNED boost::make_unsigned
+#endif
+
namespace boost
{
@@ -36,7 +48,7 @@ namespace boost
{
template sizeof(uint32_t)),
- bool is_unsigned = boost::is_unsigned::value,
+ bool is_unsigned = BOOST_IS_UNSIGNED::value,
std::size_t size_t_bits = sizeof(uint32_t) * CHAR_BIT,
std::size_t type_bits = sizeof(T) * CHAR_BIT>
struct hash_integral_impl_32;
@@ -53,7 +65,7 @@ namespace boost
{
static uint32_t fn( T v )
{
- typedef typename boost::make_unsigned::type U;
+ typedef typename BOOST_MAKE_UNSIGNED::type U;
if( v >= 0 )
{
@@ -97,7 +109,7 @@ namespace boost
} // namespace hash_detail
template
- typename boost::enable_if_::value, uint32_t>::type
+ typename BOOST_ENABLE_IF::value, uint32_t>::type
hash_value_32( T v )
{
return hash_detail::hash_integral_impl_32::fn( v );
@@ -106,7 +118,7 @@ namespace boost
// contiguous ranges (string, vector, array)
#if BOOST_VERSION_HAS_HASH_RANGE
template
- typename boost::enable_if_::value, uint32_t>::type
+ typename BOOST_ENABLE_IF::value, uint32_t>::type
hash_value_32( T const& v )
{
return boost::hash_range_32( v.data(), v.data() + v.size() );
@@ -168,5 +180,9 @@ namespace boost
} // namespace boost
#undef BOOST_HASH_CHAR_TRAITS
+#undef BOOST_ENABLE_IF
+#undef BOOST_IS_INTEGRAL
+#undef BOOST_IS_UNSIGNED
+#undef BOOST_MAKE_UNSIGNED
#endif // #ifndef BOOST_FUNCTIONAL_HASH_HASH_32_HPP
diff --git a/soh/include/boost_custom/container_hash/version.hpp b/soh/include/boost_custom/container_hash/version.hpp
index 22ad6634c..3863b507c 100644
--- a/soh/include/boost_custom/container_hash/version.hpp
+++ b/soh/include/boost_custom/container_hash/version.hpp
@@ -6,4 +6,6 @@
#define BOOST_VERSION_HAS_HASH_RANGE ((BOOST_VERSION / 100 % 1000) >= 81)
+#define BOOST_USE_STD_TYPES ((BOOST_VERSION / 100 % 1000) >= 84)
+
#endif // #ifndef BOOST_CONTAINER_HASH_VERSION_HPP
diff --git a/soh/include/variables.h b/soh/include/variables.h
index 9fd6b7247..2c226f2c6 100644
--- a/soh/include/variables.h
+++ b/soh/include/variables.h
@@ -172,7 +172,8 @@ extern "C"
extern u8 gWalkSpeedToggle2;
extern f32 iceTrapScale;
extern f32 triforcePieceScale;
-
+ extern f32 mysteryItemScale;
+
extern const s16 D_8014A6C0[];
#define gTatumsPerBeat (D_8014A6C0[1])
extern const AudioContextInitSizes D_8014A6C4;
diff --git a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
index b932d24cc..4badd8279 100644
--- a/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
+++ b/soh/soh/Enhancements/cosmetics/CosmeticsEditor.cpp
@@ -323,6 +323,7 @@ static std::map cosmeticOptions = {
COSMETIC_OPTION("World.Moon", "Moon", COSMETICS_GROUP_WORLD, ImVec4(240, 255, 180, 255), false, true, true),
COSMETIC_OPTION("World.GossipStone", "Gossip Stone", COSMETICS_GROUP_WORLD, ImVec4(200, 200, 200, 255), false, true, true),
COSMETIC_OPTION("World.RedIce", "Red Ice", COSMETICS_GROUP_WORLD, ImVec4(255, 0, 0, 255), false, true, false),
+ COSMETIC_OPTION("World.MysteryItem", "Mystery Item", COSMETICS_GROUP_WORLD, ImVec4(0, 60, 100, 255), false, true, false),
COSMETIC_OPTION("Navi.IdlePrimary", "Idle Primary", COSMETICS_GROUP_NAVI, ImVec4(255, 255, 255, 255), false, true, false),
COSMETIC_OPTION("Navi.IdleSecondary", "Idle Secondary", COSMETICS_GROUP_NAVI, ImVec4( 0, 0, 255, 0), false, true, true),
diff --git a/soh/soh/Enhancements/presets.h b/soh/soh/Enhancements/presets.h
index 1f2888809..fabefebe8 100644
--- a/soh/soh/Enhancements/presets.h
+++ b/soh/soh/Enhancements/presets.h
@@ -163,7 +163,7 @@ const std::vector enhancementsCvars = {
CVAR_ENHANCEMENT("GravediggingTourFix"),
CVAR_ENHANCEMENT("DekuNutUpgradeFix"),
CVAR_ENHANCEMENT("NaviTextFix"),
- CVAR_ENHANCEMENT("AnubixFix"),
+ CVAR_ENHANCEMENT("AnubisFix"),
CVAR_ENHANCEMENT("CrouchStabHammerFix"),
CVAR_ENHANCEMENT("CrouchStabFix"),
CVAR_ENHANCEMENT("GerudoWarriorClothingFix"),
@@ -702,7 +702,7 @@ const std::vector enhancedPresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NewDrops"), 1),
// Fix Anubis fireballs
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubixFix"), 1),
+ PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubisFix"), 1),
// Autosave
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS),
@@ -828,7 +828,7 @@ const std::vector randomizerPresetEntries = {
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("NewDrops"), 1),
// Fix Anubis fireballs
- PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubixFix"), 1),
+ PRESET_ENTRY_S32(CVAR_ENHANCEMENT("AnubisFix"), 1),
// Autosave
PRESET_ENTRY_S32(CVAR_ENHANCEMENT("Autosave"), AUTOSAVE_LOCATION_AND_MAJOR_ITEMS),
diff --git a/soh/soh/Enhancements/randomizer/draw.cpp b/soh/soh/Enhancements/randomizer/draw.cpp
index 338bfdb33..f35567b83 100644
--- a/soh/soh/Enhancements/randomizer/draw.cpp
+++ b/soh/soh/Enhancements/randomizer/draw.cpp
@@ -296,7 +296,7 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get
if (triforcePieceScale < 0.0001f) {
triforcePieceScale += 0.00003f;
}
-
+
// Animation. When not the completed triforce, create delay before showing the piece to bypass interpolation.
// If the completed triforce, make it grow slowly.
if (current != required) {
@@ -323,6 +323,29 @@ extern "C" void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry get
} else if (current == required && triforcePieceScale > 0.00008f) {
gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gTriforcePieceCompletedDL);
}
+
+ CLOSE_DISPS(play->state.gfxCtx);
+}
+
+extern "C" void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry getItemEntry) {
+ Color_RGB8 color = { 0, 60, 100 };
+ if (CVarGetInteger(CVAR_COSMETIC("World.MysteryItem.Changed"), 0)) {
+ color = CVarGetColor24(CVAR_COSMETIC("World.MysteryItem.Value"), color);
+ }
+
+ OPEN_DISPS(play->state.gfxCtx);
+
+ Gfx_SetupDL_25Xlu(play->state.gfxCtx);
+
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx, (char*)__FILE__, __LINE__), G_MTX_MODELVIEW | G_MTX_LOAD);
+
+ gDPSetGrayscaleColor(POLY_XLU_DISP++, color.r, color.g, color.b, 255);
+ gSPGrayscale(POLY_XLU_DISP++, true);
+
+ gSPDisplayList(POLY_XLU_DISP++, (Gfx*)gMysteryItemDL);
+
+ gSPGrayscale(POLY_XLU_DISP++, false);
+
CLOSE_DISPS(play->state.gfxCtx);
}
diff --git a/soh/soh/Enhancements/randomizer/draw.h b/soh/soh/Enhancements/randomizer/draw.h
index 51300f3a6..ea56e6e32 100644
--- a/soh/soh/Enhancements/randomizer/draw.h
+++ b/soh/soh/Enhancements/randomizer/draw.h
@@ -21,6 +21,10 @@ void Randomizer_DrawTriforcePieceGI(PlayState* play, GetItemEntry getItemEntry);
void Randomizer_DrawOcarinaButton(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawBronzeScale(PlayState* play, GetItemEntry* getItemEntry);
void Randomizer_DrawFishingPoleGI(PlayState* play, GetItemEntry* getItemEntry);
+void Randomizer_DrawMysteryItem(PlayState* play, GetItemEntry getItemEntry);
+
+#define GET_ITEM_MYSTERY \
+ { ITEM_NONE, 0, 0, 0, 0, 0, 0, 0, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, Randomizer_DrawMysteryItem }
#ifdef __cplusplus
};
#endif
diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp
index 6f5820952..231d5e411 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer.cpp
@@ -2466,8 +2466,16 @@ CustomMessage Randomizer::GetMerchantMessage(RandomizerInf randomizerInf, u16 te
RandomizerCheck rc = GetCheckFromRandomizerInf(randomizerInf);
RandomizerGet shopItemGet = ctx->GetItemLocation(rc)->GetPlacedRandomizerGet();
CustomMessage shopItemName;
- if (mysterious) {
- shopItemName = Rando::StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM].GetHintMessage();
+ if (mysterious|| CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) {
+ if (randomizerInf >= RAND_INF_SHOP_ITEMS_KF_SHOP_ITEM_1 && randomizerInf <= RAND_INF_SHOP_ITEMS_MARKET_BOMBCHU_SHOP_ITEM_8) {
+ shopItemName = {
+ "Mysterious Item",
+ "Mysteriösen Gegenstand",
+ "Objet Mystérieux"
+ };
+ } else {
+ shopItemName = Rando::StaticData::hintTextTable[RHT_MYSTERIOUS_ITEM].GetHintMessage();
+ }
// TODO: This should eventually be replaced with a full fledged trick model & trick name system
} else if (shopItemGet == RG_ICE_TRAP) {
shopItemGet = ctx->overrides[rc].LooksLike();
diff --git a/soh/soh/Enhancements/randomizer/randomizer.h b/soh/soh/Enhancements/randomizer/randomizer.h
index 1e9fec263..acbc3ad7f 100644
--- a/soh/soh/Enhancements/randomizer/randomizer.h
+++ b/soh/soh/Enhancements/randomizer/randomizer.h
@@ -10,6 +10,8 @@
#include "context.h"
#include
#include "soh/Enhancements/randomizer/randomizer_check_objects.h"
+#include "soh/Enhancements/randomizer/randomizer_check_tracker.h"
+#include "soh/Enhancements/randomizer/randomizer_tricks.h"
#include
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include "../custom-message/CustomMessageTypes.h"
diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
index 772d4d747..ace7781be 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
+++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp
@@ -144,8 +144,8 @@ RandomizerCheckArea currentArea = RCAREA_INVALID;
OSContPad* trackerButtonsPressed;
std::unordered_map checkNameOverrides;
-bool passesTextFilter(ImGuiTextFilter& checkSearch, const RandomizerCheck check);
-bool shouldHideArea(ImGuiTextFilter& checkSearch, std::map> checksByArea, const RandomizerCheckArea rcArea);
+bool ShouldShowCheck(RandomizerCheck rc);
+bool ShouldHideArea(RandomizerCheckArea rcArea);
void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags = 0);
bool CompareChecks(RandomizerCheck, RandomizerCheck);
bool CheckByArea(RandomizerCheckArea);
@@ -214,6 +214,7 @@ 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 };
+static ImGuiTextFilter checkSearch;
void DefaultCheckData(RandomizerCheck rc) {
gSaveContext.checkTrackerData[rc].status = RCSHOW_UNCHECKED;
@@ -943,9 +944,9 @@ void CheckTrackerWindow::DrawElement() {
optCollapseAll = true;
}
ImGui::SameLine();
- static ImGuiTextFilter checkSearch;
if (ImGui::Button("Clear")) {
checkSearch.Clear();
+ doAreaScroll = true;
}
UIWidgets::Tooltip("Clear the search field");
checkSearch.Draw();
@@ -983,6 +984,8 @@ void CheckTrackerWindow::DrawElement() {
Color_RGBA8 extraColor;
std::string stemp;
+ bool shouldHideFilteredAreas = CVarGetInteger(CVAR_TRACKER_CHECK("HideFilteredAreas"), 1);
+
for (auto& [rcArea, checks] : checksByArea) {
RandomizerCheckArea thisArea = currentArea;
@@ -996,7 +999,7 @@ void CheckTrackerWindow::DrawElement() {
previousShowHidden = showHidden;
doAreaScroll = true;
}
- if (shouldHideArea(checkSearch, checksByArea, rcArea) ||
+ if ((shouldHideFilteredAreas && ShouldHideArea(rcArea)) ||
(!showHidden && ((hideComplete && thisAreaFullyChecked) || (hideIncomplete && !thisAreaFullyChecked)))
) {
doDraw = false;
@@ -1056,7 +1059,7 @@ void CheckTrackerWindow::DrawElement() {
doAreaScroll = false;
}
for (auto rc : checks) {
- if (doDraw && isThisAreaSpoiled && IsVisibleInCheckTracker(rc) && passesTextFilter(checkSearch, rc)) {
+ if (doDraw && isThisAreaSpoiled && ShouldShowCheck(rc)) {
DrawLocation(rc);
}
}
@@ -1076,14 +1079,12 @@ void CheckTrackerWindow::DrawElement() {
}
}
-bool shouldHideArea(ImGuiTextFilter& checkSearch, std::map> checksByArea, RandomizerCheckArea rcArea) {
- bool shouldHideFilteredAreas = CVarGetInteger(CVAR_TRACKER_CHECK("HideFilteredAreas"), 1);
- if (!shouldHideFilteredAreas) {
+bool ShouldHideArea(RandomizerCheckArea rcArea) {
+ if (checkSearch.Filters.Size == 0 || checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) {
return false;
}
-
for (auto check : checksByArea[rcArea]) {
- if (IsVisibleInCheckTracker(check) && passesTextFilter(checkSearch, check)) {
+ if (ShouldShowCheck(check)) {
return false;
}
}
@@ -1091,8 +1092,10 @@ bool shouldHideArea(ImGuiTextFilter& checkSearch, std::mapGetArea()).c_str()) ||
checkSearch.PassFilter(Rando::StaticData::GetLocation(check)->GetShortName().c_str())
);
@@ -1241,7 +1244,7 @@ void LoadSettings() {
fishsanityAgeSplit = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_FISHSANITY_AGE_SPLIT);
}
-bool IsVisibleInCheckTracker(RandomizerCheck rc) {
+bool IsCheckShuffled(RandomizerCheckObject rcObj) {
Rando::Location* loc = Rando::StaticData::GetLocation(rc);
if (IS_RANDO && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_LOGIC_RULES) != RO_LOGIC_VANILLA) {
return
@@ -1255,7 +1258,7 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc) {
loc->GetQuest() == RCQUEST_MQ && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsMQ() ||
loc->GetQuest() == RCQUEST_VANILLA && OTRGlobals::Instance->gRandoContext->GetDungeons()->GetDungeonFromScene(loc->GetScene())->IsVanilla()
) &&
- (loc->GetRCType() != RCTYPE_SHOP || (showShops && (!hideShopRightChecks || hideShopRightChecks && loc->GetActorParams() > 0x03))) &&
+ (loc->GetRCType() != RCTYPE_SHOP || (showShops && loc->GetActorParams() > 0x03)) &&
(loc->GetRandomizerCheck() != RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS) &&
(rc != RC_TRIFORCE_COMPLETED || !hideTriforceCompleted) &&
(rc != RC_GIFT_FROM_SAGES || !IS_RANDO) &&
@@ -1304,6 +1307,10 @@ bool IsVisibleInCheckTracker(RandomizerCheck rc) {
return false;
}
+bool IsVisibleInCheckTracker(RandomizerCheckObject rcObj) {
+ return IsCheckShuffled(rcObj) || (rcObj.rcType == RCTYPE_SKULL_TOKEN && alwaysShowGS) || (rcObj.rcType == RCTYPE_SHOP && (showShops && (!hideShopRightChecks)));
+}
+
void UpdateInventoryChecks() {
//For all the areas with maps, if you have one, spoil the area
for (auto [scene, area] : DungeonRCAreasBySceneID) {
@@ -1494,6 +1501,8 @@ void DrawLocation(RandomizerCheck rc) {
//Draw the extra info
txt = "";
+ bool mystery = CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && OTRGlobals::Instance->gRandomizer->merchantPrices.contains(rcObj.rc);
+
if (checkData.hintItem != 0) {
// TODO hints
} else if (status != RCSHOW_UNCHECKED) {
@@ -1516,16 +1525,16 @@ void DrawLocation(RandomizerCheck rc) {
case RCSHOW_IDENTIFIED:
case RCSHOW_SEEN:
if (IS_RANDO) {
- if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP) {
+ if (itemLoc->GetPlacedRandomizerGet() == RG_ICE_TRAP && !mystery) {
if (status == RCSHOW_IDENTIFIED) {
txt = OTRGlobals::Instance->gRandoContext->overrides[rc].GetTrickName().GetForLanguage(gSaveContext.language);
} else {
txt = Rando::StaticData::RetrieveItem(OTRGlobals::Instance->gRandoContext->overrides[rc].LooksLike()).GetName().GetForLanguage(gSaveContext.language);
}
- } else {
+ } else if (!mystery) {
txt = itemLoc->GetPlacedItem().GetName().GetForLanguage(gSaveContext.language);
}
- if (status == RCSHOW_IDENTIFIED) {
+ if (!IsVisibleInCheckTracker(rcObj) && status == RCSHOW_IDENTIFIED && !mystery) {
txt += fmt::format(" - {}", gSaveContext.checkTrackerData[rc].price);
}
} else {
diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
index 9362bccc6..576a09cc7 100644
--- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
+++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h
@@ -47,6 +47,7 @@ void DefaultCheckData(RandomizerCheck rc);
void Teardown();
void UpdateAllOrdering();
bool IsVisibleInCheckTracker(RandomizerCheck rc);
+bool IsCheckShuffled(RandomizerCheck check);
void InitTrackerData(bool isDebug);
RandomizerCheckArea GetCheckArea();
void UpdateCheck(uint32_t, RandomizerCheckTrackerData);
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index 41878bcce..bf248d0e0 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -86,6 +86,7 @@ GameInteractorSail* GameInteractorSail::Instance;
#include "Enhancements/mods.h"
#include "Enhancements/game-interactor/GameInteractor.h"
+#include "Enhancements/randomizer/draw.h"
#include
// Resource Types/Factories
@@ -1808,7 +1809,7 @@ extern "C" void ResourceMgr_PatchGfxCopyCommandByName(const char* path, const ch
}
Gfx* destinationGfx = (Gfx*)&res->Instructions[destinationIndex];
- Gfx sourceGfx = res->Instructions[sourceIndex];
+ Gfx sourceGfx = *(Gfx*)&res->Instructions[sourceIndex];
if (!originalGfx.contains(path) || !originalGfx[path].contains(patchName)) {
originalGfx[path][patchName] = {
@@ -2444,6 +2445,14 @@ extern "C" ItemObtainability Randomizer_GetItemObtainabilityFromRandomizerCheck(
return OTRGlobals::Instance->gRandomizer->GetItemObtainabilityFromRandomizerCheck(randomizerCheck);
}
+extern "C" bool Randomizer_IsCheckShuffled(RandomizerCheck randomizerCheck) {
+ return CheckTracker::IsCheckShuffled(RandomizerCheckObjects::GetAllRCObjects().find(randomizerCheck)->second);
+}
+
+extern "C" GetItemEntry GetItemMystery() {
+ return { ITEM_NONE_FE, 0, 0, 0, 0, 0, 0, ITEM_NONE_FE, 0, false, ITEM_FROM_NPC, ITEM_CATEGORY_JUNK, NULL, MOD_RANDOMIZER, (CustomDrawFunc)Randomizer_DrawMysteryItem };
+}
+
extern "C" void Randomizer_GenerateSeed() {
std::string seed = "";
if (OTRGlobals::Instance->gRandoContext->IsSpoilerLoaded()) {
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index 2e566bbd2..3ea1b9c23 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -181,6 +181,8 @@ GetItemEntry Randomizer_GetItemFromActorWithoutObtainabilityCheck(s16 actorId, s
GetItemEntry Randomizer_GetItemFromKnownCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
GetItemEntry Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(RandomizerCheck randomizerCheck, GetItemID ogId);
RandomizerInf Randomizer_GetRandomizerInfFromCheck(RandomizerCheck randomizerCheck);
+bool Randomizer_IsCheckShuffled(RandomizerCheck check);
+GetItemEntry GetItemMystery();
ItemObtainability Randomizer_GetItemObtainabilityFromRandomizerCheck(RandomizerCheck randomizerCheck);
void Randomizer_GenerateSeed();
uint8_t Randomizer_IsSeedGenerated();
diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp
index 7ac3e1e20..a85c69a40 100644
--- a/soh/soh/SohMenuBar.cpp
+++ b/soh/soh/SohMenuBar.cpp
@@ -656,7 +656,7 @@ void DrawEnhancementsMenu() {
UIWidgets::PaddedEnhancementSliderInt("King Zora Speed: %dx", "##MWEEPSPEED", CVAR_ENHANCEMENT("MweepSpeed"), 1, 5, "", 1, true, false, true);
UIWidgets::PaddedEnhancementSliderInt("Vine/Ladder Climb speed +%d", "##CLIMBSPEED", CVAR_ENHANCEMENT("ClimbSpeed"), 0, 12, "", 0, true, false, true);
UIWidgets::PaddedEnhancementSliderInt("Block pushing speed +%d", "##BLOCKSPEED", CVAR_ENHANCEMENT("FasterBlockPush"), 0, 5, "", 0, true, false, true);
- UIWidgets::PaddedEnhancementSliderInt("Crawl speed %dx", "##CRAWLSPEED", CVAR_ENHANCEMENT("CrawlSpeed"), 1, 5, "", 1, true, false, true);
+ UIWidgets::PaddedEnhancementSliderInt("Crawl speed %dx", "##CRAWLSPEED", CVAR_ENHANCEMENT("CrawlSpeed"), 1, 4, "", 1, true, false, true);
UIWidgets::PaddedEnhancementCheckbox("Faster Heavy Block Lift", CVAR_ENHANCEMENT("FasterHeavyBlockLift"), false, false);
UIWidgets::Tooltip("Speeds up lifting silver rocks and obelisks");
UIWidgets::PaddedEnhancementCheckbox("Skip Pickup Messages", CVAR_ENHANCEMENT("FastDrops"), true, false);
@@ -1290,7 +1290,7 @@ void DrawEnhancementsMenu() {
UIWidgets::Tooltip("Prevents the Forest Stage Deku Nut upgrade from becoming unobtainable after receiving the Poacher's Saw");
UIWidgets::PaddedEnhancementCheckbox("Fix Navi text HUD position", CVAR_ENHANCEMENT("NaviTextFix"), true, false);
UIWidgets::Tooltip("Correctly centers the Navi text prompt on the HUD's C-Up button");
- UIWidgets::PaddedEnhancementCheckbox("Fix Anubis fireballs", CVAR_ENHANCEMENT("AnubixFix"), true, false);
+ UIWidgets::PaddedEnhancementCheckbox("Fix Anubis fireballs", CVAR_ENHANCEMENT("AnubisFix"), true, false);
UIWidgets::Tooltip("Make Anubis fireballs do fire damage when reflected back at them with the Mirror Shield");
if (UIWidgets::PaddedEnhancementCheckbox("Fix Megaton Hammer crouch stab", CVAR_ENHANCEMENT("CrouchStabHammerFix"), true, false)) {
if (!CVarGetInteger(CVAR_ENHANCEMENT("CrouchStabHammerFix"), 0)) {
@@ -2086,6 +2086,11 @@ void DrawRandomizerMenu() {
"Play unique fanfares when obtaining quest items "
"(medallions/stones/songs). Note that these fanfares are longer than usual."
);
+ UIWidgets::PaddedEnhancementCheckbox("Mysterious Shuffled Items", CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), true, false);
+ UIWidgets::Tooltip(
+ "Displays a \"Mystery Item\" model in place of any freestanding/GS/shop items that were shuffled, "
+ "and replaces item names for them and scrubs and merchants, regardless of hint settings, "
+ "so you never know what you're getting.");
ImGui::EndMenu();
}
diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c
index 8e30f462a..f286830e6 100644
--- a/soh/src/code/z_en_item00.c
+++ b/soh/src/code/z_en_item00.c
@@ -1361,7 +1361,23 @@ static const Vtx customDropVtx[] = {
* Draw Function used for most collectible types of En_Item00 (ammo, bombs, sticks, nuts, magic...).
*/
void EnItem00_DrawCollectible(EnItem00* this, PlayState* play) {
- if (this->actor.params == ITEM00_BOMBCHU) {
+ if (IS_RANDO && (this->getItemId != GI_NONE || this->actor.params == ITEM00_SMALL_KEY)) {
+ RandomizerCheck randoCheck =
+ Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams);
+ GetItemEntry giEntry = this->randoGiEntry;
+
+ if (randoCheck != RC_UNKNOWN_CHECK) {
+ this->randoGiEntry = Randomizer_GetItemFromKnownCheck(randoCheck, GI_NONE);
+ giEntry = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(randoCheck))
+ ? GetItemMystery() : this->randoGiEntry;
+ giEntry.getItemFrom = ITEM_FROM_FREESTANDING;
+ }
+
+ f32 mtxScale = 16.0f;
+ Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
+ EnItem00_CustomItemsParticles(&this->actor, play, giEntry);
+ GetItemEntry_Draw(play, giEntry);
+ } else if (this->actor.params == ITEM00_BOMBCHU) {
OPEN_DISPS(play->state.gfxCtx);
Matrix_ReplaceRotation(&play->billboardMtxF);
@@ -1441,7 +1457,24 @@ void EnItem00_DrawHeartContainer(EnItem00* this, PlayState* play) {
* Draw Function used for the Piece of Heart type of En_Item00.
*/
void EnItem00_DrawHeartPiece(EnItem00* this, PlayState* play) {
- s32 pad;
+ if (IS_RANDO) {
+ RandomizerCheck randoCheck =
+ Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->ogParams);
+ GetItemEntry giEntry = this->randoGiEntry;
+
+ if (randoCheck != RC_UNKNOWN_CHECK) {
+ this->randoGiEntry = Randomizer_GetItemFromKnownCheck(randoCheck, GI_NONE);
+ giEntry = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(randoCheck))
+ ? GetItemMystery() : this->randoGiEntry;
+ giEntry.getItemFrom = ITEM_FROM_FREESTANDING;
+ }
+
+ f32 mtxScale = 16.0f;
+ Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
+ EnItem00_CustomItemsParticles(&this->actor, play, giEntry);
+ GetItemEntry_Draw(play, giEntry);
+ } else {
+ s32 pad;
OPEN_DISPS(play->state.gfxCtx);
diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c
index 934b9486d..658e96394 100644
--- a/soh/src/code/z_parameter.c
+++ b/soh/src/code/z_parameter.c
@@ -1436,64 +1436,62 @@ Gfx* Gfx_TextureI8(Gfx* displayListHead, void* texture, s16 textureWidth, s16 te
return displayListHead;
}
-void Inventory_SwapAgeEquipment(void) {
+void Rando_Inventory_SwapAgeEquipment(void) {
s16 i;
u16 shieldEquipValue;
if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
-
-
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
if (i != 0) {
- gSaveContext.childEquips.buttonItems[i] = gSaveContext.equips.buttonItems[i];
+ gSaveContext.childEquips.buttonItems[i] =
+ gSaveContext.equips.buttonItems[i];
} else {
gSaveContext.childEquips.buttonItems[i] = ITEM_SWORD_KOKIRI;
}
if (i != 0) {
- gSaveContext.childEquips.cButtonSlots[i - 1] = gSaveContext.equips.cButtonSlots[i - 1];
+ gSaveContext.childEquips.cButtonSlots[i - 1] =
+ gSaveContext.equips.cButtonSlots[i - 1];
}
}
- // When becoming adult, remove swordless flag since we'll get master sword
- // (Unless Master Sword is shuffled)
- // Only in rando to keep swordless link bugs in vanilla
- if (IS_RANDO && !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) {
- Flags_UnsetInfTable(INFTABLE_SWORDLESS);
- }
-
gSaveContext.childEquips.equipment = gSaveContext.equips.equipment;
- if (gSaveContext.adultEquips.buttonItems[0] == ITEM_NONE && !(IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) && gSaveContext.adultEquips.equipment)) {
- if (!IS_RANDO || !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) {
- gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
- } else {
- gSaveContext.equips.buttonItems[0] = ITEM_NONE;
- Flags_SetInfTable(INFTABLE_SWORDLESS);
- }
+ // When becoming adult, remove swordless flag since we'll get master sword
+ // This gets set back appropriately later in the case of master sword shuffle
+ Flags_UnsetInfTable(INFTABLE_SWORDLESS);
+
+ // This section sets up the equipment on the first time going adult.
+ // On master sword shuffle the check for the B button is insufficient, and so checking the equipment is completely zero-ed is needed
+ // (Could just always use `gSaveContext.adultEquips.equipment == 0` for rando?)
+ if (gSaveContext.adultEquips.buttonItems[0] == ITEM_NONE && ((IS_RANDO && !Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD)) || (gSaveContext.adultEquips.equipment == 0))) {
+ gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
if (gSaveContext.inventory.items[SLOT_NUT] != ITEM_NONE) {
gSaveContext.equips.buttonItems[1] = ITEM_NUT;
gSaveContext.equips.cButtonSlots[0] = SLOT_NUT;
} else {
- gSaveContext.equips.buttonItems[1] = gSaveContext.equips.cButtonSlots[0] = ITEM_NONE;
+ gSaveContext.equips.buttonItems[1] = gSaveContext.equips.cButtonSlots[0] =
+ ITEM_NONE;
}
gSaveContext.equips.buttonItems[2] = ITEM_BOMB;
gSaveContext.equips.buttonItems[3] = gSaveContext.inventory.items[SLOT_OCARINA];
gSaveContext.equips.cButtonSlots[1] = SLOT_BOMB;
gSaveContext.equips.cButtonSlots[2] = SLOT_OCARINA;
-
gSaveContext.equips.equipment = (EQUIP_VALUE_SWORD_MASTER << (EQUIP_TYPE_SWORD * 4)) |
- (EQUIP_VALUE_SHIELD_HYLIAN << (EQUIP_TYPE_SHIELD * 4)) |
- (EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4)) |
- (EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4));
+ (EQUIP_VALUE_SHIELD_HYLIAN << (EQUIP_TYPE_SHIELD * 4)) |
+ (EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4)) |
+ (EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4));
+ // In Master Sword Shuffle we want to override the equip of the master sword from the vanilla code
+ // First check we have the Master sword in our inventory, and if not, then unequip
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) &&
- gSaveContext.equips.buttonItems[0] == ITEM_NONE) {
+ !CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_MASTER)) {
gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4));
+ gSaveContext.equips.buttonItems[0] = ITEM_NONE;
+ Flags_SetInfTable(INFTABLE_SWORDLESS);
}
-
// Set the dpad to nothing
gSaveContext.equips.buttonItems[4] = ITEM_NONE;
gSaveContext.equips.buttonItems[5] = ITEM_NONE;
@@ -1505,25 +1503,25 @@ void Inventory_SwapAgeEquipment(void) {
gSaveContext.equips.cButtonSlots[6] = SLOT_NONE;
} else {
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
- gSaveContext.equips.buttonItems[i] = gSaveContext.adultEquips.buttonItems[i];
+ gSaveContext.equips.buttonItems[i] =
+ gSaveContext.adultEquips.buttonItems[i];
if (i != 0) {
- gSaveContext.equips.cButtonSlots[i - 1] = gSaveContext.adultEquips.cButtonSlots[i - 1];
+ gSaveContext.equips.cButtonSlots[i - 1] =
+ gSaveContext.adultEquips.cButtonSlots[i - 1];
}
if (((gSaveContext.equips.buttonItems[i] >= ITEM_BOTTLE) &&
(gSaveContext.equips.buttonItems[i] <= ITEM_POE)) ||
((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) &&
(gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK))) {
- osSyncPrintf("Register_Item_Pt(%d)=%d\n", i, gSaveContext.equips.cButtonSlots[i - 1]);
gSaveContext.equips.buttonItems[i] =
gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[i - 1]];
}
}
- // In Rando, when switching to adult for the second+ time, if a sword was not previously
- // equiped in MS shuffle, then we need to set the swordless flag again
- if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) &&
+ // In Master Sword Shuffle we want to set the swordless flag if no item is on the B button
+ if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) &&
gSaveContext.equips.buttonItems[0] == ITEM_NONE) {
Flags_SetInfTable(INFTABLE_SWORDLESS);
}
@@ -1531,90 +1529,43 @@ void Inventory_SwapAgeEquipment(void) {
gSaveContext.equips.equipment = gSaveContext.adultEquips.equipment;
}
} 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 && 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(CVAR_GENERAL("SwitchAge"), 0) || CVarGetInteger(CVAR_GENERAL("SwitchTimeline"), 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;
- }
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
gSaveContext.adultEquips.buttonItems[i] = gSaveContext.equips.buttonItems[i];
if (i != 0) {
- gSaveContext.adultEquips.cButtonSlots[i - 1] = gSaveContext.equips.cButtonSlots[i - 1];
+ gSaveContext.adultEquips.cButtonSlots[i - 1] =
+ gSaveContext.equips.cButtonSlots[i - 1];
}
}
gSaveContext.adultEquips.equipment = gSaveContext.equips.equipment;
- // Switching age using enhancements separated out to make vanilla flow clear
- if (CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) || CVarGetInteger(CVAR_GENERAL("SwitchTimeline"), 0)) {
+
+ if (gSaveContext.childEquips.buttonItems[0] != ITEM_NONE) {
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
- gSaveContext.equips.buttonItems[i] = gSaveContext.childEquips.buttonItems[i];
+ gSaveContext.equips.buttonItems[i] =
+ gSaveContext.childEquips.buttonItems[i];
if (i != 0) {
- gSaveContext.equips.cButtonSlots[i - 1] = gSaveContext.childEquips.cButtonSlots[i - 1];
+ gSaveContext.equips.cButtonSlots[i - 1] =
+ gSaveContext.childEquips.cButtonSlots[i - 1];
}
if (((gSaveContext.equips.buttonItems[i] >= ITEM_BOTTLE) &&
(gSaveContext.equips.buttonItems[i] <= ITEM_POE)) ||
((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) &&
(gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK))) {
- osSyncPrintf("Register_Item_Pt(%d)=%d\n", i, gSaveContext.equips.cButtonSlots[i - 1]);
gSaveContext.equips.buttonItems[i] =
gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[i - 1]];
}
}
- 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 (!(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) {
- for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
- gSaveContext.equips.buttonItems[i] = gSaveContext.childEquips.buttonItems[i];
-
- if (i != 0) {
- gSaveContext.equips.cButtonSlots[i - 1] = gSaveContext.childEquips.cButtonSlots[i - 1];
- }
-
- if (((gSaveContext.equips.buttonItems[i] >= ITEM_BOTTLE) &&
- (gSaveContext.equips.buttonItems[i] <= ITEM_POE)) ||
- ((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) &&
- (gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK))) {
- osSyncPrintf("Register_Item_Pt(%d)=%d\n", i, gSaveContext.equips.cButtonSlots[i - 1]);
- gSaveContext.equips.buttonItems[i] =
- gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[i - 1]];
- }
- }
-
- // In Rando, when switching to child from a swordless adult, and child Link previously had a
- // sword equiped, then we need to unset the swordless flag to match
- if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_MASTER_SWORD) &&
- gSaveContext.equips.buttonItems[0] != ITEM_NONE) {
- Flags_UnsetInfTable(INFTABLE_SWORDLESS);
- }
-
gSaveContext.equips.equipment = gSaveContext.childEquips.equipment;
gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4));
gSaveContext.equips.equipment |= EQUIP_VALUE_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4);
- } else if (IS_RANDO && Randomizer_GetSettingValue(RSK_STARTING_AGE) == RO_AGE_ADULT) {
- /*If in rando and starting age is adult, childEquips is not initialized and buttonItems[0]
- will be ITEM_NONE. When changing age from adult -> child, reset equips to "default"
- (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 (CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_KOKIRI) == 0) {
- Flags_SetInfTable(INFTABLE_SWORDLESS);
- }
+ }
+ // In Rando we need an extra case to handle starting as adult. We can use the fact that the childEquips will be uninitialised (i.e. 0) at this point
+ else if (gSaveContext.childEquips.equipment == 0) {
//zero out items
for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
@@ -1629,20 +1580,147 @@ void Inventory_SwapAgeEquipment(void) {
(EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4));
}
- if ((CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) || CVarGetInteger(CVAR_GENERAL("SwitchTimeline"), 0)) &&
- (gSaveContext.equips.buttonItems[0] == ITEM_NONE)) {
+ // When becoming child in rando, set swordless flag and clear B button if player doesn't have kokiri sword
+ // Otherwise, equip sword and unset flag
+ if (!CHECK_OWNED_EQUIP(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_KOKIRI)) {
+ gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4));
+ gSaveContext.equips.buttonItems[0] = ITEM_NONE;
Flags_SetInfTable(INFTABLE_SWORDLESS);
- if (gSaveContext.childEquips.equipment == 0) {
- // force equip kokiri tunic and boots in scenario gSaveContext.childEquips.equipment is uninitialized
- gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4));
- gSaveContext.equips.equipment |= (EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4)) |
- (EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4));
- }
+ } else {
+ gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4));
+ gSaveContext.equips.equipment |= (EQUIP_VALUE_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4));
+ gSaveContext.equips.buttonItems[0] = ITEM_SWORD_KOKIRI;
+ Flags_UnsetInfTable(INFTABLE_SWORDLESS);
}
}
- CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 0);
+
shieldEquipValue = gEquipMasks[EQUIP_TYPE_SHIELD] & gSaveContext.equips.equipment;
- if (shieldEquipValue != 0) {
+ if (shieldEquipValue) {
+ shieldEquipValue >>= gEquipShifts[EQUIP_TYPE_SHIELD];
+ if (!CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, shieldEquipValue - 1)) {
+ gSaveContext.equips.equipment &= gEquipNegMasks[EQUIP_TYPE_SHIELD];
+ }
+ }
+}
+
+void Inventory_SwapAgeEquipment(void) {
+ s16 i;
+ u16 shieldEquipValue;
+
+ // Mod Enhancments can utilise the rando flow path
+ if (IS_RANDO || CVarGetInteger(CVAR_GENERAL("SwitchAge"), 0) || CVarGetInteger(CVAR_GENERAL("SwitchTimeline"), 0)) {
+ Rando_Inventory_SwapAgeEquipment();
+ CVarSetInteger(CVAR_GENERAL("SwitchTimeline"), 0);
+ return;
+ }
+
+ if (LINK_AGE_IN_YEARS == YEARS_CHILD) {
+ for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
+ if (i != 0) {
+ gSaveContext.childEquips.buttonItems[i] =
+ gSaveContext.equips.buttonItems[i];
+ } else {
+ gSaveContext.childEquips.buttonItems[i] = ITEM_SWORD_KOKIRI;
+ }
+
+ if (i != 0) {
+ gSaveContext.childEquips.cButtonSlots[i - 1] =
+ gSaveContext.equips.cButtonSlots[i - 1];
+ }
+ }
+
+ gSaveContext.childEquips.equipment = gSaveContext.equips.equipment;
+
+ if (gSaveContext.adultEquips.buttonItems[0] == ITEM_NONE) {
+ gSaveContext.equips.buttonItems[0] = ITEM_SWORD_MASTER;
+
+ if (gSaveContext.inventory.items[SLOT_NUT] != ITEM_NONE) {
+ gSaveContext.equips.buttonItems[1] = ITEM_NUT;
+ gSaveContext.equips.cButtonSlots[0] = SLOT_NUT;
+ } else {
+ gSaveContext.equips.buttonItems[1] = gSaveContext.equips.cButtonSlots[0] =
+ ITEM_NONE;
+ }
+
+ gSaveContext.equips.buttonItems[2] = ITEM_BOMB;
+ gSaveContext.equips.buttonItems[3] = gSaveContext.inventory.items[SLOT_OCARINA];
+ gSaveContext.equips.cButtonSlots[1] = SLOT_BOMB;
+ gSaveContext.equips.cButtonSlots[2] = SLOT_OCARINA;
+ gSaveContext.equips.equipment = (EQUIP_VALUE_SWORD_MASTER << (EQUIP_TYPE_SWORD * 4)) |
+ (EQUIP_VALUE_SHIELD_HYLIAN << (EQUIP_TYPE_SHIELD * 4)) |
+ (EQUIP_VALUE_TUNIC_KOKIRI << (EQUIP_TYPE_TUNIC * 4)) |
+ (EQUIP_VALUE_BOOTS_KOKIRI << (EQUIP_TYPE_BOOTS * 4));
+ // Set the dpad to nothing
+ gSaveContext.equips.buttonItems[4] = ITEM_NONE;
+ gSaveContext.equips.buttonItems[5] = ITEM_NONE;
+ gSaveContext.equips.buttonItems[6] = ITEM_NONE;
+ gSaveContext.equips.buttonItems[7] = ITEM_NONE;
+ gSaveContext.equips.cButtonSlots[3] = SLOT_NONE;
+ gSaveContext.equips.cButtonSlots[4] = SLOT_NONE;
+ gSaveContext.equips.cButtonSlots[5] = SLOT_NONE;
+ gSaveContext.equips.cButtonSlots[6] = SLOT_NONE;
+ } else {
+ for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
+ gSaveContext.equips.buttonItems[i] =
+ gSaveContext.adultEquips.buttonItems[i];
+
+ if (i != 0) {
+ gSaveContext.equips.cButtonSlots[i - 1] =
+ gSaveContext.adultEquips.cButtonSlots[i - 1];
+ }
+
+ if (((gSaveContext.equips.buttonItems[i] >= ITEM_BOTTLE) &&
+ (gSaveContext.equips.buttonItems[i] <= ITEM_POE)) ||
+ ((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) &&
+ (gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK))) {
+ osSyncPrintf("Register_Item_Pt(%d)=%d\n", i, gSaveContext.equips.cButtonSlots[i - 1]);
+ gSaveContext.equips.buttonItems[i] =
+ gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[i - 1]];
+ }
+ }
+
+ gSaveContext.equips.equipment = gSaveContext.adultEquips.equipment;
+ }
+ } else {
+ for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
+ gSaveContext.adultEquips.buttonItems[i] = gSaveContext.equips.buttonItems[i];
+
+ if (i != 0) {
+ gSaveContext.adultEquips.cButtonSlots[i - 1] =
+ gSaveContext.equips.cButtonSlots[i - 1];
+ }
+ }
+
+ gSaveContext.adultEquips.equipment = gSaveContext.equips.equipment;
+
+ if (gSaveContext.childEquips.buttonItems[0] != ITEM_NONE) {
+ for (i = 0; i < ARRAY_COUNT(gSaveContext.equips.buttonItems); i++) {
+ gSaveContext.equips.buttonItems[i] =
+ gSaveContext.childEquips.buttonItems[i];
+
+ if (i != 0) {
+ gSaveContext.equips.cButtonSlots[i - 1] =
+ gSaveContext.childEquips.cButtonSlots[i - 1];
+ }
+
+ if (((gSaveContext.equips.buttonItems[i] >= ITEM_BOTTLE) &&
+ (gSaveContext.equips.buttonItems[i] <= ITEM_POE)) ||
+ ((gSaveContext.equips.buttonItems[i] >= ITEM_WEIRD_EGG) &&
+ (gSaveContext.equips.buttonItems[i] <= ITEM_CLAIM_CHECK))) {
+ osSyncPrintf("Register_Item_Pt(%d)=%d\n", i, gSaveContext.equips.cButtonSlots[i - 1]);
+ gSaveContext.equips.buttonItems[i] =
+ gSaveContext.inventory.items[gSaveContext.equips.cButtonSlots[i - 1]];
+ }
+ }
+
+ gSaveContext.equips.equipment = gSaveContext.childEquips.equipment;
+ gSaveContext.equips.equipment &= (u16) ~(0xF << (EQUIP_TYPE_SWORD * 4));
+ gSaveContext.equips.equipment |= EQUIP_VALUE_SWORD_KOKIRI << (EQUIP_TYPE_SWORD * 4);
+ }
+ }
+
+ shieldEquipValue = gEquipMasks[EQUIP_TYPE_SHIELD] & gSaveContext.equips.equipment;
+ if (shieldEquipValue) {
shieldEquipValue >>= gEquipShifts[EQUIP_TYPE_SHIELD];
if (!CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SHIELD, shieldEquipValue - 1)) {
gSaveContext.equips.equipment &= gEquipNegMasks[EQUIP_TYPE_SHIELD];
diff --git a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
index 4af2e9f87..2e06e8975 100644
--- a/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
+++ b/soh/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c
@@ -2089,6 +2089,8 @@ void DemoEffect_DrawGetItem(Actor* thisx, PlayState* play) {
}
if (IS_RANDO && (play->sceneNum != SCENE_TEMPLE_OF_TIME || this->actor.params == DEMO_EFFECT_LIGHTARROW)) {
GetItemEntry getItemEntry = GET_ITEM_NONE;
+ if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(RC_BARINADE))
+ getItemEntry = GetItemMystery();
switch (this->actor.params) {
case DEMO_EFFECT_JEWEL_KOKIRI:
diff --git a/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c b/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c
index 0b1a2b0b7..a26f5a08b 100644
--- a/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c
+++ b/soh/src/overlays/actors/ovl_En_Anubice_Fire/z_en_anubice_fire.c
@@ -116,7 +116,7 @@ void func_809B27D8(EnAnubiceFire* this, PlayState* play) {
Audio_PlayActorSound2(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW);
this->cylinder.base.atFlags &= 0xFFE9;
this->cylinder.base.atFlags |= 8;
- this->cylinder.info.toucher.dmgFlags = CVarGetInteger(CVAR_ENHANCEMENT("AnubixFix"), 0) ? 0x800 : 2;
+ this->cylinder.info.toucher.dmgFlags = CVarGetInteger(CVAR_ENHANCEMENT("AnubisFix"), 0) ? 0x800 : 2;
this->unk_15A = 30;
this->actor.params = 1;
this->actor.velocity.x *= -1.0f;
diff --git a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
index 8b3195d72..26116664a 100644
--- a/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
+++ b/soh/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
@@ -487,12 +487,46 @@ void EnExItem_DrawItems(EnExItem* this, PlayState* play) {
}
if (this) {}
func_8002ED80(&this->actor, play, 0);
+ if (IS_RANDO) {
+ GetItemEntry randoGetItem = (GetItemEntry)GET_ITEM_NONE;
+ switch (this->type) {
+ case EXITEM_BOMB_BAG_BOWLING:
+ case EXITEM_BOMB_BAG_COUNTER:
+ randoGetItem = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE))
+ ? GetItemMystery()
+ : Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_FIRST_PRIZE, GI_BOMB_BAG_20);
+ break;
+ case EXITEM_BOMBCHUS_BOWLING:
+ case EXITEM_BOMBCHUS_COUNTER:
+ randoGetItem = Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_BOMBCHUS, GI_BOMBCHUS_10);
+ break;
+ case EXITEM_BULLET_BAG:
+ randoGetItem = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(RC_LW_TARGET_IN_WOODS))
+ ? GetItemMystery() : Randomizer_GetItemFromKnownCheck(RC_LW_TARGET_IN_WOODS, GI_BULLET_BAG_50);
+ break;
+ }
+
+ if (randoGetItem.getItemId != GI_NONE) {
+ EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem);
+ GetItemEntry_Draw(play, randoGetItem);
+ return;
+ }
+ }
+
GetItem_Draw(play, this->giDrawId);
}
void EnExItem_DrawHeartPiece(EnExItem* this, PlayState* play) {
func_8002ED80(&this->actor, play, 0);
- GetItem_Draw(play, GID_HEART_PIECE);
+
+ if (IS_RANDO) {
+ GetItemEntry randoGetItem = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE))
+ ? GetItemMystery() : Randomizer_GetItemFromKnownCheck(RC_MARKET_BOMBCHU_BOWLING_SECOND_PRIZE, GI_HEART_PIECE);
+ EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem);
+ GetItemEntry_Draw(play, randoGetItem);
+ } else {
+ GetItem_Draw(play, GID_HEART_PIECE);
+ }
}
void EnExItem_DrawMagic(EnExItem* this, PlayState* play, s16 magicIndex) {
diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c
index 11c29227f..0382735a3 100644
--- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c
+++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c
@@ -1286,8 +1286,8 @@ void EnGirlA_InitializeItemAction(EnGirlA* this, PlayState* play) {
this->basePrice = shopItemIdentity.itemPrice;
this->giDrawId = getItemEntry.gid;
- // Correct the rotation for spiritual stones
- if (getItemEntry.getItemId >= RG_KOKIRI_EMERALD && getItemEntry.getItemId <= RG_ZORA_SAPPHIRE) {
+ // Correct the rotation for spiritual stones, but only if mysterious shuffle isn't on, else it's obvious what's there in shops
+ if (!CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && (getItemEntry.getItemId >= RG_KOKIRI_EMERALD && getItemEntry.getItemId <= RG_ZORA_SAPPHIRE)) {
this->actor.shape.rot.y = this->actor.shape.rot.y + 20000;
}
}
@@ -1332,7 +1332,8 @@ void EnGirlA_Draw(Actor* thisx, PlayState* play) {
if (this->actor.params == SI_RANDOMIZED_ITEM) {
ShopItemIdentity shopItemIdentity = Randomizer_IdentifyShopItem(play->sceneNum, this->randoSlotIndex);
- GetItemEntry getItemEntry = Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId);
+ GetItemEntry getItemEntry = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && this->actor.params == SI_RANDOMIZED_ITEM) ? GetItemMystery() :
+ Randomizer_GetItemFromKnownCheckWithoutObtainabilityCheck(shopItemIdentity.randomizerCheck, shopItemIdentity.ogItemId);
EnItem00_CustomItemsParticles(&this->actor, play, getItemEntry);
GetItemEntry_Draw(play, getItemEntry);
diff --git a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c
index 170eed16e..bf0e4951d 100644
--- a/soh/src/overlays/actors/ovl_En_Si/z_en_si.c
+++ b/soh/src/overlays/actors/ovl_En_Si/z_en_si.c
@@ -155,6 +155,50 @@ void EnSi_Draw(Actor* thisx, PlayState* play) {
if (this->actionFunc != func_80AFB950) {
func_8002ED80(&this->actor, play, 0);
func_8002EBCC(&this->actor, play, 0);
- GetItem_Draw(play, GID_SKULL_TOKEN_2);
+ if (!IS_RANDO) {
+ GetItem_Draw(play, GID_SKULL_TOKEN_2);
+ } else {
+ RandomizerCheck check = Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->actor.params);
+ getItem = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(check)) ? GetItemMystery() : Randomizer_GetItemFromKnownCheck(check, GI_SKULL_TOKEN);
+ EnItem00_CustomItemsParticles(&this->actor, play, getItem);
+ if (getItem.itemId != ITEM_SKULL_TOKEN) {
+ f32 mtxScale = 1.5f;
+ Matrix_Scale(mtxScale, mtxScale, mtxScale, MTXMODE_APPLY);
+ }
+ GetItemEntry_Draw(play, getItem);
+ }
+ }
+}
+
+void EnSi_Reset() {
+ textId = 0xB4;
+ giveItemId = ITEM_SKULL_TOKEN;
+}
+
+void Randomizer_UpdateSkullReward(EnSi* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ getItem = Randomizer_GetItemFromActor(this->actor.id, play->sceneNum, this->actor.params, GI_SKULL_TOKEN);
+ getItemId = getItem.getItemId;
+ if (getItemId == RG_ICE_TRAP) {
+ textId = 0xF8;
+ } else {
+ textId = getItem.textId;
+ giveItemId = getItem.itemId;
+ }
+ player->getItemEntry = getItem;
+}
+
+void Randomizer_GiveSkullReward(EnSi* this, PlayState* play) {
+ Player* player = GET_PLAYER(play);
+
+ if (getItem.modIndex == MOD_NONE) {
+ // RANDOTOD: Move this into Item_Give() or some other more central location
+ if (getItem.getItemId == GI_SWORD_BGS) {
+ gSaveContext.bgsFlag = true;
+ }
+ Item_Give(play, giveItemId);
+ } else if (getItem.modIndex == MOD_RANDOMIZER) {
+ Randomizer_Item_Give(play, getItem);
}
}
diff --git a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c
index 5015a3908..02656e119 100644
--- a/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c
+++ b/soh/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c
@@ -93,18 +93,23 @@ void ItemBHeart_Draw(Actor* thisx, PlayState* play) {
actorIt = actorIt->next;
}
- if (flag) {
- Gfx_SetupDL_25Xlu(play->state.gfxCtx);
- gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
- G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL);
- gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL);
+ if (IS_RANDO) {
+ RandomizerCheck check = Randomizer_GetCheckFromActor(this->actor.id, play->sceneNum, this->actor.params);
+ GetItemEntry_Draw(play, (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(check)) ? GetItemMystery() : Randomizer_GetItemFromKnownCheck(check, GI_HEART_CONTAINER_2));
} else {
- Gfx_SetupDL_25Opa(play->state.gfxCtx);
- gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
- G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
- gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL);
- gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL);
+ if (flag) {
+ Gfx_SetupDL_25Xlu(play->state.gfxCtx);
+ gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_XLU_DISP++, gGiHeartBorderDL);
+ gSPDisplayList(POLY_XLU_DISP++, gGiHeartContainerDL);
+ } else {
+ Gfx_SetupDL_25Opa(play->state.gfxCtx);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(play->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPDisplayList(POLY_OPA_DISP++, gGiHeartBorderDL);
+ gSPDisplayList(POLY_OPA_DISP++, gGiHeartContainerDL);
+ }
}
CLOSE_DISPS(play->state.gfxCtx);
diff --git a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c
index 796b157a3..d27893c3a 100644
--- a/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c
+++ b/soh/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c
@@ -206,12 +206,42 @@ void ItemEtcetera_DrawThroughLens(Actor* thisx, PlayState* play) {
if (play->actorCtx.lensActive) {
func_8002EBCC(&this->actor, play, 0);
func_8002ED80(&this->actor, play, 0);
+
+ if(IS_RANDO && play->sceneNum == SCENE_TREASURE_BOX_SHOP) {
+ RandomizerCheck check = RC_MAX;
+ GetItemEntry randoGetItem = GetChestGameRandoGetItem(this->actor.room, this->giDrawId, play); //TODO Rando: add mysterious shuffle when chest minigame keys get shuffled
+ EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem);
+ if (randoGetItem.itemId != ITEM_NONE) {
+ GetItemEntry_Draw(play, randoGetItem);
+ return;
+ }
+ }
+
GetItem_Draw(play, this->giDrawId);
}
}
void ItemEtcetera_Draw(Actor* thisx, PlayState* play) {
ItemEtcetera* this = (ItemEtcetera*)thisx;
+ s32 type = this->actor.params & 0xFF;
+
+ if (IS_RANDO) {
+ GetItemEntry randoGetItem = (GetItemEntry)GET_ITEM_NONE;
+ if (type == ITEM_ETC_ARROW_FIRE) {
+ randoGetItem = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(RC_LH_SUN)) ? GetItemMystery() : Randomizer_GetItemFromKnownCheck(RC_LH_SUN, GI_ARROW_FIRE);
+ } else if (type == ITEM_ETC_LETTER) {
+ randoGetItem = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(RC_LH_UNDERWATER_ITEM)) ? GetItemMystery() : Randomizer_GetItemFromKnownCheck(RC_LH_UNDERWATER_ITEM, GI_LETTER_RUTO);
+ }
+
+ EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem);
+
+ if (randoGetItem.itemId != ITEM_NONE) {
+ func_8002EBCC(&this->actor, play, 0);
+ func_8002ED80(&this->actor, play, 0);
+ GetItemEntry_Draw(play, randoGetItem);
+ return;
+ }
+ }
func_8002EBCC(&this->actor, play, 0);
func_8002ED80(&this->actor, play, 0);
diff --git a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c
index 358a2efe7..cf83b730a 100644
--- a/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c
+++ b/soh/src/overlays/actors/ovl_Item_Ocarina/z_item_ocarina.c
@@ -212,7 +212,7 @@ void ItemOcarina_Draw(Actor* thisx, PlayState* play) {
func_8002ED80(thisx, play, 0);
if (IS_RANDO) {
- GetItemEntry randoGetItem = Randomizer_GetItemFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT);
+ GetItemEntry randoGetItem = (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0) && Randomizer_IsCheckShuffled(RC_HF_OCARINA_OF_TIME_ITEM)) ? GetItemMystery() : Randomizer_GetItemFromKnownCheck(RC_HF_OCARINA_OF_TIME_ITEM, GI_OCARINA_OOT);
EnItem00_CustomItemsParticles(&this->actor, play, randoGetItem);
GetItemEntry_Draw(play, randoGetItem);
return;