mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 21:33:40 -07:00
ShuffleFairies: ShipInit (#5582)
* ShuffleFairies: ShipInit * fix big fairy items
This commit is contained in:
parent
073205c862
commit
7f4c570a47
5 changed files with 49 additions and 72 deletions
|
@ -1,18 +1,19 @@
|
||||||
#include "ShuffleFairies.h"
|
|
||||||
#include "randomizer_grotto.h"
|
#include "randomizer_grotto.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h"
|
#include "src/overlays/actors/ovl_En_Elf/z_en_elf.h"
|
||||||
#include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h"
|
#include "src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h"
|
||||||
#include "src/overlays/actors/ovl_En_Gs/z_en_gs.h"
|
#include "src/overlays/actors/ovl_En_Gs/z_en_gs.h"
|
||||||
#include "src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h"
|
#include "src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h"
|
||||||
#include "../../OTRGlobals.h"
|
#include "soh/OTRGlobals.h"
|
||||||
#include "../../cvar_prefixes.h"
|
#include "soh/cvar_prefixes.h"
|
||||||
|
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
||||||
#include "static_data.h"
|
#include "static_data.h"
|
||||||
|
|
||||||
#define FAIRY_FLAG_TIMED (1 << 8)
|
#define FAIRY_FLAG_TIMED (1 << 8)
|
||||||
|
|
||||||
void ShuffleFairies_DrawRandomizedItem(EnElf* enElf, PlayState* play) {
|
void ShuffleFairies_DrawRandomizedItem(EnElf* enElf, PlayState* play) {
|
||||||
GetItemEntry randoGetItem = enElf->sohFairyIdentity.itemEntry;
|
GetItemEntry randoGetItem =
|
||||||
|
Rando::Context::GetInstance()->GetFinalGIEntry(enElf->sohFairyIdentity.randomizerCheck, true, GI_FAIRY);
|
||||||
if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) {
|
if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) {
|
||||||
randoGetItem = GET_ITEM_MYSTERY;
|
randoGetItem = GET_ITEM_MYSTERY;
|
||||||
}
|
}
|
||||||
|
@ -60,18 +61,17 @@ FairyIdentity ShuffleFairies_GetFairyIdentity(int32_t params) {
|
||||||
assert(false);
|
assert(false);
|
||||||
} else {
|
} else {
|
||||||
fairyIdentity.randomizerInf = static_cast<RandomizerInf>(location->GetCollectionCheck().flag);
|
fairyIdentity.randomizerInf = static_cast<RandomizerInf>(location->GetCollectionCheck().flag);
|
||||||
fairyIdentity.itemEntry =
|
fairyIdentity.randomizerCheck = location->GetRandomizerCheck();
|
||||||
Rando::Context::GetInstance()->GetFinalGIEntry(location->GetRandomizerCheck(), true, GI_FAIRY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fairyIdentity;
|
return fairyIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShuffleFairies_SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params) {
|
static bool SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params, FairyType fairyType) {
|
||||||
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
|
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
|
||||||
if (!Flags_GetRandomizerInf(fairyIdentity.randomizerInf)) {
|
if (!Flags_GetRandomizerInf(fairyIdentity.randomizerInf)) {
|
||||||
EnElf* fairy = (EnElf*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0,
|
EnElf* fairy = (EnElf*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0,
|
||||||
0, 0, FAIRY_HEAL, true);
|
0, 0, fairyType, true);
|
||||||
fairy->sohFairyIdentity = fairyIdentity;
|
fairy->sohFairyIdentity = fairyIdentity;
|
||||||
fairy->actor.draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem;
|
fairy->actor.draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem;
|
||||||
return true;
|
return true;
|
||||||
|
@ -79,58 +79,62 @@ bool ShuffleFairies_SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should, va_list originalArgs) {
|
void RegisterShuffleFairies() {
|
||||||
va_list args;
|
bool shouldRegister = IS_RANDO && RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES);
|
||||||
va_copy(args, originalArgs);
|
|
||||||
|
|
||||||
Actor* actor = va_arg(args, Actor*);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
// Grant item when picking up fairy.
|
// Grant item when picking up fairy.
|
||||||
if (id == VB_FAIRY_HEAL) {
|
COND_VB_SHOULD(VB_FAIRY_HEAL, shouldRegister, {
|
||||||
EnElf* enElf = (EnElf*)(actor);
|
EnElf* enElf = va_arg(args, EnElf*);
|
||||||
if (enElf->sohFairyIdentity.randomizerInf && enElf->sohFairyIdentity.randomizerInf != RAND_INF_MAX) {
|
if (enElf->sohFairyIdentity.randomizerInf && enElf->sohFairyIdentity.randomizerInf != RAND_INF_MAX) {
|
||||||
Flags_SetRandomizerInf(enElf->sohFairyIdentity.randomizerInf);
|
Flags_SetRandomizerInf(enElf->sohFairyIdentity.randomizerInf);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Spawn fairies in fairy fountains
|
// Spawn fairies in fairy fountains
|
||||||
} else if (id == VB_SPAWN_FOUNTAIN_FAIRIES) {
|
COND_VB_SHOULD(VB_SPAWN_FOUNTAIN_FAIRIES, shouldRegister, {
|
||||||
|
Actor* actor = va_arg(args, Actor*);
|
||||||
bool fairySpawned = false;
|
bool fairySpawned = false;
|
||||||
s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0;
|
s16 grottoId = (gPlayState->sceneNum == SCENE_FAIRYS_FOUNTAIN) ? Grotto_CurrentGrotto() : 0;
|
||||||
for (s16 index = 0; index < 8; index++) {
|
for (s16 index = 0; index < 8; index++) {
|
||||||
int32_t params = (grottoId << 8) | index;
|
int32_t params = (grottoId << 8) | index;
|
||||||
if (ShuffleFairies_SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, params)) {
|
if (SpawnFairy(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, params, FAIRY_HEAL)) {
|
||||||
fairySpawned = true;
|
fairySpawned = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fairySpawned) {
|
if (fairySpawned) {
|
||||||
*should = false;
|
*should = false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Spawn 3 fairies when playing Song of Storms next to a planted bean
|
// Spawn 3 fairies when playing Song of Storms next to a planted bean
|
||||||
} else if (id == VB_SPAWN_BEAN_STALK_FAIRIES) {
|
COND_VB_SHOULD(VB_SPAWN_BEAN_STALK_FAIRIES, shouldRegister, {
|
||||||
ObjBean* objBean = (ObjBean*)(actor);
|
ObjBean* objBean = va_arg(args, ObjBean*);
|
||||||
bool fairySpawned = false;
|
bool fairySpawned = false;
|
||||||
for (s16 index = 0; index < 3; index++) {
|
for (s16 index = 0; index < 3; index++) {
|
||||||
int32_t params = ((objBean->dyna.actor.params & 0x3F) << 8) | index;
|
int32_t params = ((objBean->dyna.actor.params & 0x3F) << 8) | index;
|
||||||
if (ShuffleFairies_SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y,
|
if (SpawnFairy(objBean->dyna.actor.world.pos.x, objBean->dyna.actor.world.pos.y,
|
||||||
objBean->dyna.actor.world.pos.z, params)) {
|
objBean->dyna.actor.world.pos.z, params, FAIRY_HEAL)) {
|
||||||
fairySpawned = true;
|
fairySpawned = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fairySpawned) {
|
if (fairySpawned) {
|
||||||
*should = false;
|
*should = false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Spawn a fairy from a ShotSun when playing the right song near it
|
// Spawn a fairy from a ShotSun when playing the right song near it
|
||||||
} else if (id == VB_SPAWN_SONG_FAIRY) {
|
COND_VB_SHOULD(VB_SPAWN_SONG_FAIRY, shouldRegister, {
|
||||||
ShotSun* shotSun = (ShotSun*)(actor);
|
ShotSun* shotSun = va_arg(args, ShotSun*);
|
||||||
if (ShuffleFairies_SpawnFairy(shotSun->actor.world.pos.x, shotSun->actor.world.pos.y,
|
if (SpawnFairy(shotSun->actor.world.pos.x, shotSun->actor.world.pos.y, shotSun->actor.world.pos.z,
|
||||||
shotSun->actor.world.pos.z,
|
TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z), FAIRY_HEAL_BIG)) {
|
||||||
TWO_ACTOR_PARAMS(0x1000, (int32_t)shotSun->actor.world.pos.z))) {
|
|
||||||
*should = false;
|
*should = false;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Handle playing both misc songs and song of storms in front of a gossip stone.
|
// Handle playing both misc songs and song of storms in front of a gossip stone.
|
||||||
} else if (id == VB_SPAWN_GOSSIP_STONE_FAIRY) {
|
COND_VB_SHOULD(VB_SPAWN_GOSSIP_STONE_FAIRY, shouldRegister, {
|
||||||
EnGs* gossipStone = (EnGs*)(actor);
|
EnGs* gossipStone = va_arg(args, EnGs*);
|
||||||
|
FairyType fairyType = FAIRY_HEAL;
|
||||||
|
|
||||||
// Mimic vanilla behaviour, only go into this path if song played is one of the ones normally spawning a fairy.
|
// Mimic vanilla behaviour, only go into this path if song played is one of the ones normally spawning a fairy.
|
||||||
// Otherwise fall back to vanilla behaviour.
|
// Otherwise fall back to vanilla behaviour.
|
||||||
|
@ -144,6 +148,7 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should,
|
||||||
// Distinguish storms fairies from the normal song fairies
|
// Distinguish storms fairies from the normal song fairies
|
||||||
if (gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_STORMS) {
|
if (gPlayState->msgCtx.unk_E3F2 == OCARINA_SONG_STORMS) {
|
||||||
params |= 0x1000;
|
params |= 0x1000;
|
||||||
|
fairyType = FAIRY_HEAL_BIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine actor + song params with position to get the right randomizer check
|
// Combine actor + song params with position to get the right randomizer check
|
||||||
|
@ -156,8 +161,8 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should,
|
||||||
// collected, the vanilla code will handle that part automatically.
|
// collected, the vanilla code will handle that part automatically.
|
||||||
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
|
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
|
||||||
if (!ShuffleFairies_FairyExists(fairyIdentity)) {
|
if (!ShuffleFairies_FairyExists(fairyIdentity)) {
|
||||||
if (ShuffleFairies_SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y,
|
if (SpawnFairy(gossipStone->actor.world.pos.x, gossipStone->actor.world.pos.y,
|
||||||
gossipStone->actor.world.pos.z, params)) {
|
gossipStone->actor.world.pos.z, params, fairyType)) {
|
||||||
Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY);
|
Audio_PlayActorSound2(&gossipStone->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY);
|
||||||
// Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well.
|
// Set vanilla check for fairy spawned so it doesn't spawn the vanilla fairy afterwards as well.
|
||||||
gossipStone->unk_19D = 0;
|
gossipStone->unk_19D = 0;
|
||||||
|
@ -167,20 +172,7 @@ void ShuffleFairies_OnVanillaBehaviorHandler(GIVanillaBehavior id, bool* should,
|
||||||
*should = false;
|
*should = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t onVanillaBehaviorHook = 0;
|
|
||||||
|
|
||||||
void ShuffleFairies_RegisterHooks() {
|
|
||||||
onVanillaBehaviorHook = GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(
|
|
||||||
ShuffleFairies_OnVanillaBehaviorHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShuffleFairies_UnregisterHooks() {
|
|
||||||
GameInteractor::Instance->UnregisterGameHook<GameInteractor::OnVanillaBehavior>(onVanillaBehaviorHook);
|
|
||||||
|
|
||||||
onVanillaBehaviorHook = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rando::StaticData::RegisterFairyLocations() {
|
void Rando::StaticData::RegisterFairyLocations() {
|
||||||
|
@ -412,4 +404,5 @@ void Rando::StaticData::RegisterFairyLocations() {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
static RegisterShipInitFunc initFunc(Rando::StaticData::RegisterFairyLocations);
|
static RegisterShipInitFunc registerShuffleFairies(RegisterShuffleFairies, { "IS_RANDO" });
|
||||||
|
static RegisterShipInitFunc registerShuffleFairiesLocations(Rando::StaticData::RegisterFairyLocations);
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <z64.h>
|
|
||||||
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
|
||||||
#include "randomizerTypes.h"
|
|
||||||
|
|
||||||
typedef struct FairyIdentity {
|
|
||||||
RandomizerInf randomizerInf;
|
|
||||||
GetItemEntry itemEntry;
|
|
||||||
} FairyIdentity;
|
|
||||||
|
|
||||||
void ShuffleFairies_RegisterHooks();
|
|
||||||
void ShuffleFairies_UnregisterHooks();
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "soh/SohGui/ImGuiUtils.h"
|
#include "soh/SohGui/ImGuiUtils.h"
|
||||||
#include "soh/Notification/Notification.h"
|
#include "soh/Notification/Notification.h"
|
||||||
#include "soh/SaveManager.h"
|
#include "soh/SaveManager.h"
|
||||||
#include "soh/Enhancements/randomizer/ShuffleFairies.h"
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
@ -2396,8 +2395,6 @@ void RandomizerRegisterHooks() {
|
||||||
|
|
||||||
shuffleFreestandingOnVanillaBehaviorHook = 0;
|
shuffleFreestandingOnVanillaBehaviorHook = 0;
|
||||||
|
|
||||||
ShuffleFairies_UnregisterHooks();
|
|
||||||
|
|
||||||
if (!IS_RANDO)
|
if (!IS_RANDO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2468,9 +2465,5 @@ void RandomizerRegisterHooks() {
|
||||||
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(
|
GameInteractor::Instance->RegisterGameHook<GameInteractor::OnVanillaBehavior>(
|
||||||
ShuffleFreestanding_OnVanillaBehaviorHandler);
|
ShuffleFreestanding_OnVanillaBehaviorHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RAND_GET_OPTION(RSK_SHUFFLE_FAIRIES)) {
|
|
||||||
ShuffleFairies_RegisterHooks();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6361,6 +6361,11 @@ typedef struct FishIdentity {
|
||||||
RandomizerCheck randomizerCheck;
|
RandomizerCheck randomizerCheck;
|
||||||
} FishIdentity;
|
} FishIdentity;
|
||||||
|
|
||||||
|
typedef struct FairyIdentity {
|
||||||
|
RandomizerInf randomizerInf;
|
||||||
|
RandomizerCheck randomizerCheck;
|
||||||
|
} FairyIdentity;
|
||||||
|
|
||||||
typedef struct GrassIdentity {
|
typedef struct GrassIdentity {
|
||||||
RandomizerInf randomizerInf;
|
RandomizerInf randomizerInf;
|
||||||
RandomizerCheck randomizerCheck;
|
RandomizerCheck randomizerCheck;
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include <libultraship/libultra.h>
|
#include <libultraship/libultra.h>
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "overlays/actors/ovl_Elf_Msg/z_elf_msg.h"
|
#include "overlays/actors/ovl_Elf_Msg/z_elf_msg.h"
|
||||||
#include "soh/Enhancements/randomizer/ShuffleFairies.h"
|
|
||||||
|
|
||||||
struct EnElf;
|
struct EnElf;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue