diff --git a/src/entity/AttributeFactory.php b/src/entity/AttributeFactory.php index 5a9cd77e3..e25f7c1c4 100644 --- a/src/entity/AttributeFactory.php +++ b/src/entity/AttributeFactory.php @@ -54,6 +54,14 @@ final class AttributeFactory{ return isset($this->attributes[$id]) ? clone $this->attributes[$id] : null; } + public function mustGet(string $id) : Attribute{ + $result = $this->get($id); + if($result === null){ + throw new \InvalidArgumentException("Attribute $id is not registered"); + } + return $result; + } + /** * @throws \InvalidArgumentException */ diff --git a/src/entity/ExperienceManager.php b/src/entity/ExperienceManager.php index 0b8fb050c..cc880198b 100644 --- a/src/entity/ExperienceManager.php +++ b/src/entity/ExperienceManager.php @@ -59,8 +59,9 @@ class ExperienceManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->add(AttributeFactory::getInstance()->get($attributeId)); - return $entity->getAttributeMap()->get($attributeId); + $attribute = AttributeFactory::getInstance()->mustGet($attributeId); + $entity->getAttributeMap()->add($attribute); + return $attribute; } /** diff --git a/src/entity/HungerManager.php b/src/entity/HungerManager.php index 331f8e96c..77eb87d11 100644 --- a/src/entity/HungerManager.php +++ b/src/entity/HungerManager.php @@ -57,8 +57,9 @@ class HungerManager{ } private static function fetchAttribute(Entity $entity, string $attributeId) : Attribute{ - $entity->getAttributeMap()->add(AttributeFactory::getInstance()->get($attributeId)); - return $entity->getAttributeMap()->get($attributeId); + $attribute = AttributeFactory::getInstance()->get($attributeId); + $entity->getAttributeMap()->add($attribute); + return $attribute; } public function getFood() : float{ diff --git a/src/entity/Living.php b/src/entity/Living.php index febc3f1c2..524f17dda 100644 --- a/src/entity/Living.php +++ b/src/entity/Living.php @@ -101,6 +101,13 @@ abstract class Living extends Entity{ /** @var int */ protected $maxBreathTicks = self::DEFAULT_BREATH_TICKS; + /** @var Attribute */ + protected $healthAttr; + /** @var Attribute */ + protected $absorptionAttr; + /** @var Attribute */ + protected $knockbackResistanceAttr; + abstract public function getName() : string; protected function initEntity(CompoundTag $nbt) : void{ @@ -153,37 +160,37 @@ abstract class Living extends Entity{ } protected function addAttributes() : void{ - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::HEALTH)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::FOLLOW_RANGE)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::KNOCKBACK_RESISTANCE)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::MOVEMENT_SPEED)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::ATTACK_DAMAGE)); - $this->attributeMap->add(AttributeFactory::getInstance()->get(Attribute::ABSORPTION)); + $this->attributeMap->add($this->healthAttr = AttributeFactory::getInstance()->mustGet(Attribute::HEALTH)); + $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::FOLLOW_RANGE)); + $this->attributeMap->add($this->knockbackResistanceAttr = AttributeFactory::getInstance()->mustGet(Attribute::KNOCKBACK_RESISTANCE)); + $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::MOVEMENT_SPEED)); + $this->attributeMap->add(AttributeFactory::getInstance()->mustGet(Attribute::ATTACK_DAMAGE)); + $this->attributeMap->add($this->absorptionAttr = AttributeFactory::getInstance()->mustGet(Attribute::ABSORPTION)); } public function setHealth(float $amount) : void{ $wasAlive = $this->isAlive(); parent::setHealth($amount); - $this->attributeMap->get(Attribute::HEALTH)->setValue(ceil($this->getHealth()), true); + $this->healthAttr->setValue(ceil($this->getHealth()), true); if($this->isAlive() and !$wasAlive){ $this->broadcastAnimation(new RespawnAnimation($this)); } } public function getMaxHealth() : int{ - return (int) $this->attributeMap->get(Attribute::HEALTH)->getMaxValue(); + return (int) $this->healthAttr->getMaxValue(); } public function setMaxHealth(int $amount) : void{ - $this->attributeMap->get(Attribute::HEALTH)->setMaxValue($amount)->setDefaultValue($amount); + $this->healthAttr->setMaxValue($amount)->setDefaultValue($amount); } public function getAbsorption() : float{ - return $this->attributeMap->get(Attribute::ABSORPTION)->getValue(); + return $this->absorptionAttr->getValue(); } public function setAbsorption(float $absorption) : void{ - $this->attributeMap->get(Attribute::ABSORPTION)->setValue($absorption); + $this->absorptionAttr->setValue($absorption); } public function saveNBT() : CompoundTag{ @@ -453,7 +460,7 @@ abstract class Living extends Entity{ if($f <= 0){ return; } - if(mt_rand() / mt_getrandmax() > $this->getAttributeMap()->get(Attribute::KNOCKBACK_RESISTANCE)->getValue()){ + if(mt_rand() / mt_getrandmax() > $this->knockbackResistanceAttr->getValue()){ $f = 1 / $f; $motion = clone $this->motion; diff --git a/tests/phpstan/configs/l8-baseline.neon b/tests/phpstan/configs/l8-baseline.neon index b34208e49..28ca59cff 100644 --- a/tests/phpstan/configs/l8-baseline.neon +++ b/tests/phpstan/configs/l8-baseline.neon @@ -185,16 +185,6 @@ parameters: count: 1 path: ../../../src/entity/Entity.php - - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" - count: 1 - path: ../../../src/entity/ExperienceManager.php - - - - message: "#^Method pocketmine\\\\entity\\\\ExperienceManager\\:\\:fetchAttribute\\(\\) should return pocketmine\\\\entity\\\\Attribute but returns pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/ExperienceManager.php - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" count: 1 @@ -205,31 +195,6 @@ parameters: count: 1 path: ../../../src/entity/HungerManager.php - - - message: "#^Parameter \\#1 \\$attribute of method pocketmine\\\\entity\\\\AttributeMap\\:\\:add\\(\\) expects pocketmine\\\\entity\\\\Attribute, pocketmine\\\\entity\\\\Attribute\\|null given\\.$#" - count: 6 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method setValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method getMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method setMaxValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 1 - path: ../../../src/entity/Living.php - - - - message: "#^Cannot call method getValue\\(\\) on pocketmine\\\\entity\\\\Attribute\\|null\\.$#" - count: 2 - path: ../../../src/entity/Living.php - - message: "#^Cannot call method getEffectLevel\\(\\) on pocketmine\\\\entity\\\\effect\\\\EffectInstance\\|null\\.$#" count: 3