From 3781794be340b16ffe22d2d9cd87aaf1c9cb321c Mon Sep 17 00:00:00 2001 From: BrainFart17 Date: Tue, 7 Apr 2026 16:04:52 -0700 Subject: [PATCH] (fishing) Fix bugs and change random catch type selection - Implement catch type random selection from decompiled java 1.7.2 code instead of using a WeighedRandomItemArray - Fix fishingTreasuresArray length being set to 5 instead of 6 - Remove testing values for nibbleTimer - Cast maxDamage of item to double before applying damage. - Add include for EnchantmentCategory in LureEnchantment.cpp and LuckOfTheSeaEnchantment.cpp. - sky obstruction is now checked before other checks. --- Minecraft.World/FishingHelper.cpp | 55 ++++++++++++--------- Minecraft.World/FishingHelper.h | 32 ++---------- Minecraft.World/FishingHook.cpp | 17 +++---- Minecraft.World/LuckOfTheSeaEnchantment.cpp | 1 + Minecraft.World/LureEnchantment.cpp | 1 + 5 files changed, 43 insertions(+), 63 deletions(-) diff --git a/Minecraft.World/FishingHelper.cpp b/Minecraft.World/FishingHelper.cpp index 86b73a67..518b76d0 100644 --- a/Minecraft.World/FishingHelper.cpp +++ b/Minecraft.World/FishingHelper.cpp @@ -5,7 +5,6 @@ #include "../Minecraft.World/ItemInstance.h" #include "../Minecraft.World/EnchantmentHelper.h" #include "net.minecraft.world.item.h" - #include FishingHelper* FishingHelper::getInstance() @@ -14,13 +13,8 @@ FishingHelper* FishingHelper::getInstance() return &instance; } -FishingHelper::FishingHelper() : catchTypeArray(3), fishingFishArray(4), fishingJunkArray(11), fishingTreasuresArray(5) +FishingHelper::FishingHelper() : fishingFishArray(4), fishingJunkArray(11), fishingTreasuresArray(6) { - // Source: https://github.com/WangTingZheng/mcp940/tree/master/src/minecraft/assets/minecraft/loot_tables/gameplay - catchTypeArray[0] = new CatchTypeWeighedItem(CatchType::FISH, 850); - catchTypeArray[1] = new CatchTypeWeighedItem(CatchType::JUNK, 100 ); - catchTypeArray[2] = new CatchTypeWeighedItem(CatchType::TREASURE, 50 ); - fishingTreasuresArray[0] = new CatchWeighedItem(Item::bow_Id, 1, 0, 1); fishingTreasuresArray[1] = new CatchWeighedItem(Item::book_Id, 1, 0, 1); fishingTreasuresArray[2] = new CatchWeighedItem(Item::fishingRod_Id, 1, 0, 1); @@ -46,16 +40,31 @@ FishingHelper::FishingHelper() : catchTypeArray(3), fishingFishArray(4), fishing fishingJunkArray[10] = new CatchWeighedItem(Item::dye_powder_Id, 10, 0, 1); // 10 ink sacs } -CatchType FishingHelper::getRandCatchType(int fishMod, int junkMod, int treasureMod, Random* random) +CatchType FishingHelper::getRandCatchType(int luckLevel, int lureLevel, Random* random) { - CatchTypeWeighedItem* catchTypeWeighedItem = nullptr; - ((CatchTypeWeighedItem*)catchTypeArray[0])->modWeight(fishMod); - ((CatchTypeWeighedItem*)catchTypeArray[1])->modWeight(junkMod); - ((CatchTypeWeighedItem*)catchTypeArray[2])->modWeight(treasureMod); - // Recalculate the weights based on the luck level of the player - catchTypeWeighedItem = static_cast(WeighedRandom::getRandomItem(random, catchTypeArray)); + float randFloat = random->nextFloat(); + float junkChance = 0.1F - (float)luckLevel * 0.025F - (float)lureLevel * 0.01F; // default 10% chance, affected by lure and luck of the sea + float treasureChance = 0.05F + (float)luckLevel * 0.01F - (float)lureLevel * 0.01F; // default 5% chance, affected by lure and luck of the sea + junkChance = clamp(junkChance, 0.0F, 1.0F); + treasureChance = clamp(treasureChance, 0.0F, 1.0F); - return catchTypeWeighedItem->getType(); + if (randFloat < junkChance) + { + return CatchType::JUNK; + } + else + { + randFloat -= junkChance; + + if (randFloat < treasureChance) + { + return CatchType::TREASURE; + } + else + { + return CatchType::FISH; + } + } } CatchWeighedItem* FishingHelper::getRandCatch(CatchType catchType, Random* random) @@ -77,26 +86,26 @@ std::shared_ptr FishingHelper::handleCatch(CatchWeighedItem* weigh ); if ((itemInstance->id == Item::fishingRod_Id && catchType == CatchType::JUNK) || (itemInstance->id == Item::boots_leather_Id)) { - itemInstance->setAuxValue((int) (itemInstance->getMaxDamage() * ((double) random->nextInt(901) + 100.0) / 1000.0)); // 10% to 100% damage + itemInstance->setAuxValue((int) ((double) itemInstance->getMaxDamage() * ((double) random->nextInt(901) + 100.0) / 1000.0)); // 10% to 100% damage } else if (itemInstance->id == Item::fishingRod_Id && catchType == CatchType::TREASURE) { - itemInstance->setAuxValue((int)(itemInstance->getMaxDamage() * ((double)random->nextInt(251) / 1000.0))); // 0% to 25% damage - itemInstance = EnchantmentHelper::enchantItem(random, itemInstance, 30); + itemInstance->setAuxValue((int)((double) itemInstance->getMaxDamage() * ((double)random->nextInt(251) / 1000.0))); // 0% to 25% damage + EnchantmentHelper::enchantItem(random, itemInstance, 30); } else if (itemInstance->id == Item::bow_Id) { - itemInstance->setAuxValue((int)(itemInstance->getMaxDamage() * ((double)random->nextInt(251) / 1000.0))); // 0% to 25% damage - itemInstance = EnchantmentHelper::enchantItem(random, itemInstance, 30); + itemInstance->setAuxValue((int)((double) itemInstance->getMaxDamage() * ((double)random->nextInt(251) / 1000.0))); // 0% to 25% damage + EnchantmentHelper::enchantItem(random, itemInstance, 30); } else if (itemInstance->id == Item::book_Id) { - itemInstance = EnchantmentHelper::enchantItem(random, itemInstance, 30); + EnchantmentHelper::enchantItem(random, itemInstance, 30); } return itemInstance; } -std::shared_ptr FishingHelper::getCatch(int fishMod, int junkMod, int treasureMod, Random* random) +std::shared_ptr FishingHelper::getCatch(int luckLevel, int lureLevel, Random* random) { - CatchType catchType = getRandCatchType(fishMod, junkMod, treasureMod, random); + CatchType catchType = getRandCatchType(luckLevel, lureLevel, random); CatchWeighedItem* catchWeighedItem = getRandCatch(catchType, random); return handleCatch(catchWeighedItem, catchType, random); } \ No newline at end of file diff --git a/Minecraft.World/FishingHelper.h b/Minecraft.World/FishingHelper.h index 99b91499..77972e11 100644 --- a/Minecraft.World/FishingHelper.h +++ b/Minecraft.World/FishingHelper.h @@ -13,31 +13,6 @@ enum CatchType { JUNK }; -class CatchTypeWeighedItem : public WeighedRandomItem { - protected: - CatchType type; - int weight; - - public: - CatchTypeWeighedItem(CatchType type, int weight) : WeighedRandomItem(weight) - { - this->type = type; - this->weight = weight; - } - - CatchType getType() - { - return type; - } - - void modWeight(int mod) { - // Modweight doesn't need clamping, this is done in FishingHook.cpp. - // randomWeight can be changed, weight stays the same. randomWeight is set equal to weight upon initialization. - this->randomWeight = this->weight + mod; - } - -}; - class CatchWeighedItem : public WeighedRandomItem { protected: int itemId; @@ -70,19 +45,18 @@ class FishingHelper private: FishingHelper(); - WeighedRandomItemArray catchTypeArray; - WeighedRandomItemArray fishingFishArray; WeighedRandomItemArray fishingJunkArray; WeighedRandomItemArray fishingTreasuresArray; CatchWeighedItem* getRandCatch(CatchType catchType, Random* random); std::shared_ptr handleCatch(CatchWeighedItem* weighedCatch, CatchType catchType, Random* random); - CatchType getRandCatchType(int fishMod, int junkMod, int treasureMod, Random* random); + CatchType getRandCatchType(int luckLevel, int lureLevel, Random* random); public: // Setup singleton FishingHelper(const FishingHelper&) = delete; FishingHelper& operator=(const FishingHelper&) = delete; static FishingHelper* getInstance(); - std::shared_ptr getCatch(int fishMod, int junkMod, int treasureMod, Random* random); + + std::shared_ptr getCatch(int luckLevel, int lureLevel, Random* random); }; \ No newline at end of file diff --git a/Minecraft.World/FishingHook.cpp b/Minecraft.World/FishingHook.cpp index ea787820..1d2de0ad 100644 --- a/Minecraft.World/FishingHook.cpp +++ b/Minecraft.World/FishingHook.cpp @@ -358,14 +358,14 @@ void FishingHook::tick() } else { - // TU 31: Raining affects the nibble timer by random chance rather than being a fixed rate. Source: https://minecraft.wiki/w/Fishing - if (!(level->isRainingAt( Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)))) { - nibbleTimer--; - } - else if (!(level->canSeeSky(Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)))) { + if (!(level->canSeeSky(Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)))) { // Don't minus the nibbleTimer if the hook obstructed from the sky. } + // TU 31: Raining affects the nibble timer by random chance rather than being a fixed rate. Source: https://minecraft.wiki/w/Fishing + else if (!(level->isRainingAt( Mth::floor(x), Mth::floor(y) + 1, Mth::floor(z)))) { + nibbleTimer--; + } else { if (random->nextInt(4) == 0) { @@ -482,12 +482,7 @@ int FishingHook::retrieve() else if (nibble > 0) { FishingHelper* helper = FishingHelper::getInstance(); - - int junkMod = clamp((-10 * this->lureLevel) + (-25 * this->luckLevel), 0, 1000); // Lure reduces by 1% per level, luck of the sea 2.5% per level. - int treasureMod = clamp((-10 * this->lureLevel) + (10 * this->luckLevel), 0, 1000); // Lure reduces by 1% per level, luck of the sea increases by 1% per level. - int fishMod = -junkMod + -treasureMod; // Fish chance is affected by junkMod and treasureMod - std::shared_ptr fishingItemInstance = helper->getCatch(fishMod, junkMod, treasureMod, random); - + std::shared_ptr fishingItemInstance = helper->getCatch(luckLevel, lureLevel, random); std::shared_ptr ie = std::make_shared(this->Entity::level, x, y, z, fishingItemInstance); double xa = owner->x - x; double ya = owner->y - y; diff --git a/Minecraft.World/LuckOfTheSeaEnchantment.cpp b/Minecraft.World/LuckOfTheSeaEnchantment.cpp index 6dd8edaa..9aacda83 100644 --- a/Minecraft.World/LuckOfTheSeaEnchantment.cpp +++ b/Minecraft.World/LuckOfTheSeaEnchantment.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "LuckOfTheSeaEnchantment.h" +#include "EnchantmentCategory.h" LuckOfTheSeaEnchantment::LuckOfTheSeaEnchantment(int id, int frequency) : Enchantment(id, frequency, EnchantmentCategory::fishing_rod) diff --git a/Minecraft.World/LureEnchantment.cpp b/Minecraft.World/LureEnchantment.cpp index d44e76a4..ef7b5b20 100644 --- a/Minecraft.World/LureEnchantment.cpp +++ b/Minecraft.World/LureEnchantment.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "LureEnchantment.h" +#include "EnchantmentCategory.h" LureEnchantment::LureEnchantment(int id, int frequency) : Enchantment(id, frequency, EnchantmentCategory::fishing_rod)