diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index 19947ff2e..6184788f3 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -66,7 +66,7 @@ public: virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) = 0; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) = 0; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) = 0; - virtual bool OnDropSpense (cWorld & a_World, cDropSpenserEntity & a_DropSpenser, int a_SlotNum) = 0; + virtual bool OnDropSpense (cWorld & a_World, cDropSpenserEntity & a_DropSpenser, int a_SlotNum) = 0; virtual bool OnKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage) = 0; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) = 0; virtual bool OnLogin (cClientHandle & a_Client, UInt32 a_ProtocolVersion, const AString & a_Username) = 0; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 352c444dc..02afaffd2 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -87,7 +87,7 @@ public: virtual bool OnHandshake (cClientHandle & a_Client, const AString & a_Username) override; virtual bool OnHopperPullingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_DstSlotNum, cBlockEntityWithItems & a_SrcEntity, int a_SrcSlotNum) override; virtual bool OnHopperPushingItem (cWorld & a_World, cHopperEntity & a_Hopper, int a_SrcSlotNum, cBlockEntityWithItems & a_DstEntity, int a_DstSlotNum) override; - virtual bool OnDropSpense (cWorld & a_World, cDropSpenserEntity & a_DropSpenser, int a_SlotNum) override; + virtual bool OnDropSpense (cWorld & a_World, cDropSpenserEntity & a_DropSpenser, int a_SlotNum) override; virtual bool OnKilled (cEntity & a_Victim, TakeDamageInfo & a_TDI, AString & a_DeathMessage) override; virtual bool OnKilling (cEntity & a_Victim, cEntity * a_Killer, TakeDamageInfo & a_TDI) override; virtual bool OnLogin (cClientHandle & a_Client, UInt32 a_ProtocolVersion, const AString & a_Username) override; diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index 243ec8594..259cec7a3 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -79,9 +79,8 @@ void cDropSpenserEntity::DropSpense(cChunk & a_Chunk) return; } - int RandomSlot = m_World->GetTickRandomNumber(SlotsCnt - 1); - - int SpenseSlot = OccupiedSlots[RandomSlot]; + const int RandomSlot = m_World->GetTickRandomNumber(SlotsCnt - 1); + const int SpenseSlot = OccupiedSlots[RandomSlot]; if (cPluginManager::Get()->CallHookDropSpense(*m_World, *this, SpenseSlot)) { diff --git a/src/Blocks/BlockGlowstone.h b/src/Blocks/BlockGlowstone.h index 930509e0a..11aa5e379 100644 --- a/src/Blocks/BlockGlowstone.h +++ b/src/Blocks/BlockGlowstone.h @@ -6,6 +6,7 @@ + class cBlockGlowstoneHandler : public cBlockHandler { @@ -22,13 +23,14 @@ private: { return cItem(E_BLOCK_GLOWSTONE, 1, 0); } - else - { - unsigned int DropNum = GetRandomProvider().RandInt(2, 4 + ToolFortuneLevel(a_Tool)); - // cap the dropnum to the max amount of 4 - DropNum = std::min(DropNum, 4); - return cItem(E_ITEM_GLOWSTONE_DUST, DropNum, 0); - } + + // Number of dust to drop, capped at the max amount of 4. + const auto Drops = std::min( + static_cast(4), + GetRandomProvider().RandInt(2, 4 + ToolFortuneLevel(a_Tool)) + ); + + return cItem(E_ITEM_GLOWSTONE_DUST, Drops); } diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 4272bc607..274460e50 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -649,16 +649,16 @@ bool cBlockHandler::ToolHasSilkTouch(const cItem * a_Tool) -unsigned int cBlockHandler::ToolFortuneLevel(const cItem * a_Tool) +unsigned char cBlockHandler::ToolFortuneLevel(const cItem * a_Tool) { - if (a_Tool != nullptr) + if ((a_Tool != nullptr) && ItemCategory::IsTool(a_Tool->m_ItemType)) { - return a_Tool->m_Enchantments.GetLevel(cEnchantments::enchFortune); - } - else // Not a tool - { - return 0; + // Return enchantment level, limited to avoid spawning excessive pickups (crashing the server) when modified items are used: + return std::min(8U, a_Tool->m_Enchantments.GetLevel(cEnchantments::enchFortune)); } + + // Not a tool: + return 0; } diff --git a/src/Blocks/BlockHandler.h b/src/Blocks/BlockHandler.h index 8d595cc4a..87b259d54 100644 --- a/src/Blocks/BlockHandler.h +++ b/src/Blocks/BlockHandler.h @@ -232,7 +232,7 @@ public: /** Returns the fortune level of a tool, if it is a valid tool. Can be used in ConvertToPickups() implementations. */ - static unsigned int ToolFortuneLevel(const cItem * a_Tool); + static unsigned char ToolFortuneLevel(const cItem * a_Tool); // Gets the blockhandler for the given block type. static const cBlockHandler & For(BLOCKTYPE a_BlockType); diff --git a/src/Blocks/BlockOre.h b/src/Blocks/BlockOre.h index 6c01a6a27..5dbeac268 100644 --- a/src/Blocks/BlockOre.h +++ b/src/Blocks/BlockOre.h @@ -3,6 +3,10 @@ #include "BlockHandler.h" + + + + class cBlockOreHandler: public cBlockHandler { @@ -21,26 +25,25 @@ private: { switch (m_BlockType) { - // If it was a glowing redstone ore, drop a normal redstone ore + // If it was a glowing redstone ore, drop a normal redstone ore: case E_BLOCK_REDSTONE_ORE_GLOWING: return cItem(E_BLOCK_REDSTONE_ORE); default: return cItem(m_BlockType); } } - auto & random = GetRandomProvider(); - const unsigned int FortuneLevel = ToolFortuneLevel(a_Tool); - // Clamp to 10 to prevent server crash if thing are mined with extremely high level fortune pick - const unsigned int DropMult = std::clamp(FloorC(random.RandReal(FortuneLevel + 2.0)), 1, 10); + auto & Random = GetRandomProvider(); + const auto FortuneLevel = ToolFortuneLevel(a_Tool); + const auto Drops = std::max(static_cast(1), FloorC(Random.RandReal(FortuneLevel + 2.0))); switch (m_BlockType) { - case E_BLOCK_LAPIS_ORE: return cItem(E_ITEM_DYE, DropMult * random.RandInt(4, 9), 4); - case E_BLOCK_REDSTONE_ORE: // handled by next case (glowing redstone), no dropMult - case E_BLOCK_REDSTONE_ORE_GLOWING: return cItem(E_ITEM_REDSTONE_DUST, random.RandInt(4, 5 + FortuneLevel), 0); - case E_BLOCK_DIAMOND_ORE: return cItem(E_ITEM_DIAMOND, DropMult); - case E_BLOCK_EMERALD_ORE: return cItem(E_ITEM_EMERALD, DropMult); - case E_BLOCK_COAL_ORE: return cItem(E_ITEM_COAL, DropMult); - case E_BLOCK_NETHER_QUARTZ_ORE: return cItem(E_ITEM_NETHER_QUARTZ, DropMult); + case E_BLOCK_LAPIS_ORE: return cItem(E_ITEM_DYE, Drops * Random.RandInt(4, 9), 4); + case E_BLOCK_REDSTONE_ORE: // Handled by next case (glowing redstone) + case E_BLOCK_REDSTONE_ORE_GLOWING: return cItem(E_ITEM_REDSTONE_DUST, Random.RandInt(4, 5 + FortuneLevel)); + case E_BLOCK_DIAMOND_ORE: return cItem(E_ITEM_DIAMOND, Drops); + case E_BLOCK_EMERALD_ORE: return cItem(E_ITEM_EMERALD, Drops); + case E_BLOCK_COAL_ORE: return cItem(E_ITEM_COAL, Drops); + case E_BLOCK_NETHER_QUARTZ_ORE: return cItem(E_ITEM_NETHER_QUARTZ, Drops); case E_BLOCK_CLAY: return cItem(E_ITEM_CLAY, 4); default: { diff --git a/src/Blocks/BlockSeaLantern.h b/src/Blocks/BlockSeaLantern.h index 1fab10a11..2ff100d85 100644 --- a/src/Blocks/BlockSeaLantern.h +++ b/src/Blocks/BlockSeaLantern.h @@ -6,6 +6,7 @@ + class cBlockSeaLanternHandler : public cBlockHandler { @@ -24,13 +25,13 @@ private: { return cItem(E_BLOCK_SEA_LANTERN, 1, 0); } - else - { - unsigned int DropNum = GetRandomProvider().RandInt(2, 3 + ToolFortuneLevel(a_Tool)); - // cap the dropnum to the max amount of 5 - DropNum = std::min(DropNum, 5); - // Reset meta to 0 - return cItem(E_ITEM_PRISMARINE_CRYSTALS, DropNum, 0); - } + + // Number of crystals to drop, capped at the max amount of 5. + const auto Drops = std::min( + static_cast(5), + GetRandomProvider().RandInt(2, 3 + ToolFortuneLevel(a_Tool)) + ); + + return cItem(E_ITEM_PRISMARINE_CRYSTALS, Drops); } } ;