From c18203878b4bc236902afe0e97e3a81aa17d8877 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 3 Aug 2022 00:14:38 -0500 Subject: [PATCH 01/11] Add shuffleCows options for randomizer --- .../randomizer/3drando/settings.cpp | 1 + .../Enhancements/randomizer/randomizer.cpp | 34 ++++++++++ .../Enhancements/randomizer/randomizerTypes.h | 1 + soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 68 ++++++++++++++++++- 4 files changed, 101 insertions(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/settings.cpp b/soh/soh/Enhancements/randomizer/3drando/settings.cpp index 6bf2070697..9c110cd1fc 100644 --- a/soh/soh/Enhancements/randomizer/3drando/settings.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/settings.cpp @@ -2500,6 +2500,7 @@ namespace Settings { ShuffleRewards.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_DUNGEON_REWARDS]); ShuffleSongs.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_SONGS]); Tokensanity.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_TOKENS]); + ShuffleCows.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_COWS]); ShuffleKokiriSword.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_KOKIRI_SWORD]); ShuffleOcarinas.SetSelectedIndex(cvarSettings[RSK_SHUFFLE_OCARINA]); diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 3a6b23bb77..a11d4d4770 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2968,10 +2968,25 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act return RC_KF_MIDOS_BOTTOM_RIGHT_CHEST; } break; + case 52: + switch (actorParams) { + case -161: + return RC_KF_LINKS_HOUSE_COW; + } + break; + case 54: + switch (actorParams) { + case -376: + return RC_LLR_STABLES_LEFT_COW; + case -138: + return RC_LLR_STABLES_RIGHT_COW; + } case 55: switch (actorParams) { case 262: return RC_KAK_IMPAS_HOUSE_FREESTANDING_POH; + case -115: + return RC_KAK_IMPAS_HOUSE_COW; } break; case 56: @@ -3008,6 +3023,10 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act return RC_HF_DEKU_SCRUB_GROTTO; case 10: return RC_LW_DEKU_SCRUB_GROTTO_FRONT; + case 1973: + return RC_DMT_COW_GROTTO_COW; + case 3194: + return RC_HF_COW_GROTTO_COW; case 22988: return RC_KF_STORMS_GROTTO_CHEST; case -22988: @@ -3094,6 +3113,10 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act break; case 76: switch (actorParams) { + case -72: + return RC_LLR_TOWER_LEFT_COW; + case -282: + return RC_LLR_TOWER_RIGHT_COW; case 262: return RC_LLR_FREESTANDING_POH; } @@ -3252,6 +3275,8 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act break; case 90: switch (actorParams) { + case -421: + return RC_GV_COW; case 23200: return RC_GV_CHEST; case 262: @@ -3438,6 +3463,7 @@ void GenerateRandomizerImgui() { cvarSettings[RSK_SHUFFLE_DUNGEON_REWARDS] = CVar_GetS32("gRandomizeShuffleDungeonReward", 0); cvarSettings[RSK_SHUFFLE_SONGS] = CVar_GetS32("gRandomizeShuffleSongs", 0); cvarSettings[RSK_SHUFFLE_TOKENS] = CVar_GetS32("gRandomizeShuffleTokens", 0); + cvarSettings[RSK_SHUFFLE_COWS] = CVar_GetS32("gRandomizeShuffleCows", 0); cvarSettings[RSK_SKIP_CHILD_ZELDA] = CVar_GetS32("gRandomizeSkipChildZelda", 0); // if we skip child zelda, we start with zelda's letter, and malon starts @@ -3956,6 +3982,14 @@ void DrawRandoEditor(bool& open) { "expected to be collected after getting Sun's Song."); PaddedSeparator(); + // Shuffle Cows + ImGui::Text(Settings::ShuffleCows.GetName().c_str()); + InsertHelpHoverText( + "Enabling this will let cows give you items upon performing Epona's Song in " + "front of them. There are 9 cows."); + SohImGui::EnhancementCombobox("gRandomizeShuffleCows", randoShuffleCows, 2, 0); + PaddedSeparator(); + if(CVar_GetS32("gRandomizeStartingKokiriSword", 0) == 0) { // Shuffle Kokiri Sword SohImGui::EnhancementCheckbox(Settings::ShuffleKokiriSword.GetName().c_str(), "gRandomizeShuffleKokiriSword"); diff --git a/soh/soh/Enhancements/randomizer/randomizerTypes.h b/soh/soh/Enhancements/randomizer/randomizerTypes.h index 04e6477832..f095ac068b 100644 --- a/soh/soh/Enhancements/randomizer/randomizerTypes.h +++ b/soh/soh/Enhancements/randomizer/randomizerTypes.h @@ -975,6 +975,7 @@ typedef enum { RSK_SHUFFLE_DUNGEON_REWARDS, RSK_SHUFFLE_SONGS, RSK_SHUFFLE_TOKENS, + RSK_SHUFFLE_COWS, RSK_SHUFFLE_WEIRD_EGG, RSK_SHUFFLE_GERUDO_MEMBERSHIP_CARD, RSK_ITEM_POOL, diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 90ff14c31a..1f3a8a0e28 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -18,6 +18,11 @@ void func_809E0070(Actor* thisx, GlobalContext* globalCtx); void func_809DF494(EnCow* this, GlobalContext* globalCtx); void func_809DF6BC(EnCow* this, GlobalContext* globalCtx); +bool EnCow_IsSecondCowInTower(EnCow* this, GlobalContext* globalCtx); +bool EnCow_IsSecondCowInStable(EnCow* this, GlobalContext* globalCtx); +bool EnCow_IsSecondCowInGrotto(EnCow* this, GlobalContext* globalCtx); +bool EnCow_IsSecondCow(EnCow* this, GlobalContext* globalCtx); +GetItemID EnCow_GetItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag); void func_809DF778(EnCow* this, GlobalContext* globalCtx); void func_809DF7D8(EnCow* this, GlobalContext* globalCtx); void func_809DF870(EnCow* this, GlobalContext* globalCtx); @@ -106,6 +111,18 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) { EnCow* this = (EnCow*)thisx; s32 pad; + // Move left cow in lon lon tower + if (EnCow_IsSecondCowInTower(thisx, globalCtx)) { + this->actor.world.pos.x = -229.0f; + this->actor.world.pos.z = 157.0f; + this->actor.shape.rot.y = 15783.0f; + } + + // Move right cow in lon lon stable + if (EnCow_IsSecondCowInStable(thisx, globalCtx)) { + this->actor.world.pos.x += 119.0f; + } + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f); switch (this->actor.params) { case 0: @@ -209,12 +226,57 @@ void func_809DF730(EnCow* this, GlobalContext* globalCtx) { } } +bool EnCow_IsSecondCowInTower(EnCow* this, GlobalContext* globalCtx) { + return + gSaveContext.n64ddFlag && + globalCtx->sceneNum == SCENE_SOUKO && + (this->actor.world.pos.x + this->actor.world.pos.z == -173 || this->actor.world.pos.x + this->actor.world.pos.z == -72); +} + +bool EnCow_IsSecondCowInStable(EnCow* this, GlobalContext* globalCtx) { + return + gSaveContext.n64ddFlag && + globalCtx->sceneNum == SCENE_MALON_STABLE && + (this->actor.world.pos.x + this->actor.world.pos.z == -257 || this->actor.world.pos.x + this->actor.world.pos.z == -138); +} + +bool EnCow_IsSecondCowInGrotto(EnCow* this, GlobalContext* globalCtx) { + return gSaveContext.n64ddFlag && globalCtx->sceneNum == SCENE_KAKUSIANA && this->actor.world.pos.x + this->actor.world.pos.z == 3194; +} + +bool EnCow_IsSecondCow(EnCow* this, GlobalContext* globalCtx) { + return EnCow_IsSecondCowInTower(this, globalCtx) || EnCow_IsSecondCowInStable(this, globalCtx) || EnCow_IsSecondCowInGrotto(this, globalCtx); +} + +GetItemID EnCow_GetItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag) { + GetItemID itemId = ITEM_NONE; + + if (Inventory_HasEmptyBottle()) { + return GI_MILK; + } + + s32 collectableFlag = 0x1A; + if (EnCow_IsSecondCow(this, globalCtx)) { + collectableFlag = 0x19; + } + + if (gSaveContext.n64ddFlag && !Flags_GetCollectible(globalCtx, collectableFlag)) { + itemId = Randomizer_GetRandomizedItemId(GI_MILK, this->actor.id, this->actor.world.pos.x + this->actor.world.pos.z, globalCtx->sceneNum); + } + + if (setFlag) { + Flags_SetCollectible(globalCtx, collectableFlag); + } + + return itemId; +} + void func_809DF778(EnCow* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; this->actionFunc = func_809DF730; } else { - func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + func_8002F434(&this->actor, globalCtx, EnCow_GetItemFromCow(this, globalCtx, true), 10000.0f, 100.0f); } } @@ -223,13 +285,13 @@ void func_809DF7D8(EnCow* this, GlobalContext* globalCtx) { this->actor.flags &= ~ACTOR_FLAG_16; Message_CloseTextbox(globalCtx); this->actionFunc = func_809DF778; - func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + func_8002F434(&this->actor, globalCtx, EnCow_GetItemFromCow(this, globalCtx, true), 10000.0f, 100.0f); } } void func_809DF870(EnCow* this, GlobalContext* globalCtx) { if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(globalCtx)) { - if (Inventory_HasEmptyBottle()) { + if (EnCow_GetItemFromCow(this, globalCtx, false) != ITEM_NONE) { Message_ContinueTextbox(globalCtx, 0x2007); this->actionFunc = func_809DF7D8; } else { From 723e34a06a058575f04546ed2a84f1d0764bd5cb Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 3 Aug 2022 08:44:48 -0500 Subject: [PATCH 02/11] Move some flags around and use global array instead of flag for shuffle cows --- soh/include/z64save.h | 1 + soh/soh/SaveManager.cpp | 12 ++ soh/src/code/z_sram.c | 6 + soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 115 ++++++++++-------- 4 files changed, 84 insertions(+), 50 deletions(-) diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 114de9fd47..b6069475e2 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -184,6 +184,7 @@ typedef struct { u8 seedIcons[5]; u8 dungeonsDone[8]; u8 trialsDone[6]; + u8 cowsMilked[10]; u8 temporaryWeapon; } SaveContext; // size = 0x1428 diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 4fe0b1cfde..7dd9e53c8d 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -736,6 +736,10 @@ void SaveManager::LoadBaseVersion1() { SaveManager::Instance->LoadArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.trialsDone[i]); }); + + SaveManager::Instance->LoadArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) { + SaveManager::Instance->LoadData("", gSaveContext.cowsMilked[i]); + }); } void SaveManager::LoadBaseVersion2() { @@ -896,6 +900,10 @@ void SaveManager::LoadBaseVersion2() { SaveManager::Instance->LoadArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone), [](size_t i) { SaveManager::Instance->LoadData("", gSaveContext.trialsDone[i]); }); + + SaveManager::Instance->LoadArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) { + SaveManager::Instance->LoadData("", gSaveContext.cowsMilked[i]); + }); } void SaveManager::SaveBase() { @@ -1052,6 +1060,10 @@ void SaveManager::SaveBase() { SaveManager::Instance->SaveArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone), [](size_t i) { SaveManager::Instance->SaveData("", gSaveContext.trialsDone[i]); }); + + SaveManager::Instance->LoadArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) { + SaveManager::Instance->LoadData("", gSaveContext.cowsMilked[i]); + }); } void SaveManager::SaveArray(const std::string& name, const size_t size, SaveArrayFunc func) { diff --git a/soh/src/code/z_sram.c b/soh/src/code/z_sram.c index 7670762c59..b238be80fb 100644 --- a/soh/src/code/z_sram.c +++ b/soh/src/code/z_sram.c @@ -5,6 +5,7 @@ #define NUM_DUNGEONS 8 #define NUM_TRIALS 6 +#define NUM_COWS 10 /** * Initialize new save. @@ -616,6 +617,11 @@ void Sram_InitSave(FileChooseContext* fileChooseCtx) { gSaveContext.trialsDone[i] = 0; } + // Sets all cows to unmilked when generating a rando save. + for (u8 i = 0; i < NUM_COWS; i++) { + gSaveContext.cowsMilked[i] = 0; + } + // Set Cutscene flags to skip them gSaveContext.eventChkInf[0xC] |= 0x10; // returned to tot with medallions gSaveContext.eventChkInf[0xC] |= 0x20; //sheik at tot pedestal diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 1f3a8a0e28..b623fc8801 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -18,11 +18,9 @@ void func_809E0070(Actor* thisx, GlobalContext* globalCtx); void func_809DF494(EnCow* this, GlobalContext* globalCtx); void func_809DF6BC(EnCow* this, GlobalContext* globalCtx); -bool EnCow_IsSecondCowInTower(EnCow* this, GlobalContext* globalCtx); -bool EnCow_IsSecondCowInStable(EnCow* this, GlobalContext* globalCtx); -bool EnCow_IsSecondCowInGrotto(EnCow* this, GlobalContext* globalCtx); -bool EnCow_IsSecondCow(EnCow* this, GlobalContext* globalCtx); -GetItemID EnCow_GetItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag); +int EnCow_GetCowId(EnCow* this, GlobalContext* globalCtx); +void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx); +GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag); void func_809DF778(EnCow* this, GlobalContext* globalCtx); void func_809DF7D8(EnCow* this, GlobalContext* globalCtx); void func_809DF870(EnCow* this, GlobalContext* globalCtx); @@ -111,16 +109,8 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) { EnCow* this = (EnCow*)thisx; s32 pad; - // Move left cow in lon lon tower - if (EnCow_IsSecondCowInTower(thisx, globalCtx)) { - this->actor.world.pos.x = -229.0f; - this->actor.world.pos.z = 157.0f; - this->actor.shape.rot.y = 15783.0f; - } - - // Move right cow in lon lon stable - if (EnCow_IsSecondCowInStable(thisx, globalCtx)) { - this->actor.world.pos.x += 119.0f; + if (gSaveContext.n64ddFlag) { + EnCow_MoveCowsForRandomizer(thisx, globalCtx); } ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f); @@ -226,46 +216,71 @@ void func_809DF730(EnCow* this, GlobalContext* globalCtx) { } } -bool EnCow_IsSecondCowInTower(EnCow* this, GlobalContext* globalCtx) { - return - gSaveContext.n64ddFlag && - globalCtx->sceneNum == SCENE_SOUKO && - (this->actor.world.pos.x + this->actor.world.pos.z == -173 || this->actor.world.pos.x + this->actor.world.pos.z == -72); +int EnCow_GetCowId(EnCow* this, GlobalContext* globalCtx) { + s32 uniqueCoords = this->actor.world.pos.x + this->actor.world.pos.z; + + switch (globalCtx->sceneNum) { + case SCENE_SOUKO: // Lon Lon Tower + switch (uniqueCoords) { + // Two cases here cause this cow is moved in randomizer + case -173: + case -72: + return 0; + default: + return 1; + } + case SCENE_MALON_STABLE: + switch (uniqueCoords) { + // Two cases here cause this cow is moved in randomizer + case -257: + case -138: + return 2; + default: + return 3; + } + case SCENE_KAKUSIANA: // Grotto + switch (uniqueCoords) { + case 1973: + return 4; + default: + return 5; + } + case SCENE_LINK_HOME: + return 6; + case SCENE_LABO: // Impa's house + return 7; + case SCENE_SPOT09: // Gerudo Valley + return 8; + // TODO: Handle Jabu MQ Cow + } } -bool EnCow_IsSecondCowInStable(EnCow* this, GlobalContext* globalCtx) { - return - gSaveContext.n64ddFlag && - globalCtx->sceneNum == SCENE_MALON_STABLE && - (this->actor.world.pos.x + this->actor.world.pos.z == -257 || this->actor.world.pos.x + this->actor.world.pos.z == -138); +void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx) { + int cowId = EnCow_GetCowId(this, globalCtx); + + // Move left cow in lon lon tower + if (cowId == 0) { + this->actor.world.pos.x = -229.0f; + this->actor.world.pos.z = 157.0f; + this->actor.shape.rot.y = 15783.0f; + // Move right cow in lon lon stable + } else if (cowId == 2) { + this->actor.world.pos.x += 119.0f; + } } -bool EnCow_IsSecondCowInGrotto(EnCow* this, GlobalContext* globalCtx) { - return gSaveContext.n64ddFlag && globalCtx->sceneNum == SCENE_KAKUSIANA && this->actor.world.pos.x + this->actor.world.pos.z == 3194; -} - -bool EnCow_IsSecondCow(EnCow* this, GlobalContext* globalCtx) { - return EnCow_IsSecondCowInTower(this, globalCtx) || EnCow_IsSecondCowInStable(this, globalCtx) || EnCow_IsSecondCowInGrotto(this, globalCtx); -} - -GetItemID EnCow_GetItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag) { +GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag) { GetItemID itemId = ITEM_NONE; + int cowId = EnCow_GetCowId(this, globalCtx); - if (Inventory_HasEmptyBottle()) { - return GI_MILK; - } - - s32 collectableFlag = 0x1A; - if (EnCow_IsSecondCow(this, globalCtx)) { - collectableFlag = 0x19; - } - - if (gSaveContext.n64ddFlag && !Flags_GetCollectible(globalCtx, collectableFlag)) { + if (!gSaveContext.cowsMilked[cowId]) { itemId = Randomizer_GetRandomizedItemId(GI_MILK, this->actor.id, this->actor.world.pos.x + this->actor.world.pos.z, globalCtx->sceneNum); - } - if (setFlag) { - Flags_SetCollectible(globalCtx, collectableFlag); + if (setFlag) { + gSaveContext.cowsMilked[cowId] = 1; + } + } else if (Inventory_HasEmptyBottle()) { + itemId = GI_MILK; } return itemId; @@ -276,7 +291,7 @@ void func_809DF778(EnCow* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = func_809DF730; } else { - func_8002F434(&this->actor, globalCtx, EnCow_GetItemFromCow(this, globalCtx, true), 10000.0f, 100.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? EnCow_GetRandomizerItemFromCow(this, globalCtx, true) : GI_MILK, 10000.0f, 100.0f); } } @@ -285,13 +300,13 @@ void func_809DF7D8(EnCow* this, GlobalContext* globalCtx) { this->actor.flags &= ~ACTOR_FLAG_16; Message_CloseTextbox(globalCtx); this->actionFunc = func_809DF778; - func_8002F434(&this->actor, globalCtx, EnCow_GetItemFromCow(this, globalCtx, true), 10000.0f, 100.0f); + func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? EnCow_GetRandomizerItemFromCow(this, globalCtx, true) : GI_MILK, 10000.0f, 100.0f); } } void func_809DF870(EnCow* this, GlobalContext* globalCtx) { if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(globalCtx)) { - if (EnCow_GetItemFromCow(this, globalCtx, false) != ITEM_NONE) { + if (Inventory_HasEmptyBottle() || (gSaveContext.n64ddFlag && EnCow_GetRandomizerItemFromCow(this, globalCtx, false) != ITEM_NONE)) { Message_ContinueTextbox(globalCtx, 0x2007); this->actionFunc = func_809DF7D8; } else { From 25a272ce0cc73dddab8bb4cf521e1b74be9494e3 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 3 Aug 2022 09:07:38 -0500 Subject: [PATCH 03/11] Fix shuffle cows bug from copy paste --- soh/soh/SaveManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soh/soh/SaveManager.cpp b/soh/soh/SaveManager.cpp index 7dd9e53c8d..fa3ff4e88e 100644 --- a/soh/soh/SaveManager.cpp +++ b/soh/soh/SaveManager.cpp @@ -1061,8 +1061,8 @@ void SaveManager::SaveBase() { SaveManager::Instance->SaveArray("trialsDone", ARRAY_COUNT(gSaveContext.trialsDone), [](size_t i) { SaveManager::Instance->SaveData("", gSaveContext.trialsDone[i]); }); - SaveManager::Instance->LoadArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) { - SaveManager::Instance->LoadData("", gSaveContext.cowsMilked[i]); + SaveManager::Instance->SaveArray("cowsMilked", ARRAY_COUNT(gSaveContext.cowsMilked), [](size_t i) { + SaveManager::Instance->SaveData("", gSaveContext.cowsMilked[i]); }); } From 8c2feb537d06abfa794669f3323fb35ac3a65e01 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Wed, 3 Aug 2022 11:26:14 -0500 Subject: [PATCH 04/11] Use 454+cowId to identify cows in randomizer.cpp --- soh/soh/Enhancements/randomizer/randomizer.cpp | 18 +++++++++--------- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index a11d4d4770..91f6751f73 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2970,22 +2970,22 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act break; case 52: switch (actorParams) { - case -161: + case 4546: return RC_KF_LINKS_HOUSE_COW; } break; case 54: switch (actorParams) { - case -376: + case 4543: return RC_LLR_STABLES_LEFT_COW; - case -138: + case 4542: return RC_LLR_STABLES_RIGHT_COW; } case 55: switch (actorParams) { case 262: return RC_KAK_IMPAS_HOUSE_FREESTANDING_POH; - case -115: + case 4547: return RC_KAK_IMPAS_HOUSE_COW; } break; @@ -3023,9 +3023,9 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act return RC_HF_DEKU_SCRUB_GROTTO; case 10: return RC_LW_DEKU_SCRUB_GROTTO_FRONT; - case 1973: + case 4544: return RC_DMT_COW_GROTTO_COW; - case 3194: + case 4545: return RC_HF_COW_GROTTO_COW; case 22988: return RC_KF_STORMS_GROTTO_CHEST; @@ -3113,9 +3113,9 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act break; case 76: switch (actorParams) { - case -72: + case 4540: return RC_LLR_TOWER_LEFT_COW; - case -282: + case 4541: return RC_LLR_TOWER_RIGHT_COW; case 262: return RC_LLR_FREESTANDING_POH; @@ -3275,7 +3275,7 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act break; case 90: switch (actorParams) { - case -421: + case 4548: return RC_GV_COW; case 23200: return RC_GV_CHEST; diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index b623fc8801..c3213796b2 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -274,7 +274,7 @@ GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx, int cowId = EnCow_GetCowId(this, globalCtx); if (!gSaveContext.cowsMilked[cowId]) { - itemId = Randomizer_GetRandomizedItemId(GI_MILK, this->actor.id, this->actor.world.pos.x + this->actor.world.pos.z, globalCtx->sceneNum); + itemId = Randomizer_GetRandomizedItemId(GI_MILK, this->actor.id, 4540 + cowId, globalCtx->sceneNum); if (setFlag) { gSaveContext.cowsMilked[cowId] = 1; From ebcf57408567b8b7811e602ef08c1dcf13907cc5 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 4 Aug 2022 19:42:58 -0500 Subject: [PATCH 05/11] Use Randomizer_GetItemIdFromKnownCheck instead for shuffleCows --- .../Enhancements/randomizer/randomizer.cpp | 25 ------- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 75 ++++++++++++++----- 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index 91f6751f73..aab46af62e 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2968,25 +2968,10 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act return RC_KF_MIDOS_BOTTOM_RIGHT_CHEST; } break; - case 52: - switch (actorParams) { - case 4546: - return RC_KF_LINKS_HOUSE_COW; - } - break; - case 54: - switch (actorParams) { - case 4543: - return RC_LLR_STABLES_LEFT_COW; - case 4542: - return RC_LLR_STABLES_RIGHT_COW; - } case 55: switch (actorParams) { case 262: return RC_KAK_IMPAS_HOUSE_FREESTANDING_POH; - case 4547: - return RC_KAK_IMPAS_HOUSE_COW; } break; case 56: @@ -3023,10 +3008,6 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act return RC_HF_DEKU_SCRUB_GROTTO; case 10: return RC_LW_DEKU_SCRUB_GROTTO_FRONT; - case 4544: - return RC_DMT_COW_GROTTO_COW; - case 4545: - return RC_HF_COW_GROTTO_COW; case 22988: return RC_KF_STORMS_GROTTO_CHEST; case -22988: @@ -3113,10 +3094,6 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act break; case 76: switch (actorParams) { - case 4540: - return RC_LLR_TOWER_LEFT_COW; - case 4541: - return RC_LLR_TOWER_RIGHT_COW; case 262: return RC_LLR_FREESTANDING_POH; } @@ -3275,8 +3252,6 @@ RandomizerCheck Randomizer::GetCheckFromActor(s16 sceneNum, s16 actorId, s16 act break; case 90: switch (actorParams) { - case 4548: - return RC_GV_COW; case 23200: return RC_GV_CHEST; case 262: diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index c3213796b2..5f6db31fbc 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -18,7 +18,7 @@ void func_809E0070(Actor* thisx, GlobalContext* globalCtx); void func_809DF494(EnCow* this, GlobalContext* globalCtx); void func_809DF6BC(EnCow* this, GlobalContext* globalCtx); -int EnCow_GetCowId(EnCow* this, GlobalContext* globalCtx); +struct CowInfo EnCow_GetCowInfo(EnCow* this, GlobalContext* globalCtx); void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx); GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag); void func_809DF778(EnCow* this, GlobalContext* globalCtx); @@ -216,8 +216,14 @@ void func_809DF730(EnCow* this, GlobalContext* globalCtx) { } } -int EnCow_GetCowId(EnCow* this, GlobalContext* globalCtx) { +struct CowInfo { + int cowId; + RandomizerCheck randomizerCheck; +}; + +struct CowInfo EnCow_GetCowInfo(EnCow* this, GlobalContext* globalCtx) { s32 uniqueCoords = this->actor.world.pos.x + this->actor.world.pos.z; + struct CowInfo cowInfo; switch (globalCtx->sceneNum) { case SCENE_SOUKO: // Lon Lon Tower @@ -225,59 +231,90 @@ int EnCow_GetCowId(EnCow* this, GlobalContext* globalCtx) { // Two cases here cause this cow is moved in randomizer case -173: case -72: - return 0; + cowInfo.cowId = 0; + cowInfo.randomizerCheck = RC_LLR_TOWER_LEFT_COW; + break; default: - return 1; + cowInfo.cowId = 1; + cowInfo.randomizerCheck = RC_LLR_TOWER_RIGHT_COW; + break; } + break; case SCENE_MALON_STABLE: switch (uniqueCoords) { // Two cases here cause this cow is moved in randomizer case -257: case -138: - return 2; + cowInfo.cowId = 2; + cowInfo.randomizerCheck = RC_LLR_STABLES_RIGHT_COW; + break; default: - return 3; + cowInfo.cowId = 3; + cowInfo.randomizerCheck = RC_LLR_STABLES_LEFT_COW; + break; } + break; case SCENE_KAKUSIANA: // Grotto switch (uniqueCoords) { case 1973: - return 4; + cowInfo.cowId = 4; + cowInfo.randomizerCheck = RC_DMT_COW_GROTTO_COW; + break; default: - return 5; + cowInfo.cowId = 5; + cowInfo.randomizerCheck = RC_HF_COW_GROTTO_COW; + break; } + break; case SCENE_LINK_HOME: - return 6; + cowInfo.cowId = 6; + cowInfo.randomizerCheck = RC_KF_LINKS_HOUSE_COW; + break; case SCENE_LABO: // Impa's house - return 7; + cowInfo.cowId = 7; + cowInfo.randomizerCheck = RC_KAK_IMPAS_HOUSE_COW; + break; case SCENE_SPOT09: // Gerudo Valley - return 8; - // TODO: Handle Jabu MQ Cow + cowInfo.cowId = 8; + cowInfo.randomizerCheck = RC_GV_COW; + break; + case SCENE_SPOT08: // Jabu's Belly + cowInfo.cowId = 9; + cowInfo.randomizerCheck = RC_JABU_JABUS_BELLY_MQ_COW; + break; } + + return cowInfo; } void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx) { - int cowId = EnCow_GetCowId(this, globalCtx); + struct CowInfo cowInfo = EnCow_GetCowInfo(this, globalCtx); + + // Only move the cow body (the tail will be moved with the body) + if (this->actor.params != 0) { + return; + } // Move left cow in lon lon tower - if (cowId == 0) { + if (cowInfo.cowId == 0) { this->actor.world.pos.x = -229.0f; this->actor.world.pos.z = 157.0f; this->actor.shape.rot.y = 15783.0f; // Move right cow in lon lon stable - } else if (cowId == 2) { + } else if (cowInfo.cowId == 2) { this->actor.world.pos.x += 119.0f; } } GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag) { GetItemID itemId = ITEM_NONE; - int cowId = EnCow_GetCowId(this, globalCtx); + struct CowInfo cowInfo = EnCow_GetCowInfo(this, globalCtx); - if (!gSaveContext.cowsMilked[cowId]) { - itemId = Randomizer_GetRandomizedItemId(GI_MILK, this->actor.id, 4540 + cowId, globalCtx->sceneNum); + if (!gSaveContext.cowsMilked[cowInfo.cowId]) { + itemId = Randomizer_GetItemIdFromKnownCheck(cowInfo.randomizerCheck, GI_MILK); if (setFlag) { - gSaveContext.cowsMilked[cowId] = 1; + gSaveContext.cowsMilked[cowInfo.cowId] = 1; } } else if (Inventory_HasEmptyBottle()) { itemId = GI_MILK; From 587147dc4097a2697b5bb936985d68595ef47c24 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 4 Aug 2022 19:44:08 -0500 Subject: [PATCH 06/11] Remove count of cows from tooltip --- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index aab46af62e..e28d13f82b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3961,7 +3961,7 @@ void DrawRandoEditor(bool& open) { ImGui::Text(Settings::ShuffleCows.GetName().c_str()); InsertHelpHoverText( "Enabling this will let cows give you items upon performing Epona's Song in " - "front of them. There are 9 cows."); + "front of them."); SohImGui::EnhancementCombobox("gRandomizeShuffleCows", randoShuffleCows, 2, 0); PaddedSeparator(); From 1789e5dddd03a3b023cde7a1ef07ccd29a44bc34 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Thu, 4 Aug 2022 20:59:46 -0500 Subject: [PATCH 07/11] Fix ice traps for cow shuffle --- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 5f6db31fbc..8a050c4aec 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -20,7 +20,7 @@ void func_809DF494(EnCow* this, GlobalContext* globalCtx); void func_809DF6BC(EnCow* this, GlobalContext* globalCtx); struct CowInfo EnCow_GetCowInfo(EnCow* this, GlobalContext* globalCtx); void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx); -GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag); +GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx); void func_809DF778(EnCow* this, GlobalContext* globalCtx); void func_809DF7D8(EnCow* this, GlobalContext* globalCtx); void func_809DF870(EnCow* this, GlobalContext* globalCtx); @@ -306,16 +306,17 @@ void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx) { } } -GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx, bool setFlag) { +void EnCow_SetCowMilked(EnCow* this, GlobalContext* globalCtx) { + struct CowInfo cowInfo = EnCow_GetCowInfo(this, globalCtx); + gSaveContext.cowsMilked[cowInfo.cowId] = 1; +} + +GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx) { GetItemID itemId = ITEM_NONE; struct CowInfo cowInfo = EnCow_GetCowInfo(this, globalCtx); if (!gSaveContext.cowsMilked[cowInfo.cowId]) { itemId = Randomizer_GetItemIdFromKnownCheck(cowInfo.randomizerCheck, GI_MILK); - - if (setFlag) { - gSaveContext.cowsMilked[cowInfo.cowId] = 1; - } } else if (Inventory_HasEmptyBottle()) { itemId = GI_MILK; } @@ -328,7 +329,16 @@ void func_809DF778(EnCow* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = func_809DF730; } else { - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? EnCow_GetRandomizerItemFromCow(this, globalCtx, true) : GI_MILK, 10000.0f, 100.0f); + if (gSaveContext.n64ddFlag) { + GetItemID itemId = EnCow_GetRandomizerItemFromCow(this, globalCtx); + func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 100.0f); + if (itemId == GI_ICE_TRAP) { + Message_StartTextbox(globalCtx, 0xF8, &this->actor); + EnCow_SetCowMilked(this, globalCtx); + } + } else { + func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + } } } @@ -337,13 +347,21 @@ void func_809DF7D8(EnCow* this, GlobalContext* globalCtx) { this->actor.flags &= ~ACTOR_FLAG_16; Message_CloseTextbox(globalCtx); this->actionFunc = func_809DF778; - func_8002F434(&this->actor, globalCtx, gSaveContext.n64ddFlag ? EnCow_GetRandomizerItemFromCow(this, globalCtx, true) : GI_MILK, 10000.0f, 100.0f); + if (gSaveContext.n64ddFlag) { + GetItemID itemId = EnCow_GetRandomizerItemFromCow(this, globalCtx); + if (itemId != GI_ICE_TRAP) { + func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 100.0f); + EnCow_SetCowMilked(this, globalCtx); + } + } else { + func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + } } } void func_809DF870(EnCow* this, GlobalContext* globalCtx) { if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(globalCtx)) { - if (Inventory_HasEmptyBottle() || (gSaveContext.n64ddFlag && EnCow_GetRandomizerItemFromCow(this, globalCtx, false) != ITEM_NONE)) { + if (Inventory_HasEmptyBottle() || (gSaveContext.n64ddFlag && EnCow_GetRandomizerItemFromCow(this, globalCtx) != ITEM_NONE)) { Message_ContinueTextbox(globalCtx, 0x2007); this->actionFunc = func_809DF7D8; } else { From 11d7a78e62c0d087436538b651203115d760162a Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 01:38:45 -0500 Subject: [PATCH 08/11] More changes from suggestions --- .../Enhancements/randomizer/randomizer.cpp | 2 + soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 66 +++++++------------ 2 files changed, 25 insertions(+), 43 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index e28d13f82b..aee02cd832 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -1394,6 +1394,7 @@ std::unordered_map SpoilerfileSettingNameToEn { "Open Settings:Token Count", RSK_RAINBOW_BRIDGE_TOKEN_COUNT }, { "Open Settings:Random Ganon's Trials", RSK_RANDOM_TRIALS }, { "Open Settings:Trial Count", RSK_TRIAL_COUNT }, + { "Shuffle Settings:Shuffle Cows", RSK_SHUFFLE_COWS }, { "Start with Deku Shield", RSK_STARTING_DEKU_SHIELD }, { "Start with Kokiri Sword", RSK_STARTING_KOKIRI_SWORD }, { "Start with Fairy Ocarina", RSK_STARTING_OCARINA }, @@ -1602,6 +1603,7 @@ void Randomizer::ParseRandomizerSettingsFile(const char* spoilerFileName) { numericValueString = it.value(); gSaveContext.randoSettings[index].value = std::stoi(numericValueString); break; + case RSK_SHUFFLE_COWS: case RSK_RANDOM_TRIALS: if(it.value() == "Off") { gSaveContext.randoSettings[index].value = 0; diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 8a050c4aec..b3cac46765 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -109,7 +109,7 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) { EnCow* this = (EnCow*)thisx; s32 pad; - if (gSaveContext.n64ddFlag) { + if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_COWS)) { EnCow_MoveCowsForRandomizer(thisx, globalCtx); } @@ -222,48 +222,34 @@ struct CowInfo { }; struct CowInfo EnCow_GetCowInfo(EnCow* this, GlobalContext* globalCtx) { - s32 uniqueCoords = this->actor.world.pos.x + this->actor.world.pos.z; struct CowInfo cowInfo; switch (globalCtx->sceneNum) { case SCENE_SOUKO: // Lon Lon Tower - switch (uniqueCoords) { - // Two cases here cause this cow is moved in randomizer - case -173: - case -72: - cowInfo.cowId = 0; - cowInfo.randomizerCheck = RC_LLR_TOWER_LEFT_COW; - break; - default: - cowInfo.cowId = 1; - cowInfo.randomizerCheck = RC_LLR_TOWER_RIGHT_COW; - break; + if (this->actor.world.pos.x == -229 && this->actor.world.pos.z == 157) { + cowInfo.cowId = 0; + cowInfo.randomizerCheck = RC_LLR_TOWER_LEFT_COW; + } else { + cowInfo.cowId = 1; + cowInfo.randomizerCheck = RC_LLR_TOWER_RIGHT_COW; } break; case SCENE_MALON_STABLE: - switch (uniqueCoords) { - // Two cases here cause this cow is moved in randomizer - case -257: - case -138: - cowInfo.cowId = 2; - cowInfo.randomizerCheck = RC_LLR_STABLES_RIGHT_COW; - break; - default: - cowInfo.cowId = 3; - cowInfo.randomizerCheck = RC_LLR_STABLES_LEFT_COW; - break; + if (this->actor.world.pos.x == 116 && this->actor.world.pos.z == -254) { + cowInfo.cowId = 2; + cowInfo.randomizerCheck = RC_LLR_STABLES_RIGHT_COW; + } else { + cowInfo.cowId = 3; + cowInfo.randomizerCheck = RC_LLR_STABLES_LEFT_COW; } break; case SCENE_KAKUSIANA: // Grotto - switch (uniqueCoords) { - case 1973: - cowInfo.cowId = 4; - cowInfo.randomizerCheck = RC_DMT_COW_GROTTO_COW; - break; - default: - cowInfo.cowId = 5; - cowInfo.randomizerCheck = RC_HF_COW_GROTTO_COW; - break; + if (this->actor.world.pos.x == 2444 && this->actor.world.pos.z == -471) { + cowInfo.cowId = 4; + cowInfo.randomizerCheck = RC_DMT_COW_GROTTO_COW; + } else { + cowInfo.cowId = 5; + cowInfo.randomizerCheck = RC_HF_COW_GROTTO_COW; } break; case SCENE_LINK_HOME: @@ -296,12 +282,12 @@ void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx) { } // Move left cow in lon lon tower - if (cowInfo.cowId == 0) { + if (globalCtx->sceneNum == SCENE_SOUKO && this->actor.world.pos.x == -108 && this->actor.world.pos.z == -65) { this->actor.world.pos.x = -229.0f; this->actor.world.pos.z = 157.0f; this->actor.shape.rot.y = 15783.0f; // Move right cow in lon lon stable - } else if (cowInfo.cowId == 2) { + } else if (globalCtx->sceneNum == SCENE_MALON_STABLE && this->actor.world.pos.x == -3 && this->actor.world.pos.z == -254) { this->actor.world.pos.x += 119.0f; } } @@ -332,9 +318,9 @@ void func_809DF778(EnCow* this, GlobalContext* globalCtx) { if (gSaveContext.n64ddFlag) { GetItemID itemId = EnCow_GetRandomizerItemFromCow(this, globalCtx); func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 100.0f); + EnCow_SetCowMilked(this, globalCtx); if (itemId == GI_ICE_TRAP) { Message_StartTextbox(globalCtx, 0xF8, &this->actor); - EnCow_SetCowMilked(this, globalCtx); } } else { func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); @@ -347,13 +333,7 @@ void func_809DF7D8(EnCow* this, GlobalContext* globalCtx) { this->actor.flags &= ~ACTOR_FLAG_16; Message_CloseTextbox(globalCtx); this->actionFunc = func_809DF778; - if (gSaveContext.n64ddFlag) { - GetItemID itemId = EnCow_GetRandomizerItemFromCow(this, globalCtx); - if (itemId != GI_ICE_TRAP) { - func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 100.0f); - EnCow_SetCowMilked(this, globalCtx); - } - } else { + if (!gSaveContext.n64ddFlag) { func_8002F434(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); } } From 528dbcdc179af5a6e8ff9db5c42c22c5f7e72d17 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 14:59:04 -0500 Subject: [PATCH 09/11] More suggested changes --- .../Enhancements/randomizer/randomizer.cpp | 4 +-- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 26 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index aee02cd832..e3f4f85f3a 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3962,8 +3962,8 @@ void DrawRandoEditor(bool& open) { // Shuffle Cows ImGui::Text(Settings::ShuffleCows.GetName().c_str()); InsertHelpHoverText( - "Enabling this will let cows give you items upon performing Epona's Song in " - "front of them."); + "Cows give a randomized item from the pool upon performing Epona's\n" + "Song in front of them."); SohImGui::EnhancementCombobox("gRandomizeShuffleCows", randoShuffleCows, 2, 0); PaddedSeparator(); diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index b3cac46765..a6eca02619 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -18,9 +18,9 @@ void func_809E0070(Actor* thisx, GlobalContext* globalCtx); void func_809DF494(EnCow* this, GlobalContext* globalCtx); void func_809DF6BC(EnCow* this, GlobalContext* globalCtx); -struct CowInfo EnCow_GetCowInfo(EnCow* this, GlobalContext* globalCtx); -void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx); -GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx); +struct CowInfo EnCow_GetInfo(EnCow* this, GlobalContext* globalCtx); +void EnCow_MoveForRandomizer(EnCow* this, GlobalContext* globalCtx); +GetItemID EnCow_GetRandomizerItem(EnCow* this, GlobalContext* globalCtx); void func_809DF778(EnCow* this, GlobalContext* globalCtx); void func_809DF7D8(EnCow* this, GlobalContext* globalCtx); void func_809DF870(EnCow* this, GlobalContext* globalCtx); @@ -110,7 +110,7 @@ void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; if (gSaveContext.n64ddFlag && Randomizer_GetSettingValue(RSK_SHUFFLE_COWS)) { - EnCow_MoveCowsForRandomizer(thisx, globalCtx); + EnCow_MoveForRandomizer(thisx, globalCtx); } ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f); @@ -221,7 +221,7 @@ struct CowInfo { RandomizerCheck randomizerCheck; }; -struct CowInfo EnCow_GetCowInfo(EnCow* this, GlobalContext* globalCtx) { +struct CowInfo EnCow_GetInfo(EnCow* this, GlobalContext* globalCtx) { struct CowInfo cowInfo; switch (globalCtx->sceneNum) { @@ -273,14 +273,14 @@ struct CowInfo EnCow_GetCowInfo(EnCow* this, GlobalContext* globalCtx) { return cowInfo; } -void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx) { - struct CowInfo cowInfo = EnCow_GetCowInfo(this, globalCtx); - +void EnCow_MoveForRandomizer(EnCow* this, GlobalContext* globalCtx) { // Only move the cow body (the tail will be moved with the body) if (this->actor.params != 0) { return; } + struct CowInfo cowInfo = EnCow_GetInfo(this, globalCtx); + // Move left cow in lon lon tower if (globalCtx->sceneNum == SCENE_SOUKO && this->actor.world.pos.x == -108 && this->actor.world.pos.z == -65) { this->actor.world.pos.x = -229.0f; @@ -293,13 +293,13 @@ void EnCow_MoveCowsForRandomizer(EnCow* this, GlobalContext* globalCtx) { } void EnCow_SetCowMilked(EnCow* this, GlobalContext* globalCtx) { - struct CowInfo cowInfo = EnCow_GetCowInfo(this, globalCtx); + struct CowInfo cowInfo = EnCow_GetInfo(this, globalCtx); gSaveContext.cowsMilked[cowInfo.cowId] = 1; } -GetItemID EnCow_GetRandomizerItemFromCow(EnCow* this, GlobalContext* globalCtx) { +GetItemID EnCow_GetRandomizerItem(EnCow* this, GlobalContext* globalCtx) { GetItemID itemId = ITEM_NONE; - struct CowInfo cowInfo = EnCow_GetCowInfo(this, globalCtx); + struct CowInfo cowInfo = EnCow_GetInfo(this, globalCtx); if (!gSaveContext.cowsMilked[cowInfo.cowId]) { itemId = Randomizer_GetItemIdFromKnownCheck(cowInfo.randomizerCheck, GI_MILK); @@ -316,7 +316,7 @@ void func_809DF778(EnCow* this, GlobalContext* globalCtx) { this->actionFunc = func_809DF730; } else { if (gSaveContext.n64ddFlag) { - GetItemID itemId = EnCow_GetRandomizerItemFromCow(this, globalCtx); + GetItemID itemId = EnCow_GetRandomizerItem(this, globalCtx); func_8002F434(&this->actor, globalCtx, itemId, 10000.0f, 100.0f); EnCow_SetCowMilked(this, globalCtx); if (itemId == GI_ICE_TRAP) { @@ -341,7 +341,7 @@ void func_809DF7D8(EnCow* this, GlobalContext* globalCtx) { void func_809DF870(EnCow* this, GlobalContext* globalCtx) { if ((Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_EVENT) && Message_ShouldAdvance(globalCtx)) { - if (Inventory_HasEmptyBottle() || (gSaveContext.n64ddFlag && EnCow_GetRandomizerItemFromCow(this, globalCtx) != ITEM_NONE)) { + if (Inventory_HasEmptyBottle() || (gSaveContext.n64ddFlag && EnCow_GetRandomizerItem(this, globalCtx) != ITEM_NONE)) { Message_ContinueTextbox(globalCtx, 0x2007); this->actionFunc = func_809DF7D8; } else { From de34fd7e944161307bf638dbadbcba8a1dee23d2 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 16:11:17 -0500 Subject: [PATCH 10/11] Check coords for other cows rather than falling back --- soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c index a6eca02619..b5e7992e2b 100644 --- a/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/soh/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -223,13 +223,16 @@ struct CowInfo { struct CowInfo EnCow_GetInfo(EnCow* this, GlobalContext* globalCtx) { struct CowInfo cowInfo; + + cowInfo.cowId = -1; + cowInfo.randomizerCheck = RC_UNKNOWN_CHECK; switch (globalCtx->sceneNum) { case SCENE_SOUKO: // Lon Lon Tower if (this->actor.world.pos.x == -229 && this->actor.world.pos.z == 157) { cowInfo.cowId = 0; cowInfo.randomizerCheck = RC_LLR_TOWER_LEFT_COW; - } else { + } else if (this->actor.world.pos.x == -142 && this->actor.world.pos.z == -140) { cowInfo.cowId = 1; cowInfo.randomizerCheck = RC_LLR_TOWER_RIGHT_COW; } @@ -238,7 +241,7 @@ struct CowInfo EnCow_GetInfo(EnCow* this, GlobalContext* globalCtx) { if (this->actor.world.pos.x == 116 && this->actor.world.pos.z == -254) { cowInfo.cowId = 2; cowInfo.randomizerCheck = RC_LLR_STABLES_RIGHT_COW; - } else { + } else if (this->actor.world.pos.x == -122 && this->actor.world.pos.z == -254) { cowInfo.cowId = 3; cowInfo.randomizerCheck = RC_LLR_STABLES_LEFT_COW; } @@ -247,7 +250,7 @@ struct CowInfo EnCow_GetInfo(EnCow* this, GlobalContext* globalCtx) { if (this->actor.world.pos.x == 2444 && this->actor.world.pos.z == -471) { cowInfo.cowId = 4; cowInfo.randomizerCheck = RC_DMT_COW_GROTTO_COW; - } else { + } else if (this->actor.world.pos.x == 3485 && this->actor.world.pos.z == -291) { cowInfo.cowId = 5; cowInfo.randomizerCheck = RC_HF_COW_GROTTO_COW; } @@ -279,8 +282,6 @@ void EnCow_MoveForRandomizer(EnCow* this, GlobalContext* globalCtx) { return; } - struct CowInfo cowInfo = EnCow_GetInfo(this, globalCtx); - // Move left cow in lon lon tower if (globalCtx->sceneNum == SCENE_SOUKO && this->actor.world.pos.x == -108 && this->actor.world.pos.z == -65) { this->actor.world.pos.x = -229.0f; From 9a145221eccff9c1f88ab0b9d22be700cdd27588 Mon Sep 17 00:00:00 2001 From: Garrett Cox Date: Fri, 5 Aug 2022 21:02:02 -0500 Subject: [PATCH 11/11] Remove newline --- soh/soh/Enhancements/randomizer/randomizer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index e3f4f85f3a..692fbecd4e 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -3961,9 +3961,7 @@ void DrawRandoEditor(bool& open) { // Shuffle Cows ImGui::Text(Settings::ShuffleCows.GetName().c_str()); - InsertHelpHoverText( - "Cows give a randomized item from the pool upon performing Epona's\n" - "Song in front of them."); + InsertHelpHoverText("Cows give a randomized item from the pool upon performing Epona's Song in front of them."); SohImGui::EnhancementCombobox("gRandomizeShuffleCows", randoShuffleCows, 2, 0); PaddedSeparator();