mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2024-12-21 23:58:51 -05:00
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).
This commit is contained in:
parent
b099b5649b
commit
04d0cd8532
@ -146,6 +146,7 @@ public:
|
|||||||
DEFINE_HOOK(OnGameFrameUpdate, void());
|
DEFINE_HOOK(OnGameFrameUpdate, void());
|
||||||
DEFINE_HOOK(OnItemReceive, void(GetItemEntry itemEntry));
|
DEFINE_HOOK(OnItemReceive, void(GetItemEntry itemEntry));
|
||||||
DEFINE_HOOK(OnSaleEnd, 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(OnSceneInit, void(int16_t sceneNum));
|
||||||
DEFINE_HOOK(OnPlayerUpdate, void());
|
DEFINE_HOOK(OnPlayerUpdate, void());
|
||||||
DEFINE_HOOK(OnActorUpdate, void(void* actor));
|
DEFINE_HOOK(OnActorUpdate, void(void* actor));
|
||||||
|
@ -22,6 +22,10 @@ void GameInteractor_ExecuteOnSaleEndHooks(GetItemEntry itemEntry) {
|
|||||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSaleEnd>(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) {
|
void GameInteractor_ExecuteOnSceneInitHooks(int16_t sceneNum) {
|
||||||
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneInit>(sceneNum);
|
GameInteractor::Instance->ExecuteHooks<GameInteractor::OnSceneInit>(sceneNum);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ extern "C" void GameInteractor_ExecuteOnExitGame(int32_t fileNum);
|
|||||||
extern "C" void GameInteractor_ExecuteOnGameFrameUpdate();
|
extern "C" void GameInteractor_ExecuteOnGameFrameUpdate();
|
||||||
extern "C" void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
|
extern "C" void GameInteractor_ExecuteOnItemReceiveHooks(GetItemEntry itemEntry);
|
||||||
extern "C" void GameInteractor_ExecuteOnSaleEndHooks(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_ExecuteOnSceneInit(int16_t sceneNum);
|
||||||
extern "C" void GameInteractor_ExecuteOnPlayerUpdate();
|
extern "C" void GameInteractor_ExecuteOnPlayerUpdate();
|
||||||
extern "C" void GameInteractor_ExecuteOnActorUpdate(void* actor);
|
extern "C" void GameInteractor_ExecuteOnActorUpdate(void* actor);
|
||||||
|
@ -20,10 +20,10 @@ bool ItemTableManager::AddItemEntry(uint16_t tableID, uint16_t getItemID, GetIte
|
|||||||
} catch (const std::out_of_range& oor) { return false; }
|
} 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 {
|
try {
|
||||||
ItemTable* itemTable = RetrieveItemTable(tableID);
|
ItemTable* itemTable = RetrieveItemTable(tableID);
|
||||||
GetItemEntry getItemEntry = itemTable->at(itemID);
|
GetItemEntry getItemEntry = itemTable->at(getItemID);
|
||||||
getItemEntry.drawItemId = getItemEntry.itemId;
|
getItemEntry.drawItemId = getItemEntry.itemId;
|
||||||
getItemEntry.drawModIndex = getItemEntry.modIndex;
|
getItemEntry.drawModIndex = getItemEntry.modIndex;
|
||||||
return getItemEntry;
|
return getItemEntry;
|
||||||
|
@ -13,7 +13,7 @@ class ItemTableManager {
|
|||||||
~ItemTableManager();
|
~ItemTableManager();
|
||||||
bool AddItemTable(uint16_t tableID);
|
bool AddItemTable(uint16_t tableID);
|
||||||
bool AddItemEntry(uint16_t tableID, uint16_t getItemID, GetItemEntry getItemEntry);
|
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);
|
bool ClearItemTable(uint16_t tableID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -11,6 +11,8 @@ extern "C" {
|
|||||||
extern SaveContext gSaveContext;
|
extern SaveContext gSaveContext;
|
||||||
extern PlayState* gPlayState;
|
extern PlayState* gPlayState;
|
||||||
}
|
}
|
||||||
|
bool performDelayedSave = false;
|
||||||
|
bool performSave = false;
|
||||||
|
|
||||||
void RegisterInfiniteMoney() {
|
void RegisterInfiniteMoney() {
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnGameFrameUpdate>([]() {
|
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 during the Ganon fight when picking up the Master Sword
|
||||||
// Don't autosave in grottos since resuming from grottos breaks the game.
|
// Don't autosave in grottos since resuming from grottos breaks the game.
|
||||||
if ((CVarGetInteger("gAutosave", 0) > 0) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) &&
|
if ((CVarGetInteger("gAutosave", 0) > 0) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) &&
|
||||||
(gPlayState->sceneNum != SCENE_YOUSEI_IZUMI_TATE) && (gPlayState->sceneNum != SCENE_KAKUSIANA) &&
|
(gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0) && (gPlayState->sceneNum != SCENE_GANON_DEMO)) {
|
||||||
(gPlayState->sceneNum != SCENE_KENJYANOMA) && (gPlayState->sceneNum != SCENE_GANON_DEMO) &&
|
if (((CVarGetInteger("gAutosave", 0) == 2) || (CVarGetInteger("gAutosave", 0) == 5)) && (item != ITEM_NONE)) {
|
||||||
(gPlayState->gameplayFrames > 60 && gSaveContext.cutsceneIndex < 0xFFF0)) {
|
|
||||||
if ((CVarGetInteger("gAutosave", 0) == 2) || (CVarGetInteger("gAutosave", 0) == 5) && (item != ITEM_NONE)) {
|
|
||||||
// Autosave for all items
|
// 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
|
// Autosave for major items
|
||||||
switch (item) {
|
if (itemEntry.modIndex == 0) {
|
||||||
case ITEM_STICK:
|
switch (item) {
|
||||||
case ITEM_NUT:
|
case ITEM_STICK:
|
||||||
case ITEM_BOMB:
|
case ITEM_NUT:
|
||||||
case ITEM_BOW:
|
case ITEM_BOMB:
|
||||||
case ITEM_SEEDS:
|
case ITEM_BOW:
|
||||||
case ITEM_FISHING_POLE:
|
case ITEM_SEEDS:
|
||||||
case ITEM_MAGIC_SMALL:
|
case ITEM_FISHING_POLE:
|
||||||
case ITEM_MAGIC_LARGE:
|
case ITEM_MAGIC_SMALL:
|
||||||
case ITEM_INVALID_4:
|
case ITEM_MAGIC_LARGE:
|
||||||
case ITEM_INVALID_5:
|
case ITEM_INVALID_4:
|
||||||
case ITEM_INVALID_6:
|
case ITEM_INVALID_5:
|
||||||
case ITEM_INVALID_7:
|
case ITEM_INVALID_6:
|
||||||
case ITEM_HEART:
|
case ITEM_INVALID_7:
|
||||||
case ITEM_RUPEE_GREEN:
|
case ITEM_HEART:
|
||||||
case ITEM_RUPEE_BLUE:
|
case ITEM_RUPEE_GREEN:
|
||||||
case ITEM_RUPEE_RED:
|
case ITEM_RUPEE_BLUE:
|
||||||
case ITEM_RUPEE_PURPLE:
|
case ITEM_RUPEE_RED:
|
||||||
case ITEM_RUPEE_GOLD:
|
case ITEM_RUPEE_PURPLE:
|
||||||
case ITEM_INVALID_8:
|
case ITEM_RUPEE_GOLD:
|
||||||
case ITEM_STICKS_5:
|
case ITEM_INVALID_8:
|
||||||
case ITEM_STICKS_10:
|
case ITEM_STICKS_5:
|
||||||
case ITEM_NUTS_5:
|
case ITEM_STICKS_10:
|
||||||
case ITEM_NUTS_10:
|
case ITEM_NUTS_5:
|
||||||
case ITEM_BOMBS_5:
|
case ITEM_NUTS_10:
|
||||||
case ITEM_BOMBS_10:
|
case ITEM_BOMBS_5:
|
||||||
case ITEM_BOMBS_20:
|
case ITEM_BOMBS_10:
|
||||||
case ITEM_BOMBS_30:
|
case ITEM_BOMBS_20:
|
||||||
case ITEM_ARROWS_SMALL:
|
case ITEM_BOMBS_30:
|
||||||
case ITEM_ARROWS_MEDIUM:
|
case ITEM_ARROWS_SMALL:
|
||||||
case ITEM_ARROWS_LARGE:
|
case ITEM_ARROWS_MEDIUM:
|
||||||
case ITEM_SEEDS_30:
|
case ITEM_ARROWS_LARGE:
|
||||||
case ITEM_NONE:
|
case ITEM_SEEDS_30:
|
||||||
break;
|
case ITEM_NONE:
|
||||||
case ITEM_BOMBCHU:
|
break;
|
||||||
case ITEM_BOMBCHUS_5:
|
case ITEM_BOMBCHU:
|
||||||
case ITEM_BOMBCHUS_20:
|
case ITEM_BOMBCHUS_5:
|
||||||
if (!CVarGetInteger("gBombchuDrops", 0)) {
|
case ITEM_BOMBCHUS_20:
|
||||||
Play_PerformSave(gPlayState);
|
if (!CVarGetInteger("gBombchuDrops", 0)) {
|
||||||
}
|
performSave = true;
|
||||||
break;
|
}
|
||||||
default:
|
break;
|
||||||
Play_PerformSave(gPlayState);
|
default:
|
||||||
break;
|
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() {
|
void RegisterAutoSave() {
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry itemEntry) { AutoSave(itemEntry); });
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>([](GetItemEntry itemEntry) { AutoSave(itemEntry); });
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSaleEnd>([](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() {
|
void RegisterRupeeDash() {
|
||||||
|
@ -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() {
|
extern "C" void OTRExtScanner() {
|
||||||
auto lst = *OTRGlobals::Instance->context->GetResourceManager()->ListFiles("*.*").get();
|
auto lst = *OTRGlobals::Instance->context->GetResourceManager()->ListFiles("*.*").get();
|
||||||
|
|
||||||
|
@ -138,6 +138,8 @@ void Entrance_ClearEntranceTrackingData(void);
|
|||||||
void Entrance_InitEntranceTrackingData(void);
|
void Entrance_InitEntranceTrackingData(void);
|
||||||
void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex);
|
void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex);
|
||||||
void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex);
|
void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex);
|
||||||
|
|
||||||
|
uint32_t GetGIID(uint32_t itemID);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1704,8 +1704,13 @@ u8 Return_Item_Entry(GetItemEntry itemEntry, ItemID returnItem ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Processes Item_Give returns
|
// Processes Item_Give returns
|
||||||
u8 Return_Item(u8 item, ModIndex modId, ItemID returnItem) {
|
u8 Return_Item(u8 itemID, ModIndex modId, ItemID returnItem) {
|
||||||
return Return_Item_Entry(ItemTable_RetrieveEntry(modId, item), 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) {
|
u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry) {
|
||||||
uint16_t item = giEntry.itemId;
|
uint16_t item = giEntry.getItemId;
|
||||||
uint16_t temp;
|
uint16_t temp;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint16_t slot;
|
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);
|
Audio_PlaySoundGeneral(NA_SE_SY_RUPY_COUNT, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
|
||||||
}
|
}
|
||||||
if (gSaveContext.rupeeAccumulator == 0) {
|
if (gSaveContext.rupeeAccumulator == 0) {
|
||||||
u16 tempSaleItem = gSaveContext.pendingSale;
|
if (gSaveContext.pendingSale != ITEM_NONE) {
|
||||||
u16 tempSaleMod = gSaveContext.pendingSaleMod;
|
u16 tempSaleItem = gSaveContext.pendingSale;
|
||||||
gSaveContext.pendingSale = ITEM_NONE;
|
u16 tempSaleMod = gSaveContext.pendingSaleMod;
|
||||||
gSaveContext.pendingSaleMod = MOD_NONE;
|
gSaveContext.pendingSale = ITEM_NONE;
|
||||||
GameInteractor_ExecuteOnSaleEndHooks(ItemTable_RetrieveEntry(tempSaleMod,tempSaleItem));
|
gSaveContext.pendingSaleMod = MOD_NONE;
|
||||||
|
if (tempSaleMod == 0) {
|
||||||
|
tempSaleItem = GetGIID(tempSaleItem);
|
||||||
|
}
|
||||||
|
GameInteractor_ExecuteOnSaleEndHooks(ItemTable_RetrieveEntry(tempSaleMod, tempSaleItem));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gSaveContext.rupeeAccumulator = 0;
|
gSaveContext.rupeeAccumulator = 0;
|
||||||
|
@ -869,15 +869,8 @@ void Play_Update(PlayState* play) {
|
|||||||
gTrnsnUnkState = 0;
|
gTrnsnUnkState = 0;
|
||||||
R_UPDATE_RATE = 3;
|
R_UPDATE_RATE = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autosave on area transition unless you're in a cutscene or a grotto since resuming from grottos breaks the game
|
GameInteractor_ExecuteOnTransitionEndHooks(play->sceneNum);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
play->sceneLoadFlag = 0;
|
play->sceneLoadFlag = 0;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user