summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalkierian <malkierian@gmail.com>2023-04-02 01:47:23 -0700
committerGitHub <noreply@github.com>2023-04-02 04:47:23 -0400
commit04d0cd8532c70143511fd09cfca8a1091cc31d4b (patch)
tree4790ed624be8f361676e75ca4ae2c6f78e8a441a
parentb099b5649beb13ec9cce1ce4f9e2de94c518e964 (diff)
Adds `OnTransitionEnd` hook to `GameInteractor`, called at the end of a transition after all mid-transition setup is called. (#2635)
Transitions final autosave location to `OnTransitionEnd`. Adds functionality to autosave to set a delayed save flag if AutoSave is set to Major or All Items and one is obtained in a grotto, to avoid grotto autosaving but still provide for the autosave when location-based saving is off. Fixes small bug with item lookup where sometimes an item's `modIndex` would sometimes be reported one way, but the way Randomizer does things it would be in a the other `modIndex`, and the lookup would fail. Minor variable name clarification in ItemTableManager. Modifies AutoSave to account for item ID overlap from `MOD_RANDOMIZER` table (all items in the randomizer table is considered major for AutoSave purposes except ice traps).
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor.h1
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp4
-rw-r--r--soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h1
-rw-r--r--soh/soh/Enhancements/item-tables/ItemTableManager.cpp4
-rw-r--r--soh/soh/Enhancements/item-tables/ItemTableManager.h2
-rw-r--r--soh/soh/Enhancements/mods.cpp124
-rw-r--r--soh/soh/OTRGlobals.cpp132
-rw-r--r--soh/soh/OTRGlobals.h2
-rw-r--r--soh/src/code/z_parameter.c26
-rw-r--r--soh/src/code/z_play.c11
10 files changed, 237 insertions, 70 deletions
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h
index 1489c1d8f..f0ab0363b 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h
@@ -146,6 +146,7 @@ public:
DEFINE_HOOK(OnGameFrameUpdate, void());
DEFINE_HOOK(OnItemReceive, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry));
+ DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum));
DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum));
DEFINE_HOOK(OnPlayerUpdate, void());
DEFINE_HOOK(OnActorUpdate, void(void* actor));
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
index 09153f5ed..7bc85e017 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
@@ -22,6 +22,10 @@ void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaleEnd>(itemEntry);
}
+void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum) {
+ GameInteractor::Instance->ExecuteHooks<GameInteractor::OnTransitionEnd>(sceneNum);
+}
+
void GameInteractor_ExecuteOnSceneInitHooks(int16_t sceneNum) {
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneInit>(sceneNum);
}
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
index 6449c3613..6c0a003b1 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
@@ -6,6 +6,7 @@ extern "C" void GameInteractor_ExecuteOnExitGame(int32_t fileNum);
extern "C" void GameInteractor_ExecuteOnGameFrameUpdate();
extern "C" void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
extern "C" void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry);
+extern "C" void GameInteractor_ExecuteOnTransitionEndHooks(int16_t sceneNum);
extern "C" void GameInteractor_ExecuteOnSceneInit(int16_t sceneNum);
extern "C" void GameInteractor_ExecuteOnPlayerUpdate();
extern "C" void GameInteractor_ExecuteOnActorUpdate(void* actor);
diff --git a/soh/soh/Enhancements/item-tables/ItemTableManager.cpp b/soh/soh/Enhancements/item-tables/ItemTableManager.cpp
index 69ac56553..a98a6bddc 100644
--- a/soh/soh/Enhancements/item-tables/ItemTableManager.cpp
+++ b/soh/soh/Enhancements/item-tables/ItemTableManager.cpp
@@ -20,10 +20,10 @@ bool ItemTableManager::AddItemEntry(uint16_t tableID, uint16_t getItemID, GetIte
} catch (const std::out_of_range& oor) { return false; }
}
-GetItemEntry ItemTableManager::RetrieveItemEntry(uint16_t tableID, uint16_t itemID) {
+GetItemEntry ItemTableManager::RetrieveItemEntry(uint16_t tableID, uint16_t getItemID) {
try {
ItemTable* itemTable = RetrieveItemTable(tableID);
- GetItemEntry getItemEntry = itemTable->at(itemID);
+ GetItemEntry getItemEntry = itemTable->at(getItemID);
getItemEntry.drawItemId = getItemEntry.itemId;
getItemEntry.drawModIndex = getItemEntry.modIndex;
return getItemEntry;
diff --git a/soh/soh/Enhancements/item-tables/ItemTableManager.h b/soh/soh/Enhancements/item-tables/ItemTableManager.h
index 622782265..e20632f38 100644
--- a/soh/soh/Enhancements/item-tables/ItemTableManager.h
+++ b/soh/soh/Enhancements/item-tables/ItemTableManager.h
@@ -13,7 +13,7 @@ class ItemTableManager {
~ItemTableManager();
bool AddItemTable(uint16_t tableID);
bool AddItemEntry(uint16_t tableID, uint16_t getItemID, GetItemEntry getItemEntry);
- GetItemEntry RetrieveItemEntry(uint16_t tableID, uint16_t itemID);
+ GetItemEntry RetrieveItemEntry(uint16_t tableID, uint16_t getItemID);
bool ClearItemTable(uint16_t tableID);
private:
diff --git a/soh/soh/Enhancements/mods.cpp b/soh/soh/Enhancements/mods.cpp
index 917c6b495..6dc595f00 100644
--- a/soh/soh/Enhancements/mods.cpp
+++ b/soh/soh/Enhancements/mods.cpp
@@ -11,6 +11,8 @@ extern "C" {
extern SaveContext gSaveContext;
extern PlayState* gPlayState;
}
+bool performDelayedSave = false;
+bool performSave = false;
void RegisterInfiniteMoney() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
@@ -177,60 +179,81 @@ void AutoSave(GetItemEntry itemEntry) {
// Don't autosave during the Ganon fight when picking up the Master Sword
// Don't autosave in grottos since resuming from grottos breaks the game.
if ((CVarGetInteger("gAutosave", 0) > 0) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) &&
- (gPlayState->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (gPlayState->sceneNum != SCENE_KAKUSIANA) &&
- (gPlayState->sceneNum != SCENE_KENJYANOMA) && (gPlayState->sceneNum != SCENE_GANON_DEMO) &&
- (gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0)) {
- if ((CVarGetInteger("gAutosave", 0) == 2) || (CVarGetInteger("gAutosave", 0) == 5) && (item != ITEM_NONE)) {
+ (gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0) && (gPlayState->sceneNum != SCENE_GANON_DEMO)) {
+ if (((CVarGetInteger("gAutosave", 0) == 2) || (CVarGetInteger("gAutosave", 0) == 5)) && (item != ITEM_NONE)) {
// Autosave for all items
- Play_PerformSave(gPlayState);
+ performSave = true;
- } else if ((CVarGetInteger("gAutosave", 0) == 1) || (CVarGetInteger("gAutosave", 0) == 4) && (item != ITEM_NONE)) {
+ } else if (((CVarGetInteger("gAutosave", 0) == 1) || (CVarGetInteger("gAutosave", 0) == 4)) && (item != ITEM_NONE)) {
// Autosave for major items
- switch (item) {
- case ITEM_STICK:
- case ITEM_NUT:
- case ITEM_BOMB:
- case ITEM_BOW:
- case ITEM_SEEDS:
- case ITEM_FISHING_POLE:
- case ITEM_MAGIC_SMALL:
- case ITEM_MAGIC_LARGE:
- case ITEM_INVALID_4:
- case ITEM_INVALID_5:
- case ITEM_INVALID_6:
- case ITEM_INVALID_7:
- case ITEM_HEART:
- case ITEM_RUPEE_GREEN:
- case ITEM_RUPEE_BLUE:
- case ITEM_RUPEE_RED:
- case ITEM_RUPEE_PURPLE:
- case ITEM_RUPEE_GOLD:
- case ITEM_INVALID_8:
- case ITEM_STICKS_5:
- case ITEM_STICKS_10:
- case ITEM_NUTS_5:
- case ITEM_NUTS_10:
- case ITEM_BOMBS_5:
- case ITEM_BOMBS_10:
- case ITEM_BOMBS_20:
- case ITEM_BOMBS_30:
- case ITEM_ARROWS_SMALL:
- case ITEM_ARROWS_MEDIUM:
- case ITEM_ARROWS_LARGE:
- case ITEM_SEEDS_30:
- case ITEM_NONE:
- break;
- case ITEM_BOMBCHU:
- case ITEM_BOMBCHUS_5:
- case ITEM_BOMBCHUS_20:
- if (!CVarGetInteger("gBombchuDrops", 0)) {
- Play_PerformSave(gPlayState);
- }
- break;
- default:
- Play_PerformSave(gPlayState);
- break;
+ if (itemEntry.modIndex == 0) {
+ switch (item) {
+ case ITEM_STICK:
+ case ITEM_NUT:
+ case ITEM_BOMB:
+ case ITEM_BOW:
+ case ITEM_SEEDS:
+ case ITEM_FISHING_POLE:
+ case ITEM_MAGIC_SMALL:
+ case ITEM_MAGIC_LARGE:
+ case ITEM_INVALID_4:
+ case ITEM_INVALID_5:
+ case ITEM_INVALID_6:
+ case ITEM_INVALID_7:
+ case ITEM_HEART:
+ case ITEM_RUPEE_GREEN:
+ case ITEM_RUPEE_BLUE:
+ case ITEM_RUPEE_RED:
+ case ITEM_RUPEE_PURPLE:
+ case ITEM_RUPEE_GOLD:
+ case ITEM_INVALID_8:
+ case ITEM_STICKS_5:
+ case ITEM_STICKS_10:
+ case ITEM_NUTS_5:
+ case ITEM_NUTS_10:
+ case ITEM_BOMBS_5:
+ case ITEM_BOMBS_10:
+ case ITEM_BOMBS_20:
+ case ITEM_BOMBS_30:
+ case ITEM_ARROWS_SMALL:
+ case ITEM_ARROWS_MEDIUM:
+ case ITEM_ARROWS_LARGE:
+ case ITEM_SEEDS_30:
+ case ITEM_NONE:
+ break;
+ case ITEM_BOMBCHU:
+ case ITEM_BOMBCHUS_5:
+ case ITEM_BOMBCHUS_20:
+ if (!CVarGetInteger("gBombchuDrops", 0)) {
+ performSave = true;
+ }
+ break;
+ default:
+ performSave = true;
+ break;
+ }
+ } else if (itemEntry.modIndex == 1 && item != RG_ICE_TRAP) {
+ performSave = true;
+ }
+ } else if ((CVarGetInteger("gAutosave", 0) > 0 && (CVarGetInteger("gAutosave", 0) < 4))) {
+ performSave = true;
+ }
+ if ((gPlayState->sceneNum == SCENE_YOUSEI_IZUMI_TATE) || (gPlayState->sceneNum == SCENE_KAKUSIANA) ||
+ (gPlayState->sceneNum == SCENE_KENJYANOMA)) {
+ if ((CVarGetInteger("gAutosave", 0) > 0 && (CVarGetInteger("gAutosave", 0) < 4))) {
+ performSave = false;
+ return;
}
+ if (performSave) {
+ performSave = false;
+ performDelayedSave = true;
+ }
+ return;
+ }
+ if (performSave || performDelayedSave) {
+ Play_PerformSave(gPlayState);
+ performSave = false;
+ performDelayedSave = false;
}
}
}
@@ -238,6 +261,7 @@ void AutoSave(GetItemEntry itemEntry) {
void RegisterAutoSave() {
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry itemEntry) { AutoSave(itemEntry); });
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSaleEnd>([](GetItemEntry itemEntry) { AutoSave(itemEntry); });
+ GameInteractor::Instance->RegisterGameHook<GameInteractor::OnTransitionEnd>([](int32_t sceneNum) { AutoSave(GET_ITEM_NONE); });
}
void RegisterRupeeDash() {
diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp
index 0738864c9..a7d81c6dc 100644
--- a/soh/soh/OTRGlobals.cpp
+++ b/soh/soh/OTRGlobals.cpp
@@ -553,6 +553,138 @@ extern "C" void VanillaItemTable_Init() {
}
}
+std::unordered_map<uint32_t, uint32_t> ItemIDtoGetItemID{
+ { ITEM_ARROWS_LARGE, GI_ARROWS_LARGE },
+ { ITEM_ARROWS_MEDIUM, GI_ARROWS_MEDIUM },
+ { ITEM_ARROWS_SMALL, GI_ARROWS_SMALL },
+ { ITEM_ARROW_FIRE, GI_ARROW_FIRE },
+ { ITEM_ARROW_ICE, GI_ARROW_ICE },
+ { ITEM_ARROW_LIGHT, GI_ARROW_LIGHT },
+ { ITEM_BEAN, GI_BEAN },
+ { ITEM_BIG_POE, GI_BIG_POE },
+ { ITEM_BLUE_FIRE, GI_BLUE_FIRE },
+ { ITEM_BOMB, GI_BOMBS_1 },
+ { ITEM_BOMBCHU, GI_BOMBCHUS_10 },
+ { ITEM_BOMBCHUS_20, GI_BOMBCHUS_20 },
+ { ITEM_BOMBCHUS_5, GI_BOMBCHUS_5 },
+ { ITEM_BOMBS_10, GI_BOMBS_10 },
+ { ITEM_BOMBS_20, GI_BOMBS_20 },
+ { ITEM_BOMBS_30, GI_BOMBS_30 },
+ { ITEM_BOMBS_5, GI_BOMBS_5 },
+ { ITEM_BOMB_BAG_20, GI_BOMB_BAG_20 },
+ { ITEM_BOMB_BAG_30, GI_BOMB_BAG_30 },
+ { ITEM_BOMB_BAG_40, GI_BOMB_BAG_40 },
+ { ITEM_BOOMERANG, GI_BOOMERANG },
+ { ITEM_BOOTS_HOVER, GI_BOOTS_HOVER },
+ { ITEM_BOOTS_IRON, GI_BOOTS_IRON },
+ { ITEM_BOTTLE, GI_BOTTLE },
+ { ITEM_BOW, GI_BOW },
+ { ITEM_BRACELET, GI_BRACELET },
+ { ITEM_BUG, GI_BUGS },
+ { ITEM_BULLET_BAG_30, GI_BULLET_BAG_30 },
+ { ITEM_BULLET_BAG_40, GI_BULLET_BAG_40 },
+ { ITEM_BULLET_BAG_50, GI_BULLET_BAG_50 }, { ITEM_CHICKEN, GI_CHICKEN },
+ { ITEM_CLAIM_CHECK, GI_CLAIM_CHECK },
+ { ITEM_COJIRO, GI_COJIRO },
+ { ITEM_COMPASS, GI_COMPASS },
+ { ITEM_DINS_FIRE, GI_DINS_FIRE },
+ { ITEM_DUNGEON_MAP, GI_MAP },
+ { ITEM_EYEDROPS, GI_EYEDROPS },
+ { ITEM_FAIRY, GI_FAIRY },
+ { ITEM_FARORES_WIND, GI_FARORES_WIND },
+ { ITEM_FISH, GI_FISH },
+ { ITEM_FROG, GI_FROG },
+ { ITEM_GAUNTLETS_GOLD, GI_GAUNTLETS_GOLD },
+ { ITEM_GAUNTLETS_SILVER, GI_GAUNTLETS_SILVER },
+ { ITEM_GERUDO_CARD, GI_GERUDO_CARD },
+ { ITEM_HAMMER, GI_HAMMER },
+ { ITEM_HEART, GI_HEART },
+ { ITEM_HEART_CONTAINER, GI_HEART_CONTAINER },
+ { ITEM_HEART_CONTAINER, GI_HEART_CONTAINER_2 },
+ { ITEM_HEART_PIECE_2, GI_HEART_PIECE },
+ { ITEM_HEART_PIECE_2, GI_HEART_PIECE_WIN },
+ { ITEM_HOOKSHOT, GI_HOOKSHOT },
+ { ITEM_KEY_BOSS, GI_KEY_BOSS },
+ { ITEM_KEY_SMALL, GI_DOOR_KEY },
+ { ITEM_KEY_SMALL, GI_KEY_SMALL },
+ { ITEM_LENS, GI_LENS },
+ { ITEM_LETTER_RUTO, GI_LETTER_RUTO },
+ { ITEM_LETTER_ZELDA, GI_LETTER_ZELDA },
+ { ITEM_LONGSHOT, GI_LONGSHOT },
+ { ITEM_MAGIC_LARGE, GI_MAGIC_LARGE },
+ { ITEM_MAGIC_SMALL, GI_MAGIC_SMALL },
+ { ITEM_MASK_BUNNY, GI_MASK_BUNNY },
+ { ITEM_MASK_GERUDO, GI_MASK_GERUDO },
+ { ITEM_MASK_GORON, GI_MASK_GORON },
+ { ITEM_MASK_KEATON, GI_MASK_KEATON },
+ { ITEM_MASK_SKULL, GI_MASK_SKULL },
+ { ITEM_MASK_SPOOKY, GI_MASK_SPOOKY },
+ { ITEM_MASK_TRUTH, GI_MASK_TRUTH },
+ { ITEM_MASK_ZORA, GI_MASK_ZORA },
+ { ITEM_MILK, GI_MILK },
+ { ITEM_MILK_BOTTLE, GI_MILK_BOTTLE },
+ { ITEM_NAYRUS_LOVE, GI_NAYRUS_LOVE },
+ { ITEM_NUT, GI_NUTS_5 },
+ { ITEM_NUTS_10, GI_NUTS_10 },
+ { ITEM_NUTS_5, GI_NUTS_5 },
+ { ITEM_NUTS_5, GI_NUTS_5_2 },
+ { ITEM_NUT_UPGRADE_30, GI_NUT_UPGRADE_30 },
+ { ITEM_NUT_UPGRADE_40, GI_NUT_UPGRADE_40 },
+ { ITEM_OCARINA_FAIRY, GI_OCARINA_FAIRY },
+ { ITEM_OCARINA_TIME, GI_OCARINA_OOT },
+ { ITEM_ODD_MUSHROOM, GI_ODD_MUSHROOM },
+ { ITEM_ODD_POTION, GI_ODD_POTION },
+ { ITEM_POCKET_CUCCO, GI_POCKET_CUCCO },
+ { ITEM_POCKET_EGG, GI_POCKET_EGG },
+ { ITEM_POE, GI_POE },
+ { ITEM_POTION_BLUE, GI_POTION_BLUE },
+ { ITEM_POTION_GREEN, GI_POTION_GREEN },
+ { ITEM_POTION_RED, GI_POTION_RED },
+ { ITEM_PRESCRIPTION, GI_PRESCRIPTION },
+ { ITEM_QUIVER_40, GI_QUIVER_40 },
+ { ITEM_QUIVER_50, GI_QUIVER_50 },
+ { ITEM_RUPEE_BLUE, GI_RUPEE_BLUE },
+ { ITEM_RUPEE_BLUE, GI_RUPEE_BLUE_LOSE },
+ { ITEM_RUPEE_GOLD, GI_RUPEE_GOLD },
+ { ITEM_RUPEE_GREEN, GI_RUPEE_GREEN },
+ { ITEM_RUPEE_GREEN, GI_RUPEE_GREEN_LOSE },
+ { ITEM_RUPEE_PURPLE, GI_RUPEE_PURPLE },
+ { ITEM_RUPEE_PURPLE, GI_RUPEE_PURPLE_LOSE },
+ { ITEM_RUPEE_RED, GI_RUPEE_RED },
+ { ITEM_RUPEE_RED, GI_RUPEE_RED_LOSE },
+ { ITEM_SAW, GI_SAW },
+ { ITEM_SCALE_GOLDEN, GI_SCALE_GOLD },
+ { ITEM_SCALE_SILVER, GI_SCALE_SILVER },
+ { ITEM_SEEDS, GI_SEEDS_5 },
+ { ITEM_SEEDS_30, GI_SEEDS_30 },
+ { ITEM_SHIELD_DEKU, GI_SHIELD_DEKU },
+ { ITEM_SHIELD_HYLIAN, GI_SHIELD_HYLIAN },
+ { ITEM_SHIELD_MIRROR, GI_SHIELD_MIRROR },
+ { ITEM_SKULL_TOKEN, GI_SKULL_TOKEN },
+ { ITEM_SLINGSHOT, GI_SLINGSHOT },
+ { ITEM_STICK, GI_STICKS_1 },
+ { ITEM_STICKS_10, GI_STICKS_10 },
+ { ITEM_STICKS_5, GI_STICKS_5 },
+ { ITEM_STICK_UPGRADE_20, GI_STICK_UPGRADE_20 },
+ { ITEM_STICK_UPGRADE_30, GI_STICK_UPGRADE_30 },
+ { ITEM_STONE_OF_AGONY, GI_STONE_OF_AGONY },
+ { ITEM_SWORD_BGS, GI_SWORD_BGS },
+ { ITEM_SWORD_BGS, GI_SWORD_KNIFE },
+ { ITEM_SWORD_BROKEN, GI_SWORD_BROKEN },
+ { ITEM_SWORD_KOKIRI, GI_SWORD_KOKIRI },
+ { ITEM_TUNIC_GORON, GI_TUNIC_GORON },
+ { ITEM_TUNIC_ZORA, GI_TUNIC_ZORA },
+ { ITEM_WALLET_ADULT, GI_WALLET_ADULT },
+ { ITEM_WALLET_GIANT, GI_WALLET_GIANT },
+ { ITEM_WEIRD_EGG, GI_WEIRD_EGG }
+};
+
+extern "C" uint32_t GetGIID(uint32_t itemID) {
+ if (ItemIDtoGetItemID.contains(itemID))
+ return ItemIDtoGetItemID.at(itemID);
+ return -1;
+}
+
extern "C" void OTRExtScanner() {
auto lst = *OTRGlobals::Instance->context->GetResourceManager()->ListFiles("*.*").get();
diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h
index 398a91b6c..c77d6f56e 100644
--- a/soh/soh/OTRGlobals.h
+++ b/soh/soh/OTRGlobals.h
@@ -138,6 +138,8 @@ void Entrance_ClearEntranceTrackingData(void);
void Entrance_InitEntranceTrackingData(void);
void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex);
void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex);
+
+uint32_t GetGIID(uint32_t itemID);
#endif
#endif
diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c
index b3cece3b5..488c9a320 100644
--- a/soh/src/code/z_parameter.c
+++ b/soh/src/code/z_parameter.c
@@ -1704,8 +1704,13 @@ u8 Return_Item_Entry(GetItemEntry itemEntry, ItemID returnItem ) {
}
// Processes Item_Give returns
-u8 Return_Item(u8 item, ModIndex modId, ItemID returnItem) {
- return Return_Item_Entry(ItemTable_RetrieveEntry(modId, item), returnItem);
+u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) {
+ uint32_t get = GetGIID(itemID);
+ if (get == -1) {
+ modId = MOD_RANDOMIZER;
+ get = itemID;
+ }
+ return Return_Item_Entry(ItemTable_RetrieveEntry(modId, get), returnItem);
}
/**
@@ -2313,7 +2318,7 @@ u8 Item_Give(PlayState* play, u8 item) {
}
u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
- uint16_t item = giEntry.itemId;
+ uint16_t item = giEntry.getItemId;
uint16_t temp;
uint16_t i;
uint16_t slot;
@@ -6196,11 +6201,16 @@ void Interface_Update(PlayState* play) {
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
}
if (gSaveContext.rupeeAccumulator == 0) {
- u16 tempSaleItem = gSaveContext.pendingSale;
- u16 tempSaleMod = gSaveContext.pendingSaleMod;
- gSaveContext.pendingSale = ITEM_NONE;
- gSaveContext.pendingSaleMod = MOD_NONE;
- GameInteractor_ExecuteOnSaleEndHooks(ItemTable_RetrieveEntry(tempSaleMod,tempSaleItem));
+ if (gSaveContext.pendingSale != ITEM_NONE) {
+ u16 tempSaleItem = gSaveContext.pendingSale;
+ u16 tempSaleMod = gSaveContext.pendingSaleMod;
+ gSaveContext.pendingSale = ITEM_NONE;
+ gSaveContext.pendingSaleMod = MOD_NONE;
+ if (tempSaleMod == 0) {
+ tempSaleItem = GetGIID(tempSaleItem);
+ }
+ GameInteractor_ExecuteOnSaleEndHooks(ItemTable_RetrieveEntry(tempSaleMod, tempSaleItem));
+ }
}
} else {
gSaveContext.rupeeAccumulator = 0;
diff --git a/soh/src/code/z_play.c b/soh/src/code/z_play.c
index 418eff501..5d280ca0b 100644
--- a/soh/src/code/z_play.c
+++ b/soh/src/code/z_play.c
@@ -869,15 +869,8 @@ void Play_Update(PlayState* play) {
gTrnsnUnkState = 0;
R_UPDATE_RATE = 3;
}
-
- // Autosave on area transition unless you're in a cutscene or a grotto since resuming from grottos breaks the game
- // Also don't save when you first load a file to prevent consumables like magic from being lost
- // Also don't save if there's a pending shop sale to prevent getting the item for a discount!
- if ((CVarGetInteger("gAutosave", 0) >= 1) && (CVarGetInteger("gAutosave", 0) <= 3) &&
- (gSaveContext.cutsceneIndex < 0xFFF0) && (play->gameplayFrames > 60) && (gSaveContext.pendingSale == ITEM_NONE) &&
- (play->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (play->sceneNum != SCENE_KAKUSIANA) && (play->sceneNum != SCENE_KENJYANOMA)) {
- Play_PerformSave(play);
- }
+
+ GameInteractor_ExecuteOnTransitionEndHooks(play->sceneNum);
}
play->sceneLoadFlag = 0;
} else {