2023-02-26 19:46:25 -05:00
|
|
|
#include "mods.h"
|
2023-02-15 14:30:34 -05:00
|
|
|
#include <libultraship/bridge.h>
|
2023-02-26 19:46:25 -05:00
|
|
|
#include "game-interactor/GameInteractor.h"
|
2023-02-15 14:30:34 -05:00
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#include <z64.h>
|
|
|
|
extern SaveContext gSaveContext;
|
|
|
|
extern PlayState* gPlayState;
|
|
|
|
extern void Play_PerformSave(PlayState* play);
|
2023-02-28 03:52:32 -05:00
|
|
|
extern s32 Health_ChangeBy(PlayState* play, s16 healthChange);
|
|
|
|
extern void Rupees_ChangeBy(s16 rupeeChange);
|
2023-02-15 14:30:34 -05:00
|
|
|
}
|
|
|
|
|
2023-02-26 19:46:25 -05:00
|
|
|
void RegisterAutoSaveOnReceiveItemHook() {
|
2023-02-15 14:30:34 -05:00
|
|
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnReceiveItem>([](u8 item) {
|
2023-02-28 00:07:47 -05:00
|
|
|
|
|
|
|
// Don't autosave immediately after buying items from shops to prevent getting them for free!
|
|
|
|
// Don't autosave in the Chamber of Sages since resuming from that map breaks the game
|
|
|
|
// Don't autosave during the Ganon fight when picking up the Master Sword
|
|
|
|
if ((CVarGetInteger("gAutosave", 0) > 0) && (gPlayState != NULL) && (gSaveContext.pendingSale == ITEM_NONE) &&
|
|
|
|
(gPlayState->sceneNum != SCENE_KENJYANOMA) && (gPlayState->sceneNum != SCENE_GANON_DEMO)) {
|
|
|
|
if ((CVarGetInteger("gAutosave", 0) == 2) || (CVarGetInteger("gAutosave", 0) == 5)) {
|
|
|
|
// Autosave for all items
|
2023-02-15 14:30:34 -05:00
|
|
|
Play_PerformSave(gPlayState);
|
2023-02-28 00:07:47 -05:00
|
|
|
|
|
|
|
} else if ((CVarGetInteger("gAutosave", 0) == 1) || (CVarGetInteger("gAutosave", 0) == 4)) {
|
|
|
|
// Autosave for major items
|
2023-02-15 14:30:34 -05:00
|
|
|
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:
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-02-28 03:52:32 -05:00
|
|
|
void RegisterRupeeDash() {
|
|
|
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnPlayerUpdate>([]() {
|
|
|
|
if (!CVarGetInteger("gRupeeDash", 0)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize Timer
|
|
|
|
static uint16_t rupeeDashTimer = 0;
|
|
|
|
uint16_t rdmTime = CVarGetInteger("gDashInterval", 5) * 20;
|
|
|
|
|
|
|
|
// Did time change by DashInterval?
|
|
|
|
if (rupeeDashTimer >= rdmTime) {
|
|
|
|
rupeeDashTimer = 0;
|
|
|
|
if (gSaveContext.rupees > 0) {
|
|
|
|
Rupees_ChangeBy(-1);
|
|
|
|
} else {
|
|
|
|
Health_ChangeBy(gPlayState, -16);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
rupeeDashTimer++;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-02-26 19:46:25 -05:00
|
|
|
void InitMods() {
|
2023-02-28 03:52:32 -05:00
|
|
|
RegisterRupeeDash();
|
2023-02-26 19:46:25 -05:00
|
|
|
RegisterAutoSaveOnReceiveItemHook();
|
2023-02-15 14:30:34 -05:00
|
|
|
}
|