55#include " soh/Notification/Notification.h"
66#include " soh/OTRGlobals.h"
77#include " soh/SohGui/ImGuiUtils.h"
8+ #include " soh/SaveManager.h"
89
910extern " C" {
1011#include " variables.h"
@@ -13,6 +14,7 @@ extern "C" {
1314extern PlayState* gPlayState ;
1415GetItemEntry ItemTable_RetrieveEntry (s16 modIndex, s16 getItemID);
1516GetItemID RetrieveGetItemIDFromItemID (ItemID itemID);
17+ RandomizerGet RetrieveRandomizerGetFromItemID (ItemID itemID);
1618}
1719
1820#define CVAR_EXTRA_TRAPS_NAME CVAR_ENHANCEMENT (" ExtraTraps.Enabled" )
@@ -31,20 +33,48 @@ typedef enum {
3133 ADD_KILL_TRAP ,
3234 ADD_TELEPORT_TRAP ,
3335 ADD_POCKET_TRAP ,
36+ ADD_PERMADEATH_TRAP ,
3437 ADD_TRAP_MAX
3538} AltTrapType;
3639
3740static AltTrapType roll = ADD_TRAP_MAX ;
3841static int statusTimer = -1 ;
3942static int eventTimer = -1 ;
43+ static int permaDeathTimer = -1 ;
44+ bool shouldFileDelete = false ;
4045
4146const char * altTrapTypeCvars[] = {
4247 CVAR_ENHANCEMENT (" ExtraTraps.Ice" ), CVAR_ENHANCEMENT (" ExtraTraps.Burn" ),
4348 CVAR_ENHANCEMENT (" ExtraTraps.Shock" ), CVAR_ENHANCEMENT (" ExtraTraps.Knockback" ),
4449 CVAR_ENHANCEMENT (" ExtraTraps.Speed" ), CVAR_ENHANCEMENT (" ExtraTraps.Bomb" ),
4550 CVAR_ENHANCEMENT (" ExtraTraps.Void" ), CVAR_ENHANCEMENT (" ExtraTraps.Ammo" ),
4651 CVAR_ENHANCEMENT (" ExtraTraps.Kill" ), CVAR_ENHANCEMENT (" ExtraTraps.Teleport" ),
47- CVAR_ENHANCEMENT (" ExtraTraps.Pocket" ),
52+ CVAR_ENHANCEMENT (" ExtraTraps.Pocket" ), CVAR_ENHANCEMENT (" ExtraTraps.Permadeath" ),
53+ };
54+
55+ static std::unordered_map<ItemID, QuestItem> itemToQuestMap = {
56+ { ITEM_MEDALLION_FOREST , QUEST_MEDALLION_FOREST },
57+ { ITEM_MEDALLION_FIRE , QUEST_MEDALLION_FIRE },
58+ { ITEM_MEDALLION_WATER , QUEST_MEDALLION_WATER },
59+ { ITEM_MEDALLION_SPIRIT , QUEST_MEDALLION_SPIRIT },
60+ { ITEM_MEDALLION_SHADOW , QUEST_MEDALLION_SHADOW },
61+ { ITEM_MEDALLION_LIGHT , QUEST_MEDALLION_LIGHT },
62+ { ITEM_SONG_MINUET , QUEST_SONG_MINUET },
63+ { ITEM_SONG_BOLERO , QUEST_SONG_BOLERO },
64+ { ITEM_SONG_SERENADE , QUEST_SONG_SERENADE },
65+ { ITEM_SONG_REQUIEM , QUEST_SONG_REQUIEM },
66+ { ITEM_SONG_NOCTURNE , QUEST_SONG_NOCTURNE },
67+ { ITEM_SONG_PRELUDE , QUEST_SONG_PRELUDE },
68+ { ITEM_SONG_LULLABY , QUEST_SONG_LULLABY },
69+ { ITEM_SONG_EPONA , QUEST_SONG_EPONA },
70+ { ITEM_SONG_SARIA , QUEST_SONG_SARIA },
71+ { ITEM_SONG_SUN , QUEST_SONG_SUN },
72+ { ITEM_SONG_TIME , QUEST_SONG_TIME },
73+ { ITEM_SONG_STORMS , QUEST_SONG_STORMS },
74+ { ITEM_KOKIRI_EMERALD , QUEST_KOKIRI_EMERALD },
75+ { ITEM_GORON_RUBY , QUEST_GORON_RUBY },
76+ { ITEM_ZORA_SAPPHIRE , QUEST_ZORA_SAPPHIRE },
77+ { ITEM_GERUDO_CARD , QUEST_GERUDO_CARD },
4878};
4979
5080std::vector<AltTrapType> getEnabledAddTraps () {
@@ -104,6 +134,16 @@ void ExecutePocketTrap() {
104134 for (auto & items : itemMapping) {
105135 if (INV_CONTENT (items.second .id ) == items.second .id ) {
106136 currentLoadout.push_back (items.second .id );
137+ continue ;
138+ }
139+ auto questItem = itemToQuestMap.find (
140+ (ItemID)items.second .id ); // std::find(itemToQuestMap.begin(), itemToQuestMap.end(), items.second.id);
141+ if (questItem == itemToQuestMap.end ()) {
142+ continue ;
143+ }
144+ if (CHECK_QUEST_ITEM (questItem->second )) {
145+ currentLoadout.push_back (items.second .id );
146+ continue ;
107147 }
108148 }
109149
@@ -112,18 +152,23 @@ void ExecutePocketTrap() {
112152 return ;
113153 }
114154
115- uint32_t roll = Random (0 , currentLoadout.size () - 1 );
116- GetItemID getItemId = RetrieveGetItemIDFromItemID ((ItemID)currentLoadout[roll]);
117155 RandomizerGet rgItem = RG_NONE ;
118156
119- for (auto & randoGet : Rando::StaticData::GetItemTable ()) {
120- if (randoGet.GetItemID () == getItemId) {
121- rgItem = randoGet.GetRandomizerGet ();
122- break ;
157+ uint32_t roll = Random (0 , currentLoadout.size () - 1 );
158+ if (currentLoadout[roll] >= ITEM_SONG_MINUET ) {
159+ rgItem = RetrieveRandomizerGetFromItemID ((ItemID)currentLoadout[roll]);
160+ } else {
161+ GetItemID getItemId = RetrieveGetItemIDFromItemID ((ItemID)currentLoadout[roll]);
162+ for (auto & randoGet : Rando::StaticData::GetItemTable ()) {
163+ if (randoGet.GetItemID () == getItemId) {
164+ rgItem = randoGet.GetRandomizerGet ();
165+ break ;
166+ }
123167 }
124168 }
125169
126170 if (rgItem == RG_NONE ) {
171+ GameInteractor::RawAction::FreezePlayer ();
127172 return ;
128173 }
129174
@@ -191,7 +236,7 @@ static void RollRandomTrap(uint32_t seed) {
191236 uint32_t finalSeed = seed + (IS_RANDO ? Rando::Context::GetInstance ()->GetSeed ()
192237 : static_cast <uint32_t >(gSaveContext .ship .stats .fileCreatedAt ));
193238 Random_Init (finalSeed);
194- // roll = ADD_POCKET_TRAP ;
239+ // roll = ADD_PERMADEATH_TRAP ;
195240 roll = RandomElement (getEnabledAddTraps ());
196241 switch (roll) {
197242 case ADD_ICE_TRAP :
@@ -234,6 +279,15 @@ static void RollRandomTrap(uint32_t seed) {
234279 case ADD_POCKET_TRAP :
235280 ExecutePocketTrap ();
236281 break ;
282+ case ADD_PERMADEATH_TRAP :
283+ permaDeathTimer = 180 ;
284+ shouldFileDelete = true ;
285+ Notification::Emit ({ .itemIcon = (const char *)gItemIcons [ITEM_BOMB ],
286+ .message = " Collect a Check or Perma Death executes in " ,
287+ .messageColor = UIWidgets::ColorValues.at (UIWidgets::Colors::White),
288+ .suffix = " 60 seconds." ,
289+ .suffixColor = UIWidgets::ColorValues.at (UIWidgets::Colors::Red) });
290+ break ;
237291 default :
238292 break ;
239293 }
@@ -298,6 +352,17 @@ static void OnPlayerUpdate() {
298352 break ;
299353 }
300354 }
355+ if (permaDeathTimer == 0 ) {
356+ if (shouldFileDelete) {
357+ SaveManager::Instance->DeleteZeldaFile (gSaveContext .fileNum );
358+ std::reinterpret_pointer_cast<Ship::ConsoleWindow>(
359+ Ship::Context::GetInstance ()->GetWindow ()->GetGui ()->GetGuiWindow (" Console" ))
360+ ->Dispatch (" reset" );
361+ }
362+ }
363+ if (permaDeathTimer >= 0 ) {
364+ permaDeathTimer--;
365+ }
301366 if (statusTimer >= 0 ) {
302367 statusTimer--;
303368 }
@@ -326,6 +391,20 @@ void RegisterExtraTraps() {
326391 GameInteractor::RawAction::FreezePlayer ();
327392 }
328393 });
394+
395+ COND_HOOK (OnFlagSet, CVAR_EXTRA_TRAPS_NAME , [](int16_t flagType, int16_t flag) {
396+ SPDLOG_INFO (" Flag Set Here {}" , std::to_string (flagType).c_str ());
397+ if (flagType != FLAG_SCENE_CLEAR ) {
398+ shouldFileDelete = false ;
399+ }
400+ });
401+
402+ COND_HOOK (OnSceneFlagSet, CVAR_EXTRA_TRAPS_NAME , [](int16_t sceneNum, int16_t flagType, int16_t flag) {
403+ SPDLOG_INFO (" Scene Flag Set Here {}" , std::to_string (flagType).c_str ());
404+ if (flagType != FLAG_SCENE_CLEAR ) {
405+ shouldFileDelete = false ;
406+ }
407+ });
329408}
330409
331410static RegisterShipInitFunc initFunc (RegisterExtraTraps, { CVAR_EXTRA_TRAPS_NAME });
0 commit comments