From c6945a6118abcc4c2520e2c5cf721ea4fa0699c6 Mon Sep 17 00:00:00 2001 From: Eric Hoey <121978037+A-Green-Spoon@users.noreply.github.com> Date: Thu, 3 Oct 2024 13:19:09 -0400 Subject: [PATCH] cvar + better drops table + better drops function --- soh/soh/SohMenuBar.cpp | 2 + soh/src/code/z_en_item00.c | 377 +++++++----------- .../overlays/actors/ovl_En_Ishi/z_en_ishi.c | 6 +- .../overlays/actors/ovl_En_Kusa/z_en_kusa.c | 6 +- 4 files changed, 151 insertions(+), 240 deletions(-) diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index d1d3f1d04bb..edbacd72fdc 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -998,6 +998,8 @@ void DrawEnhancementsMenu() { UIWidgets::Tooltip("Bonking into trees will have a chance to drop up to 3 sticks. Must already have obtained sticks."); UIWidgets::PaddedEnhancementCheckbox("No Heart Drops", CVAR_ENHANCEMENT("NoHeartDrops"), true, false); UIWidgets::Tooltip("Disables heart drops, but not heart placements, like from a Deku Scrub running off\nThis simulates Hero Mode from other games in the series"); + UIWidgets::PaddedEnhancementCheckbox("Grass and Rocks Never Drop Nothing", CVAR_ENHANCEMENT("GrassNeverDropsNothing"), true, false); + UIWidgets::Tooltip("Prevents grass and small rocks from dropping nothing."); if (UIWidgets::PaddedEnhancementCheckbox("Hyper Bosses", CVAR_ENHANCEMENT("HyperBosses"), true, false)) { UpdateHyperBossesState(); } diff --git a/soh/src/code/z_en_item00.c b/soh/src/code/z_en_item00.c index fa5f7225add..b4ba5b43f3a 100644 --- a/soh/src/code/z_en_item00.c +++ b/soh/src/code/z_en_item00.c @@ -318,245 +318,14 @@ static u8 sItemDropIds[] = { }; static u8 sBetterItemDropIds[] = { - ITEM00_RUPEE_GREEN, - ITEM00_RUPEE_BLUE, - 0xFF, - 0xFF, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_GREEN, - ITEM00_MAGIC_SMALL, - ITEM00_HEART, - ITEM00_HEART, - 0xFF, - ITEM00_MAGIC_SMALL, - ITEM00_FLEXIBLE, - ITEM00_SEEDS, - ITEM00_SEEDS, - 0xFF, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_GREEN, - ITEM00_MAGIC_SMALL, - ITEM00_RUPEE_GREEN, - ITEM00_RUPEE_BLUE, - ITEM00_HEART, - 0xFF, - ITEM00_HEART, - 0xFF, - ITEM00_FLEXIBLE, - 0xFF, - ITEM00_BOMBS_A, - 0xFF, - ITEM00_SEEDS, - 0xFF, - 0xFF, - ITEM00_MAGIC_SMALL, - ITEM00_RUPEE_GREEN, - ITEM00_RUPEE_GREEN, - ITEM00_MAGIC_SMALL, - 0xFF, - ITEM00_HEART, - 0xFF, - 0xFF, - ITEM00_HEART, - 0xFF, - ITEM00_SEEDS, - ITEM00_SEEDS, - 0xFF, - ITEM00_BOMBS_A, - 0xFF, - ITEM00_FLEXIBLE, - ITEM00_MAGIC_SMALL, - ITEM00_RUPEE_GREEN, - ITEM00_RUPEE_GREEN, - ITEM00_NUTS, - 0xFF, - ITEM00_SEEDS, - ITEM00_SEEDS, - ITEM00_NUTS, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_SEEDS, - 0xFF, - ITEM00_FLEXIBLE, - 0xFF, - 0xFF, - 0xFF, - 0xFF, - ITEM00_RUPEE_GREEN, - ITEM00_RUPEE_GREEN, - ITEM00_SEEDS, - ITEM00_BOMBS_A, - ITEM00_MAGIC_SMALL, - ITEM00_BOMBS_A, - 0xFF, - 0xFF, - ITEM00_HEART, - 0xFF, - 0xFF, - ITEM00_HEART, - ITEM00_HEART, - 0xFF, - 0xFF, - ITEM00_MAGIC_SMALL, - ITEM00_RUPEE_GREEN, - ITEM00_MAGIC_SMALL, - ITEM00_RUPEE_GREEN, - 0xFF, - ITEM00_RUPEE_BLUE, - 0xFF, - 0xFF, - ITEM00_HEART, - 0xFF, - 0xFF, - ITEM00_HEART, - ITEM00_FLEXIBLE, - ITEM00_SEEDS, - ITEM00_SEEDS, - 0xFF, - ITEM00_MAGIC_SMALL, - ITEM00_RUPEE_GREEN, - ITEM00_RUPEE_BLUE, - 0xFF, - ITEM00_RUPEE_GREEN, - 0xFF, - ITEM00_HEART, - 0xFF, - 0xFF, - ITEM00_BOMBS_A, - ITEM00_ARROWS_SMALL, - 0xFF, - ITEM00_ARROWS_MEDIUM, - ITEM00_MAGIC_SMALL, - ITEM00_FLEXIBLE, - 0xFF, + ITEM00_RUPEE_GREEN, + ITEM00_RUPEE_BLUE, + ITEM00_RUPEE_GREEN, + ITEM00_HEART, + ITEM00_BOMBS_A, + ITEM00_ARROWS_SMALL, + ITEM00_MAGIC_SMALL, ITEM00_MAGIC_LARGE, - ITEM00_RUPEE_GREEN, - 0xFF, - ITEM00_RUPEE_BLUE, - 0xFF, - ITEM00_RUPEE_GREEN, - ITEM00_HEART, - ITEM00_FLEXIBLE, - ITEM00_BOMBS_A, - ITEM00_ARROWS_SMALL, - 0xFF, - 0xFF, - 0xFF, - ITEM00_MAGIC_SMALL, - 0xFF, - 0xFF, - ITEM00_MAGIC_LARGE, - ITEM00_ARROWS_LARGE, - ITEM00_ARROWS_MEDIUM, - ITEM00_ARROWS_MEDIUM, - ITEM00_ARROWS_SMALL, - ITEM00_ARROWS_SMALL, - ITEM00_FLEXIBLE, - ITEM00_ARROWS_SMALL, - ITEM00_ARROWS_SMALL, - ITEM00_ARROWS_SMALL, - ITEM00_ARROWS_MEDIUM, - ITEM00_ARROWS_SMALL, - ITEM00_ARROWS_SMALL, - ITEM00_ARROWS_SMALL, - ITEM00_ARROWS_MEDIUM, - ITEM00_ARROWS_LARGE, - ITEM00_ARROWS_LARGE, - ITEM00_MAGIC_LARGE, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_LARGE, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_LARGE, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_LARGE, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_SMALL, - ITEM00_MAGIC_LARGE, - ITEM00_BOMBS_A, - 0xFF, - ITEM00_BOMBS_A, - 0xFF, - ITEM00_BOMBS_A, - ITEM00_FLEXIBLE, - ITEM00_BOMBS_A, - ITEM00_BOMBS_A, - ITEM00_BOMBS_A, - 0xFF, - 0xFF, - 0xFF, - 0xFF, - ITEM00_BOMBS_A, - 0xFF, - ITEM00_BOMBS_A, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_HEART, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_BLUE, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_RED, - ITEM00_RUPEE_RED, - ITEM00_SEEDS, - 0xFF, - ITEM00_NUTS, - 0xFF, - ITEM00_STICK, - 0xFF, - 0xFF, - ITEM00_SEEDS, - 0xFF, - 0xFF, - 0xFF, - ITEM00_NUTS, - 0xFF, - ITEM00_NUTS, - ITEM00_HEART, - ITEM00_SEEDS, - ITEM00_HEART, - 0xFF, - ITEM00_SEEDS, - 0xFF, - ITEM00_HEART, - 0xFF, - 0xFF, - ITEM00_HEART, - ITEM00_HEART, - 0xFF, - 0xFF, - ITEM00_HEART, - 0xFF, - ITEM00_HEART, - ITEM00_SEEDS, ITEM00_FLEXIBLE, }; @@ -2043,3 +1812,135 @@ void Item_DropCollectibleRandom(PlayState* play, Actor* fromActor, Vec3f* spawnP } } } + +void Item_DropCollectibleRandomBetter(PlayState* play, Actor* fromActor, Vec3f* spawnPos, s16 params) { + s32 pad; + EnItem00* spawnedActor; + s16 dropQuantity; + s16 param8000; + s16 dropTableIndex = Rand_ZeroOne() * 9.0f; + u8 dropId; + + param8000 = params & 0x8000; + params &= 0x7FFF; + + if (CVarGetInteger(CVAR_ENHANCEMENT("NoRandomDrops"), 0)) { + return; + } + + if (fromActor != NULL) { + if (fromActor->dropFlag) { + if (fromActor->dropFlag & 0x01) { + params = 1 * 0x10; + dropTableIndex = 11; + } else if (fromActor->dropFlag & 0x02) { + params = 1 * 0x10; + dropTableIndex = 6; + } else if (fromActor->dropFlag & 0x04) { + params = 6 * 0x10; + dropTableIndex = 9; + } else if (fromActor->dropFlag & 0x08) { + params = 3 * 0x10; + dropTableIndex = 11; + } else if (fromActor->dropFlag & 0x10) { + params = 6 * 0x10; + dropTableIndex = 12; + } else if (fromActor->dropFlag & 0x20) { + params = 0 * 0x10; + dropTableIndex = 0; + } else if (fromActor->dropFlag & 0x40) { + params = 0 * 0x10; + dropTableIndex = 1; + } + } + if (fromActor->dropFlag & 0x20) { + dropId = ITEM00_RUPEE_PURPLE; + } else { + dropId = sBetterItemDropIds[params + dropTableIndex]; + } + } else { + dropId = sBetterItemDropIds[params + dropTableIndex]; + } + + if (dropId == ITEM00_FLEXIBLE) { + if (gSaveContext.health <= 0x10) { // 1 heart or less + Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, + FAIRY_HEAL_TIMED, true); + EffectSsDeadSound_SpawnStationary(play, spawnPos, NA_SE_EV_BUTTERFRY_TO_FAIRY, true, + DEADSOUND_REPEAT_MODE_OFF, 40); + return; + } else if (gSaveContext.health <= 0x30 && + !CVarGetInteger(CVAR_ENHANCEMENT("NoHeartDrops"), 0)) { // 3 hearts or less + params = 0xB * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_HEART; + } else if (gSaveContext.health <= 0x50 && + !CVarGetInteger(CVAR_ENHANCEMENT("NoHeartDrops"), 0)) { // 5 hearts or less + params = 0xA * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_HEART; + } else if ((gSaveContext.magicLevel != 0) && (gSaveContext.magic == 0)) { // Empty magic meter + params = 0xA * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_MAGIC_LARGE; + } else if ((gSaveContext.magicLevel != 0) && (gSaveContext.magic <= (gSaveContext.magicLevel >> 1))) { + params = 0xA * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_MAGIC_SMALL; + } else if (!LINK_IS_ADULT && (AMMO(ITEM_SLINGSHOT) < 6)) { + params = 0xA * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_SEEDS; + } else if (LINK_IS_ADULT && (AMMO(ITEM_BOW) < 6)) { + params = 0xA * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_ARROWS_MEDIUM; + } else if (AMMO(ITEM_BOMB) < 6) { + params = 0xD * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_BOMBS_A; + } else if (gSaveContext.rupees < 11) { + params = 0xA * 0x10; + dropTableIndex = 0x0; + dropId = ITEM00_RUPEE_RED; + } else { + dropTableIndex = Rand_ZeroOne() * 8.0f; + dropId = sBetterItemDropIds[dropTableIndex]; + } + } + + if (dropId != 0xFF && (!CVarGetInteger(CVAR_ENHANCEMENT("NoHeartDrops"), 0) || dropId != ITEM00_HEART)) { + dropQuantity = sDropQuantities[params + dropTableIndex]; + while (dropQuantity > 0) { + if (!param8000) { + dropId = func_8001F404(dropId); + if (dropId != 0xFF) { + spawnedActor = (EnItem00*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_ITEM00, spawnPos->x, + spawnPos->y, spawnPos->z, 0, 0, 0, dropId, true); + if ((spawnedActor != NULL) && (dropId != 0xFF)) { + spawnedActor->actor.velocity.y = 8.0f; + spawnedActor->actor.speedXZ = 2.0f; + spawnedActor->actor.gravity = -0.9f; + spawnedActor->actor.world.rot.y = Rand_ZeroOne() * 40000.0f; + Actor_SetScale(&spawnedActor->actor, 0.0f); + EnItem00_SetupAction(spawnedActor, func_8001E304); + spawnedActor->actor.flags |= ACTOR_FLAG_UPDATE_WHILE_CULLED; + if ((spawnedActor->actor.params != ITEM00_SMALL_KEY) && + (spawnedActor->actor.params != ITEM00_HEART_PIECE) && + (spawnedActor->actor.params != ITEM00_HEART_CONTAINER)) { + spawnedActor->actor.room = -1; + } + spawnedActor->unk_15A = 220; + } + } + } else { + if (CVarGetInteger(CVAR_ENHANCEMENT("BushDropFix"), 0)) { + Item_DropCollectible(play, spawnPos, dropId | 0x8000); + } else { + Item_DropCollectible(play, spawnPos, params | 0x8000); + } + } + dropQuantity--; + } + } +} diff --git a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index af10aa086d2..cde652ccacb 100644 --- a/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/soh/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -257,7 +257,11 @@ void EnIshi_DropCollectible(EnIshi* this, PlayState* play) { dropParams = 0; } - Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, dropParams << 4); + if (CVarGetInteger(CVAR_ENHANCEMENT("GrassNeverDropsNothing"), 0)) { + Item_DropCollectibleRandomBetter(play, NULL, &this->actor.world.pos, 0); + } else { + Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, dropParams << 4); + } } } diff --git a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c index 04b0ca1e31c..c344612fd4b 100644 --- a/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c +++ b/soh/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c @@ -134,7 +134,11 @@ void EnKusa_DropCollectible(EnKusa* this, PlayState* play) { if (dropParams >= 0xD) { dropParams = 0; } - Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, dropParams << 4); + if (CVarGetInteger(CVAR_ENHANCEMENT("GrassNeverDropsNothing"), 0)) { + Item_DropCollectibleRandomBetter(play, NULL, &this->actor.world.pos, 0); + } else { + Item_DropCollectibleRandom(play, NULL, &this->actor.world.pos, dropParams << 4); + } break; case ENKUSA_TYPE_1: if (CVarGetInteger(CVAR_ENHANCEMENT("NoRandomDrops"), 0)) {