|
| 1 | +<?php |
| 2 | + |
| 3 | +/* |
| 4 | + * |
| 5 | + * ____ _ _ __ __ _ __ __ ____ |
| 6 | + * | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \ |
| 7 | + * | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) | |
| 8 | + * | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/ |
| 9 | + * |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_| |
| 10 | + * |
| 11 | + * This program is free software: you can redistribute it and/or modify |
| 12 | + * it under the terms of the GNU Lesser General Public License as published by |
| 13 | + * the Free Software Foundation, either version 3 of the License, or |
| 14 | + * (at your option) any later version. |
| 15 | + * |
| 16 | + * @author PocketMine Team |
| 17 | + * @link http://www.pocketmine.net/ |
| 18 | + * |
| 19 | + * |
| 20 | + */ |
| 21 | + |
| 22 | +declare(strict_types=1); |
| 23 | + |
| 24 | +namespace pocketmine\block\anvil; |
| 25 | + |
| 26 | +use pocketmine\inventory\transaction\TransactionValidationException; |
| 27 | +use pocketmine\item\EnchantedBook; |
| 28 | +use pocketmine\item\enchantment\AvailableEnchantmentRegistry; |
| 29 | +use pocketmine\item\enchantment\EnchantmentInstance; |
| 30 | +use pocketmine\item\enchantment\Rarity; |
| 31 | +use pocketmine\item\Item; |
| 32 | +use function max; |
| 33 | +use function min; |
| 34 | + |
| 35 | +final class CombineEnchantmentsAction extends AnvilAction{ |
| 36 | + public function canBeApplied() : bool{ |
| 37 | + return $this->material->hasEnchantments(); |
| 38 | + } |
| 39 | + |
| 40 | + public function process(Item $resultItem) : void{ |
| 41 | + foreach($this->material->getEnchantments() as $instance){ |
| 42 | + $enchantment = $instance->getType(); |
| 43 | + $level = $instance->getLevel(); |
| 44 | + if(!AvailableEnchantmentRegistry::getInstance()->isAvailableForItem($enchantment, $this->base)){ |
| 45 | + continue; |
| 46 | + } |
| 47 | + if(($targetEnchantment = $this->base->getEnchantment($enchantment)) !== null){ |
| 48 | + // Enchant already present on the target item |
| 49 | + $targetLevel = $targetEnchantment->getLevel(); |
| 50 | + $newLevel = ($targetLevel === $level ? $targetLevel + 1 : max($targetLevel, $level)); |
| 51 | + $level = min($newLevel, $enchantment->getMaxLevel()); |
| 52 | + $instance = new EnchantmentInstance($enchantment, $level); |
| 53 | + }else{ |
| 54 | + // Check if the enchantment is compatible with the existing enchantments |
| 55 | + foreach($this->base->getEnchantments() as $testedInstance){ |
| 56 | + $testedEnchantment = $testedInstance->getType(); |
| 57 | + if(!$testedEnchantment->isCompatibleWith($enchantment)){ |
| 58 | + $this->xpCost++; |
| 59 | + continue 2; |
| 60 | + } |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + $costAddition = match($enchantment->getRarity()){ |
| 65 | + Rarity::COMMON => 1, |
| 66 | + Rarity::UNCOMMON => 2, |
| 67 | + Rarity::RARE => 4, |
| 68 | + Rarity::MYTHIC => 8, |
| 69 | + default => throw new TransactionValidationException("Invalid rarity " . $enchantment->getRarity() . " found") |
| 70 | + }; |
| 71 | + |
| 72 | + if($this->material instanceof EnchantedBook){ |
| 73 | + // Enchanted books are half as expensive to combine |
| 74 | + $costAddition = max(1, $costAddition / 2); |
| 75 | + } |
| 76 | + $levelDifference = $instance->getLevel() - $this->base->getEnchantmentLevel($instance->getType()); |
| 77 | + $this->xpCost += $costAddition * $levelDifference; |
| 78 | + $resultItem->addEnchantment($instance); |
| 79 | + } |
| 80 | + } |
| 81 | +} |
0 commit comments