diff --git a/src/block/anvil/AnvilAction.php b/src/block/anvil/AnvilAction.php index 35fb31c3b..459763c29 100644 --- a/src/block/anvil/AnvilAction.php +++ b/src/block/anvil/AnvilAction.php @@ -26,6 +26,7 @@ namespace pocketmine\block\anvil; use pocketmine\item\Item; abstract class AnvilAction{ + /** @phpstan-var int<0, max> */ protected int $xpCost = 0; final public function __construct( @@ -34,6 +35,12 @@ abstract class AnvilAction{ protected ?string $customName ){ } + /** + * Returns the XP cost requested for this action. + * This XP cost will be summed up to the total XP cost of the anvil operation. + * + * @phpstan-return int<0, max> + */ final public function getXpCost() : int{ return $this->xpCost; } @@ -46,7 +53,14 @@ abstract class AnvilAction{ return false; } + /** + * Processing an action means applying the changes to the result item + * and updating the XP cost property of the action. + */ abstract public function process(Item $resultItem) : void; + /** + * Returns whether this action is valid and can be applied. + */ abstract public function canBeApplied() : bool; } diff --git a/src/block/anvil/CombineEnchantmentsAction.php b/src/block/anvil/CombineEnchantmentsAction.php index 6419c48c0..585caf659 100644 --- a/src/block/anvil/CombineEnchantmentsAction.php +++ b/src/block/anvil/CombineEnchantmentsAction.php @@ -29,6 +29,7 @@ use pocketmine\item\enchantment\AvailableEnchantmentRegistry; use pocketmine\item\enchantment\EnchantmentInstance; use pocketmine\item\enchantment\Rarity; use pocketmine\item\Item; +use function floor; use function max; use function min; @@ -74,7 +75,7 @@ final class CombineEnchantmentsAction extends AnvilAction{ $costAddition = max(1, $costAddition / 2); } $levelDifference = $instance->getLevel() - $this->base->getEnchantmentLevel($instance->getType()); - $this->xpCost += $costAddition * $levelDifference; + $this->xpCost += (int) floor($costAddition * $levelDifference); $resultItem->addEnchantment($instance); } } diff --git a/src/block/anvil/RepairWithMaterialAction.php b/src/block/anvil/RepairWithMaterialAction.php index 9d9b12b15..817513d08 100644 --- a/src/block/anvil/RepairWithMaterialAction.php +++ b/src/block/anvil/RepairWithMaterialAction.php @@ -53,6 +53,6 @@ final class RepairWithMaterialAction extends AnvilAction{ } $resultItem->setDamage(max(0, $damage)); - $this->xpCost = $numberRepair * self::COST; + $this->xpCost = (int) floor($numberRepair * self::COST); } } diff --git a/src/block/utils/AnvilHelper.php b/src/block/utils/AnvilHelper.php index 86542318c..6066c0be9 100644 --- a/src/block/utils/AnvilHelper.php +++ b/src/block/utils/AnvilHelper.php @@ -51,10 +51,10 @@ final class AnvilHelper{ $xpCost += $action->getXpCost(); } - $xpCost += 2 ** $resultItem->getRepairCost() - 1; - $xpCost += 2 ** $material->getRepairCost() - 1; - $resultItem->setRepairCost( - max($resultItem->getRepairCost(), $material->getRepairCost()) + $additionnalRepairCost + $xpCost += 2 ** $resultItem->getAnvilRepairCost() - 1; + $xpCost += 2 ** $material->getAnvilRepairCost() - 1; + $resultItem->setAnvilRepairCost( + max($resultItem->getAnvilRepairCost(), $material->getAnvilRepairCost()) + $additionnalRepairCost ); if($xpCost <= 0 || ($xpCost > self::COST_LIMIT && !$player->isCreative())){ diff --git a/src/item/Item.php b/src/item/Item.php index ceeeecb20..f21a2000b 100644 --- a/src/item/Item.php +++ b/src/item/Item.php @@ -85,7 +85,7 @@ class Item implements \JsonSerializable{ protected string $customName = ""; /** @var string[] */ protected array $lore = []; - protected int $repairCost = 0; + protected int $anvilRepairCost = 0; /** TODO: this needs to die in a fire */ protected ?CompoundTag $blockEntityTag = null; @@ -285,19 +285,26 @@ class Item implements \JsonSerializable{ } /** - * Returns the repair cost of the item. + * Returns the anvil repair cost of the item. + * This value is used in anvil to determine the XP cost of repairing the item. + * + * In vanilla, this value is stored in the "RepairCost" tag. */ - public function getRepairCost() : int{ - return $this->repairCost; + public function getAnvilRepairCost() : int{ + return $this->anvilRepairCost; } /** - * Sets the repair cost of the item. + * Sets the anvil repair cost value of the item. + * This value is used in anvil to determine the XP cost of repairing the item. + * Higher cost means more XP is required to repair the item. + * + * In vanilla, this value is stored in the "RepairCost" tag. * * @return $this */ - public function setRepairCost(int $cost) : self{ - $this->repairCost = $cost; + public function setAnvilRepairCost(int $cost) : self{ + $this->anvilRepairCost = $cost; return $this; } @@ -357,7 +364,7 @@ class Item implements \JsonSerializable{ } $this->keepOnDeath = $tag->getByte(self::TAG_KEEP_ON_DEATH, 0) !== 0; - $this->repairCost = $tag->getInt(self::TAG_REPAIR_COST, 0); + $this->anvilRepairCost = $tag->getInt(self::TAG_REPAIR_COST, 0); } protected function serializeCompoundTag(CompoundTag $tag) : void{ @@ -427,8 +434,8 @@ class Item implements \JsonSerializable{ $tag->removeTag(self::TAG_KEEP_ON_DEATH); } - if($this->repairCost > 0){ - $tag->setInt(self::TAG_REPAIR_COST, $this->repairCost); + if($this->anvilRepairCost > 0){ + $tag->setInt(self::TAG_REPAIR_COST, $this->anvilRepairCost); }else{ $tag->removeTag(self::TAG_REPAIR_COST); }