diff --git a/libultraship/libultraship/SohImGuiImpl.cpp b/libultraship/libultraship/SohImGuiImpl.cpp index 5ea017173..3efb91429 100644 --- a/libultraship/libultraship/SohImGuiImpl.cpp +++ b/libultraship/libultraship/SohImGuiImpl.cpp @@ -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"); diff --git a/soh/soh/Enhancements/randomizer.cpp b/soh/soh/Enhancements/randomizer.cpp index e0884b3e8..4721ffc79 100644 --- a/soh/soh/Enhancements/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer.cpp @@ -529,13 +529,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: @@ -553,9 +558,23 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) { case BOMBCHUS_10: return GI_BOMBCHUS_10; case BOW: - return GI_BOW; + switch (CUR_UPG_VALUE(UPG_QUIVER)) { + case 0: + return GI_BOW; + case 1: + return GI_QUIVER_40; + case 2: + return GI_QUIVER_50; + } case SLINGSHOT: - return GI_SLINGSHOT; + switch (CUR_UPG_VALUE(UPG_BULLET_BAG)) { + case 0: + return GI_SLINGSHOT; + case 1: + return GI_BULLET_BAG_40; + case 2: + return GI_BULLET_BAG_50; + } case BOOMERANG: return GI_BOOMERANG; case PROGRESSIVE_HOOKSHOT: @@ -586,7 +605,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) { case HOVER_BOOTS: return GI_BOOTS_HOVER; case BOMB_BAG: - switch (CUR_UPG_VALUE(1)) { + switch (CUR_UPG_VALUE(UPG_BOMB_BAG)) { case ITEM_NONE: return GI_BOMB_BAG_20; case ITEM_BOMB_BAG_20: @@ -595,7 +614,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) { return GI_BOMB_BAG_40; } case PROGRESSIVE_STRENGTH_UPGRADE: - switch (CUR_UPG_VALUE(3)) { + switch (CUR_UPG_VALUE(UPG_STRENGTH)) { case 0: return GI_BRACELET; case 1: @@ -604,7 +623,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) { return GI_GAUNTLETS_GOLD; } case PROGRESSIVE_SCALE: - switch (CUR_UPG_VALUE(2)) { + switch (CUR_UPG_VALUE(UPG_SCALE)) { case 0: return GI_SCALE_SILVER; case 1: @@ -645,7 +664,7 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) { return GI_MAGIC_LARGE; } case PROGRESSIVE_WALLET: - switch (CUR_UPG_VALUE(4)) { + switch (CUR_UPG_VALUE(UPG_WALLET)) { case 0: return GI_WALLET_ADULT; case 1: @@ -688,14 +707,14 @@ GetItemID Randomizer::GetItemFromGet(RandomizerGet randoGet) { case PIECE_OF_HEART_TREASURE_CHEST_GAME: return GI_HEART_PIECE_WIN; case DEKU_STICK_CAPACITY: - switch (CUR_UPG_VALUE(6)) { + switch (CUR_UPG_VALUE(UPG_STICKS)) { case 0: return GI_STICK_UPGRADE_20; case 1: return GI_STICK_UPGRADE_30; } case DEKU_NUT_CAPACITY: - switch (CUR_UPG_VALUE(7)) { + switch (CUR_UPG_VALUE(UPG_NUTS)) { case 0: return GI_NUT_UPGRADE_30; case 1: @@ -712,11 +731,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.n64ddFlag) { + 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.n64ddFlag) { + return UNKNOWN_CHECK; + } + switch(sceneNum) { case 40: switch(actorParams) { diff --git a/soh/soh/Enhancements/randomizer.h b/soh/soh/Enhancements/randomizer.h index 3dca65538..5e564622b 100644 --- a/soh/soh/Enhancements/randomizer.h +++ b/soh/soh/Enhancements/randomizer.h @@ -506,7 +506,8 @@ typedef enum { class Randomizer { private: std::unordered_map 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 diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index d9c1a64ec..f6f2dbd36 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -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); } \ No newline at end of file diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 4081f18d3..756366d79 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -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 \ No newline at end of file diff --git a/soh/src/code/title_setup.c b/soh/src/code/title_setup.c index 1e709dc12..131c97627 100644 --- a/soh/src/code/title_setup.c +++ b/soh/src/code/title_setup.c @@ -4,7 +4,7 @@ void TitleSetup_InitImpl(GameState* gameState) { osSyncPrintf("ゼルダ共通データ初期化\n"); // "Zelda common data initalization" SaveContext_Init(); gameState->running = false; - SET_NEXT_GAMESTATE(gameState, Title_Init, TitleContext); + SET_NEXT_GAMESTATE(gameState, FileChoose_Init, TitleContext); } void TitleSetup_Destroy(GameState* gameState) { diff --git a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c index 9417a0a5b..58a92abcd 100644 --- a/soh/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/soh/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -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); diff --git a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c index 272e7c693..6543e69c8 100644 --- a/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c +++ b/soh/src/overlays/actors/ovl_En_Niw_Lady/z_en_niw_lady.c @@ -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); } diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 570eedd1f..2f7e9da2b 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -198,15 +198,24 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { this->nameEntryBoxPosX = 120; this->nameEntryBoxAlpha = 0; memcpy(&this->fileNames[this->buttonIndex][0], &emptyName, 8); - } else if (this->n64ddFlags[this->buttonIndex] == this->n64ddFlag) { + } else if (this->n64ddFlags[this->buttonIndex] == 0 && CVar_GetS32("gRandomizer", 0) == 0) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->actionTimer = 8; this->selectMode = SM_FADE_MAIN_TO_SELECT; this->selectedFileIndex = this->buttonIndex; this->menuMode = FS_MENU_MODE_SELECT; this->nextTitleLabel = FS_TITLE_OPEN_FILE; - } else if (!this->n64ddFlags[this->buttonIndex]) { + } else if (this->n64ddFlags[this->buttonIndex] == 0 && CVar_GetS32("gRandomizer", 0) != 0) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (this->n64ddFlags[this->buttonIndex] != 0 && CVar_GetS32("gRandomizer", 0) == 0) { + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + } else if (this->n64ddFlags[this->buttonIndex] != 0 && CVar_GetS32("gRandomizer", 0) != 0) { + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + this->actionTimer = 8; + this->selectMode = SM_FADE_MAIN_TO_SELECT; + this->selectedFileIndex = this->buttonIndex; + this->menuMode = FS_MENU_MODE_SELECT; + this->nextTitleLabel = FS_TITLE_OPEN_FILE; } } else { if (this->warningLabel == FS_WARNING_NONE) { @@ -990,7 +999,11 @@ void FileChoose_DrawWindowContents(GameState* thisx) { // draw file button gSPVertex(POLY_OPA_DISP++, &this->windowContentVtx[temp], 20, 0); - isActive = ((this->n64ddFlag == this->n64ddFlags[i]) || (this->nameBoxAlpha[i] == 0)) ? 0 : 1; + isActive = + (((this->n64ddFlags[i] == 0 && CVar_GetS32("gRandomizer", 0) == 0) || + (this->n64ddFlags[i] != 0 && CVar_GetS32("gRandomizer", 0) != 0) || (this->nameBoxAlpha[i] == 0) + ? 0 + : 1)); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sWindowContentColors[isActive][0], sWindowContentColors[isActive][1], sWindowContentColors[isActive][2], this->fileButtonAlpha[i]); @@ -1032,7 +1045,12 @@ void FileChoose_DrawWindowContents(GameState* thisx) { // draw file info for (fileIndex = 0; fileIndex < 3; fileIndex++) { - isActive = ((this->n64ddFlag == this->n64ddFlags[fileIndex]) || (this->nameBoxAlpha[fileIndex] == 0)) ? 0 : 1; + isActive = + (((this->n64ddFlags[fileIndex] == 0 && CVar_GetS32("gRandomizer", 0) == 0) || + (this->n64ddFlags[fileIndex] != 0 && CVar_GetS32("gRandomizer", 0) != 0) || + (this->nameBoxAlpha[fileIndex] == 0) + ? 0 + : 1)); FileChoose_DrawFileInfo(&this->state, fileIndex, isActive); } @@ -1598,8 +1616,6 @@ void FileChoose_Main(GameState* thisx) { OPEN_DISPS(this->state.gfxCtx, "../z_file_choose.c", 2898); - this->n64ddFlag = 0; - gSPSegment(POLY_OPA_DISP++, 0x00, NULL); gSPSegment(POLY_OPA_DISP++, 0x01, this->staticSegment); gSPSegment(POLY_OPA_DISP++, 0x02, this->parameterSegment); @@ -1852,8 +1868,10 @@ void FileChoose_InitContext(GameState* thisx) { gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] = gSaveContext.buttonStatus[3] = gSaveContext.buttonStatus[4] = BTN_ENABLED; + /* this->n64ddFlags[0] = this->n64ddFlags[1] = this->n64ddFlags[2] = this->defense[0] = this->defense[1] = this->defense[2] = 0; + */ SsSram_ReadWrite(OS_K1_TO_PHYSICAL(0xA8000000), sramCtx->readBuff, SRAM_SIZE, OS_READ); diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c index 70bc991d5..c1e8ee6f4 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c @@ -436,12 +436,21 @@ void FileChoose_DrawNameEntry(GameState* thisx) { if (validName) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + gSaveContext.fileNum = this->buttonIndex; + + this->n64ddFlags[this->buttonIndex] = CVar_GetS32("gRandomizer", 0) != 0; + gSaveContext.n64ddFlag = CVar_GetS32("gRandomizer", 0) != 0; + 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;