Shipwright/soh/soh/Enhancements/game-interactor/GameInteractor.h

601 lines
23 KiB
C
Raw Normal View History

#pragma once
#ifndef GameInteractor_h
#define GameInteractor_h
#include "libultraship/libultraship.h"
#include "GameInteractionEffect.h"
[GI] Item_Give and OnReceiveItem updates (#2580) * Changed OnReceiveItem hook to pass GetItemEntry, which required the following changes: Reworked the references to it in `z_parameter` to call a single function with the item return and hook call in it for ease of editing. Modified the pendingSale functionality to set and pass a modIndex value as well, as mod items (like randomizer) in shops still use the vanilla sale path. * Missed some files for the pendingSale changes. Also added Randomizer_Item_Give to the OnReceiveItem system. * Ice traps now trigger OnReceiveItem. * All ice traps truly do work now. As a side effect, item autosave doesn't work for shop/scrub/merchant transactions, requires new OnSaleEnded hook that can also call the autosave. * Removed unnecessary calls to ItemTable_RetrieveEntry where GetItemEntry properties were being used to call it. General code cleanup. * Added OnSaleEnd hook for when rupees are finished deducting after a sale. Migrated AutoSave to its own function, registered AutoSave function to OnReceiveItem and OnSaleEnd hooks to help with autsaving after buying items. Some futureproofing for AutoSave function with parameters for skipping autosave, for when transition end is migrated to AutoSave function (whether through direct call or through a hook). * Renamed hook paramaters, and registered hook function parameters, to a more descriptive alternative. * Missed a couple, fixed a typo. * One more missed paramater name refactor. Refactored all references to OnReceiveItem to OnItemReceive to mirror upcoming full hook refactor for name ordering conventions. Up-to-date with develop.
2023-03-12 03:00:03 -04:00
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include <z64.h>
typedef enum {
GI_SCHEME_SAIL,
GI_SCHEME_CROWD_CONTROL,
} GIScheme;
typedef enum {
/* 0x00 */ GI_LINK_SIZE_NORMAL,
/* 0x01 */ GI_LINK_SIZE_GIANT,
/* 0x02 */ GI_LINK_SIZE_MINISH,
/* 0x03 */ GI_LINK_SIZE_PAPER,
/* 0x03 */ GI_LINK_SIZE_SQUISHED,
/* 0x04 */ GI_LINK_SIZE_RESET
} GILinkSize;
typedef enum {
/* 0x00 */ GI_GRAVITY_LEVEL_LIGHT,
/* 0x01 */ GI_GRAVITY_LEVEL_NORMAL,
/* 0x02 */ GI_GRAVITY_LEVEL_HEAVY,
} GIGravityLevel;
typedef enum {
/* 0x00 */ GI_BUTTONS_CBUTTONS,
/* 0x01 */ GI_BUTTONS_DPAD,
} GIButtonSet;
typedef enum {
/* */ GI_TIMEOFDAY_DAWN = 32768,
/* */ GI_TIMEOFDAY_NOON = 49152,
/* */ GI_TIMEOFDAY_DUSK = 0,
/* */ GI_TIMEOFDAY_MIDNIGHT = 16384,
} GITimeOfDay;
typedef enum {
/* 0x00 */ GI_COSMETICS_TUNICS,
/* 0x01 */ GI_COSMETICS_NAVI,
/* 0x02 */ GI_COSMETICS_HAIR,
} GICosmeticCategories;
typedef enum {
/* 0x00 */ GI_COLOR_RED,
/* 0x01 */ GI_COLOR_GREEN,
/* 0x02 */ GI_COLOR_BLUE,
/* 0x03 */ GI_COLOR_ORANGE,
/* 0x04 */ GI_COLOR_YELLOW,
/* 0x05 */ GI_COLOR_PURPLE,
/* 0x06 */ GI_COLOR_PINK,
/* 0x07 */ GI_COLOR_BROWN,
/* 0x08 */ GI_COLOR_BLACK,
} GIColors;
typedef enum {
/* */ GI_TP_DEST_LINKSHOUSE = ENTR_LINKS_HOUSE_0,
/* */ GI_TP_DEST_MINUET = ENTR_SACRED_FOREST_MEADOW_2,
/* */ GI_TP_DEST_BOLERO = ENTR_DEATH_MOUNTAIN_CRATER_4,
/* */ GI_TP_DEST_SERENADE = ENTR_LAKE_HYLIA_8,
/* */ GI_TP_DEST_REQUIEM = ENTR_DESERT_COLOSSUS_5,
/* */ GI_TP_DEST_NOCTURNE = ENTR_GRAVEYARD_7,
/* */ GI_TP_DEST_PRELUDE = ENTR_TEMPLE_OF_TIME_7,
} GITeleportDestinations;
typedef enum {
// Vanilla condition: gSaveContext.showTitleCard
GI_VB_SHOW_TITLE_CARD,
// Opt: *EnWonderTalk2
GI_VB_WONDER_TALK,
// Opt: *ElfMsg
GI_VB_NAVI_TALK,
// Vanilla condition: INFTABLE_GREETED_BY_SARIA
GI_VB_NOT_BE_GREETED_BY_SARIA,
// Opt: *EnMd
// Vanilla condition: EnMd->interactInfo.talkState == NPC_TALK_STATE_ACTION
GI_VB_MOVE_MIDO_IN_KOKIRI_FOREST,
// Opt: *EnMd
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
GI_VB_MIDO_CONSIDER_DEKU_TREE_DEAD,
// Opt: *EnKo
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_KOKIRI_EMERALD)
GI_VB_OPEN_KOKIRI_FOREST,
// Opt: *EnOwl
// Vanilla condition: EnOwl->actor.xzDistToPlayer < targetDist
GI_VB_OWL_INTERACTION,
// Vanilla condition: EVENTCHKINF_TALON_RETURNED_FROM_CASTLE
GI_VB_MALON_RETURN_FROM_CASTLE,
// Vanilla condition: CUR_UPG_VALUE(UPG_STRENGTH) <= 0
GI_VB_BE_ELIGIBLE_FOR_DARUNIAS_JOY_REWARD,
/* Vanilla condition:
```
LINK_IS_ADULT &&
(gEntranceTable[((void)0, gSaveContext.entranceIndex)].scene == SCENE_TEMPLE_OF_TIME) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SPIRIT) &&
CHECK_QUEST_ITEM(QUEST_MEDALLION_SHADOW) &&
!Flags_GetEventChkInf(EVENTCHKINF_RETURNED_TO_TEMPLE_OF_TIME_WITH_ALL_MEDALLIONS);
```
*/
GI_VB_BE_ELIGIBLE_FOR_LIGHT_ARROWS,
// Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SARIA)
GI_VB_BE_ELIGIBLE_FOR_SARIAS_SONG,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_SONG_EPONA)
GI_VB_MALON_ALREADY_TAUGHT_EPONAS_SONG,
// Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)
GI_VB_BE_ELIGIBLE_FOR_SERENADE_OF_WATER,
// Vanilla condition: (!CHECK_OWNED_EQUIP(EQUIP_TYPE_BOOTS, EQUIP_INV_BOOTS_IRON) && !Flags_GetEventChkInf(EVENTCHKINF_LEARNED_SERENADE_OF_WATER)) && LINK_IS_ADULT
GI_VB_SHIEK_PREPARE_TO_GIVE_SERENADE_OF_WATER,
// Vanilla condition: !EVENTCHKINF_LEARNED_PRELUDE_OF_LIGHT and EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP
GI_VB_BE_ELIGIBLE_FOR_PRELUDE_OF_LIGHT,
/* Vanilla Condition:
```
LINK_IS_ADULT &&
gSaveContext.entranceIndex == ENTR_KAKARIKO_VILLAGE_0 &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FOREST_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_FIRE_TEMPLE_BLUE_WARP) &&
Flags_GetEventChkInf(EVENTCHKINF_USED_WATER_TEMPLE_BLUE_WARP) &&
!Flags_GetEventChkInf(EVENTCHKINF_BONGO_BONGO_ESCAPED_FROM_WELL);
```
*/
GI_VB_BE_ELIGIBLE_FOR_NOCTURNE_OF_SHADOW,
// Opt: *EnGo2
// Vanilla condition: CUR_CAPACITY(UPG_BOMB_BAG) >= 20 && this->waypoint > 7 && this->waypoint < 12
GI_VB_BE_ELIGIBLE_FOR_CHILD_ROLLING_GORON_REWARD,
// Vanilla condition: !CHECK_OWNED_EQUIP_ALT(EQUIP_TYPE_SWORD, EQUIP_INV_SWORD_BIGGORON)
GI_VB_BE_ELIGIBLE_FOR_GIANTS_KNIFE_PURCHASE,
// Opt: *EnMs
// Vanilla condition: gSaveContext.rupees >= sPrices[BEANS_BOUGHT]
GI_VB_BE_ELIGIBLE_FOR_MAGIC_BEANS_PURCHASE,
// Opt: *EnItem00
// Vanilla condition: Flags_GetCollectible(play, this->collectibleFlag)
GI_VB_ITEM00_DESPAWN,
// Opt: *EnTk
// Vanilla condition: gSaveContext.dayTime <= 0xC000 || gSaveContext.dayTime >= 0xE000 || LINK_IS_ADULT || play->sceneNum != SCENE_GRAVEYARD
GI_VB_DAMPE_IN_GRAVEYARD_DESPAWN,
// Opt: *EnTk
// Vanilla condition: this->validDigHere == 1
GI_VB_BE_VALID_GRAVEDIGGING_SPOT,
// Opt: *EnTk
// Vanilla condition: this->currentReward == 3
GI_VB_BE_DAMPE_GRAVEDIGGING_GRAND_PRIZE,
// Opt: *EnTk
// Vanilla condition: !Flags_GetItemGetInf(ITEMGETINF_1C)
GI_VB_DAMPE_GRAVEDIGGING_GRAND_PRIZE_BE_HEART_PIECE,
// Opt: *EnShopnuts
/* Vanilla Condition:
```
((this->actor.params == 0x0002) && (Flags_GetItemGetInf(ITEMGETINF_0B))) ||
((this->actor.params == 0x0009) && (Flags_GetInfTable(INFTABLE_192))) ||
((this->actor.params == 0x000A) && (Flags_GetInfTable(INFTABLE_193)))
```
*/
GI_VB_BUSINESS_SCRUB_DESPAWN,
// Opt: *EnCow
// Vanilla condition: play->sceneNum == SCENE_LINKS_HOUSE && (!LINK_IS_ADULT || !Flags_GetEventChkInf(EVENTCHKINF_WON_COW_IN_MALONS_RACE))
GI_VB_DESPAWN_HORSE_RACE_COW,
// Opt: *EnHs
// Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30)
GI_VB_DESPAWN_GROG,
// Opt: *EnKo
// Vanilla condition: (INV_CONTENT(ITEM_TRADE_ADULT) == ITEM_ODD_POTION) ? true : false;
GI_VB_SPAWN_LW_FADO,
// Opt: *EnMk
GI_VB_PLAY_EYEDROP_CREATION_ANIM,
// Opt: *EnDs
GI_VB_PLAY_ODD_POTION_ANIM,
// Opt: *EnMk
// Vanilla condition: INV_CONTENT(ITEM_ODD_MUSHROOM) == ITEM_EYEDROPS
GI_VB_USE_EYEDROP_DIALOGUE,
// Opt: *EnMk
// Vanilla condition: Flags_GetItemGetInf(ITEMGETINF_30)
GI_VB_OFFER_BLUE_POTION,
// Vanilla condition: Inventory_HasEmptyBottle() == 0
GI_VB_NEED_BOTTLE_FOR_GRANNYS_ITEM,
// Opt: *EnNiwLady
GI_VB_SET_CUCCO_COUNT,
// Opt: *EnKz
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_ZORA_SAPPHIRE)
GI_VB_KING_ZORA_THANK_CHILD,
// Opt: *EnKz
// Vanilla condition: this->actor.textId == 0x401A
GI_VB_BE_ABLE_TO_EXCHANGE_RUTOS_LETTER,
// Opt: *EnKz
// Vanilla condition: Flags_GetEventChkInf(EVENTCHKINF_KING_ZORA_MOVED)
GI_VB_KING_ZORA_BE_MOVED,
// Vanilla condition: gSaveState.bgsFlag
GI_VB_BIGGORON_CONSIDER_TRADE_COMPLETE,
// Vanilla condition: gSaveState.bgsFlag
GI_VB_BIGGORON_CONSIDER_SWORD_COLLECTED,
// Vanilla condition: Environment_GetBgsDayCount() >= 3
GI_VB_BIGGORON_CONSIDER_SWORD_FORGED,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_MEDALLION_FIRE)
GI_VB_GORONS_CONSIDER_FIRE_TEMPLE_FINISHED,
// Vanilla condition: CHECK_QUEST_ITEM(QUEST_GORON_RUBY)
GI_VB_GORONS_CONSIDER_DODONGOS_CAVERN_FINISHED,
// Opt: *uint16_t
// Vanilla condition: false
GI_VB_OVERRIDE_LINK_THE_GORON_DIALOGUE,
// Vanilla condition: CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_GORON)
GI_VB_GORONS_CONSIDER_TUNIC_COLLECTED,
// Opt: *EnSyatekiMan
// Vanilla condition: (this->getItemId == GI_QUIVER_40) || (this->getItemId == GI_QUIVER_50)
GI_VB_BE_ELIGIBLE_FOR_ADULT_SHOOTING_GAME_REWARD,
2024-02-21 15:01:49 -05:00
// Opt: *EnOkarinaTag
// Vanilla condition: !Flags_GetEventChkInf(EVENTCHKINF_OPENED_THE_DOOR_OF_TIME)
GI_VB_BE_ELIGIBLE_TO_OPEN_DOT,
2024-02-24 10:17:48 -05:00
// Opt: *BgDyYoseizo
// Vanilla condition: see soh/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c
GI_VB_BE_ELIGIBLE_FOR_GREAT_FAIRY_REWARD,
/*** Play Cutscenes ***/
GI_VB_PLAY_TRANSITION_CS,
// Opt: *EventChkInf flag
GI_VB_PLAY_ENTRANCE_CS,
// Opt: *cutsceneId
GI_VB_PLAY_ONEPOINT_CS,
// Opt: *actor
GI_VB_PLAY_ONEPOINT_ACTOR_CS,
// Opt: *BgTreemouth
GI_VB_PLAY_DEKU_TREE_INTRO_CS,
// Vanilla condition: !EventChkInf except for spirit & shadow temple which are !medallion, and Jabu which always is true
GI_VB_PLAY_BLUE_WARP_CS,
GI_VB_PLAY_DARUNIAS_JOY_CS,
GI_VB_PLAY_SHIEK_BLOCK_MASTER_SWORD_CS,
// Vanilla condition: !EVENTCHKINF_PULLED_MASTER_SWORD_FROM_PEDESTAL
GI_VB_PLAY_PULL_MASTER_SWORD_CS,
GI_VB_PLAY_DROP_FISH_FOR_JABU_CS,
// Vanilla condition: player->getItemId == GI_GAUNTLETS_SILVER
GI_VB_PLAY_NABOORU_CAPTURED_CS,
GI_VB_PLAY_ZELDAS_LULLABY_CS,
// Opt: *EnSa
GI_VB_PLAY_SARIAS_SONG_CS,
GI_VB_PLAY_PRELUDE_OF_LIGHT_CS,
GI_VB_PLAY_MINUET_OF_FOREST_CS,
GI_VB_PLAY_BOLERO_OF_FIRE_CS,
GI_VB_PLAY_SERENADE_OF_WATER_CS,
GI_VB_PLAY_EYEDROPS_CS,
2024-02-21 15:01:49 -05:00
// Opt: *EnOkarinaTag
GI_VB_PLAY_DRAIN_WELL_CS,
// Opt: *EnOkarinaTag
// Vanilla condition: !CHECK_QUEST_ITEM(QUEST_SONG_SUN)
GI_VB_PLAY_SUNS_SONG_CS,
// Opt: *EnOkarinaTag
GI_VB_PLAY_ROYAL_FAMILY_TOMB_CS,
GI_VB_PLAY_ROYAL_FAMILY_TOMB_EXPLODE,
// Opt: *EnOkarinaTag
GI_VB_PLAY_DOOR_OF_TIME_CS,
/*** Give Items ***/
GI_VB_GIVE_ITEM_FROM_CHEST,
GI_VB_GIVE_ITEM_FROM_BLUE_WARP,
// Opt: *EnItem00
GI_VB_GIVE_ITEM_FROM_ITEM_00,
// Opt: *EnSi
GI_VB_GIVE_ITEM_SKULL_TOKEN,
// Opt: *EnCow
GI_VB_GIVE_ITEM_FROM_COW,
// Opt: *EnDns
GI_VB_GIVE_ITEM_FROM_BUSINESS_SCRUB,
// Opt: *EnMk
GI_VB_GIVE_ITEM_FROM_LAB_DIVE,
// Opt: *EnDs
GI_VB_GIVE_ITEM_FROM_GRANNYS_SHOP,
// Opt: *EnNiwLady
GI_VB_GIVE_ITEM_FROM_ANJU_AS_CHILD,
// Opt: *EnNiwLady
GI_VB_GIVE_ITEM_FROM_ANJU_AS_ADULT,
// Opt: *EnKz
// Vanilla condition: !CHECK_OWNED_EQUIP(EQUIP_TYPE_TUNIC, EQUIP_INV_TUNIC_ZORA)
GI_VB_GIVE_ITEM_FROM_THAWING_KING_ZORA,
// Opt: *EnGo2
GI_VB_GIVE_ITEM_FROM_GORON,
// Opt: *EnJs
GI_VB_GIVE_ITEM_FROM_CARPET_SALESMAN,
// Opt: *EnGm
GI_VB_GIVE_ITEM_FROM_MEDIGORON,
// Opt: *EnMs
GI_VB_GIVE_ITEM_FROM_MAGIC_BEAN_SALESMAN,
// Opt: *EnFr
GI_VB_GIVE_ITEM_FROM_FROGS,
// Opt: *EnSkj
GI_VB_GIVE_ITEM_FROM_SKULL_KID_SARIAS_SONG,
2024-02-10 12:06:34 -05:00
GI_VB_GIVE_ITEM_FROM_MAN_ON_ROOF,
// Opt: *EnSyatekiMan
GI_VB_GIVE_ITEM_FROM_SHOOTING_GALLERY,
// Opt: *EnExItem
GI_VB_GIVE_ITEM_FROM_TARGET_IN_WOODS,
2024-04-04 11:55:07 -04:00
// Opt: *EnTa
GI_VB_GIVE_ITEM_FROM_TALONS_CHICKENS,
2024-04-04 11:30:45 -04:00
// Opt: *EnDivingGame
GI_VB_GIVE_ITEM_FROM_DIVING_MINIGAME,
// Opt: *EnGe1
GI_VB_GIVE_ITEM_FROM_HORSEBACK_ARCHERY,
2024-04-08 11:55:16 -04:00
// Opt: *EnSth
GI_VB_GIVE_ITEM_FROM_SKULLTULA_REWARD,
GI_VB_GIVE_ITEM_FAIRY_OCARINA,
GI_VB_GIVE_ITEM_WEIRD_EGG,
GI_VB_GIVE_ITEM_LIGHT_ARROW,
GI_VB_GIVE_ITEM_STRENGTH_1,
GI_VB_GIVE_ITEM_ZELDAS_LETTER,
GI_VB_GIVE_ITEM_MASTER_SWORD,
GI_VB_GIVE_ITEM_OCARINA_OF_TIME,
GI_VB_GIVE_ITEM_KOKIRI_EMERALD,
GI_VB_GIVE_ITEM_GORON_RUBY,
GI_VB_GIVE_ITEM_ZORA_SAPPHIRE,
GI_VB_GIVE_ITEM_LIGHT_MEDALLION,
GI_VB_GIVE_ITEM_FOREST_MEDALLION,
GI_VB_GIVE_ITEM_FIRE_MEDALLION,
GI_VB_GIVE_ITEM_WATER_MEDALLION,
GI_VB_GIVE_ITEM_SPIRIT_MEDALLION,
GI_VB_GIVE_ITEM_SHADOW_MEDALLION,
/*** Give Songs ***/
GI_VB_GIVE_ITEM_ZELDAS_LULLABY,
GI_VB_GIVE_ITEM_SARIAS_SONG,
GI_VB_GIVE_ITEM_EPONAS_SONG,
GI_VB_GIVE_ITEM_SUNS_SONG,
GI_VB_GIVE_ITEM_SONG_OF_TIME,
GI_VB_GIVE_ITEM_SONG_OF_STORMS,
GI_VB_GIVE_ITEM_MINUET_OF_FOREST,
GI_VB_GIVE_ITEM_BOLERO_OF_FIRE,
GI_VB_GIVE_ITEM_SERENADE_OF_WATER,
GI_VB_GIVE_ITEM_REQUIEM_OF_SPIRIT,
GI_VB_GIVE_ITEM_NOCTURNE_OF_SHADOW,
GI_VB_GIVE_ITEM_PRELUDE_OF_LIGHT,
/*** Adult Trade ***/
// Opt: *EnNiwLady
GI_VB_TRADE_POCKET_CUCCO,
// Opt: *EnHs
GI_VB_TRADE_COJIRO,
// Opt: *EnDs
GI_VB_TRADE_ODD_MUSHROOM,
// Opt: *EnKo
GI_VB_TRADE_ODD_POTION,
// Opt: *EnToryo
GI_VB_TRADE_SAW,
// Opt: *EnKz,
GI_VB_TRADE_PRESCRIPTION,
// Opt: *EnMk
GI_VB_TRADE_FROG,
GI_VB_TRADE_TIMER_ODD_MUSHROOM,
GI_VB_TRADE_TIMER_EYEDROPS,
GI_VB_TRADE_TIMER_FROG,
// Opt: *EnNiwLady
GI_VB_ANJU_SET_OBTAINED_TRADE_ITEM,
/*** Fixes ***/
// Vanilla condition: false
GI_VB_FIX_SAW_SOFTLOCK,
} GIVanillaBehavior;
#ifdef __cplusplus
extern "C" {
#endif
uint8_t GameInteractor_NoUIActive();
GILinkSize GameInteractor_GetLinkSize();
void GameInteractor_SetLinkSize(GILinkSize size);
uint8_t GameInteractor_InvisibleLinkActive();
uint8_t GameInteractor_OneHitKOActive();
uint8_t GameInteractor_PacifistModeActive();
uint8_t GameInteractor_DisableZTargetingActive();
uint8_t GameInteractor_ReverseControlsActive();
int32_t GameInteractor_DefenseModifier();
int32_t GameInteractor_RunSpeedModifier();
GIGravityLevel GameInteractor_GravityLevel();
uint32_t GameInteractor_GetEmulatedButtons();
void GameInteractor_SetEmulatedButtons(uint32_t buttons);
uint8_t GameInteractor_GetRandomBombFuseTimerActive();
uint8_t GameInteractor_GetDisableLedgeGrabsActive();
uint8_t GameInteractor_GetRandomWindActive();
uint8_t GameInteractor_GetRandomBonksActive();
uint8_t GameInteractor_GetSlipperyFloorActive();
uint8_t GameInteractor_SecondCollisionUpdate();
void GameInteractor_SetTriforceHuntPieceGiven(uint8_t state);
void GameInteractor_SetTriforceHuntCreditsWarpActive(uint8_t state);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
#include <thread>
2023-02-15 14:30:34 -05:00
#include <vector>
#include <functional>
#include <string>
2023-02-15 14:30:34 -05:00
#ifdef ENABLE_REMOTE_CONTROL
#include <SDL2/SDL_net.h>
#include <nlohmann/json.hpp>
#endif
2023-02-15 14:30:34 -05:00
#define DEFINE_HOOK(name, type) \
struct name { \
typedef std::function<type> fn; \
}
class GameInteractor {
public:
static GameInteractor* Instance;
// Gsme State
class State {
public:
static bool NoUIActive;
static GILinkSize LinkSize;
static bool InvisibleLinkActive;
static bool OneHitKOActive;
static bool PacifistModeActive;
static bool DisableZTargetingActive;
static bool ReverseControlsActive;
static int32_t DefenseModifier;
static int32_t RunSpeedModifier;
static GIGravityLevel GravityLevel;
static uint32_t EmulatedButtons;
static uint8_t RandomBombFuseTimerActive;
static uint8_t DisableLedgeGrabsActive;
static uint8_t RandomWindActive;
static uint8_t RandomWindSecondsSinceLastDirectionChange;
static uint8_t RandomBonksActive;
static uint8_t SlipperyFloorActive;
static uint8_t SecondCollisionUpdate;
static uint8_t TriforceHuntPieceGiven;
static uint8_t TriforceHuntCreditsWarpActive;
static void SetPacifistMode(bool active);
};
#ifdef ENABLE_REMOTE_CONTROL
bool isRemoteInteractorEnabled;
bool isRemoteInteractorConnected;
void EnableRemoteInteractor();
void DisableRemoteInteractor();
void RegisterRemoteDataHandler(std::function<void(char payload[512])> method);
void RegisterRemoteJsonHandler(std::function<void(nlohmann::json)> method);
void RegisterRemoteConnectedHandler(std::function<void()> method);
void RegisterRemoteDisconnectedHandler(std::function<void()> method);
void TransmitDataToRemote(const char* payload);
void TransmitJsonToRemote(nlohmann::json packet);
#endif
// Effects
static GameInteractionEffectQueryResult CanApplyEffect(GameInteractionEffectBase* effect);
static GameInteractionEffectQueryResult ApplyEffect(GameInteractionEffectBase* effect);
static GameInteractionEffectQueryResult RemoveEffect(RemovableGameInteractionEffect* effect);
2023-02-15 14:30:34 -05:00
// Game Hooks
2024-02-15 21:08:31 -05:00
uint32_t nextHookId = 1;
template <typename H> struct RegisteredGameHooks { inline static std::unordered_map<uint32_t, typename H::fn> functions; };
template <typename H> struct HooksToUnregister { inline static std::vector<uint32_t> hooks; };
template <typename H> uint32_t RegisterGameHook(typename H::fn h) {
2024-02-15 21:08:31 -05:00
// Ensure hook id is unique and not 0, which is reserved for invalid hooks
if (this->nextHookId == 0 || this->nextHookId >= UINT32_MAX) this->nextHookId = 1;
while (RegisteredGameHooks<H>::functions.find(this->nextHookId) != RegisteredGameHooks<H>::functions.end()) {
this->nextHookId++;
}
2024-02-15 21:08:31 -05:00
RegisteredGameHooks<H>::functions[this->nextHookId] = h;
return this->nextHookId++;
}
template <typename H> void UnregisterGameHook(uint32_t id) {
HooksToUnregister<H>::hooks.push_back(id);
}
2024-02-15 21:08:31 -05:00
2023-02-15 14:30:34 -05:00
template <typename H, typename... Args> void ExecuteHooks(Args&&... args) {
for (auto& hookId : HooksToUnregister<H>::hooks) {
RegisteredGameHooks<H>::functions.erase(hookId);
}
HooksToUnregister<H>::hooks.clear();
for (auto& hook : RegisteredGameHooks<H>::functions) {
hook.second(std::forward<Args>(args)...);
2023-02-15 14:30:34 -05:00
}
}
DEFINE_HOOK(OnLoadGame, void(int32_t fileNum));
DEFINE_HOOK(OnExitGame, void(int32_t fileNum));
DEFINE_HOOK(OnGameFrameUpdate, void());
[GI] Item_Give and OnReceiveItem updates (#2580) * Changed OnReceiveItem hook to pass GetItemEntry, which required the following changes: Reworked the references to it in `z_parameter` to call a single function with the item return and hook call in it for ease of editing. Modified the pendingSale functionality to set and pass a modIndex value as well, as mod items (like randomizer) in shops still use the vanilla sale path. * Missed some files for the pendingSale changes. Also added Randomizer_Item_Give to the OnReceiveItem system. * Ice traps now trigger OnReceiveItem. * All ice traps truly do work now. As a side effect, item autosave doesn't work for shop/scrub/merchant transactions, requires new OnSaleEnded hook that can also call the autosave. * Removed unnecessary calls to ItemTable_RetrieveEntry where GetItemEntry properties were being used to call it. General code cleanup. * Added OnSaleEnd hook for when rupees are finished deducting after a sale. Migrated AutoSave to its own function, registered AutoSave function to OnReceiveItem and OnSaleEnd hooks to help with autsaving after buying items. Some futureproofing for AutoSave function with parameters for skipping autosave, for when transition end is migrated to AutoSave function (whether through direct call or through a hook). * Renamed hook paramaters, and registered hook function parameters, to a more descriptive alternative. * Missed a couple, fixed a typo. * One more missed paramater name refactor. Refactored all references to OnReceiveItem to OnItemReceive to mirror upcoming full hook refactor for name ordering conventions. Up-to-date with develop.
2023-03-12 03:00:03 -04:00
DEFINE_HOOK(OnItemReceive, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnSaleEnd, void(GetItemEntry itemEntry));
DEFINE_HOOK(OnTransitionEnd, void(int16_t sceneNum));
2023-03-02 03:27:28 -05:00
DEFINE_HOOK(OnSceneInit, void(int16_t sceneNum));
DEFINE_HOOK(OnSceneFlagSet, void(int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneFlagUnset, void(int16_t sceneNum, int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagSet, void(int16_t flagType, int16_t flag));
DEFINE_HOOK(OnFlagUnset, void(int16_t flagType, int16_t flag));
DEFINE_HOOK(OnSceneSpawnActors, void());
DEFINE_HOOK(OnPlayerUpdate, void());
DEFINE_HOOK(OnOcarinaSongAction, void());
Check Tracker Update (#2668) * Initial commit. What works so far: Data file loads, saves, deletes, and is created properly. - Need to run `HasItemBeenCollected` when creating in case of mid-seed regen. Organized checks into maps set by area. Areas show in tracker. - Checks pulled from checkObjectsByArea are not currently listed. - Areas are being assumed completed and hidden at the start. * Checks now populate. Still not counting area totals properly. * Don't track RC_LINKS_POCKET in the data file, and instead manually add it in every time a save is load. rcObjects doesn't contain Link's Pocket location (duh). * Moved ItemReceive hook to randomizer_check_tracker.cpp. Skipped items are properly sorted and formatted. Saved items contribute to an area's gotten/skipped checks on load. Changed skipped items default main color to gray. General code cleanup. * Skipped checks now contribute to area totals for area completion logic. * Mid-menu rework transfer. * Started check lookup on item receive. Tried to enable scum checking on save. * Fixed scum check on save. * More code cleanup, which revealed some issues with loading and saving. Loading now works 100%, but entries in checkTrackerData are disappearing in code somewhere, causing issues with later checks. Scummed color now displays properly. Collected but unsaved displays properly. Unchecked, Skipped, Seen and Scummed checks all have arrows for skipping/unskipping. Counts a little messed up, probably double adding skips. * Fixed item counts being off across resets. Restarts were fine. * Beginning of rework for individual check updates. Adds `Actor lastCheck` to PlayState to allow assigning of last actor to give an item. This allows precise tracking of GS, freestanding PoH, etc. Works for chests too. Currently does not work for shops, unknown for normal NPC gives. Doesn't track last gives for non-checks, like drops from grass, pots, crates, etc. * Actor-based checks fully fleshed out, but can't help with sale-based checks. Implemented `pendingSaleCheck` to back out of an RC check cycle if `gSaveContext->pendingSale` is not NONE when `OnItemReceive` is called, processed through `OnSaleEnd`. This should be the final change necessary to streamline the checks. * Temporary hook to message box close to tie in trackers for non-gs/chest actors that aren't added to `GetCheckFromActor`. This triggers a 2-frame countdown to check with `HasItemBeenCollected` since half of the methods in there aren't updated until after a text box closes. Added scene tracking to get last scene so that checks in scenes that span several overworld areas could be tied to their areas properly. Modified tracker data creation to apply Link's Pocket and Song from Impa conditionally based on randomizer settings instead of just being assumed to be done. May need modification for checking click and drag spoiler loading. Removed the scene equivalence check from CheckChecks so that an entire area is checked each time to avoid issues with, e.g., leaving a shop before a pending sale finishes. * Changed check data creation to use RSKs from gRandomizer to account for settings loaded from drag and drop spoilers. * Beginning of tracker code organization. Changed check color defaults. * Reverted moving tracker colors to header. Some individual check fixes. * Missed something from previous merge? * Removed last remnant of removed performance mode. * Better handle checking when skullsanity is off. * Song checks sceneIDs don't match the scenes they're actually in for some reason. Removed that check. * SaleEnd checks don't need the GetItemEntry parameter. Also set a flag that should prevent the check tracker from running during vanilla saves should that not be resolved by the time it's merged. * Attempting to have only the relevant checks added to the tracker data, as well as showing vanilla checks for non-rando saves. Not working yet (everything is displayed in vanilla). * Added vanilla check tracker population via `vanillaCheck` bool in `RandomizerCheckObject`. This is also added to `IsVisibleInImGui` to handle file loading and saving to eliminate checks that aren't part of vanilla or the rando seed. Implemented deleted tracker data file recreation. Added some extra item name text checks. Songs are still... tricky, so they stay blank. Utilize local copies of the randomizer check objects that are applicable for performance purposes. Fixed vanilla item-giving cutscene crashes when triggered mid-transition. * Apparently not all toolchains can handle macro instantiation without all parameters, like VS can. * Fixed scummed detail color not showing properly on tracker. * Fixed dungeon area totals and GS checks not functioning properly. * Major revamp of checking code. Doesn't rely on `GetCheckFromActor` at all anymore, but instead simply sets a flag to evaluate a number of checks in an area every frame until the check that was gotten is identified. With the new setup, it's much less hardware intensive, and at 60fps 6 checks per frame shows no noticeable effect on framerate. I can envision needing to add a collectedCount in order to account for times when two checks are gotten one right after the other. Changed area scroll to happen from `OnTransitionEnd`, and allow for scrolling in bazaar (was disabled previously because it would jump back and forth between Kak and Market while you were in one). Also setup area check order updating by area instead of all at the same time. * Fixed shooting gallery not reporting proper area. Prevent checks from actually happening if area is RCAREA_INVALID, now that all areas are reporting something if they have checks. Fixed `GetCheckArea()` not updating checks for standard scenes. Lots of vanilla tracking updates, mainly manual checks for gems, medallions and songs, since the often don't have proper scenes in the data. Prevent vanilla from triggering check loops if junk items are collected. Fixed sorting based on saved vs collected. Prevent item name display for vanilla runs. Change coloring of checks so the check name reflects status in vanilla runs. * Fixed "Recheck Area" button erroneously adding to an area's check totals? * Fix DMC vanilla checks. * Fix check tracker data recreation on data file loss. Removed redundant file exists check from SaveTrackerDataHook, as it doesn't matter if it exists or not at that point. Limited check loops to 3 to avoid infinite check loops on non-check/junk item pickup. Added more checks to disable tracker operations if a save is not running. Changed check ordering to put boss reward and heart container checks at the end of whatever RCSHOW group they belong to. * Fixed IsRunning calculation. Further improving vanilla checking. Starting framework for checking medallions, stones, and songs on data file recreation. Fixed medallion check collection. Added GIFT_FROM_SAGES to check list for vanilla file for tracking light medallion. Added check loop limitation to prevent infinite checking after picking up junk item from the ground. * Finished vanilla file recreation and recheck (songs and dungeon rewards all check properly now). This includes deku shield with KF shop item 3. Finished Gift from Raoru light medallion tracking for vanilla. Commented all CheckByScene functionality for now. * Fixed new save data file creation. Disabled entrance area calculation for now, as it only tracks the previous entrance for some reason. Fixed area detection for ToT checks. * GetCheckArea() now utilizes EntranceData almost exclusively, via either `gSaveContext.entranceIndex` or the entrance tracker's `currentGrottoId` in the case of grottos. This also means that EVERYTHING CAN AUTOSCROLL NOW. Entrance shuffles are now much easier to track. Autoscroll is now also triggered on save, just in case someone isn't autosaving and has a lot of checks that get converted to saved. * Fixed missing GS check in LW. * Added area scroll on toggling Show Hidden Items. May configure differently later. Fixed area detection for entrances in Gerudo Fortress/Valley and Collossus. Haunted wasteland doesn't autoscroll due to a bug in `OnTransitionEnd` hook, but checks still evaluate properly there. Rely on scene-based area detection if scene is a main overworld or dungeon scene. * Fixed grotto detection when shuffle is off. * Small code cleanup. Fixed Colossus hand chest checks. * Missing lus bump from merge conflict resolution * Fixed Colossus Grotto making `GetCheckArea` return Wasteland. * Improved OnItemReceive processing for non-token GS checks, since they can sometimes take long enough for the checking process to time out before the item is registered as received. * First attempt at thread safety for tracker data file writing. Seems to work, but might need more testing. * Fixed Recheck Area not unskipping items that register as saved. Improved delayed saving with autosaving, as the autosave triggered quite often before the tracker data save, making things not properly register as saved. * merge cleanup * Converted check tracker data to the sectional saves, adding `CheckTrackerData` to `SaveContext`. Implemented section ID returning and fullSave boolean passing to section functions from my PR temporarily for it to work properly. Moved `RandomizerCheckTrackerData` enum to `randomizerTypes.h` to accommodate that. Changed `Randomizer_SaveInit` to a `SaveManager::InitFunc` to allow for other randomizer-dependent sections to be initialized after that. Required a little refactoring to maintain intro cutscene skip when starting a randomizer file. * Revert section index return and randomizer init changes. Will need to wait on yet more changes to main. * Fixed check tracker initialization (shouldn't be tied to window initialization), restored saving/loading functionality. * Removed `CheckTracker::Init` and put SaveManager calls in `CheckTrackerWindow::InitElement`. Also a bit of cleanup from transition back to save file use. * Fixed tracker displaying check categories while file not loaded. * Fix Darunia's Joy check not marking in vanilla. * Fix autosave not triggering change from collected to saved in tracker data. * Changed default colors for scummed and collected display. * Merge upgrade code cleanup. * Add `OnTransitionEnd` calls to sandstorm transitions both to and from Wasteland. Also improved `gSaveContext.lastScene` assignment for both transition types. Allowed a bit of cleanup in `GetCheckArea`. * Added `StateButton`, a button like `ArrowButton` but that allows text instead of arrow icons. Apparently the changes from ArrowButton to StateButton happened in a previous commit... * Changed section name to `trackerDataCheck` to force SoH to load it after the randomizer section, as it required some randoSettings to be loaded first, and nothing else I tried to make the randomizer section load before it worked. This hacks a solution to checks not displaying on fast file load to a specific slot. F*** you, SaveManager, and f*** you too, JSON. * Forgot to change the section string for loading with the name change. * Fix check ordering for checks that trigger the autosave. * Adds option to remove right-side shop items (slots 1-4) from the tracker list. Enabled by default. * Fix default state of Hide Shop Right Checks checkbox. * Fixes grotto and great fairy scrolling and checks. Fixes array overflow from `checkTrackerData` which was creating the issue trying to load the base and randomizer sections first, among other things. That also fixed the massive file loads that were being exhibited in debug mode. * Fix shooting galleries being set as collected again when being played a second time after getting the checks. * Fix Bazaar autoscroll. * Add Saria's Song to `GetCheckFromActor` and removed some limitations from the messageCloseCheck function to make that check track properly. * Fix Song from Impa check. Implemented prevention for multiple "collections" of great fairies, just in case getting the health refill would trigger it with the previous setup. * Fix ice traps on GS tokens not triggering OnItemReceive. * Complete fix for ice trap collection from GS. Add autoscroll when clicking "Expand All". * Add `OnShopSlotChange` with cursorSlot and basePrice parameters. * Fixed include in en_ossan for shop slot hook. Added registration for `OnShopSlotChange` in the tracker, storing the price in a new `price` field in `CheckTrackerData`. Added "seen" functionality to shop checks. Displays the model item name upon first entering a shop, adding the price and switching to trickName (if it's an ice trap) upon navigating to the slot in buy mode, triggered by an invisible "identified" status that mirrors "seen" in every other way. Added tooltips to most options for check tracker color picking to describe what each status actually means. * `std::format` pls * So apparently std::format just decided to break with the latest merge from develop, but fmt::format exists and works? * Removed the last vestiges of `locationsSkipped`. Other general code and formatting cleanups. Moved `IsGameRunning` to `OTRGlobals` so the item tracker could also access it. Used preceding to "fix" item and bottle display in the item tracker on startup. * Some more code cleanup. Removed "Recheck Area" button and relevant code. Backported changes to Anchor branch applicable for single-player, including making a checkAreas vector and structuring the frame by frame checks around that. Also includes fix for Silver Gauntlets and Mirror Shield check collection crash associated with those changes. Fixed Kakariko Bazaar "seen" updates. Fixed tracker window not showing on initial load like it should. * Forgot 1 formatting fix. * Removed conditions for showing Song from Impa (isn't junk under certain conditions, so should show all the time). * Fix vanilla checks, add Zelda's Letter and Malon's Egg to manual check collection. Fix autoscroll while in child stealth section. * Fix crash in Happy Mask Shop in OnSlotChange (referenced non-existent shop id in a tracker-specific enum). * General code cleanup. * Missed one reversion. * One more. * Fix column alignment in `randomizer_check_objects`. * Fix file encoding on `randomizer_check_tracker`. Again. * Fix indentation for `actualItemtrackerItemMap`. Also removed unnecessary parts of the map. * Rename `HasEqItem` to `HasEquipment`. * Slightly better indentation for `actualItemTrackerItemMap`. * Add magic bean salesman to vanilla check tracking, and genericized deku shield to trigger KF shop item 3 wherever you get the shield. Renamed `vanillaCheck` to `vanillaHundoCheck` to (supposedly) clarify the meaning of the usage. * One more rename to `vanillaCompletion` to avoid possible confusion with 100% speedrun conditions. * give me a break XD Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com> * Changes suggested by briaguya (rename `RandomizerCheckShow` to `Status`, unused code, newline formatting) * Remove unused `itemNames` table. * Remove `IsGameRunning` in favor of `GameInteractor::IsSaveLoaded`. * Restore anti-spoiler functionality for dungeons with dungeon maps. * Review cleanup. * Fix prices not showing for Kak bazaar items. --------- Co-authored-by: briaguya <70942617+briaguya-ai@users.noreply.github.com>
2023-10-04 11:03:36 -04:00
DEFINE_HOOK(OnShopSlotChange, void(uint8_t cursorIndex, int16_t price));
DEFINE_HOOK(OnActorInit, void(void* actor));
DEFINE_HOOK(OnActorUpdate, void(void* actor));
DEFINE_HOOK(OnActorKill, void(void* actor));
DEFINE_HOOK(OnEnemyDefeat, void(void* actor));
DEFINE_HOOK(OnPlayerBonk, void());
DEFINE_HOOK(OnPlayDestroy, void());
DEFINE_HOOK(OnPlayDrawEnd, void());
DEFINE_HOOK(OnVanillaBehavior, void(GIVanillaBehavior flag, bool* result, void* opt));
DEFINE_HOOK(OnSaveFile, void(int32_t fileNum));
DEFINE_HOOK(OnLoadFile, void(int32_t fileNum));
DEFINE_HOOK(OnDeleteFile, void(int32_t fileNum));
2023-03-02 03:27:28 -05:00
DEFINE_HOOK(OnDialogMessage, void());
DEFINE_HOOK(OnPresentTitleCard, void());
DEFINE_HOOK(OnInterfaceUpdate, void());
DEFINE_HOOK(OnKaleidoscopeUpdate, void(int16_t inDungeonScene));
DEFINE_HOOK(OnPresentFileSelect, void());
DEFINE_HOOK(OnUpdateFileSelectSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileSelectConfirmationSelection, void(uint16_t optionIndex));
2023-03-02 03:27:28 -05:00
DEFINE_HOOK(OnUpdateFileCopySelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileCopyConfirmationSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileEraseSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileAudioSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileTargetSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileLanguageSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileQuestSelection, void(uint8_t questIndex));
DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, void(uint8_t optionIndex, uint8_t optionValue));
DEFINE_HOOK(OnUpdateFileNameSelection, void(int16_t charCode));
2023-03-02 03:27:28 -05:00
DEFINE_HOOK(OnSetGameLanguage, void());
2023-02-15 14:30:34 -05:00
DEFINE_HOOK(OnFileDropped, void(std::string filePath));
DEFINE_HOOK(OnAssetAltChange, void());
Pause Warp Enhancement (#3223) * Pause Warp Enhancement This commit introduces the PauseWarp mod, a feature that allows players to warp to different locations in the game directly from the pause menu. - Add PauseWarpState structure to manage flags and cooldowns for the pause warp feature. - Implement IsStateValid function for state validation. - Implement ResetStateFlags function to reset all state flags to default values. - Add InitiateWarp function to handle the initiation of warp sequences. - Implement HandleWarpConfirmation function to confirm and execute warp actions. - Implement HandleCooldowns function to manage various cooldown timers. - Add PauseWarp_Main function as the main logic, called every frame to handle pause warp functionality. - Map warp song messages to in-game text messages. * Warp Song Check -Now if you do not have a warp song you won't be able to select the empty slot and still teleport. * Added Audio Fanfares and Changed stateFlag1 to PLAYER_STATE1_IN_CUTSCENE -When selecting a warp song the audio for the applicable warp song will now play for a extra vanilla feel. -Changed the stateFlag1 because previously it just disabled input allowing enemies to harm you. Now that won't happen because the game is put into a cutscene state. * Feedback Update -A new hook was created 'OnPauseMenu' so now PauseWarp_Main is only called when the pause menu is open -Moved pauswarp.c to the Enhancements folder -Removed from graph.c PR Change: Changing to the main branch instead of sulu * Feedback Update #2 -Introduced new function 'PauseWarp_Idle' now that 'PauseWarp_Main' is no longer called every frame -Added C wrapper to access 'GameInteractor::IsSaveLoaded' and scrapped the 'IsStateValid' function -Added 'PauseWarp_Idle' to the the 'RegisterPauseWarp' function -Refactored the code some * Linux Compile Issue -Added a missing header that was causing a compile issue for linux -Hopefully, it won't crash * Minor Bug Fix -Now link won't get soft locked when warping to the same location twice * Update libultraship * Revert "Update libultraship" This reverts commit 746fc234795c06261a4fb69484f4656676f1eaaa. * Bug Fix -Added more checks to ensure vanilla behavior when a Ocarina is not in the players inventory. * WIP * Done unless I'm missing headers * now we done * clean up, these arn't needed anymore * Rename OnPauseMenu to OnKaleidoUpdate
2024-02-15 20:13:54 -05:00
DEFINE_HOOK(OnKaleidoUpdate, void());
// Helpers
static bool IsSaveLoaded(bool allowDbgSave = false);
static bool IsGameplayPaused();
static bool CanSpawnActor();
static bool CanAddOrTakeAmmo(int16_t amount, int16_t item);
class RawAction {
public:
static void SetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag);
static void UnsetSceneFlag(int16_t sceneNum, int16_t flagType, int16_t flag);
static void SetFlag(int16_t flagType, int16_t chestNum);
static void UnsetFlag(int16_t flagType, int16_t chestNum);
static void AddOrRemoveHealthContainers(int16_t amount);
static void AddOrRemoveMagic(int8_t amount);
static void HealOrDamagePlayer(int16_t hearts);
static void SetPlayerHealth(int16_t hearts);
static void SetLinkInvisibility(bool active);
static void SetWeatherStorm(bool active);
static void ForceEquipBoots(int8_t boots);
static void FreezePlayer();
static void BurnPlayer();
static void ElectrocutePlayer();
static void KnockbackPlayer(float strength);
static void GiveOrTakeShield(int32_t shield);
static void ForceInterfaceUpdate();
static void UpdateActor(void* refActor);
static void TeleportPlayer(int32_t nextEntrance);
static void ClearAssignedButtons(uint8_t buttonSet);
static void SetTimeOfDay(uint32_t time);
static void SetCollisionViewer(bool active);
static void SetCosmeticsColor(uint8_t cosmeticCategory, uint8_t colorValue);
static void RandomizeCosmeticsColors(bool excludeBiddingWarColors);
static void EmulateButtonPress(int32_t button);
static void AddOrTakeAmmo(int16_t amount, int16_t item);
static void EmulateRandomButtonPress(uint32_t chancePercentage = 100);
static void SetRandomWind(bool active);
static void SetPlayerInvincibility(bool active);
static void ClearCutscenePointer();
static GameInteractionEffectQueryResult SpawnEnemyWithOffset(uint32_t enemyId, int32_t enemyParams);
static GameInteractionEffectQueryResult SpawnActor(uint32_t actorId, int32_t actorParams);
};
private:
#ifdef ENABLE_REMOTE_CONTROL
IPaddress remoteIP;
TCPsocket remoteSocket;
std::thread remoteThreadReceive;
std::function<void(char payload[512])> remoteDataHandler;
std::function<void(nlohmann::json)> remoteJsonHandler;
std::function<void()> remoteConnectedHandler;
std::function<void()> remoteDisconnectedHandler;
void ReceiveFromServer();
void HandleRemoteData(char payload[512]);
void HandleRemoteJson(std::string payload);
#endif
};
#endif /* __cplusplus */
#endif /* GameInteractor_h */