mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-14 10:37:17 -07:00
Shuffles: use ObjectExtension system for rando object identity (#5603)
Some checks are pending
Some checks are pending
This commit is contained in:
parent
1d24edaa92
commit
9e686ae6f6
14 changed files with 142 additions and 105 deletions
|
@ -1,6 +1,5 @@
|
|||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "soh/Enhancements/randomizer/context.h"
|
||||
|
||||
extern "C" {
|
||||
extern PlayState* gPlayState;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <soh/OTRGlobals.h>
|
||||
#include "static_data.h"
|
||||
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||
|
||||
extern "C" {
|
||||
#include "src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h"
|
||||
|
@ -10,12 +11,14 @@ extern void EnItem00_DrawRandomizedItem(EnItem00* enItem00, PlayState* play);
|
|||
|
||||
void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) {
|
||||
s16 params = objComb->actor.params & 0x1F;
|
||||
const auto beehiveIdentity = ObjectExtension::GetInstance().Get<BeehiveIdentity>(&objComb->actor);
|
||||
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity != nullptr &&
|
||||
!Flags_GetRandomizerInf(beehiveIdentity->randomizerInf)) {
|
||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &objComb->actor.world.pos, ITEM00_SOH_DUMMY);
|
||||
item00->randoInf = objComb->beehiveIdentity.randomizerInf;
|
||||
item00->randoInf = beehiveIdentity->randomizerInf;
|
||||
item00->itemEntry =
|
||||
OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(objComb->beehiveIdentity.randomizerCheck, GI_NONE);
|
||||
OTRGlobals::Instance->gRandomizer->GetItemFromKnownCheck(beehiveIdentity->randomizerCheck, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
return;
|
||||
}
|
||||
|
@ -37,10 +40,11 @@ void ObjComb_RandomizerChooseItemDrop(ObjComb* objComb, PlayState* play) {
|
|||
}
|
||||
|
||||
void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
|
||||
s32 dmgFlags;
|
||||
|
||||
objComb->unk_1B0 -= 50;
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && !Flags_GetRandomizerInf(objComb->beehiveIdentity.randomizerInf)) {
|
||||
|
||||
const auto beehiveIdentity = ObjectExtension::GetInstance().Get<BeehiveIdentity>(&objComb->actor);
|
||||
if (RAND_GET_OPTION(RSK_SHUFFLE_BEEHIVES) && beehiveIdentity == nullptr &&
|
||||
!Flags_GetRandomizerInf(beehiveIdentity->randomizerInf)) {
|
||||
if (objComb->unk_1B0 <= -5000) {
|
||||
objComb->unk_1B0 = 1500;
|
||||
}
|
||||
|
@ -50,7 +54,7 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
|
|||
|
||||
if ((objComb->collider.base.acFlags & AC_HIT) != 0) {
|
||||
objComb->collider.base.acFlags &= ~AC_HIT;
|
||||
dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags;
|
||||
s32 dmgFlags = objComb->collider.elements[0].info.acHitInfo->toucher.dmgFlags;
|
||||
if (dmgFlags & 0x4001F866) {
|
||||
objComb->unk_1B0 = 1500;
|
||||
} else {
|
||||
|
@ -70,8 +74,9 @@ void ObjComb_RandomizerWait(ObjComb* objComb, PlayState* play) {
|
|||
void ObjComb_RandomizerInit(void* actor) {
|
||||
ObjComb* objComb = static_cast<ObjComb*>(actor);
|
||||
s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1);
|
||||
objComb->beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(
|
||||
auto beehiveIdentity = OTRGlobals::Instance->gRandomizer->IdentifyBeehive(
|
||||
gPlayState->sceneNum, (s16)objComb->actor.world.pos.x, respawnData);
|
||||
ObjectExtension::GetInstance().Set<BeehiveIdentity>(actor, std::move(beehiveIdentity));
|
||||
objComb->actionFunc = (ObjCombActionFunc)ObjComb_RandomizerWait;
|
||||
}
|
||||
|
||||
|
@ -132,4 +137,5 @@ void Rando::StaticData::RegisterBeehiveLocations() {
|
|||
// clang-format-on
|
||||
}
|
||||
|
||||
static ObjectExtension::Register<BeehiveIdentity> RegisterBeehiveIdentity;
|
||||
static RegisterShipInitFunc registerFunc(Rando::StaticData::RegisterBeehiveLocations);
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "ShuffleCrates.h"
|
||||
#include <soh/OTRGlobals.h>
|
||||
#include "soh_assets.h"
|
||||
#include "static_data.h"
|
||||
#include <libultraship/libultra.h>
|
||||
#include "global.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||
|
||||
extern "C" {
|
||||
#include "variables.h"
|
||||
|
@ -31,8 +32,14 @@ extern "C" void ObjKibako2_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||
return;
|
||||
}
|
||||
|
||||
const auto crateIdentity = ObjectExtension::GetInstance().Get<CrateIdentity>(thisx);
|
||||
if (crateIdentity == nullptr) {
|
||||
Gfx_DrawDListOpa(play, (Gfx*)gLargeRandoCrateDL);
|
||||
return;
|
||||
}
|
||||
|
||||
GetItemEntry crateItem =
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(crateActor->crateIdentity.randomizerCheck, true, GI_NONE);
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE);
|
||||
getItemCategory = crateItem.getItemCategory;
|
||||
|
||||
// If they have bombchus, don't consider the bombchu item major
|
||||
|
@ -99,8 +106,14 @@ extern "C" void ObjKibako_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||
return;
|
||||
}
|
||||
|
||||
GetItemEntry smallCrateItem = Rando::Context::GetInstance()->GetFinalGIEntry(
|
||||
smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE);
|
||||
const auto crateIdentity = ObjectExtension::GetInstance().Get<SmallCrateIdentity>(thisx);
|
||||
if (crateIdentity == nullptr) {
|
||||
Gfx_DrawDListOpa(play, (Gfx*)gSmallRandoCrateDL);
|
||||
return;
|
||||
}
|
||||
|
||||
GetItemEntry smallCrateItem =
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE);
|
||||
getItemCategory = smallCrateItem.getItemCategory;
|
||||
|
||||
// If they have bombchus, don't consider the bombchu item major
|
||||
|
@ -154,15 +167,19 @@ extern "C" void ObjKibako_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||
}
|
||||
|
||||
uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play) {
|
||||
RandomizerCheck rc = crateActor->crateIdentity.randomizerCheck;
|
||||
const auto crateIdentity = ObjectExtension::GetInstance().Get<CrateIdentity>(&crateActor->dyna.actor);
|
||||
if (crateIdentity == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RandomizerCheck rc = crateIdentity->randomizerCheck;
|
||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||
uint8_t crateSetting = RAND_GET_OPTION(RSK_SHUFFLE_CRATES);
|
||||
|
||||
// Don't pull randomized item if crate isn't randomized or is already checked
|
||||
if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) ||
|
||||
(crateSetting == RO_SHUFFLE_CRATES_DUNGEONS && !isDungeon) ||
|
||||
Flags_GetRandomizerInf(crateActor->crateIdentity.randomizerInf) ||
|
||||
crateActor->crateIdentity.randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
Flags_GetRandomizerInf(crateIdentity->randomizerInf) || crateIdentity->randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -170,15 +187,19 @@ uint8_t ObjKibako2_RandomizerHoldsItem(ObjKibako2* crateActor, PlayState* play)
|
|||
}
|
||||
|
||||
uint8_t ObjKibako_RandomizerHoldsItem(ObjKibako* smallCrateActor, PlayState* play) {
|
||||
RandomizerCheck rc = smallCrateActor->smallCrateIdentity.randomizerCheck;
|
||||
const auto crateIdentity = ObjectExtension::GetInstance().Get<SmallCrateIdentity>(&smallCrateActor->actor);
|
||||
if (crateIdentity == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RandomizerCheck rc = crateIdentity->randomizerCheck;
|
||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||
uint8_t crateSetting = RAND_GET_OPTION(RSK_SHUFFLE_CRATES);
|
||||
|
||||
// Don't pull randomized item if crate isn't randomized or is already checked
|
||||
if (!IS_RANDO || (crateSetting == RO_SHUFFLE_CRATES_OVERWORLD && isDungeon) ||
|
||||
(crateSetting == RO_SHUFFLE_CRATES_DUNGEONS && !isDungeon) ||
|
||||
Flags_GetRandomizerInf(smallCrateActor->smallCrateIdentity.randomizerInf) ||
|
||||
smallCrateActor->smallCrateIdentity.randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
Flags_GetRandomizerInf(crateIdentity->randomizerInf) || crateIdentity->randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -186,10 +207,14 @@ uint8_t ObjKibako_RandomizerHoldsItem(ObjKibako* smallCrateActor, PlayState* pla
|
|||
}
|
||||
|
||||
void ObjKibako2_RandomizerSpawnCollectible(ObjKibako2* crateActor, PlayState* play) {
|
||||
const auto crateIdentity = ObjectExtension::GetInstance().Get<CrateIdentity>(&crateActor->dyna.actor);
|
||||
if (crateIdentity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &crateActor->dyna.actor.world.pos, ITEM00_SOH_DUMMY);
|
||||
item00->randoInf = crateActor->crateIdentity.randomizerInf;
|
||||
item00->itemEntry =
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(crateActor->crateIdentity.randomizerCheck, true, GI_NONE);
|
||||
item00->randoInf = crateIdentity->randomizerInf;
|
||||
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
|
@ -197,10 +222,14 @@ void ObjKibako2_RandomizerSpawnCollectible(ObjKibako2* crateActor, PlayState* pl
|
|||
}
|
||||
|
||||
void ObjKibako_RandomizerSpawnCollectible(ObjKibako* smallCrateActor, PlayState* play) {
|
||||
const auto crateIdentity = ObjectExtension::GetInstance().Get<SmallCrateIdentity>(&smallCrateActor->actor);
|
||||
if (crateIdentity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &smallCrateActor->actor.world.pos, ITEM00_SOH_DUMMY);
|
||||
item00->randoInf = smallCrateActor->smallCrateIdentity.randomizerInf;
|
||||
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(
|
||||
smallCrateActor->smallCrateIdentity.randomizerCheck, true, GI_NONE);
|
||||
item00->randoInf = crateIdentity->randomizerInf;
|
||||
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(crateIdentity->randomizerCheck, true, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
|
@ -231,8 +260,9 @@ void ObjKibako2_RandomizerInit(void* actorRef) {
|
|||
|
||||
ObjKibako2* crateActor = static_cast<ObjKibako2*>(actorRef);
|
||||
|
||||
crateActor->crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCrate(
|
||||
gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z);
|
||||
auto crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifyCrate(gPlayState->sceneNum, (s16)actor->world.pos.x,
|
||||
(s16)actor->world.pos.z);
|
||||
ObjectExtension::GetInstance().Set<CrateIdentity>(actor, std::move(crateIdentity));
|
||||
}
|
||||
|
||||
void ObjKibako_RandomizerInit(void* actorRef) {
|
||||
|
@ -243,8 +273,9 @@ void ObjKibako_RandomizerInit(void* actorRef) {
|
|||
|
||||
ObjKibako* smallCrateActor = static_cast<ObjKibako*>(actorRef);
|
||||
|
||||
smallCrateActor->smallCrateIdentity = OTRGlobals::Instance->gRandomizer->IdentifySmallCrate(
|
||||
auto crateIdentity = OTRGlobals::Instance->gRandomizer->IdentifySmallCrate(
|
||||
gPlayState->sceneNum, (s16)actor->home.pos.x, (s16)actor->home.pos.z);
|
||||
ObjectExtension::GetInstance().Set<SmallCrateIdentity>(actor, std::move(crateIdentity));
|
||||
}
|
||||
|
||||
void RegisterShuffleCrates() {
|
||||
|
@ -564,5 +595,7 @@ void Rando::StaticData::RegisterCrateLocations() {
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
static ObjectExtension::Register<CrateIdentity> RegisterCrateIdentity;
|
||||
static ObjectExtension::Register<SmallCrateIdentity> RegisterSmallCrateIdentity;
|
||||
static RegisterShipInitFunc initFunc(RegisterShuffleCrates, { "IS_RANDO" });
|
||||
static RegisterShipInitFunc locFunc(Rando::StaticData::RegisterCrateLocations);
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef ShuffleCrates_H
|
||||
#define ShuffleCrates_H
|
||||
|
||||
#include <z64.h>
|
||||
#include <soh/OTRGlobals.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void ObjKibako2_RandomizerInit(void* actorRef);
|
||||
void ObjKibako_RandomizerInit(void* actorRef);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // ShuffleCrates_H
|
|
@ -1,19 +1,28 @@
|
|||
#include "soh/OTRGlobals.h"
|
||||
#include "randomizer_grotto.h"
|
||||
#include "draw.h"
|
||||
#include "soh/cvar_prefixes.h"
|
||||
#include "static_data.h"
|
||||
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
||||
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||
|
||||
extern "C" {
|
||||
#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_En_Gs/z_en_gs.h"
|
||||
#include "src/overlays/actors/ovl_Shot_Sun/z_shot_sun.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/cvar_prefixes.h"
|
||||
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
|
||||
#include "static_data.h"
|
||||
}
|
||||
|
||||
#define FAIRY_FLAG_TIMED (1 << 8)
|
||||
|
||||
void ShuffleFairies_DrawRandomizedItem(EnElf* enElf, PlayState* play) {
|
||||
const auto fairyIdentity = ObjectExtension::GetInstance().Get<FairyIdentity>(&enElf->actor);
|
||||
if (fairyIdentity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
GetItemEntry randoGetItem =
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(enElf->sohFairyIdentity.randomizerCheck, true, GI_FAIRY);
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(fairyIdentity->randomizerCheck, true, GI_FAIRY);
|
||||
if (CVarGetInteger(CVAR_RANDOMIZER_ENHANCEMENT("MysteriousShuffle"), 0)) {
|
||||
randoGetItem = GET_ITEM_MYSTERY;
|
||||
}
|
||||
|
@ -33,8 +42,8 @@ bool ShuffleFairies_FairyExists(FairyIdentity fairyIdentity) {
|
|||
if (actor->id != ACTOR_EN_ELF) {
|
||||
actor = actor->next;
|
||||
} else {
|
||||
EnElf* enElf = (EnElf*)(actor);
|
||||
if (fairyIdentity.randomizerInf == enElf->sohFairyIdentity.randomizerInf) {
|
||||
const auto actorFairyIdentity = ObjectExtension::GetInstance().Get<FairyIdentity>(&actor);
|
||||
if (actorFairyIdentity != nullptr && fairyIdentity.randomizerInf == actorFairyIdentity->randomizerInf) {
|
||||
return true;
|
||||
}
|
||||
actor = actor->next;
|
||||
|
@ -70,10 +79,10 @@ FairyIdentity ShuffleFairies_GetFairyIdentity(int32_t params) {
|
|||
static bool SpawnFairy(f32 posX, f32 posY, f32 posZ, int32_t params, FairyType fairyType) {
|
||||
FairyIdentity fairyIdentity = ShuffleFairies_GetFairyIdentity(params);
|
||||
if (!Flags_GetRandomizerInf(fairyIdentity.randomizerInf)) {
|
||||
EnElf* fairy = (EnElf*)Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0,
|
||||
0, 0, fairyType, true);
|
||||
fairy->sohFairyIdentity = fairyIdentity;
|
||||
fairy->actor.draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem;
|
||||
Actor* fairy = Actor_Spawn(&gPlayState->actorCtx, gPlayState, ACTOR_EN_ELF, posX, posY - 30.0f, posZ, 0, 0, 0,
|
||||
fairyType, true);
|
||||
ObjectExtension::GetInstance().Set<FairyIdentity>(fairy, std::move(fairyIdentity));
|
||||
fairy->draw = (ActorFunc)ShuffleFairies_DrawRandomizedItem;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -85,8 +94,14 @@ void RegisterShuffleFairies() {
|
|||
// Grant item when picking up fairy.
|
||||
COND_VB_SHOULD(VB_FAIRY_HEAL, shouldRegister, {
|
||||
EnElf* enElf = va_arg(args, EnElf*);
|
||||
if (enElf->sohFairyIdentity.randomizerInf && enElf->sohFairyIdentity.randomizerInf != RAND_INF_MAX) {
|
||||
Flags_SetRandomizerInf(enElf->sohFairyIdentity.randomizerInf);
|
||||
|
||||
const auto fairyIdentity = ObjectExtension::GetInstance().Get<FairyIdentity>(&enElf->actor);
|
||||
if (fairyIdentity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fairyIdentity != nullptr && fairyIdentity->randomizerInf && fairyIdentity->randomizerInf != RAND_INF_MAX) {
|
||||
Flags_SetRandomizerInf(fairyIdentity->randomizerInf);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -404,5 +419,6 @@ void Rando::StaticData::RegisterFairyLocations() {
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
static ObjectExtension::Register<FairyIdentity> RegisterFairyIdentity;
|
||||
static RegisterShipInitFunc registerShuffleFairies(RegisterShuffleFairies, { "IS_RANDO" });
|
||||
static RegisterShipInitFunc registerShuffleFairiesLocations(Rando::StaticData::RegisterFairyLocations);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "ShuffleGrass.h"
|
||||
#include <soh/OTRGlobals.h>
|
||||
#include "soh_assets.h"
|
||||
#include "static_data.h"
|
||||
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||
#include "soh/Enhancements/enhancementTypes.h"
|
||||
|
||||
extern "C" {
|
||||
|
@ -27,18 +28,20 @@ extern "C" void EnKusa_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||
static Gfx* dLists[] = { (Gfx*)gRandoBushJunkDL, (Gfx*)gRandoCuttableGrassJunkDL, (Gfx*)gRandoCuttableGrassJunkDL };
|
||||
auto grassActor = ((EnKusa*)thisx);
|
||||
|
||||
const auto grassIdentity = ObjectExtension::GetInstance().Get<GrassIdentity>(thisx);
|
||||
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
Gfx_SetupDL_25Opa(play->state.gfxCtx);
|
||||
|
||||
if (grassActor->grassIdentity.randomizerCheck != RC_MAX &&
|
||||
Flags_GetRandomizerInf(grassActor->grassIdentity.randomizerInf) == 0) {
|
||||
if (grassIdentity != nullptr && grassIdentity->randomizerCheck != RC_MAX &&
|
||||
Flags_GetRandomizerInf(grassIdentity->randomizerInf) == 0) {
|
||||
int csmc = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"), CSMC_DISABLED);
|
||||
int requiresStoneAgony = CVarGetInteger(CVAR_ENHANCEMENT("ChestSizeDependsStoneOfAgony"), 0);
|
||||
|
||||
if ((csmc == CSMC_BOTH || csmc == CSMC_TEXTURE) &&
|
||||
(!requiresStoneAgony || (requiresStoneAgony && CHECK_QUEST_ITEM(QUEST_STONE_OF_AGONY)))) {
|
||||
auto itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(grassActor->grassIdentity.randomizerCheck,
|
||||
true, GI_NONE);
|
||||
auto itemEntry =
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(grassIdentity->randomizerCheck, true, GI_NONE);
|
||||
GetItemCategory getItemCategory = itemEntry.getItemCategory;
|
||||
|
||||
switch (getItemCategory) {
|
||||
|
@ -88,19 +91,19 @@ extern "C" void EnKusa_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||
}
|
||||
|
||||
uint8_t EnKusa_RandomizerHoldsItem(EnKusa* grassActor, PlayState* play) {
|
||||
if (grassActor->grassIdentity.randomizerCheck == RC_MAX)
|
||||
const auto grassIdentity = ObjectExtension::GetInstance().Get<GrassIdentity>(&grassActor->actor);
|
||||
|
||||
if (grassIdentity == nullptr || grassIdentity->randomizerCheck == RC_MAX)
|
||||
return false;
|
||||
|
||||
RandomizerCheck rc = grassActor->grassIdentity.randomizerCheck;
|
||||
|
||||
RandomizerCheck rc = grassIdentity->randomizerCheck;
|
||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||
uint8_t grassSetting = RAND_GET_OPTION(RSK_SHUFFLE_GRASS);
|
||||
|
||||
// Don't pull randomized item if grass isn't randomized or is already checked
|
||||
if (!IS_RANDO || (grassSetting == RO_SHUFFLE_GRASS_OVERWORLD && isDungeon) ||
|
||||
(grassSetting == RO_SHUFFLE_GRASS_DUNGEONS && !isDungeon) ||
|
||||
Flags_GetRandomizerInf(grassActor->grassIdentity.randomizerInf) ||
|
||||
grassActor->grassIdentity.randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
Flags_GetRandomizerInf(grassIdentity->randomizerInf) || rc == RC_UNKNOWN_CHECK) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -108,10 +111,14 @@ uint8_t EnKusa_RandomizerHoldsItem(EnKusa* grassActor, PlayState* play) {
|
|||
}
|
||||
|
||||
void EnKusa_RandomizerSpawnCollectible(EnKusa* grassActor, PlayState* play) {
|
||||
const auto grassIdentity = ObjectExtension::GetInstance().Get<GrassIdentity>(&grassActor->actor);
|
||||
if (grassIdentity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &grassActor->actor.world.pos, ITEM00_SOH_DUMMY);
|
||||
item00->randoInf = grassActor->grassIdentity.randomizerInf;
|
||||
item00->itemEntry =
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(grassActor->grassIdentity.randomizerCheck, true, GI_NONE);
|
||||
item00->randoInf = grassIdentity->randomizerInf;
|
||||
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(grassIdentity->randomizerCheck, true, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
|
@ -127,8 +134,9 @@ void EnKusa_RandomizerInit(void* actorRef) {
|
|||
EnKusa* grassActor = static_cast<EnKusa*>(actorRef);
|
||||
s16 respawnData = gSaveContext.respawn[RESPAWN_MODE_RETURN].data & ((1 << 8) - 1);
|
||||
|
||||
grassActor->grassIdentity = OTRGlobals::Instance->gRandomizer->IdentifyGrass(
|
||||
auto grassIdentity = OTRGlobals::Instance->gRandomizer->IdentifyGrass(
|
||||
gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z, respawnData, gPlayState->linkAgeOnLoad);
|
||||
ObjectExtension::GetInstance().Set<GrassIdentity>(actor, std::move(grassIdentity));
|
||||
}
|
||||
|
||||
void RegisterShuffleGrass() {
|
||||
|
@ -150,8 +158,10 @@ void RegisterShuffleGrass() {
|
|||
EnKusa* grassActor = va_arg(args, EnKusa*);
|
||||
if (EnKusa_RandomizerHoldsItem(grassActor, gPlayState)) {
|
||||
EnKusa_RandomizerSpawnCollectible(grassActor, gPlayState);
|
||||
grassActor->grassIdentity.randomizerCheck = RC_MAX;
|
||||
grassActor->grassIdentity.randomizerInf = RAND_INF_MAX;
|
||||
ObjectExtension::GetInstance().Set<GrassIdentity>(&grassActor->actor, std::move(GrassIdentity{
|
||||
.randomizerInf = RAND_INF_MAX,
|
||||
.randomizerCheck = RC_MAX,
|
||||
}));
|
||||
*should = false;
|
||||
} else {
|
||||
*should = true;
|
||||
|
@ -519,5 +529,6 @@ void Rando::StaticData::RegisterGrassLocations() {
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
static ObjectExtension::Register<GrassIdentity> RegisterGrassIdentity;
|
||||
static RegisterShipInitFunc registerShuffleGrass(RegisterShuffleGrass, { "IS_RANDO" });
|
||||
static RegisterShipInitFunc registerShuffleGrassLocations(Rando::StaticData::RegisterGrassLocations);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef SHUFFLEGRASS_H
|
||||
#define SHUFFLEGRASS_H
|
||||
|
||||
#include <z64.h>
|
||||
#include <soh/OTRGlobals.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void EnKusa_RandomizerInit(void* actorRef);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // SHUFFLEGRASS_H
|
|
@ -1,6 +1,7 @@
|
|||
#include "soh/OTRGlobals.h"
|
||||
#include "soh_assets.h"
|
||||
#include "static_data.h"
|
||||
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||
|
||||
extern "C" {
|
||||
#include "variables.h"
|
||||
|
@ -25,15 +26,19 @@ extern "C" void ObjTsubo_RandomizerDraw(Actor* thisx, PlayState* play) {
|
|||
}
|
||||
|
||||
uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) {
|
||||
RandomizerCheck rc = potActor->potIdentity.randomizerCheck;
|
||||
const auto potIdentity = ObjectExtension::GetInstance().Get<PotIdentity>(&potActor->actor);
|
||||
if (potIdentity == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RandomizerCheck rc = potIdentity->randomizerCheck;
|
||||
uint8_t isDungeon = Rando::StaticData::GetLocation(rc)->IsDungeon();
|
||||
uint8_t potSetting = RAND_GET_OPTION(RSK_SHUFFLE_POTS);
|
||||
|
||||
// Don't pull randomized item if pot isn't randomized or is already checked
|
||||
if (!IS_RANDO || (potSetting == RO_SHUFFLE_POTS_OVERWORLD && isDungeon) ||
|
||||
(potSetting == RO_SHUFFLE_POTS_DUNGEONS && !isDungeon) ||
|
||||
Flags_GetRandomizerInf(potActor->potIdentity.randomizerInf) ||
|
||||
potActor->potIdentity.randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
(potSetting == RO_SHUFFLE_POTS_DUNGEONS && !isDungeon) || Flags_GetRandomizerInf(potIdentity->randomizerInf) ||
|
||||
potIdentity->randomizerCheck == RC_UNKNOWN_CHECK) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -41,10 +46,14 @@ uint8_t ObjTsubo_RandomizerHoldsItem(ObjTsubo* potActor, PlayState* play) {
|
|||
}
|
||||
|
||||
void ObjTsubo_RandomizerSpawnCollectible(ObjTsubo* potActor, PlayState* play) {
|
||||
const auto potIdentity = ObjectExtension::GetInstance().Get<PotIdentity>(&potActor->actor);
|
||||
if (potIdentity == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnItem00* item00 = (EnItem00*)Item_DropCollectible2(play, &potActor->actor.world.pos, ITEM00_SOH_DUMMY);
|
||||
item00->randoInf = potActor->potIdentity.randomizerInf;
|
||||
item00->itemEntry =
|
||||
Rando::Context::GetInstance()->GetFinalGIEntry(potActor->potIdentity.randomizerCheck, true, GI_NONE);
|
||||
item00->randoInf = potIdentity->randomizerInf;
|
||||
item00->itemEntry = Rando::Context::GetInstance()->GetFinalGIEntry(potIdentity->randomizerCheck, true, GI_NONE);
|
||||
item00->actor.draw = (ActorFunc)EnItem00_DrawRandomizedItem;
|
||||
item00->actor.velocity.y = 8.0f;
|
||||
item00->actor.speedXZ = 2.0f;
|
||||
|
@ -58,8 +67,9 @@ void RegisterShufflePots() {
|
|||
Actor* actor = static_cast<Actor*>(actorRef);
|
||||
ObjTsubo* potActor = static_cast<ObjTsubo*>(actorRef);
|
||||
|
||||
potActor->potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot(
|
||||
gPlayState->sceneNum, (s16)actor->world.pos.x, (s16)actor->world.pos.z);
|
||||
auto potIdentity = OTRGlobals::Instance->gRandomizer->IdentifyPot(gPlayState->sceneNum, (s16)actor->world.pos.x,
|
||||
(s16)actor->world.pos.z);
|
||||
ObjectExtension::GetInstance().Set<PotIdentity>(actor, std::move(potIdentity));
|
||||
});
|
||||
|
||||
// Draw custom model for pot to indicate it holding a randomized item.
|
||||
|
@ -649,5 +659,6 @@ void Rando::StaticData::RegisterPotLocations() {
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
static ObjectExtension::Register<PotIdentity> RegisterPotIdentity;
|
||||
static RegisterShipInitFunc registerShufflePots(RegisterShufflePots, { "IS_RANDO" });
|
||||
static RegisterShipInitFunc registerShufflePotLocations(Rando::StaticData::RegisterPotLocations);
|
||||
|
|
|
@ -42,9 +42,6 @@ typedef struct EnElf {
|
|||
/* 0x02C7 */ u8 unk_2C7;
|
||||
/* 0x02C8 */ EnElfUnkFunc func_2C8;
|
||||
/* 0x02CC */ EnElfActionFunc actionFunc;
|
||||
// #region SOH [Randomizer]
|
||||
/* */ FairyIdentity sohFairyIdentity;
|
||||
// #endregion
|
||||
} EnElf; // size = 0x02D0
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -20,7 +20,6 @@ typedef struct EnKusa {
|
|||
/* 0x0150 */ ColliderCylinder collider;
|
||||
/* 0x019C */ s16 timer;
|
||||
/* 0x019E */ s8 objBankIndex;
|
||||
/* */ GrassIdentity grassIdentity;
|
||||
} EnKusa; // size = 0x01A0
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,7 +15,6 @@ typedef struct ObjComb {
|
|||
/* 0x0170 */ ColliderJntSphElement colliderItems[1];
|
||||
/* 0x01B0 */ s16 unk_1B0;
|
||||
/* 0x01B2 */ s16 unk_1B2;
|
||||
/* */ BeehiveIdentity beehiveIdentity;
|
||||
} ObjComb; // size = 0x01B4
|
||||
|
||||
void ObjComb_Break(ObjComb* objComb, PlayState* play);
|
||||
|
|
|
@ -12,7 +12,6 @@ typedef struct ObjKibako {
|
|||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ ObjKibakoActionFunc actionFunc;
|
||||
/* 0x0150 */ ColliderCylinder collider;
|
||||
/* */ SmallCrateIdentity smallCrateIdentity;
|
||||
} ObjKibako; // size = 0x019C
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,6 @@ typedef struct ObjKibako2 {
|
|||
/* 0x0164 */ ColliderCylinder collider;
|
||||
/* 0x01B0 */ ObjKibako2ActionFunc actionFunc;
|
||||
/* 0x01B4 */ s16 collectibleFlag;
|
||||
/* */ CrateIdentity crateIdentity;
|
||||
} ObjKibako2; // size = 0x01B8
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,6 @@ typedef struct ObjTsubo {
|
|||
/* 0x014C */ ObjTsuboActionFunc actionFunc;
|
||||
/* 0x0150 */ ColliderCylinder collider;
|
||||
/* 0x019C */ s8 objTsuboBankIndex;
|
||||
/* */ PotIdentity potIdentity;
|
||||
} ObjTsubo; // size = 0x01A0
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue