From 9eb190e734b1ae5487803e9d2c430af9690be8a8 Mon Sep 17 00:00:00 2001 From: aMannus Date: Wed, 21 Dec 2022 16:40:23 +0100 Subject: [PATCH 01/13] Fix particle regression (#2228) --- soh/src/code/z_en_item00.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 627776ffa..88fb1b8ab 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -1339,25 +1339,26 @@ void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry { 154, 154, 154 } // White Color placeholder }; - static Vec3f velocity = { 0.0f, 0.2f, 0.0f }; - static Vec3f accel = { 0.0f, 0.05f, 0.0f }; + static Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + static Vec3f accel = { 0.0f, 0.0f, 0.0f }; Color_RGBA8 primColor = { colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 0 }; Color_RGBA8 envColor = { colors[color_slot][0], colors[color_slot][1], colors[color_slot][2], 0 }; Vec3f pos; - velocity.y = -0.00f; - accel.y = -0.0f; - pos.x = Rand_CenteredFloat(15.0f) + Parent->world.pos.x; - // Shop items are rendered at a different height than the rest, so a different y offset is required + // Make particles more compact for shop items and use a different height offset for them. if (Parent->id == ACTOR_EN_GIRLA) { + pos.x = Rand_CenteredFloat(15.0f) + Parent->world.pos.x; pos.y = (Rand_ZeroOne() * 10.0f) + Parent->world.pos.y + 3; + pos.z = Rand_CenteredFloat(15.0f) + Parent->world.pos.z; + EffectSsKiraKira_SpawnFocused(play, &pos, &velocity, &accel, &primColor, &envColor, 1000, 30); } else { - pos.y = (Rand_ZeroOne() * 10.0f) + Parent->world.pos.y + 25; + pos.x = Rand_CenteredFloat(32.0f) + Parent->world.pos.x; + pos.y = (Rand_ZeroOne() * 6.0f) + Parent->world.pos.y + 25; + pos.z = Rand_CenteredFloat(32.0f) + Parent->world.pos.z; + velocity.y = -0.05f; + accel.y = -0.025f; + EffectSsKiraKira_SpawnDispersed(play, &pos, &velocity, &accel, &primColor, &envColor, 1000, 30); } - pos.z = Rand_CenteredFloat(15.0f) + Parent->world.pos.z; - - - EffectSsKiraKira_SpawnFocused(play, &pos, &velocity, &accel, &primColor, &envColor, 1000, 30); } /** From 565775a3dcfe0bd7b41a1e4805dba6f3a7883b6a Mon Sep 17 00:00:00 2001 From: aMannus Date: Wed, 21 Dec 2022 17:14:00 +0100 Subject: [PATCH 02/13] Fix ice trap particles (#2229) --- soh/soh/Enhancements/item-tables/ItemTableManager.cpp | 5 ++++- soh/soh/Enhancements/item-tables/ItemTableTypes.h | 4 +++- soh/soh/Enhancements/randomizer/randomizer.cpp | 2 ++ soh/src/code/z_en_item00.c | 6 +++--- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/item-tables/ItemTableManager.cpp b/soh/soh/Enhancements/item-tables/ItemTableManager.cpp index 57f6464e3..69ac56553 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableManager.cpp +++ b/soh/soh/Enhancements/item-tables/ItemTableManager.cpp @@ -23,7 +23,10 @@ bool ItemTableManager::AddItemEntry(uint16_t tableID, uint16_t getItemID, GetIte GetItemEntry ItemTableManager::RetrieveItemEntry(uint16_t tableID, uint16_t itemID) { try { ItemTable* itemTable = RetrieveItemTable(tableID); - return itemTable->at(itemID); + GetItemEntry getItemEntry = itemTable->at(itemID); + getItemEntry.drawItemId = getItemEntry.itemId; + getItemEntry.drawModIndex = getItemEntry.modIndex; + return getItemEntry; } catch (std::out_of_range& oor) { return GET_ITEM_NONE; } } diff --git a/soh/soh/Enhancements/item-tables/ItemTableTypes.h b/soh/soh/Enhancements/item-tables/ItemTableTypes.h index 34c7b556b..f16762db9 100644 --- a/soh/soh/Enhancements/item-tables/ItemTableTypes.h +++ b/soh/soh/Enhancements/item-tables/ItemTableTypes.h @@ -52,5 +52,7 @@ typedef struct GetItemEntry { /* 0x0C */ uint16_t collectable; // determines whether the item can be collected on the overworld. Will be true in most cases. /* 0x0E */ GetItemFrom getItemFrom; /* 0x0F */ GetItemCategory getItemCategory; // Primarily made and used for chest size/texture matches contents + /* 0x10 */ uint16_t drawItemId; // Will be a copy of itemId unless the item is an ice trap. Needed for particles to function on ice traps. + /* 0x11 */ uint16_t drawModIndex; // Will be a copy of modIndex unless the item is an ice trap. Needed for particles to function on ice traps. CustomDrawFunc drawFunc; -}; // size = 0x0F +}; // size = 0x11 diff --git a/soh/soh/Enhancements/randomizer/randomizer.cpp b/soh/soh/Enhancements/randomizer/randomizer.cpp index e67cb031c..c72fbde1b 100644 --- a/soh/soh/Enhancements/randomizer/randomizer.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer.cpp @@ -2608,6 +2608,8 @@ GetItemEntry Randomizer::GetItemEntryFromRGData(RandomizerGetData rgData, GetIte GetItemEntry fakeGiEntry = ItemTableManager::Instance->RetrieveItemEntry(modIndex, GetItemIdFromRandomizerGet(rgData.fakeRgID, ogItemId)); giEntry.gid = fakeGiEntry.gid; giEntry.gi = fakeGiEntry.gi; + giEntry.drawItemId = fakeGiEntry.drawItemId; + giEntry.drawModIndex = fakeGiEntry.drawModIndex; giEntry.drawFunc = fakeGiEntry.drawFunc; } return giEntry; diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index 88fb1b8ab..9a4b53124 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -1264,9 +1264,9 @@ void EnItem00_Draw(Actor* thisx, PlayState* play) { void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry giEntry) { s16 color_slot; - switch (giEntry.modIndex) { + switch (giEntry.drawModIndex) { case MOD_NONE: - switch (giEntry.itemId) { + switch (giEntry.drawItemId) { case ITEM_SONG_MINUET: color_slot = 0; break; @@ -1298,7 +1298,7 @@ void EnItem00_CustomItemsParticles(Actor* Parent, PlayState* play, GetItemEntry } break; case MOD_RANDOMIZER: - switch (giEntry.itemId) { + switch (giEntry.drawItemId) { case RG_MAGIC_SINGLE: case RG_MAGIC_DOUBLE: case RG_MAGIC_BEAN_PACK: From 6eaf51c2bd8df14cf61221b572e018114e062d2e Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Wed, 21 Dec 2022 14:11:19 -0500 Subject: [PATCH 03/13] version bump (#2232) --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85ea03232..041f65bd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) project(Ship LANGUAGES C CXX - VERSION 5.1.1) -set(PROJECT_BUILD_NAME "BRADLEY BRAVO" CACHE STRING "") + VERSION 5.1.2) +set(PROJECT_BUILD_NAME "BRADLEY CHARLIE" CACHE STRING "") set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) From 07bae6b84c6bfe244e6fa47b3a3c6cc86e36964c Mon Sep 17 00:00:00 2001 From: aMannus Date: Sat, 24 Dec 2022 04:25:38 +0100 Subject: [PATCH 04/13] Fix common enemy rando crashes (#2242) --- soh/src/code/z_actor.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index c4e89adf7..48ca8d414 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -3326,6 +3326,15 @@ Actor* Actor_SpawnAsChild(ActorContext* actorCtx, Actor* parent, PlayState* play return NULL; } + // The following enemies break when the parent actor isn't the same as what would happen in authentic gameplay. + // As such, don't assign a parent to them at all when spawned with Enemy Randomizer. + // Gohma (z_boss_goma.c), the Stalchildren spawner (z_en_encount1.c) and the falling platform spawning Stalfos in + // Forest Temple (z_bg_mori_bigst.c) that normally rely on this behaviour are changed when + // Enemy Rando is on so they still work properly even without assigning a parent. + if (CVar_GetS32("gRandomizedEnemies", 0) && (spawnedActor->id == ACTOR_EN_FLOORMAS || spawnedActor->id == ACTOR_EN_PEEHAT)) { + return spawnedActor; + } + parent->child = spawnedActor; spawnedActor->parent = parent; From d215c76ebaf28138d74ca614dad67de2a6c8d4b9 Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Fri, 23 Dec 2022 22:26:01 -0500 Subject: [PATCH 05/13] fix shopsanity spawning objects for actors (#2247) --- soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index faf5f92db..1ceb58e36 100644 --- a/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/soh/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -422,10 +422,10 @@ void EnGirlA_InitItem(EnGirlA* this, PlayState* play) { objectId = getItemEntry.objectId; } - // Weird edge case here, sold out object reports as loaded for Kokiri shop but doesn't render so we force it to load here - if (Object_IsLoaded(&play->objectCtx, objectId) && (params != SI_SOLD_OUT && play->sceneNum == SCENE_KOKIRI_SHOP)) { - this->objBankIndex = Object_GetIndex(&play->objectCtx, objectId); - } else { + this->objBankIndex = Object_GetIndex(&play->objectCtx, objectId); + + // If the object isn't normally spawned by the shop scene, then spawn it now + if (this->objBankIndex < 0) { this->objBankIndex = Object_Spawn(&play->objectCtx, objectId); } } From 99367ebb53004ddf6ea95bf62dc606ad1a01792f Mon Sep 17 00:00:00 2001 From: aMannus Date: Sat, 24 Dec 2022 04:26:26 +0100 Subject: [PATCH 06/13] Fix silver rupee room in GtG (#2252) --- soh/soh/Enhancements/enemyrandomizer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/soh/soh/Enhancements/enemyrandomizer.cpp b/soh/soh/Enhancements/enemyrandomizer.cpp index 9b09fce22..a5c0b9b6b 100644 --- a/soh/soh/Enhancements/enemyrandomizer.cpp +++ b/soh/soh/Enhancements/enemyrandomizer.cpp @@ -259,6 +259,10 @@ bool IsEnemyFoundToRandomize(int16_t sceneNum, int8_t roomNum, int16_t actorId, // Only randomize the initial deku scrub actor (single and triple attack), not the flower they spawn. case ACTOR_EN_DEKUNUTS: return (params == -256 || params == 768); + // Don't randomize the OoB wallmaster in the silver rupee room because it's only there to + // not trigger unlocking the door after killing the other wallmaster in authentic gameplay. + case ACTOR_EN_WALLMAS: + return (!(!isMQ && sceneNum == SCENE_MEN && roomNum == 2 && posX == -2345)); // Only randomize initial floormaster actor (it can split and does some spawning on init). case ACTOR_EN_FLOORMAS: return (params == 0 || params == -32768); From f6a7f3d13cf666318f471a6c1aa29126e384593e Mon Sep 17 00:00:00 2001 From: aMannus Date: Sat, 24 Dec 2022 04:27:01 +0100 Subject: [PATCH 07/13] Fix enemy rando flags (#2253) --- soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c | 4 +++- soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c index 80259df9a..4f9a898f5 100644 --- a/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c +++ b/soh/src/overlays/actors/ovl_En_Ik/z_en_ik.c @@ -656,7 +656,9 @@ void func_80A75A38(EnIk* this, PlayState* play) { } if (this->unk_2F9 == 0) { Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xB0); - if (this->switchFlags != 0xFF) { + // Don't set flag when Iron Knuckle is spawned by Enemy Rando. + // Instead Iron Knuckles rely on the "clear room" flag when Enemy Rando is on. + if (this->switchFlags != 0xFF && !CVar_GetS32("gRandomizedEnemies",0)) { Flags_SetSwitch(play, this->switchFlags); } Actor_Kill(&this->actor); diff --git a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c index d01d3c4e7..7aa37cedb 100644 --- a/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/soh/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -663,7 +663,8 @@ void func_80AE3C98(EnRd* this, PlayState* play) { if (SkelAnime_Update(&this->skelAnime)) { if (this->unk_30C == 0) { - if (!Flags_GetSwitch(play, this->unk_312 & 0x7F)) { + // Don't set this flag in Enemy Rando as it can overlap with other objects using the same flag. + if (!Flags_GetSwitch(play, this->unk_312 & 0x7F) && !CVar_GetS32("gRandomizedEnemies", 0)) { Flags_SetSwitch(play, this->unk_312 & 0x7F); } if (this->unk_314 != 0) { From 0017bf1fcc280096bab5b413dc750333ab94677c Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Fri, 23 Dec 2022 22:27:19 -0500 Subject: [PATCH 08/13] fix: correct item ordering in kak potion shop (#2256) Co-authored-by: briaguya --- .../Enhancements/randomizer/3drando/item_location.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp index dc4ca4701..d88117cec 100644 --- a/soh/soh/Enhancements/randomizer/3drando/item_location.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/item_location.cpp @@ -807,14 +807,14 @@ void LocationTable_Init() { locationTable[KF_SHOP_ITEM_7] = ItemLocation::Base(RC_KF_SHOP_ITEM_7, 0x2D, 0x36, "KF Shop Item 7", KF_SHOP_ITEM_7, BUY_ARROWS_30, {Category::cKokiriForest, Category::cForest, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x2D, 6), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); locationTable[KF_SHOP_ITEM_8] = ItemLocation::Base(RC_KF_SHOP_ITEM_8, 0x2D, 0x37, "KF Shop Item 8", KF_SHOP_ITEM_8, BUY_HEART, {Category::cKokiriForest, Category::cForest, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x2D, 7), SpoilerCollectionCheckGroup::GROUP_KOKIRI_FOREST); - locationTable[KAK_POTION_SHOP_ITEM_1] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_1, 0x30, 0x30, "Kak Potion Shop Item 1", KAK_POTION_SHOP_ITEM_1, BUY_DEKU_NUT_5, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_2] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_2, 0x30, 0x31, "Kak Potion Shop Item 2", KAK_POTION_SHOP_ITEM_2, BUY_FISH, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_POTION_SHOP_ITEM_1] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_1, 0x30, 0x30, "Kak Potion Shop Item 1", KAK_POTION_SHOP_ITEM_1, BUY_GREEN_POTION, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 0), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_POTION_SHOP_ITEM_2] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_2, 0x30, 0x31, "Kak Potion Shop Item 2", KAK_POTION_SHOP_ITEM_2, BUY_BLUE_FIRE, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 1), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_POTION_SHOP_ITEM_3] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_3, 0x30, 0x32, "Kak Potion Shop Item 3", KAK_POTION_SHOP_ITEM_3, BUY_RED_POTION_30, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 2), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_4] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_4, 0x30, 0x33, "Kak Potion Shop Item 4", KAK_POTION_SHOP_ITEM_4, BUY_GREEN_POTION, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_5] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_5, 0x30, 0x34, "Kak Potion Shop Item 5", KAK_POTION_SHOP_ITEM_5, BUY_BLUE_FIRE, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_POTION_SHOP_ITEM_4] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_4, 0x30, 0x33, "Kak Potion Shop Item 4", KAK_POTION_SHOP_ITEM_4, BUY_FAIRYS_SPIRIT, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 3), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_POTION_SHOP_ITEM_5] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_5, 0x30, 0x34, "Kak Potion Shop Item 5", KAK_POTION_SHOP_ITEM_5, BUY_DEKU_NUT_5, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 4), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_POTION_SHOP_ITEM_6] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_6, 0x30, 0x35, "Kak Potion Shop Item 6", KAK_POTION_SHOP_ITEM_6, BUY_BOTTLE_BUG, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 5), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[KAK_POTION_SHOP_ITEM_7] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_7, 0x30, 0x36, "Kak Potion Shop Item 7", KAK_POTION_SHOP_ITEM_7, BUY_POE, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 6), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); - locationTable[KAK_POTION_SHOP_ITEM_8] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_8, 0x30, 0x37, "Kak Potion Shop Item 8", KAK_POTION_SHOP_ITEM_8, BUY_FAIRYS_SPIRIT, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); + locationTable[KAK_POTION_SHOP_ITEM_8] = ItemLocation::Base(RC_KAK_POTION_SHOP_ITEM_8, 0x30, 0x37, "Kak Potion Shop Item 8", KAK_POTION_SHOP_ITEM_8, BUY_FISH, {Category::cKakarikoVillage, Category::cKakariko, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x30, 7), SpoilerCollectionCheckGroup::GROUP_KAKARIKO); locationTable[MARKET_BOMBCHU_SHOP_ITEM_1] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_1, 0x32, 0x30, "MK Bombchu Shop Item 1", MARKET_BOMBCHU_SHOP_ITEM_1, BUY_BOMBCHU_10, {Category::cInnerMarket, Category::cMarket, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x32, 0), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); locationTable[MARKET_BOMBCHU_SHOP_ITEM_2] = ItemLocation::Base(RC_MARKET_BOMBCHU_SHOP_ITEM_2, 0x32, 0x31, "MK Bombchu Shop Item 2", MARKET_BOMBCHU_SHOP_ITEM_2, BUY_BOMBCHU_10, {Category::cInnerMarket, Category::cMarket, Category::cShop}, SpoilerCollectionCheck::ShopItem(0x32, 1), SpoilerCollectionCheckGroup::GROUP_HYRULE_CASTLE); From 9529cc121786540ed4c45869624c587b49bdfc39 Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Fri, 23 Dec 2022 23:50:39 -0500 Subject: [PATCH 09/13] SFX: Support replaying the current BGM when changed (#2150) * add support for reloading the current bgm when changing it in the sfx editor * clarify audio command with comment * fix wrong seq type after merge --- soh/soh/Enhancements/sfx-editor/SfxEditor.cpp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp b/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp index 43367f749..9ac5a0cbe 100644 --- a/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp +++ b/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp @@ -181,6 +181,28 @@ std::map> sfxEditorSequenceMa {NA_SE_EV_CHICKEN_CRY_A, {"Chicken Cry", "NA_SE_EV_CHICKEN_CRY_A", SEQ_SFX}}, }; +// Grabs the current BGM sequence ID and replays it +// which will lookup the proper override, or reset back to vanilla +void ReplayCurrentBGM() { + u16 curSeqId = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); + // TODO: replace with Audio_StartSeq when the macro is shared + // The fade time and audio player flags will always be 0 in the case of replaying the BGM, so they are not set here + Audio_QueueSeqCmd(0x00000000 | curSeqId); +} + +// Attempt to update the BGM if it matches the current sequence that is being played +// The seqKey that is passed in should be the vanilla ID, not the override ID +void UpdateCurrentBGM(u16 seqKey, SeqType seqType) { + if (seqType != SEQ_BGM_WORLD) { + return; + } + + u16 curSeqId = func_800FA0B4(SEQ_PLAYER_BGM_MAIN); + if (curSeqId == seqKey) { + ReplayCurrentBGM(); + } +} + void Draw_SfxTab(const std::string& tabId, const std::map>& map, SeqType type) { const std::string hiddenTabId = "##" + tabId; const std::string resetAllButton = "Reset All" + hiddenTabId; @@ -198,6 +220,9 @@ void Draw_SfxTab(const std::string& tabId, const std::map(seqData).c_str())) { CVar_SetS32(cvarKey.c_str(), value); SohImGui::RequestCvarSaveOnNextTick(); + UpdateCurrentBGM(defaultValue, type); } } @@ -299,6 +328,7 @@ void Draw_SfxTab(const std::string& tabId, const std::map Date: Sat, 24 Dec 2022 00:45:02 -0500 Subject: [PATCH 10/13] hi mom (#2261) Co-authored-by: aMannus --- soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c b/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c index ea355b8ad..eefb5b21c 100644 --- a/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c +++ b/soh/src/overlays/actors/ovl_Bg_Haka/z_bg_haka.c @@ -113,9 +113,17 @@ void func_8087B938(BgHaka* this, PlayState* play) { actor = actor->next; } player->stateFlags2 &= ~0x10; + if (this->dyna.actor.params == 1) { func_80078884(NA_SE_SY_CORRECT_CHIME); - } else if (play->sceneNum == SCENE_SPOT02 && allPulled) { + } else if (!IS_DAY && play->sceneNum == SCENE_SPOT02) { + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_POH, this->dyna.actor.home.pos.x, + this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z, 0, this->dyna.actor.shape.rot.y, 0, + 1, true); + } + + // un tss un tss + if (play->sceneNum == SCENE_SPOT02 && allPulled) { func_80078884(NA_SE_SY_CORRECT_CHIME); func_800F5ACC(NA_BGM_STAFF_2); Actor* actor2 = play->actorCtx.actorLists[ACTORCAT_BG].head; @@ -126,11 +134,8 @@ void func_8087B938(BgHaka* this, PlayState* play) { } actor2 = actor2->next; } - } else if (!IS_DAY && play->sceneNum == SCENE_SPOT02) { - Actor_Spawn(&play->actorCtx, play, ACTOR_EN_POH, this->dyna.actor.home.pos.x, - this->dyna.actor.home.pos.y, this->dyna.actor.home.pos.z, 0, this->dyna.actor.shape.rot.y, 0, - 1, true); } + this->actionFunc = func_8087BAAC; } func_8002F974(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); From 776886925172040c8e260afba829aa5c0f448414 Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Sat, 24 Dec 2022 00:58:15 -0500 Subject: [PATCH 11/13] bump version --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 041f65bd9..84da81a12 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,8 @@ set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use") set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) project(Ship LANGUAGES C CXX - VERSION 5.1.2) -set(PROJECT_BUILD_NAME "BRADLEY CHARLIE" CACHE STRING "") + VERSION 5.1.3) +set(PROJECT_BUILD_NAME "BRADLEY DELTA" CACHE STRING "") set(PROJECT_TEAM "github.com/harbourmasters" CACHE STRING "") set_property(DIRECTORY ${CMAKE_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT soh) From 85bccab1bb38e0fb497fc60e5e3db3aa35bc7b8e Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Sat, 24 Dec 2022 17:49:54 -0500 Subject: [PATCH 12/13] bump lus version (#2269) * bump lus version * Fixed StringHelper issues caused by the latest lus version Co-authored-by: KiritoDv --- ZAPDTR/ZAPD/ZFile.cpp | 6 +++--- libultraship | 2 +- soh/soh/Enhancements/sfx-editor/SfxEditor.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ZAPDTR/ZAPD/ZFile.cpp b/ZAPDTR/ZAPD/ZFile.cpp index 1ea5cd553..a1d9978a1 100644 --- a/ZAPDTR/ZAPD/ZFile.cpp +++ b/ZAPDTR/ZAPD/ZFile.cpp @@ -221,7 +221,7 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) // Check for repeated attributes. if (offsetXml != nullptr) { - rawDataIndex = strtol(StringHelper::Split(offsetXml, "0x")[1].c_str(), NULL, 16); + rawDataIndex = strtol(StringHelper::Split(std::string(offsetXml), "0x")[1].c_str(), NULL, 16); if (offsetSet.find(offsetXml) != offsetSet.end()) { @@ -831,7 +831,7 @@ void ZFile::GenerateSourceHeaderFiles() xmlPath = StringHelper::Replace(xmlPath, "\\", "/"); auto pathList = StringHelper::Split(xmlPath, "/"); std::string outPath = ""; - + for (int i = 0; i < 3; i++) outPath += pathList[i] + "/"; @@ -1192,7 +1192,7 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] const std::strin if (declarations.find(currentOffset) != declarations.end()) declarations.at(currentOffset)->size = currentTex->GetRawDataSize(); - + currentTex->DeclareVar(GetName(), ""); } else diff --git a/libultraship b/libultraship index df3a6dd29..b1c75c86e 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit df3a6dd292c3fbed56969f17d9d018b44c8d2a46 +Subproject commit b1c75c86e902e5036ee1d36afad1a35313988fe7 diff --git a/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp b/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp index 9ac5a0cbe..357b911f2 100644 --- a/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp +++ b/soh/soh/Enhancements/sfx-editor/SfxEditor.cpp @@ -358,7 +358,7 @@ extern "C" u16 SfxEditor_GetReplacementSeq(u16 seqId) { seqId = NA_BGM_FIELD_LOGIC; } } - + if (sfxEditorSequenceMap.find(seqId) == sfxEditorSequenceMap.end()) { return seqId; } @@ -460,7 +460,7 @@ void InitSfxEditor() { } extern "C" void SfxEditor_AddSequence(char *otrPath, uint16_t seqNum) { - std::vector splitName = StringHelper::Split(otrPath, "/"); + std::vector splitName = StringHelper::Split(std::string(otrPath), "/"); std::string fileName = splitName[splitName.size() - 1]; std::vector splitFileName = StringHelper::Split(fileName, "_"); std::string sequenceName = splitFileName[0]; From f42f86e3ef4636e224eee474654eeda86c8d3a2b Mon Sep 17 00:00:00 2001 From: briaguya <70942617+briaguya-ai@users.noreply.github.com> Date: Mon, 26 Dec 2022 06:37:40 -0500 Subject: [PATCH 13/13] fix: make fisherman rumble text work (#2279) we weren't correctly setting the pakType in padMgr because the depreciated `gRumbleEnabled` cvar was being checked --- soh/soh/OTRGlobals.cpp | 11 ++++++----- soh/soh/OTRGlobals.h | 2 +- soh/src/code/padmgr.c | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index a0fe66a2e..d63aee918 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -1757,12 +1757,13 @@ extern "C" void AudioPlayer_Play(const uint8_t* buf, uint32_t len) { } } -extern "C" int Controller_ShouldRumble(size_t i) { +extern "C" int Controller_ShouldRumble(size_t slot) { auto controlDeck = Ship::Window::GetInstance()->GetControlDeck(); - - for (int i = 0; i < controlDeck->GetNumVirtualDevices(); ++i) { - auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(i); - if (physicalDevice->CanRumble()) { + + if (slot < controlDeck->GetNumVirtualDevices()) { + auto physicalDevice = controlDeck->GetPhysicalDeviceFromVirtualSlot(slot); + + if (physicalDevice->getProfile(slot)->UseRumble && physicalDevice->CanRumble()) { return 1; } } diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 51744dfb4..e8f068429 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -104,7 +104,7 @@ int AudioPlayer_Buffered(void); int AudioPlayer_GetDesiredBuffered(void); void AudioPlayer_Play(const uint8_t* buf, uint32_t len); void AudioMgr_CreateNextAudioBuffer(s16* samples, u32 num_samples); -int Controller_ShouldRumble(size_t i); +int Controller_ShouldRumble(size_t slot); void Controller_BlockGameInput(); void Controller_UnblockGameInput(); void Hooks_ExecuteAudioInit(); diff --git a/soh/src/code/padmgr.c b/soh/src/code/padmgr.c index ed18dcbac..48752fed1 100644 --- a/soh/src/code/padmgr.c +++ b/soh/src/code/padmgr.c @@ -331,7 +331,7 @@ void PadMgr_HandleRetraceMsg(PadMgr* padMgr) { osContGetReadData(padMgr->pads); for (i = 0; i < __osMaxControllers; i++) { - padMgr->padStatus[i].status = CVar_GetS32("gRumbleEnabled", 0) && Controller_ShouldRumble(i); + padMgr->padStatus[i].status = Controller_ShouldRumble(i); } if (padMgr->preNMIShutdown) {