Fairysanity: allow using bottle (#6021)
Based on fishsanity, which is refactored with hooks Also open up logic catching fairies at oasis if player has bottle
This commit is contained in:
@@ -98,17 +98,22 @@ void RegisterShuffleFairies() {
|
||||
// Grant item when picking up fairy.
|
||||
COND_VB_SHOULD(VB_FAIRY_HEAL, shouldRegister, {
|
||||
EnElf* enElf = va_arg(args, EnElf*);
|
||||
|
||||
const auto fairyIdentity = ObjectExtension::GetInstance().Get<FairyIdentity>(&enElf->actor);
|
||||
if (fairyIdentity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fairyIdentity != nullptr && fairyIdentity->randomizerInf && fairyIdentity->randomizerInf != RAND_INF_MAX) {
|
||||
if (fairyIdentity != nullptr && fairyIdentity->randomizerInf != RAND_INF_MAX) {
|
||||
Flags_SetRandomizerInf(fairyIdentity->randomizerInf);
|
||||
}
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_BOTTLE_ACTOR, shouldRegister, {
|
||||
Actor* actor = va_arg(args, Actor*);
|
||||
const auto fairyIdentity = ObjectExtension::GetInstance().Get<FairyIdentity>(actor);
|
||||
if (fairyIdentity != nullptr && fairyIdentity->randomizerInf != RAND_INF_MAX) {
|
||||
Flags_SetRandomizerInf(fairyIdentity->randomizerInf);
|
||||
actor->parent = &GET_PLAYER(gPlayState)->actor;
|
||||
*should = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Spawn fairies in fairy fountains
|
||||
COND_VB_SHOULD(VB_SPAWN_FOUNTAIN_FAIRIES, shouldRegisterFountain, {
|
||||
Actor* actor = va_arg(args, Actor*);
|
||||
|
||||
@@ -51,11 +51,12 @@ ActorFunc drawFishing = NULL;
|
||||
ActorFunc drawEnFish = NULL;
|
||||
Color_RGB8 fsPulseColor = { 30, 240, 200 };
|
||||
|
||||
static s16 fishGroupCounter = 0;
|
||||
static bool enableAdvance = false;
|
||||
|
||||
namespace Rando {
|
||||
const FishIdentity Fishsanity::defaultIdentity = { RAND_INF_MAX, RC_UNKNOWN_CHECK };
|
||||
bool Fishsanity::fishsanityHelpersInit = false;
|
||||
s16 Fishsanity::fishGroupCounter = 0;
|
||||
bool Fishsanity::enableAdvance = false;
|
||||
std::unordered_map<RandomizerCheck, LinkAge> Fishsanity::pondFishAgeMap;
|
||||
std::vector<RandomizerCheck> Fishsanity::childPondFish;
|
||||
std::vector<RandomizerCheck> Fishsanity::adultPondFish;
|
||||
@@ -447,38 +448,6 @@ void Fishsanity::OnActorUpdateHandler(void* refActor) {
|
||||
fishGroupCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Fishsanity::OnSceneInitHandler(int16_t sceneNum) {
|
||||
if (sceneNum == SCENE_ZORAS_DOMAIN) {
|
||||
fishGroupCounter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Fishsanity::OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) {
|
||||
va_list args;
|
||||
va_copy(args, originalArgs);
|
||||
|
||||
Actor* actor = va_arg(args, Actor*);
|
||||
auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity();
|
||||
|
||||
va_end(args);
|
||||
|
||||
if (id == VB_BOTTLE_ACTOR && actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) {
|
||||
FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params);
|
||||
if (fish.randomizerCheck != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(fish.randomizerInf)) {
|
||||
Flags_SetRandomizerInf(fish.randomizerInf);
|
||||
actor->parent = &GET_PLAYER(gPlayState)->actor;
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Fishsanity::OnItemReceiveHandler(GetItemEntry itemEntry) {
|
||||
if (enableAdvance) {
|
||||
enableAdvance = false;
|
||||
OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond();
|
||||
}
|
||||
}
|
||||
} // namespace Rando
|
||||
|
||||
// C interface
|
||||
@@ -575,6 +544,37 @@ void Fishsanity_CloseGreyscaleColor(PlayState* play) {
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterShuffleFish() {
|
||||
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF;
|
||||
COND_HOOK(OnSceneInit, shouldRegister, [](int16_t sceneNum) {
|
||||
if (sceneNum == SCENE_ZORAS_DOMAIN) {
|
||||
fishGroupCounter = 0;
|
||||
}
|
||||
});
|
||||
|
||||
COND_HOOK(OnActorInit, shouldRegister, Rando::Fishsanity::OnActorInitHandler);
|
||||
COND_HOOK(OnActorUpdate, shouldRegister, Rando::Fishsanity::OnActorUpdateHandler);
|
||||
COND_HOOK(OnItemReceive, shouldRegister, [](GetItemEntry itemEntry) {
|
||||
if (enableAdvance) {
|
||||
enableAdvance = false;
|
||||
OTRGlobals::Instance->gRandoContext->GetFishsanity()->AdvancePond();
|
||||
}
|
||||
});
|
||||
|
||||
COND_VB_SHOULD(VB_BOTTLE_ACTOR, shouldRegister, {
|
||||
Actor* actor = va_arg(args, Actor*);
|
||||
auto fs = OTRGlobals::Instance->gRandoContext->GetFishsanity();
|
||||
if (actor->id == ACTOR_EN_FISH && fs->GetOverworldFishShuffled()) {
|
||||
FishIdentity fish = OTRGlobals::Instance->gRandomizer->IdentifyFish(gPlayState->sceneNum, actor->params);
|
||||
if (fish.randomizerCheck != RC_UNKNOWN_CHECK && !Flags_GetRandomizerInf(fish.randomizerInf)) {
|
||||
Flags_SetRandomizerInf(fish.randomizerInf);
|
||||
actor->parent = &GET_PLAYER(gPlayState)->actor;
|
||||
*should = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Rando::StaticData::RegisterFishLocations() {
|
||||
static bool registered = false;
|
||||
if (registered)
|
||||
@@ -634,4 +634,5 @@ void Rando::StaticData::RegisterFishLocations() {
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc registerShuffleFish(RegisterShuffleFish, { "IS_RANDO" });
|
||||
static RegisterShipInitFunc initFunc(Rando::StaticData::RegisterFishLocations);
|
||||
|
||||
@@ -137,28 +137,11 @@ class Fishsanity {
|
||||
*/
|
||||
static void OnActorInitHandler(void* refActor);
|
||||
|
||||
/**
|
||||
* @brief PlayerUpdate hook handler for fishsanity
|
||||
*/
|
||||
static void OnPlayerUpdateHandler();
|
||||
|
||||
/**
|
||||
* @brief ActorUpdate hook handler for fishsanity
|
||||
*/
|
||||
static void OnActorUpdateHandler(void* refActor);
|
||||
|
||||
/**
|
||||
* @brief SceneInit hook handler for fishsanity
|
||||
*/
|
||||
static void OnSceneInitHandler(int16_t sceneNum);
|
||||
|
||||
/**
|
||||
* @brief VB hook handler for fishsanity
|
||||
*/
|
||||
static void OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs);
|
||||
|
||||
static void OnItemReceiveHandler(GetItemEntry itemEntry);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Initialize helper statics if they have not been initialized yet
|
||||
@@ -184,9 +167,6 @@ class Fishsanity {
|
||||
*/
|
||||
static bool fishsanityHelpersInit;
|
||||
|
||||
static s16 fishGroupCounter;
|
||||
static bool enableAdvance;
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//// Helper data structures derived from static data ////
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include "soh/Enhancements/item-tables/ItemTableManager.h"
|
||||
#include "soh/Enhancements/randomizer/randomizerTypes.h"
|
||||
#include "soh/Enhancements/randomizer/dungeon.h"
|
||||
#include "soh/Enhancements/randomizer/fishsanity.h"
|
||||
#include "soh/Enhancements/randomizer/static_data.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
@@ -2438,12 +2437,6 @@ void RandomizerRegisterHooks() {
|
||||
static uint32_t onKaleidoUpdateHook = 0;
|
||||
static uint32_t onCuccoOrChickenHatchHook = 0;
|
||||
|
||||
static uint32_t fishsanityOnActorInitHook = 0;
|
||||
static uint32_t fishsanityOnActorUpdateHook = 0;
|
||||
static uint32_t fishsanityOnSceneInitHook = 0;
|
||||
static uint32_t fishsanityOnVanillaBehaviorHook = 0;
|
||||
static uint32_t fishsanityOnItemReceiveHook = 0;
|
||||
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnLoadGame>([](int32_t fileNum) {
|
||||
ShipInit::Init("IS_RANDO");
|
||||
|
||||
@@ -2470,13 +2463,6 @@ void RandomizerRegisterHooks() {
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnKaleidoscopeUpdate>(onKaleidoUpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnCuccoOrChickenHatch>(onCuccoOrChickenHatchHook);
|
||||
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorInit>(fishsanityOnActorInitHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnActorUpdate>(fishsanityOnActorUpdateHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnSceneInit>(fishsanityOnSceneInitHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(
|
||||
fishsanityOnVanillaBehaviorHook);
|
||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnItemReceive>(fishsanityOnItemReceiveHook);
|
||||
|
||||
onFlagSetHook = 0;
|
||||
onSceneFlagSetHook = 0;
|
||||
onPlayerUpdateForRCQueueHook = 0;
|
||||
@@ -2496,12 +2482,6 @@ void RandomizerRegisterHooks() {
|
||||
onKaleidoUpdateHook = 0;
|
||||
onCuccoOrChickenHatchHook = 0;
|
||||
|
||||
fishsanityOnActorInitHook = 0;
|
||||
fishsanityOnActorUpdateHook = 0;
|
||||
fishsanityOnSceneInitHook = 0;
|
||||
fishsanityOnVanillaBehaviorHook = 0;
|
||||
fishsanityOnItemReceiveHook = 0;
|
||||
|
||||
if (!IS_RANDO)
|
||||
return;
|
||||
|
||||
@@ -2553,18 +2533,6 @@ void RandomizerRegisterHooks() {
|
||||
|
||||
if (RAND_GET_OPTION(RSK_FISHSANITY) != RO_FISHSANITY_OFF) {
|
||||
OTRGlobals::Instance->gRandoContext->GetFishsanity()->InitializeFromSave();
|
||||
|
||||
fishsanityOnActorInitHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorInit>(
|
||||
Rando::Fishsanity::OnActorInitHandler);
|
||||
fishsanityOnActorUpdateHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnActorUpdate>(
|
||||
Rando::Fishsanity::OnActorUpdateHandler);
|
||||
fishsanityOnSceneInitHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnSceneInit>(
|
||||
Rando::Fishsanity::OnSceneInitHandler);
|
||||
fishsanityOnVanillaBehaviorHook =
|
||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(
|
||||
Rando::Fishsanity::OnVanillaBehaviorHandler);
|
||||
fishsanityOnItemReceiveHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnItemReceive>(
|
||||
Rando::Fishsanity::OnItemReceiveHandler);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ void RegionTable_Init_DesertColossus() {
|
||||
}, {
|
||||
//Exits
|
||||
//You can kinda get the fairies without entering the water, but it relies on them cooperating and leevers are jerks. should be a trick
|
||||
Entrance(RR_DESERT_COLOSSUS_OASIS, []{return logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS));}),
|
||||
Entrance(RR_DESERT_COLOSSUS_OASIS, []{return logic->CanUse(RG_SONG_OF_STORMS) && (logic->HasItem(RG_BRONZE_SCALE) || logic->CanUse(RG_IRON_BOOTS) || logic->CanUse(RG_EMPTY_BOTTLE));}),
|
||||
Entrance(RR_COLOSSUS_GREAT_FAIRY_FOUNTAIN, []{return logic->HasExplosives();}),
|
||||
Entrance(RR_SPIRIT_TEMPLE_ENTRYWAY, []{return true;}),
|
||||
Entrance(RR_WASTELAND_NEAR_COLOSSUS, []{return true;}),
|
||||
|
||||
Reference in New Issue
Block a user