diff --git a/src/block/Beetroot.php b/src/block/Beetroot.php index b87a841ea..cf92fdda2 100644 --- a/src/block/Beetroot.php +++ b/src/block/Beetroot.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Beetroot extends Crops{ @@ -33,7 +33,7 @@ class Beetroot extends Crops{ if($this->age >= self::MAX_AGE){ return [ VanillaItems::BEETROOT(), - VanillaItems::BEETROOT_SEEDS()->setCount(mt_rand(0, 3)) + VanillaItems::BEETROOT_SEEDS()->setCount(FortuneDropHelper::binomial($item, 0)) ]; } diff --git a/src/block/Carrot.php b/src/block/Carrot.php index 895b0a37d..7d8947afa 100644 --- a/src/block/Carrot.php +++ b/src/block/Carrot.php @@ -23,15 +23,15 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Carrot extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::CARROT()->setCount($this->age >= self::MAX_AGE ? mt_rand(1, 4) : 1) + VanillaItems::CARROT()->setCount($this->age >= self::MAX_AGE ? FortuneDropHelper::binomial($item, 1) : 1) ]; } diff --git a/src/block/CoalOre.php b/src/block/CoalOre.php index 47a0e255d..19032b011 100644 --- a/src/block/CoalOre.php +++ b/src/block/CoalOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class CoalOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::COAL() + VanillaItems::COAL()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/CopperOre.php b/src/block/CopperOre.php index ad02cc50f..3b8ef12a0 100644 --- a/src/block/CopperOre.php +++ b/src/block/CopperOre.php @@ -23,13 +23,16 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; final class CopperOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ - return [VanillaItems::RAW_COPPER()]; + return [ + VanillaItems::RAW_COPPER()->setCount(FortuneDropHelper::weighted($item, min: 2, maxBase: 5)), + ]; } public function isAffectedBySilkTouch() : bool{ return true; } diff --git a/src/block/DiamondOre.php b/src/block/DiamondOre.php index 8407bdf15..b0486dcfb 100644 --- a/src/block/DiamondOre.php +++ b/src/block/DiamondOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class DiamondOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::DIAMOND() + VanillaItems::DIAMOND()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/DoubleTallGrass.php b/src/block/DoubleTallGrass.php index fc37442f5..e90f2ec61 100644 --- a/src/block/DoubleTallGrass.php +++ b/src/block/DoubleTallGrass.php @@ -23,9 +23,8 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; -use pocketmine\item\VanillaItems; -use function mt_rand; class DoubleTallGrass extends DoublePlant{ @@ -34,8 +33,8 @@ class DoubleTallGrass extends DoublePlant{ } public function getDropsForIncompatibleTool(Item $item) : array{ - if($this->top && mt_rand(0, 7) === 0){ - return [VanillaItems::WHEAT_SEEDS()]; + if($this->top){ + return FortuneDropHelper::grass($item); } return []; } diff --git a/src/block/EmeraldOre.php b/src/block/EmeraldOre.php index 6e997223d..8e5d96191 100644 --- a/src/block/EmeraldOre.php +++ b/src/block/EmeraldOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class EmeraldOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::EMERALD() + VanillaItems::EMERALD()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/GildedBlackstone.php b/src/block/GildedBlackstone.php index e01d6bfdc..75c822f8e 100644 --- a/src/block/GildedBlackstone.php +++ b/src/block/GildedBlackstone.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -30,7 +31,7 @@ use function mt_rand; final class GildedBlackstone extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ - if(mt_rand(1, 10) === 1){ + if(FortuneDropHelper::bonusChanceDivisor($item, 10, 3)){ return [VanillaItems::GOLD_NUGGET()->setCount(mt_rand(2, 5))]; } diff --git a/src/block/Glowstone.php b/src/block/Glowstone.php index 3b567aa5b..1fead9abe 100644 --- a/src/block/Glowstone.php +++ b/src/block/Glowstone.php @@ -23,9 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; +use function min; class Glowstone extends Transparent{ @@ -35,7 +36,7 @@ class Glowstone extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::GLOWSTONE_DUST()->setCount(mt_rand(2, 4)) + VanillaItems::GLOWSTONE_DUST()->setCount(min(4, FortuneDropHelper::discrete($item, 2, 4))) ]; } diff --git a/src/block/Gravel.php b/src/block/Gravel.php index 4bff2208f..6445ce30e 100644 --- a/src/block/Gravel.php +++ b/src/block/Gravel.php @@ -25,15 +25,15 @@ namespace pocketmine\block; use pocketmine\block\utils\Fallable; use pocketmine\block\utils\FallableTrait; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Gravel extends Opaque implements Fallable{ use FallableTrait; public function getDropsForCompatibleTool(Item $item) : array{ - if(mt_rand(1, 10) === 1){ + if(FortuneDropHelper::bonusChanceDivisor($item, 10, 3)){ return [ VanillaItems::FLINT() ]; diff --git a/src/block/LapisOre.php b/src/block/LapisOre.php index 656b0a895..ce54321a4 100644 --- a/src/block/LapisOre.php +++ b/src/block/LapisOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class LapisOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::LAPIS_LAZULI()->setCount(mt_rand(4, 8)) + VanillaItems::LAPIS_LAZULI()->setCount(FortuneDropHelper::weighted($item, min: 4, maxBase: 9)) ]; } diff --git a/src/block/Leaves.php b/src/block/Leaves.php index dc5e9ce80..235190454 100644 --- a/src/block/Leaves.php +++ b/src/block/Leaves.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\block\utils\LeavesType; use pocketmine\block\utils\SupportType; use pocketmine\data\runtime\RuntimeDataDescriber; @@ -138,7 +139,8 @@ class Leaves extends Transparent{ } $drops = []; - if(mt_rand(1, 20) === 1){ //Saplings + if(FortuneDropHelper::bonusChanceDivisor($item, 20, 4)){ //Saplings + // TODO: according to the wiki, the jungle saplings have a different drop rate $sapling = (match($this->leavesType){ LeavesType::ACACIA() => VanillaBlocks::ACACIA_SAPLING(), LeavesType::BIRCH() => VanillaBlocks::BIRCH_SAPLING(), @@ -155,10 +157,13 @@ class Leaves extends Transparent{ $drops[] = $sapling; } } - if(($this->leavesType->equals(LeavesType::OAK()) || $this->leavesType->equals(LeavesType::DARK_OAK())) && mt_rand(1, 200) === 1){ //Apples + if( + ($this->leavesType->equals(LeavesType::OAK()) || $this->leavesType->equals(LeavesType::DARK_OAK())) && + FortuneDropHelper::bonusChanceDivisor($item, 200, 20) + ){ //Apples $drops[] = VanillaItems::APPLE(); } - if(mt_rand(1, 50) === 1){ + if(FortuneDropHelper::bonusChanceDivisor($item, 50, 5)){ $drops[] = VanillaItems::STICK()->setCount(mt_rand(1, 2)); } diff --git a/src/block/Melon.php b/src/block/Melon.php index 42d54c0ab..4a32332e1 100644 --- a/src/block/Melon.php +++ b/src/block/Melon.php @@ -23,15 +23,16 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; +use function min; class Melon extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::MELON()->setCount(mt_rand(3, 7)) + VanillaItems::MELON()->setCount(min(9, FortuneDropHelper::discrete($item, 3, 7))) ]; } diff --git a/src/block/NetherGoldOre.php b/src/block/NetherGoldOre.php index 7782f4fc4..fd6745df4 100644 --- a/src/block/NetherGoldOre.php +++ b/src/block/NetherGoldOre.php @@ -23,14 +23,14 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; final class NetherGoldOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ - return [VanillaItems::GOLD_NUGGET()->setCount(mt_rand(2, 6))]; + return [VanillaItems::GOLD_NUGGET()->setCount(FortuneDropHelper::weighted($item, min: 2, maxBase: 6))]; } public function isAffectedBySilkTouch() : bool{ return true; } diff --git a/src/block/NetherQuartzOre.php b/src/block/NetherQuartzOre.php index c2ab20491..0981974ee 100644 --- a/src/block/NetherQuartzOre.php +++ b/src/block/NetherQuartzOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,7 @@ class NetherQuartzOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::NETHER_QUARTZ() + VanillaItems::NETHER_QUARTZ()->setCount(FortuneDropHelper::weighted($item, min: 1, maxBase: 1)) ]; } diff --git a/src/block/NetherVines.php b/src/block/NetherVines.php index adf611785..ac075f667 100644 --- a/src/block/NetherVines.php +++ b/src/block/NetherVines.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\block\utils\SupportType; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\entity\Entity; @@ -179,7 +180,7 @@ class NetherVines extends Flowable{ } public function getDropsForCompatibleTool(Item $item) : array{ - if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0 || mt_rand(1, 3) === 1){ + if(($item->getBlockToolType() & BlockToolType::SHEARS) !== 0 || FortuneDropHelper::bonusChanceFixed($item, 1 / 3, 2 / 9)){ return [$this->asItem()]; } return []; diff --git a/src/block/NetherWartPlant.php b/src/block/NetherWartPlant.php index 76de2a470..6a8fe1f7a 100644 --- a/src/block/NetherWartPlant.php +++ b/src/block/NetherWartPlant.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\event\block\BlockGrowEvent; use pocketmine\item\Item; @@ -85,7 +86,7 @@ class NetherWartPlant extends Flowable{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - $this->asItem()->setCount($this->age === self::MAX_AGE ? mt_rand(2, 4) : 1) + $this->asItem()->setCount($this->age === self::MAX_AGE ? FortuneDropHelper::discrete($item, 2, 4) : 1) ]; } } diff --git a/src/block/Potato.php b/src/block/Potato.php index 47d39f612..4d1bbf979 100644 --- a/src/block/Potato.php +++ b/src/block/Potato.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; use function mt_rand; @@ -31,7 +32,8 @@ class Potato extends Crops{ public function getDropsForCompatibleTool(Item $item) : array{ $result = [ - VanillaItems::POTATO()->setCount($this->age >= self::MAX_AGE ? mt_rand(1, 5) : 1) + //min/max would be 2-5 in Java + VanillaItems::POTATO()->setCount($this->age >= self::MAX_AGE ? FortuneDropHelper::binomial($item, 1) : 1) ]; if($this->age >= self::MAX_AGE && mt_rand(0, 49) === 0){ $result[] = VanillaItems::POISONOUS_POTATO(); diff --git a/src/block/RedstoneOre.php b/src/block/RedstoneOre.php index 74708c2bd..75f5063ee 100644 --- a/src/block/RedstoneOre.php +++ b/src/block/RedstoneOre.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\item\Item; use pocketmine\item\VanillaItems; @@ -81,7 +82,7 @@ class RedstoneOre extends Opaque{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::REDSTONE_DUST()->setCount(mt_rand(4, 5)) + VanillaItems::REDSTONE_DUST()->setCount(FortuneDropHelper::discrete($item, 4, 5)) ]; } diff --git a/src/block/SeaLantern.php b/src/block/SeaLantern.php index 27ed73f0d..ff0c97d73 100644 --- a/src/block/SeaLantern.php +++ b/src/block/SeaLantern.php @@ -23,8 +23,10 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; +use function min; class SeaLantern extends Transparent{ @@ -34,7 +36,7 @@ class SeaLantern extends Transparent{ public function getDropsForCompatibleTool(Item $item) : array{ return [ - VanillaItems::PRISMARINE_CRYSTALS()->setCount(3) + VanillaItems::PRISMARINE_CRYSTALS()->setCount(min(5, FortuneDropHelper::discrete($item, 2, 3))) ]; } diff --git a/src/block/SweetBerryBush.php b/src/block/SweetBerryBush.php index b75a343ec..5ead39390 100644 --- a/src/block/SweetBerryBush.php +++ b/src/block/SweetBerryBush.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\data\runtime\RuntimeDataDescriber; use pocketmine\entity\Entity; use pocketmine\entity\Living; @@ -108,13 +109,14 @@ class SweetBerryBush extends Flowable{ } public function getDropsForCompatibleTool(Item $item) : array{ - if(($dropAmount = $this->getBerryDropAmount()) > 0){ - return [ - $this->asItem()->setCount($dropAmount) - ]; - } - - return []; + $count = match($this->age){ + self::STAGE_MATURE => FortuneDropHelper::discrete($item, 2, 3), + self::STAGE_BUSH_SOME_BERRIES => FortuneDropHelper::discrete($item, 1, 2), + default => 0 + }; + return [ + $this->asItem()->setCount($count) + ]; } public function onNearbyBlockChange() : void{ diff --git a/src/block/TallGrass.php b/src/block/TallGrass.php index e8f533325..019b911bc 100644 --- a/src/block/TallGrass.php +++ b/src/block/TallGrass.php @@ -23,13 +23,12 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; -use pocketmine\item\VanillaItems; use pocketmine\math\Facing; use pocketmine\math\Vector3; use pocketmine\player\Player; use pocketmine\world\BlockTransaction; -use function mt_rand; class TallGrass extends Flowable{ @@ -56,13 +55,7 @@ class TallGrass extends Flowable{ } public function getDropsForIncompatibleTool(Item $item) : array{ - if(mt_rand(0, 15) === 0){ - return [ - VanillaItems::WHEAT_SEEDS() - ]; - } - - return []; + return FortuneDropHelper::grass($item); } public function getFlameEncouragement() : int{ diff --git a/src/block/Wheat.php b/src/block/Wheat.php index 15701c976..92f155f76 100644 --- a/src/block/Wheat.php +++ b/src/block/Wheat.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace pocketmine\block; +use pocketmine\block\utils\FortuneDropHelper; use pocketmine\item\Item; use pocketmine\item\VanillaItems; -use function mt_rand; class Wheat extends Crops{ @@ -33,7 +33,7 @@ class Wheat extends Crops{ if($this->age >= self::MAX_AGE){ return [ VanillaItems::WHEAT(), - VanillaItems::WHEAT_SEEDS()->setCount(mt_rand(0, 3)) + VanillaItems::WHEAT_SEEDS()->setCount(FortuneDropHelper::binomial($item, 0)) ]; }else{ return [ diff --git a/src/block/utils/FortuneDropHelper.php b/src/block/utils/FortuneDropHelper.php new file mode 100644 index 000000000..4bce36138 --- /dev/null +++ b/src/block/utils/FortuneDropHelper.php @@ -0,0 +1,150 @@ +getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + + return mt_rand($min, + $fortuneLevel > 0 && mt_rand() / mt_getrandmax() > 2 / ($fortuneLevel + 2) ? + $maxBase * ($fortuneLevel + 1) : + $maxBase + ); + } + + /** + * Increases the drop amount according to a binomial distribution. The function will roll maxBase+level times, and add 1 + * if a random number between 0-1 is less than the given probability. Each level of fortune adds one extra roll. + * + * As many as maxBase+level items can be dropped. This applies even if the fortune level is 0. + * + * @param float $chance The chance of adding 1 to the amount for each roll, must be in the range 0-1 + * @param int $min Minimum amount + * @param int $minRolls Number of rolls if fortune level is 0, added to fortune level to calculate total rolls + * + * @return int the number of items to drop + */ + public static function binomial(Item $usedItem, int $min, int $minRolls = 3, float $chance = 4 / 7) : int{ + $fortuneLevel = $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + + $count = $min; + $rolls = $minRolls + $fortuneLevel; + for($i = 0; $i < $rolls; ++$i){ + if(mt_rand() / mt_getrandmax() < $chance){ + ++$count; + } + } + + return $count; + } + + /** + * Grass have a fixed chance to drop wheat seed. + * Fortune level increases the maximum number of seeds that can be dropped. + * A discrete uniform distribution is used to determine the number of seeds dropped. + * + * TODO: I'm not sure this really belongs here, but it's preferable not to duplicate this code between grass and + * tall grass. + * + * @return Item[] + */ + public static function grass(Item $usedItem) : array{ + if(FortuneDropHelper::bonusChanceDivisor($usedItem, 8, 2)){ + return [ + VanillaItems::WHEAT_SEEDS() + ]; + } + + return []; + } + + /** + * Adds the fortune level to the base max and picks a random number between the minimim and adjusted maximum. + * Each amount in the range has an equal chance of being picked. + * + * @param int $maxBase Maximum base amount, as if the fortune level was 0 + * + * @return int the number of items to drop + */ + public static function discrete(Item $usedItem, int $min, int $maxBase) : int{ + if($maxBase < $min){ + throw new \InvalidArgumentException("Minimum base drop amount must be less than or equal to maximum base drop amount"); + } + + $max = $maxBase + $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + return mt_rand($min, $max); + } + + /** + * Calculates a chance of getting an extra bonus drop by reducing the chance divisor by a given amount per fortune + * level. + * + * @param int $divisorBase The number to divide 1 by to get the chance, as if the fortune level was 0 + * @param int $divisorSubtractPerLevel The amount to subtract from the divisor for each level of fortune + * + * @return bool whether the bonus drop should be added + */ + public static function bonusChanceDivisor(Item $usedItem, int $divisorBase, int $divisorSubtractPerLevel) : bool{ + $fortuneLevel = $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + return mt_rand(1, max(1, $divisorBase - ($fortuneLevel * $divisorSubtractPerLevel))) === 1; + } + + /** + * Calculates a chance of getting an extra bonus drop by increasing the chance by a fixed amount per fortune level. + * + * @param float $chanceBase The base chance of getting a bonus drop, as if the fortune level was 0 + * @param float $addedChancePerLevel The amount to add to the chance for each level of fortune + */ + public static function bonusChanceFixed(Item $usedItem, float $chanceBase, float $addedChancePerLevel) : bool{ + $fortuneLevel = $usedItem->getEnchantmentLevel(VanillaEnchantments::FORTUNE()); + $chance = min(1, $chanceBase + ($fortuneLevel * $addedChancePerLevel)); + return mt_rand() / mt_getrandmax() < $chance; + } +} diff --git a/src/data/bedrock/EnchantmentIdMap.php b/src/data/bedrock/EnchantmentIdMap.php index d7f436fa3..1d974ed6e 100644 --- a/src/data/bedrock/EnchantmentIdMap.php +++ b/src/data/bedrock/EnchantmentIdMap.php @@ -62,6 +62,7 @@ final class EnchantmentIdMap{ $this->register(EnchantmentIds::FIRE_ASPECT, VanillaEnchantments::FIRE_ASPECT()); $this->register(EnchantmentIds::EFFICIENCY, VanillaEnchantments::EFFICIENCY()); + $this->register(EnchantmentIds::FORTUNE, VanillaEnchantments::FORTUNE()); $this->register(EnchantmentIds::SILK_TOUCH, VanillaEnchantments::SILK_TOUCH()); $this->register(EnchantmentIds::UNBREAKING, VanillaEnchantments::UNBREAKING()); diff --git a/src/item/enchantment/StringToEnchantmentParser.php b/src/item/enchantment/StringToEnchantmentParser.php index e76e71642..cd57eb203 100644 --- a/src/item/enchantment/StringToEnchantmentParser.php +++ b/src/item/enchantment/StringToEnchantmentParser.php @@ -43,6 +43,7 @@ final class StringToEnchantmentParser extends StringToTParser{ $result->register("fire_aspect", fn() => VanillaEnchantments::FIRE_ASPECT()); $result->register("fire_protection", fn() => VanillaEnchantments::FIRE_PROTECTION()); $result->register("flame", fn() => VanillaEnchantments::FLAME()); + $result->register("fortune", fn() => VanillaEnchantments::FORTUNE()); $result->register("infinity", fn() => VanillaEnchantments::INFINITY()); $result->register("knockback", fn() => VanillaEnchantments::KNOCKBACK()); $result->register("mending", fn() => VanillaEnchantments::MENDING()); diff --git a/src/item/enchantment/VanillaEnchantments.php b/src/item/enchantment/VanillaEnchantments.php index 2be5eed71..ac2f5c57e 100644 --- a/src/item/enchantment/VanillaEnchantments.php +++ b/src/item/enchantment/VanillaEnchantments.php @@ -39,6 +39,7 @@ use pocketmine\utils\RegistryTrait; * @method static FireAspectEnchantment FIRE_ASPECT() * @method static ProtectionEnchantment FIRE_PROTECTION() * @method static Enchantment FLAME() + * @method static Enchantment FORTUNE() * @method static Enchantment INFINITY() * @method static KnockbackEnchantment KNOCKBACK() * @method static Enchantment MENDING() @@ -85,6 +86,7 @@ final class VanillaEnchantments{ self::register("FIRE_ASPECT", new FireAspectEnchantment(KnownTranslationFactory::enchantment_fire(), Rarity::RARE, ItemFlags::SWORD, ItemFlags::NONE, 2)); self::register("EFFICIENCY", new Enchantment(KnownTranslationFactory::enchantment_digging(), Rarity::COMMON, ItemFlags::DIG, ItemFlags::SHEARS, 5)); + self::register("FORTUNE", new Enchantment(KnownTranslationFactory::enchantment_lootBonusDigger(), Rarity::RARE, ItemFlags::DIG, ItemFlags::NONE, 3)); self::register("SILK_TOUCH", new Enchantment(KnownTranslationFactory::enchantment_untouching(), Rarity::MYTHIC, ItemFlags::DIG, ItemFlags::SHEARS, 1)); self::register("UNBREAKING", new Enchantment(KnownTranslationFactory::enchantment_durability(), Rarity::UNCOMMON, ItemFlags::DIG | ItemFlags::ARMOR | ItemFlags::FISHING_ROD | ItemFlags::BOW, ItemFlags::TOOL | ItemFlags::CARROT_STICK | ItemFlags::ELYTRA, 3));