actor item detection functions + save context for randomized file

This commit is contained in:
MelonSpeedruns 2022-05-27 16:44:11 -04:00
commit 31d5db49ab
9 changed files with 74 additions and 21 deletions

View file

@ -813,6 +813,12 @@ namespace SohImGui {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Randomizer"))
{
EnhancementCheckbox("Enable Randomizer", "gRandomizer");
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Developer Tools"))
{
EnhancementCheckbox("OoT Debug Mode", "gDebugEnabled");

View file

@ -173,6 +173,7 @@ typedef struct {
/* 0x1420 */ s16 worldMapArea;
/* 0x1422 */ s16 sunsSongState; // controls the effects of suns song
/* 0x1424 */ s16 healthAccumulator;
/* 0x1426 */ s8 randomizerFlag;
} SaveContext; // size = 0x1428
typedef enum {

View file

@ -528,13 +528,18 @@ void Randomizer::PopulateItemLocations(std::string spoilerFileName) {
}
}
GetItemID Randomizer::GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams) {
return GetItemFromGet(this->itemLocations[GetCheckFromSceneAndParams(sceneNum, actorParams)]);
GetItemID Randomizer::GetItemFromActor(s16 actorId, GetItemID ogItemId) {
return GetItemFromGet(this->itemLocations[GetCheckFromActor(actorId, ogItemId)], ogItemId);
}
GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) {
// todo update this to handle progressive upgrades (need to pass in more than just randoGet)
GetItemID Randomizer::GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams, GetItemID ogItemId) {
return GetItemFromGet(this->itemLocations[GetCheckFromSceneAndParams(sceneNum, actorParams)], ogItemId);
}
GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId) {
switch(randoGet) {
case UNKNOWN_GET:
return ogItemId;
case KOKIRI_SWORD:
return GI_SWORD_KOKIRI;
case DEKU_SHIELD:
@ -725,11 +730,33 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) {
case DEKU_STICK_1:
return GI_STICKS_1;
default:
return GI_NONE;
return ogItemId;
}
}
RandomizerCheck Randomizer::GetCheckFromActor(s16 actorId, GetItemID ogItemId) {
if (!gSaveContext.randomizerFlag) {
return UNKNOWN_CHECK;
}
switch (actorId) {
case 316:
switch (ogItemId) {
case GI_BOTTLE:
return KAK_ANJU_AS_CHILD;
case GI_POCKET_EGG:
return KAK_ANJU_AS_ADULT;
}
}
return UNKNOWN_CHECK;
}
RandomizerCheck Randomizer::GetCheckFromSceneAndParams(s16 sceneNum, s16 actorParams) {
if (!gSaveContext.randomizerFlag) {
return UNKNOWN_CHECK;
}
switch(sceneNum) {
case 40:
switch(actorParams) {

View file

@ -278,6 +278,7 @@ typedef enum {
// based on https://github.com/TestRunnerSRL/OoT-Randomizer/blob/e337d7f603b91a6bacb618fb32cc7fd70ed9ffca/ItemList.py
typedef enum {
UNKNOWN_GET = 0,
BOMBS_5,
DEKU_NUTS_5,
BOMBCHUS_10,
@ -499,14 +500,14 @@ typedef enum {
WATER_MEDALLION,
SPIRIT_MEDALLION,
SHADOW_MEDALLION,
LIGHT_MEDALLION,
UNKNOWN_GET
LIGHT_MEDALLION
} RandomizerGet;
class Randomizer {
private:
std::unordered_map<RandomizerCheck, RandomizerGet> itemLocations;
GetItemID GetItemFromGet(RandomizerGet randoGet);
GetItemID GetItemFromGet(RandomizerGet randoGet, GetItemID ogItemId);
RandomizerCheck GetCheckFromActor(s16 actorId, GetItemID ogItemId);
RandomizerCheck GetCheckFromSceneAndParams(s16 sceneNum, s16 actorParams);
public:
@ -514,7 +515,8 @@ class Randomizer {
~Randomizer();
void PopulateItemLocations(std::string spoilerfilename);
GetItemID GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams);
GetItemID GetItemFromActor(s16 actorId, GetItemID ogItemId);
GetItemID GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams, GetItemID ogItemId);
};
#endif

View file

@ -1000,6 +1000,10 @@ extern "C" void PopulateItemLocations(const char* spoilerfilename) {
OTRGlobals::Instance->gRandomizer->PopulateItemLocations(spoilerfilename);
}
extern "C" GetItemID GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams) {
return OTRGlobals::Instance->gRandomizer->GetItemFromSceneAndParams(sceneNum, actorParams);
extern "C" GetItemID GetItemFromActor(s16 actorId, GetItemID ogItemId) {
return OTRGlobals::Instance->gRandomizer->GetItemFromActor(actorId, ogItemId);
}
extern "C" GetItemID GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams, GetItemID ogItemId) {
return OTRGlobals::Instance->gRandomizer->GetItemFromSceneAndParams(sceneNum, actorParams, ogItemId);
}

View file

@ -75,7 +75,8 @@ void AudioPlayer_Play(const uint8_t* buf, uint32_t len);
void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples);
int Controller_ShouldRumble(size_t i);
void PopulateItemLocations(const char* spoilerfilename);
GetItemID GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams);
GetItemID GetItemFromActor(s16 actorId, GetItemID ogItemId);
GetItemID GetItemFromSceneAndParams(s16 sceneNum, s16 actorParams, GetItemID ogItemId);
#endif
#endif

View file

@ -383,11 +383,8 @@ void EnBox_AppearAnimation(EnBox* this, GlobalContext* globalCtx) {
}
}
s32 GetRandomizedItemId(s16 actorParams, s16 sceneNum) {
s32 itemId = GetItemFromSceneAndParams(sceneNum, actorParams);
if (itemId == GI_NONE) {
itemId = actorParams >> 5 & 0x7F;
}
s32 EnBox_GetRandomizedItemId(s16 actorParams, s16 sceneNum) {
s32 itemId = GetItemFromSceneAndParams(sceneNum, actorParams, actorParams >> 5 & 0x7F);
return 0 - itemId;
}
@ -432,7 +429,8 @@ void EnBox_WaitOpen(EnBox* this, GlobalContext* globalCtx) {
func_8002DBD0(&this->dyna.actor, &sp4C, &player->actor.world.pos);
if (sp4C.z > -50.0f && sp4C.z < 0.0f && fabsf(sp4C.y) < 10.0f && fabsf(sp4C.x) < 20.0f &&
Player_IsFacingActor(&this->dyna.actor, 0x3000, globalCtx)) {
func_8002F554(&this->dyna.actor, globalCtx, GetRandomizedItemId(this->dyna.actor.params, globalCtx->sceneNum));
func_8002F554(&this->dyna.actor, globalCtx,
EnBox_GetRandomizedItemId(this->dyna.actor.params, globalCtx->sceneNum));
}
if (Flags_GetTreasure(globalCtx, this->dyna.actor.params & 0x1F)) {
EnBox_SetupAction(this, EnBox_Open);

View file

@ -294,6 +294,11 @@ void func_80ABA244(EnNiwLady* this, GlobalContext* globalCtx) {
}
}
s32 NiwLady_GetRandomizedItemId(EnNiwLady* this, GetItemID ogId) {
s32 itemId = GetItemFromActor(this->actor.id, ogId);
return itemId;
}
void func_80ABA654(EnNiwLady* this, GlobalContext* globalCtx) {
if (this->unk_262 == Message_GetState(&globalCtx->msgCtx) && Message_ShouldAdvance(globalCtx)) {
Message_CloseTextbox(globalCtx);
@ -303,8 +308,10 @@ void func_80ABA654(EnNiwLady* this, GlobalContext* globalCtx) {
this->unk_26E = 0xB;
if (!(gSaveContext.itemGetInf[0] & 0x1000)) {
this->actor.parent = NULL;
this->getItemId = GI_BOTTLE;
func_8002F434(&this->actor, globalCtx, GI_BOTTLE, 100.0f, 50.0f);
this->getItemId = NiwLady_GetRandomizedItemId(this, GI_BOTTLE);
func_8002F434(&this->actor, globalCtx, NiwLady_GetRandomizedItemId(this, GI_BOTTLE), 100.0f, 50.0f);
this->actionFunc = func_80ABAC00;
return;
}
@ -438,7 +445,8 @@ void func_80ABAC00(EnNiwLady* this, GlobalContext* globalCtx) {
} else {
getItemId = this->getItemId;
if (LINK_IS_ADULT) {
getItemId = !(gSaveContext.itemGetInf[2] & 0x1000) ? GI_POCKET_EGG : GI_COJIRO;
getItemId =
!(gSaveContext.itemGetInf[2] & 0x1000) ? NiwLady_GetRandomizedItemId(this, GI_POCKET_EGG) : GI_COJIRO;
}
func_8002F434(&this->actor, globalCtx, getItemId, 200.0f, 100.0f);
}

View file

@ -437,11 +437,17 @@ void FileChoose_DrawNameEntry(GameState* thisx) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0,
&D_801333E8);
gSaveContext.fileNum = this->buttonIndex;
gSaveContext.randomizerFlag = (CVar_GetS32("gRandomizer", 0) == 1);
dayTime = ((void)0, gSaveContext.dayTime);
Sram_InitSave(this, &this->sramCtx);
// todo: load spoilerfile data
PopulateItemLocations("blarg");
// todo: fill link's pocket here
gSaveContext.dayTime = dayTime;
this->configMode = CM_NAME_ENTRY_TO_MAIN;
this->nameBoxAlpha[this->buttonIndex] = this->nameAlpha[this->buttonIndex] = 200;