From 6b5c0af161860c0756a6d7b615be282332cb816e Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Mon, 7 Aug 2017 15:54:03 +0100 Subject: [PATCH] Separation of effect handling from Entity, fixes #886 --- src/pocketmine/block/Fire.php | 7 +- src/pocketmine/block/Lava.php | 8 +- src/pocketmine/entity/Entity.php | 277 +++++++----------- src/pocketmine/entity/Living.php | 222 +++++++++++++- .../entity/EntityDamageByEntityEvent.php | 13 +- .../event/entity/EntityDamageEvent.php | 5 - 6 files changed, 338 insertions(+), 194 deletions(-) diff --git a/src/pocketmine/block/Fire.php b/src/pocketmine/block/Fire.php index 45120c692..fb3919e66 100644 --- a/src/pocketmine/block/Fire.php +++ b/src/pocketmine/block/Fire.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace pocketmine\block; use pocketmine\entity\Arrow; -use pocketmine\entity\Effect; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; @@ -63,10 +62,8 @@ class Fire extends Flowable{ } public function onEntityCollide(Entity $entity){ - if(!$entity->hasEffect(Effect::FIRE_RESISTANCE)){ - $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); - $entity->attack($ev->getFinalDamage(), $ev); - } + $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_FIRE, 1); + $entity->attack($ev->getFinalDamage(), $ev); $ev = new EntityCombustByBlockEvent($this, $entity, 8); if($entity instanceof Arrow){ diff --git a/src/pocketmine/block/Lava.php b/src/pocketmine/block/Lava.php index 88cc81f6a..7d67f4cb6 100644 --- a/src/pocketmine/block/Lava.php +++ b/src/pocketmine/block/Lava.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\block; -use pocketmine\entity\Effect; use pocketmine\entity\Entity; use pocketmine\event\entity\EntityCombustByBlockEvent; use pocketmine\event\entity\EntityDamageByBlockEvent; @@ -50,10 +49,9 @@ class Lava extends Liquid{ public function onEntityCollide(Entity $entity){ $entity->fallDistance *= 0.5; - if(!$entity->hasEffect(Effect::FIRE_RESISTANCE)){ - $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4); - $entity->attack($ev->getFinalDamage(), $ev); - } + + $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_LAVA, 4); + $entity->attack($ev->getFinalDamage(), $ev); $ev = new EntityCombustByBlockEvent($this, $entity, 15); Server::getInstance()->getPluginManager()->callEvent($ev); diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index f306f4e3d..31a85fc63 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -51,17 +51,14 @@ use pocketmine\nbt\tag\ByteTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\DoubleTag; use pocketmine\nbt\tag\FloatTag; -use pocketmine\nbt\tag\IntTag; use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ShortTag; use pocketmine\nbt\tag\StringTag; -use pocketmine\network\mcpe\protocol\MobEffectPacket; use pocketmine\network\mcpe\protocol\RemoveEntityPacket; use pocketmine\network\mcpe\protocol\SetEntityDataPacket; use pocketmine\Player; use pocketmine\plugin\Plugin; use pocketmine\Server; -use pocketmine\utils\Binary; abstract class Entity extends Location implements Metadatable{ @@ -225,9 +222,6 @@ abstract class Entity extends Location implements Metadatable{ */ protected $hasSpawned = []; - /** @var Effect[] */ - protected $effects = []; - protected $id; protected $dataProperties = [ @@ -294,7 +288,8 @@ abstract class Entity extends Location implements Metadatable{ protected $stepHeight = 0; public $keepMovement = false; - public $fallDistance = 0; + /** @var float */ + public $fallDistance = 0.0; public $ticksLived = 0; public $lastUpdate; public $maxFireTicks; @@ -480,6 +475,11 @@ abstract class Entity extends Location implements Metadatable{ $this->setDataProperty(self::DATA_SCALE, self::DATA_TYPE_FLOAT, $value); } + public function getBoundingBox(){ + return $this->boundingBox; + } + + public function isSneaking(){ return $this->getDataFlag(self::DATA_FLAGS, self::DATA_FLAG_SNEAKING); } @@ -617,85 +617,59 @@ abstract class Entity extends Location implements Metadatable{ } /** + * @deprecated + * * @return Effect[] */ - public function getEffects(){ - return $this->effects; + public function getEffects() : array{ + return []; } + /** + * @deprecated + */ public function removeAllEffects(){ - foreach($this->effects as $effect){ - $this->removeEffect($effect->getId()); - } + } - public function removeEffect($effectId){ - if(isset($this->effects[$effectId])){ - $effect = $this->effects[$effectId]; - unset($this->effects[$effectId]); - $effect->remove($this); + /** + * @deprecated + * + * @param int $effectId + */ + public function removeEffect(int $effectId){ - $this->recalculateEffectColor(); - } } - public function getEffect($effectId){ - return $this->effects[$effectId] ?? null; + /** + * @deprecated + * + * @param int $effectId + * + * @return Effect|null + */ + public function getEffect(int $effectId){ + return null; } - public function hasEffect($effectId){ - return isset($this->effects[$effectId]); + /** + * @deprecated + * + * @param int $effectId + * + * @return bool + */ + public function hasEffect(int $effectId) : bool{ + return false; } + /** + * @deprecated + * + * @param Effect $effect + */ public function addEffect(Effect $effect){ - if(isset($this->effects[$effect->getId()])){ - $oldEffect = $this->effects[$effect->getId()]; - if( - abs($effect->getAmplifier()) < $oldEffect->getAmplifier() - or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) - and $effect->getDuration() < $oldEffect->getDuration()) - ){ - return; - } - $effect->add($this, true, $oldEffect); - }else{ - $effect->add($this, false); - } - - $this->effects[$effect->getId()] = $effect; - - $this->recalculateEffectColor(); - } - - protected function recalculateEffectColor(){ - //TODO: add transparency values - $color = [0, 0, 0]; //RGB - $count = 0; - $ambient = true; - foreach($this->effects as $effect){ - if($effect->isVisible() and $effect->hasBubbles()){ - $c = $effect->getColor(); - $color[0] += $c[0] * $effect->getEffectLevel(); - $color[1] += $c[1] * $effect->getEffectLevel(); - $color[2] += $c[2] * $effect->getEffectLevel(); - $count += $effect->getEffectLevel(); - if(!$effect->isAmbient()){ - $ambient = false; - } - } - } - - if($count > 0){ - $r = ($color[0] / $count) & 0xff; - $g = ($color[1] / $count) & 0xff; - $b = ($color[2] / $count) & 0xff; - - $this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, 0xff000000 | ($r << 16) | ($g << 8) | $b); - $this->setDataProperty(Entity::DATA_POTION_AMBIENT, Entity::DATA_TYPE_BYTE, $ambient ? 1 : 0); - }else{ - $this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, 0); - $this->setDataProperty(Entity::DATA_POTION_AMBIENT, Entity::DATA_TYPE_BYTE, 0); - } + throw new \BadMethodCallException("Cannot add effects to non-living entities"); } /** @@ -775,23 +749,6 @@ abstract class Entity extends Location implements Metadatable{ $this->namedtag->Air = new ShortTag("Air", $this->getDataProperty(self::DATA_AIR)); $this->namedtag->OnGround = new ByteTag("OnGround", $this->onGround ? 1 : 0); $this->namedtag->Invulnerable = new ByteTag("Invulnerable", $this->invulnerable ? 1 : 0); - - if(count($this->effects) > 0){ - $effects = []; - foreach($this->effects as $effect){ - $effects[] = new CompoundTag("", [ - new ByteTag("Id", $effect->getId()), - new ByteTag("Amplifier", Binary::signByte($effect->getAmplifier())), - new IntTag("Duration", $effect->getDuration()), - new ByteTag("Ambient", 0), - new ByteTag("ShowParticles", $effect->isVisible() ? 1 : 0) - ]); - } - - $this->namedtag->ActiveEffects = new ListTag("ActiveEffects", $effects); - }else{ - unset($this->namedtag->ActiveEffects); - } } protected function initEntity(){ @@ -805,24 +762,10 @@ abstract class Entity extends Location implements Metadatable{ } $this->scheduleUpdate(); - - if(isset($this->namedtag->ActiveEffects)){ - foreach($this->namedtag->ActiveEffects->getValue() as $e){ - $amplifier = Binary::unsignByte($e->Amplifier->getValue()); //0-255 only - - $effect = Effect::getEffect($e["Id"]); - if($effect === null){ - continue; - } - - $effect->setAmplifier($amplifier)->setDuration($e["Duration"])->setVisible($e["ShowParticles"] > 0); - - $this->addEffect($effect); - } - } } protected function addAttributes(){ + } /** @@ -841,18 +784,13 @@ abstract class Entity extends Location implements Metadatable{ } } + /** + * @deprecated + * + * @param Player $player + */ public function sendPotionEffects(Player $player){ - foreach($this->effects as $effect){ - $pk = new MobEffectPacket(); - $pk->entityRuntimeId = $this->id; - $pk->effectId = $effect->getId(); - $pk->amplifier = $effect->getAmplifier(); - $pk->particles = $effect->isVisible(); - $pk->duration = $effect->getDuration(); - $pk->eventId = MobEffectPacket::EVENT_ADD; - $player->dataPacket($pk); - } } /** @@ -901,15 +839,6 @@ abstract class Entity extends Location implements Metadatable{ * */ public function attack($damage, EntityDamageEvent $source){ - if($this->hasEffect(Effect::FIRE_RESISTANCE) and ( - $source->getCause() === EntityDamageEvent::CAUSE_FIRE - or $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK - or $source->getCause() === EntityDamageEvent::CAUSE_LAVA - ) - ){ - $source->setCancelled(); - } - $this->server->getPluginManager()->callEvent($source); if($source->isCancelled()){ return; @@ -1141,18 +1070,6 @@ abstract class Entity extends Location implements Metadatable{ $this->changedDataProperties = []; } - if(count($this->effects) > 0){ - foreach($this->effects as $effect){ - if($effect->canTick()){ - $effect->applyEffect($this); - } - $effect->setDuration($effect->getDuration() - $tickDiff); - if($effect->getDuration() <= 0){ - $this->removeEffect($effect->getId()); - } - } - } - $hasUpdate = false; $this->checkBlockCollision(); @@ -1163,27 +1080,8 @@ abstract class Entity extends Location implements Metadatable{ $hasUpdate = true; } - if($this->fireTicks > 0){ - if($this->isFireProof()){ - if($this->fireTicks > 1){ - $this->fireTicks = 1; - }else{ - $this->fireTicks -= 1; - } - }else{ - if(!$this->hasEffect(Effect::FIRE_RESISTANCE) and (($this->fireTicks % 20) === 0 or $tickDiff > 20)){ - $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FIRE_TICK, 1); - $this->attack($ev->getFinalDamage(), $ev); - } - $this->fireTicks -= $tickDiff; - } - - if($this->fireTicks <= 0){ - $this->extinguish(); - }else{ - $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ONFIRE, true); - $hasUpdate = true; - } + if($this->isOnFire()){ + $hasUpdate = ($hasUpdate || $this->doOnFireTick($tickDiff)); } if($this->noDamageTicks > 0){ @@ -1199,6 +1097,36 @@ abstract class Entity extends Location implements Metadatable{ return $hasUpdate; } + protected function doOnFireTick(int $tickDiff = 1) : bool{ + if($this->isFireProof() and $this->fireTicks > 1){ + $this->fireTicks = 1; + }else{ + $this->fireTicks -= $tickDiff; + } + + + + if(($this->fireTicks % 20 === 0) or $tickDiff > 20){ + $this->dealFireDamage(); + } + + if(!$this->isOnFire()){ + $this->extinguish(); + }else{ + return true; + } + + return false; + } + + /** + * Called to deal damage to entities when they are on fire. + */ + protected function dealFireDamage(){ + $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FIRE_TICK, 1); + $this->attack($ev->getFinalDamage(), $ev); + } + protected function updateMovement(){ $diffPosition = ($this->x - $this->lastX) ** 2 + ($this->y - $this->lastY) ** 2 + ($this->z - $this->lastZ) ** 2; $diffRotation = ($this->yaw - $this->lastYaw) ** 2 + ($this->pitch - $this->lastPitch) ** 2; @@ -1293,6 +1221,13 @@ abstract class Entity extends Location implements Metadatable{ if($ticks > $this->fireTicks){ $this->fireTicks = $ticks; } + + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ONFIRE, true); + } + + public function extinguish(){ + $this->fireTicks = 0; + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ONFIRE, false); } public function isFireProof() : bool{ @@ -1317,25 +1252,24 @@ abstract class Entity extends Location implements Metadatable{ } } - public function extinguish(){ - $this->fireTicks = 0; - $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ONFIRE, false); - } + public function canTriggerWalking(){ return true; } public function resetFallDistance(){ - $this->fallDistance = 0; + $this->fallDistance = 0.0; } - protected function updateFallState($distanceThisTick, $onGround){ + /** + * @param float $distanceThisTick + * @param bool $onGround + */ + protected function updateFallState(float $distanceThisTick, bool $onGround){ if($onGround === true){ if($this->fallDistance > 0){ - if($this instanceof Living){ - $this->fall($this->fallDistance); - } + $this->fall($this->fallDistance); $this->resetFallDistance(); } }elseif($distanceThisTick < 0){ @@ -1343,16 +1277,13 @@ abstract class Entity extends Location implements Metadatable{ } } - public function getBoundingBox(){ - return $this->boundingBox; - } + /** + * Called when a falling entity hits the ground. + * + * @param float $fallDistance + */ + public function fall(float $fallDistance){ - public function fall($fallDistance){ - $damage = floor($fallDistance - 3 - ($this->hasEffect(Effect::JUMP) ? $this->getEffect(Effect::JUMP)->getEffectLevel() : 0)); - if($damage > 0){ - $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); - $this->attack($ev->getFinalDamage(), $ev); - } } public function handleLavaMovement(){ //TODO diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 46c5c7c22..3f7c9e7f8 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -32,8 +32,15 @@ use pocketmine\event\entity\EntityRegainHealthEvent; use pocketmine\event\Timings; use pocketmine\item\Item as ItemItem; use pocketmine\math\Vector3; +use pocketmine\nbt\tag\ByteTag; +use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\FloatTag; +use pocketmine\nbt\tag\IntTag; +use pocketmine\nbt\tag\ListTag; use pocketmine\network\mcpe\protocol\EntityEventPacket; +use pocketmine\network\mcpe\protocol\MobEffectPacket; +use pocketmine\Player; +use pocketmine\utils\Binary; use pocketmine\utils\BlockIterator; abstract class Living extends Entity implements Damageable{ @@ -47,6 +54,11 @@ abstract class Living extends Entity implements Damageable{ protected $jumpVelocity = 0.42; + /** @var Effect[] */ + protected $effects = []; + + abstract public function getName(); + protected function initEntity(){ parent::initEntity(); @@ -62,6 +74,21 @@ abstract class Living extends Entity implements Damageable{ } $this->setHealth($this->namedtag["Health"]); + + if(isset($this->namedtag->ActiveEffects)){ + foreach($this->namedtag->ActiveEffects->getValue() as $e){ + $amplifier = Binary::unsignByte($e->Amplifier->getValue()); //0-255 only + + $effect = Effect::getEffect($e["Id"]); + if($effect === null){ + continue; + } + + $effect->setAmplifier($amplifier)->setDuration($e["Duration"])->setVisible($e["ShowParticles"] > 0); + + $this->addEffect($effect); + } + } } protected function addAttributes(){ @@ -104,9 +131,25 @@ abstract class Living extends Entity implements Damageable{ public function saveNBT(){ parent::saveNBT(); $this->namedtag->Health = new FloatTag("Health", $this->getHealth()); + + if(count($this->effects) > 0){ + $effects = []; + foreach($this->effects as $effect){ + $effects[] = new CompoundTag("", [ + new ByteTag("Id", $effect->getId()), + new ByteTag("Amplifier", Binary::signByte($effect->getAmplifier())), + new IntTag("Duration", $effect->getDuration()), + new ByteTag("Ambient", 0), + new ByteTag("ShowParticles", $effect->isVisible() ? 1 : 0) + ]); + } + + $this->namedtag->ActiveEffects = new ListTag("ActiveEffects", $effects); + }else{ + unset($this->namedtag->ActiveEffects); + } } - abstract public function getName(); public function hasLineOfSight(Entity $entity){ //TODO: head height @@ -123,6 +166,140 @@ abstract class Living extends Entity implements Damageable{ $this->attackTime = 0; } + /** + * Returns an array of Effects currently active on the mob. + * @return Effect[] + */ + public function getEffects() : array{ + return $this->effects; + } + + /** + * Removes all effects from the mob. + */ + public function removeAllEffects(){ + foreach($this->effects as $effect){ + $this->removeEffect($effect->getId()); + } + } + + /** + * Removes the effect with the specified ID from the mob. + * + * @param int $effectId + */ + public function removeEffect(int $effectId){ + if(isset($this->effects[$effectId])){ + $effect = $this->effects[$effectId]; + unset($this->effects[$effectId]); + $effect->remove($this); + + $this->recalculateEffectColor(); + } + } + + /** + * Returns the effect instance active on this entity with the specified ID, or null if the mob does not have the + * effect. + * + * @param int $effectId + * + * @return Effect|null + */ + public function getEffect(int $effectId){ + return $this->effects[$effectId] ?? null; + } + + /** + * Returns whether the specified effect is active on the mob. + * + * @param int $effectId + * + * @return bool + */ + public function hasEffect(int $effectId) : bool{ + return isset($this->effects[$effectId]); + } + + /** + * Adds an effect to the mob. + * If a weaker effect of the same type is already applied, it will be replaced. + * If a weaker or equal-strength effect is already applied but has a shorter duration, it will be replaced. + * + * @param Effect $effect + */ + public function addEffect(Effect $effect){ + if(isset($this->effects[$effect->getId()])){ + $oldEffect = $this->effects[$effect->getId()]; + if( + abs($effect->getAmplifier()) < $oldEffect->getAmplifier() + or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) and $effect->getDuration() < $oldEffect->getDuration()) + ){ + return; + } + $effect->add($this, true, $oldEffect); + }else{ + $effect->add($this, false); + } + + $this->effects[$effect->getId()] = $effect; + + $this->recalculateEffectColor(); + } + + /** + * Recalculates the mob's potion bubbles colour based on the active effects. + */ + protected function recalculateEffectColor(){ + //TODO: add transparency values + $color = [0, 0, 0]; //RGB + $count = 0; + $ambient = true; + foreach($this->effects as $effect){ + if($effect->isVisible() and $effect->hasBubbles()){ + $c = $effect->getColor(); + $color[0] += $c[0] * $effect->getEffectLevel(); + $color[1] += $c[1] * $effect->getEffectLevel(); + $color[2] += $c[2] * $effect->getEffectLevel(); + $count += $effect->getEffectLevel(); + if(!$effect->isAmbient()){ + $ambient = false; + } + } + } + + if($count > 0){ + $r = ($color[0] / $count) & 0xff; + $g = ($color[1] / $count) & 0xff; + $b = ($color[2] / $count) & 0xff; + + $this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, 0xff000000 | ($r << 16) | ($g << 8) | $b); + $this->setDataProperty(Entity::DATA_POTION_AMBIENT, Entity::DATA_TYPE_BYTE, $ambient ? 1 : 0); + }else{ + $this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, 0); + $this->setDataProperty(Entity::DATA_POTION_AMBIENT, Entity::DATA_TYPE_BYTE, 0); + } + } + + /** + * Sends the mob's potion effects to the specified player. + * @param Player $player + */ + public function sendPotionEffects(Player $player){ + foreach($this->effects as $effect){ + $pk = new MobEffectPacket(); + $pk->entityRuntimeId = $this->id; + $pk->effectId = $effect->getId(); + $pk->amplifier = $effect->getAmplifier(); + $pk->particles = $effect->isVisible(); + $pk->duration = $effect->getDuration(); + $pk->eventId = MobEffectPacket::EVENT_ADD; + + $player->dataPacket($pk); + } + } + + /** * Returns the initial upwards velocity of a jumping entity in blocks/tick, including additional velocity due to effects. * @return float @@ -140,6 +317,14 @@ abstract class Living extends Entity implements Damageable{ } } + public function fall(float $fallDistance){ + $damage = floor($fallDistance - 3 - ($this->hasEffect(Effect::JUMP) ? $this->getEffect(Effect::JUMP)->getEffectLevel() : 0)); + if($damage > 0){ + $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); + $this->attack($ev->getFinalDamage(), $ev); + } + } + public function attack($damage, EntityDamageEvent $source){ if($this->attackTime > 0 or $this->noDamageTicks > 0){ $lastCause = $this->getLastDamageCause(); @@ -148,6 +333,19 @@ abstract class Living extends Entity implements Damageable{ } } + if($this->hasEffect(Effect::FIRE_RESISTANCE) and ( + $source->getCause() === EntityDamageEvent::CAUSE_FIRE + or $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK + or $source->getCause() === EntityDamageEvent::CAUSE_LAVA + ) + ){ + $source->setCancelled(); + } + + if($this->hasEffect(Effect::DAMAGE_RESISTANCE)){ + $source->setDamage(-($source->getDamage(EntityDamageEvent::MODIFIER_BASE) * 0.20 * $this->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + } + parent::attack($damage, $source); if($source->isCancelled()){ @@ -224,6 +422,8 @@ abstract class Living extends Entity implements Damageable{ $hasUpdate = parent::entityBaseTick($tickDiff); + $this->doEffectsTick($tickDiff); + if($this->isAlive()){ if($this->isInsideOfSolid()){ $hasUpdate = true; @@ -271,6 +471,26 @@ abstract class Living extends Entity implements Damageable{ return $hasUpdate; } + protected function doEffectsTick(int $tickDiff = 1){ + if(count($this->effects) > 0){ + foreach($this->effects as $effect){ + if($effect->canTick()){ + $effect->applyEffect($this); + } + $effect->setDuration($effect->getDuration() - $tickDiff); + if($effect->getDuration() <= 0){ + $this->removeEffect($effect->getId()); + } + } + } + } + + protected function dealFireDamage(){ + if(!$this->hasEffect(Effect::FIRE_RESISTANCE)){ + parent::dealFireDamage(); + } + } + /** * @return ItemItem[] */ diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index 9ea89e188..561f4d3ab 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -25,6 +25,7 @@ namespace pocketmine\event\entity; use pocketmine\entity\Effect; use pocketmine\entity\Entity; +use pocketmine\entity\Living; /** * Called when an entity takes damage from another entity. @@ -51,12 +52,14 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ } protected function addAttackerModifiers(Entity $damager){ - if($damager->hasEffect(Effect::STRENGTH)){ - $this->setDamage($this->getDamage(self::MODIFIER_BASE) * 0.3 * $damager->getEffect(Effect::STRENGTH)->getEffectLevel(), self::MODIFIER_STRENGTH); - } + if($damager instanceof Living){ //TODO: move this to entity classes + if($damager->hasEffect(Effect::STRENGTH)){ + $this->setDamage($this->getDamage(self::MODIFIER_BASE) * 0.3 * $damager->getEffect(Effect::STRENGTH)->getEffectLevel(), self::MODIFIER_STRENGTH); + } - if($damager->hasEffect(Effect::WEAKNESS)){ - $this->setDamage(-($this->getDamage(self::MODIFIER_BASE) * 0.2 * $damager->getEffect(Effect::WEAKNESS)->getEffectLevel()), self::MODIFIER_WEAKNESS); + if($damager->hasEffect(Effect::WEAKNESS)){ + $this->setDamage(-($this->getDamage(self::MODIFIER_BASE) * 0.2 * $damager->getEffect(Effect::WEAKNESS)->getEffectLevel()), self::MODIFIER_WEAKNESS); + } } } diff --git a/src/pocketmine/event/entity/EntityDamageEvent.php b/src/pocketmine/event/entity/EntityDamageEvent.php index e59f859a1..05ba56e7d 100644 --- a/src/pocketmine/event/entity/EntityDamageEvent.php +++ b/src/pocketmine/event/entity/EntityDamageEvent.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace pocketmine\event\entity; -use pocketmine\entity\Effect; use pocketmine\entity\Entity; use pocketmine\event\Cancellable; @@ -86,10 +85,6 @@ class EntityDamageEvent extends EntityEvent implements Cancellable{ if(!isset($this->modifiers[self::MODIFIER_BASE])){ throw new \InvalidArgumentException("BASE Damage modifier missing"); } - - if($entity->hasEffect(Effect::DAMAGE_RESISTANCE)){ - $this->setDamage(-($this->getDamage(self::MODIFIER_BASE) * 0.20 * $entity->getEffect(Effect::DAMAGE_RESISTANCE)->getEffectLevel()), self::MODIFIER_RESISTANCE); - } } /**