From f356bf0893959808ec65c39fd66f562bd7da4790 Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Fri, 5 Jul 2019 16:15:58 +0100 Subject: [PATCH] Extracted an EffectManager unit from Living --- changelogs/4.0-snapshot.md | 11 + .../command/defaults/EffectCommand.php | 13 +- src/pocketmine/entity/Human.php | 8 +- src/pocketmine/entity/Living.php | 197 +++-------------- .../entity/effect/EffectManager.php | 203 ++++++++++++++++++ .../entity/projectile/SplashPotion.php | 2 +- .../entity/EntityDamageByEntityEvent.php | 9 +- src/pocketmine/item/MilkBucket.php | 2 +- .../mcpe/handler/PreSpawnPacketHandler.php | 2 +- src/pocketmine/player/Player.php | 8 +- 10 files changed, 260 insertions(+), 195 deletions(-) create mode 100644 src/pocketmine/entity/effect/EffectManager.php diff --git a/changelogs/4.0-snapshot.md b/changelogs/4.0-snapshot.md index 2e23e8c91..8dec8eac6 100644 --- a/changelogs/4.0-snapshot.md +++ b/changelogs/4.0-snapshot.md @@ -154,6 +154,17 @@ This version features substantial changes to the network system, improving coher - `Entity->entityBaseTick()` is now `protected`. - `Entity->move()` is now `protected`. - `Living->knockBack()` now accepts `float, float, float` (the first two parameters have been removed). + - `Living->getEffects()` now returns `EffectManager` instead of `Effect[]`. +- The following classes have been added: + - `effect\EffectManager`: contains effect-management functionality extracted from `Living` +- The following API methods have been moved / renamed: + - `Living->removeAllEffects()` -> `EffectManager->clear()` + - `Living->removeEffect()` -> `EffectManager->remove()` + - `Living->addEffect()` -> `EffectManager->add()` + - `Living->getEffect()` -> `EffectManager->get()` + - `Living->hasEffect()` -> `EffectManager->has()` + - `Living->hasEffects()` -> `EffectManager->hasEffects()` + - `Living->getEffects()` -> `EffectManager->all()` - The following classes have been removed: - `Creature` - `Damageable` diff --git a/src/pocketmine/command/defaults/EffectCommand.php b/src/pocketmine/command/defaults/EffectCommand.php index 373434c66..4eea21c74 100644 --- a/src/pocketmine/command/defaults/EffectCommand.php +++ b/src/pocketmine/command/defaults/EffectCommand.php @@ -59,11 +59,10 @@ class EffectCommand extends VanillaCommand{ $sender->sendMessage(new TranslationContainer(TextFormat::RED . "%commands.generic.player.notFound")); return true; } + $effectManager = $player->getEffects(); if(strtolower($args[1]) === "clear"){ - foreach($player->getEffects() as $effect){ - $player->removeEffect($effect->getType()); - } + $effectManager->clear(); $sender->sendMessage(new TranslationContainer("commands.effect.success.removed.all", [$player->getDisplayName()])); return true; @@ -107,8 +106,8 @@ class EffectCommand extends VanillaCommand{ } if($duration === 0){ - if(!$player->hasEffect($effect)){ - if(count($player->getEffects()) === 0){ + if(!$effectManager->has($effect)){ + if(count($effectManager->all()) === 0){ $sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive.all", [$player->getDisplayName()])); }else{ $sender->sendMessage(new TranslationContainer("commands.effect.failure.notActive", [$effect->getName(), $player->getDisplayName()])); @@ -116,11 +115,11 @@ class EffectCommand extends VanillaCommand{ return true; } - $player->removeEffect($effect); + $effectManager->remove($effect); $sender->sendMessage(new TranslationContainer("commands.effect.success.removed", [$effect->getName(), $player->getDisplayName()])); }else{ $instance = new EffectInstance($effect, $duration, $amplification, $visible); - $player->addEffect($instance); + $effectManager->add($instance); self::broadcastCommandMessage($sender, new TranslationContainer("%commands.effect.success", [$effect->getName(), $instance->getAmplifier(), $player->getDisplayName(), $instance->getDuration() / 20, $effect->getId()])); } diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index 128b4ccda..6364e72c8 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -732,11 +732,11 @@ class Human extends Living implements ProjectileSource, InventoryHolder{ parent::applyPostDamageEffects($source); $totemModifier = $source->getModifier(EntityDamageEvent::MODIFIER_TOTEM); if($totemModifier < 0){ //Totem prevented death - $this->removeAllEffects(); + $this->effectManager->clear(); - $this->addEffect(new EffectInstance(Effect::REGENERATION(), 40 * 20, 1)); - $this->addEffect(new EffectInstance(Effect::FIRE_RESISTANCE(), 40 * 20, 1)); - $this->addEffect(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); + $this->effectManager->add(new EffectInstance(Effect::REGENERATION(), 40 * 20, 1)); + $this->effectManager->add(new EffectInstance(Effect::FIRE_RESISTANCE(), 40 * 20, 1)); + $this->effectManager->add(new EffectInstance(Effect::ABSORPTION(), 5 * 20, 1)); $this->broadcastEntityEvent(EntityEventPacket::CONSUME_TOTEM); $this->world->addSound($this->add(0, $this->eyeHeight, 0), new TotemUseSound()); diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index c0fd5338b..c17a9c206 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -26,6 +26,7 @@ namespace pocketmine\entity; use pocketmine\block\Block; use pocketmine\entity\effect\Effect; use pocketmine\entity\effect\EffectInstance; +use pocketmine\entity\effect\EffectManager; use pocketmine\event\entity\EntityDamageByChildEntityEvent; use pocketmine\event\entity\EntityDamageByEntityEvent; use pocketmine\event\entity\EntityDamageEvent; @@ -81,8 +82,8 @@ abstract class Living extends Entity{ protected $jumpVelocity = 0.42; - /** @var EffectInstance[] */ - protected $effects = []; + /** @var EffectManager */ + protected $effectManager; /** @var ArmorInventory */ protected $armorInventory; @@ -92,6 +93,8 @@ abstract class Living extends Entity{ protected function initEntity(CompoundTag $nbt) : void{ parent::initEntity($nbt); + $this->effectManager = new EffectManager($this); + $this->armorInventory = new ArmorInventory($this); //TODO: load/save armor inventory contents $this->armorInventory->addChangeListeners(CallbackInventoryChangeListener::onAnyChange( @@ -122,7 +125,7 @@ abstract class Living extends Entity{ continue; } - $this->addEffect(new EffectInstance( + $this->effectManager->add(new EffectInstance( $effect, $e->getInt("Duration"), Binary::unsignByte($e->getByte("Amplifier")), @@ -171,9 +174,9 @@ abstract class Living extends Entity{ $nbt = parent::saveNBT(); $nbt->setFloat("Health", $this->getHealth()); - if(count($this->effects) > 0){ + if(!empty($this->effectManager->all())){ $effects = []; - foreach($this->effects as $effect){ + foreach($this->effectManager->all() as $effect){ $effects[] = CompoundTag::create() ->setByte("Id", $effect->getId()) ->setByte("Amplifier", Binary::signByte($effect->getAmplifier())) @@ -195,162 +198,25 @@ abstract class Living extends Entity{ //return $this->getLevel()->rayTraceBlocks(Vector3::createVector($this->x, $this->y + $this->height, $this->z), Vector3::createVector($entity->x, $entity->y + $entity->height, $entity->z)) === null; } - /** - * Returns an array of Effects currently active on the mob. - * @return EffectInstance[] - */ - public function getEffects() : array{ - return $this->effects; + public function getEffects() : EffectManager{ + return $this->effectManager; } /** - * Removes all effects from the mob. - */ - public function removeAllEffects() : void{ - foreach($this->effects as $effect){ - $this->removeEffect($effect->getType()); - } - } - - /** - * Removes the effect with the specified ID from the mob. - * - * @param Effect $effectType - */ - public function removeEffect(Effect $effectType) : void{ - $index = $effectType->getId(); - if(isset($this->effects[$index])){ - $effect = $this->effects[$index]; - $hasExpired = $effect->hasExpired(); - $ev = new EntityEffectRemoveEvent($this, $effect); - $ev->call(); - if($ev->isCancelled()){ - if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed - $this->onEffectAdded($ev->getEffect(), true); - } - return; - } - - unset($this->effects[$index]); - $effect->getType()->remove($this, $effect); - $this->onEffectRemoved($effect); - - $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 Effect $effect - * - * @return EffectInstance|null - */ - public function getEffect(Effect $effect) : ?EffectInstance{ - return $this->effects[$effect->getId()] ?? null; - } - - /** - * Returns whether the specified effect is active on the mob. - * - * @param Effect $effect - * - * @return bool - */ - public function hasEffect(Effect $effect) : bool{ - return isset($this->effects[$effect->getId()]); - } - - /** - * Returns whether the mob has any active effects. - * @return bool - */ - public function hasEffects() : bool{ - return !empty($this->effects); - } - - /** - * 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. + * @internal * * @param EffectInstance $effect - * - * @return bool whether the effect has been successfully applied. + * @param bool $replacesOldEffect */ - public function addEffect(EffectInstance $effect) : bool{ - $oldEffect = null; - $cancelled = false; + public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ - $index = $effect->getType()->getId(); - if(isset($this->effects[$index])){ - $oldEffect = $this->effects[$index]; - if( - abs($effect->getAmplifier()) < $oldEffect->getAmplifier() - or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) and $effect->getDuration() < $oldEffect->getDuration()) - ){ - $cancelled = true; - } - } - - $ev = new EntityEffectAddEvent($this, $effect, $oldEffect); - $ev->setCancelled($cancelled); - - $ev->call(); - if($ev->isCancelled()){ - return false; - } - - if($oldEffect !== null){ - $oldEffect->getType()->remove($this, $oldEffect); - } - - $effect->getType()->add($this, $effect); - $this->onEffectAdded($effect, $oldEffect !== null); - - $this->effects[$index] = $effect; - - $this->recalculateEffectColor(); - - return true; } /** - * Recalculates the mob's potion bubbles colour based on the active effects. + * @internal + * @param EffectInstance $effect */ - protected function recalculateEffectColor() : void{ - /** @var Color[] $colors */ - $colors = []; - $ambient = true; - foreach($this->effects as $effect){ - if($effect->isVisible() and $effect->getType()->hasBubbles()){ - $level = $effect->getEffectLevel(); - $color = $effect->getColor(); - for($i = 0; $i < $level; ++$i){ - $colors[] = $color; - } - - if(!$effect->isAmbient()){ - $ambient = false; - } - } - } - - if(!empty($colors)){ - $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, Color::mix(...$colors)->toARGB()); - $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $ambient ? 1 : 0); - }else{ - $this->propertyManager->setInt(EntityMetadataProperties::POTION_COLOR, 0); - $this->propertyManager->setByte(EntityMetadataProperties::POTION_AMBIENT, 0); - } - } - - protected function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ - - } - - protected function onEffectRemoved(EffectInstance $effect) : void{ + public function onEffectRemoved(EffectInstance $effect) : void{ } @@ -364,7 +230,7 @@ abstract class Living extends Entity{ */ public function consumeObject(Consumable $consumable) : bool{ foreach($consumable->getAdditionalEffects() as $effect){ - $this->addEffect($effect); + $this->effectManager->add($effect); } $consumable->onConsume($this); @@ -377,7 +243,7 @@ abstract class Living extends Entity{ * @return float */ public function getJumpVelocity() : float{ - return $this->jumpVelocity + ($this->hasEffect(Effect::JUMP_BOOST()) ? ($this->getEffect(Effect::JUMP_BOOST())->getEffectLevel() / 10) : 0); + return $this->jumpVelocity + ($this->effectManager->has(Effect::JUMP_BOOST()) ? ($this->effectManager->get(Effect::JUMP_BOOST())->getEffectLevel() / 10) : 0); } /** @@ -390,7 +256,7 @@ abstract class Living extends Entity{ } public function fall(float $fallDistance) : void{ - $damage = ceil($fallDistance - 3 - ($this->hasEffect(Effect::JUMP_BOOST()) ? $this->getEffect(Effect::JUMP_BOOST())->getEffectLevel() : 0)); + $damage = ceil($fallDistance - 3 - ($this->effectManager->has(Effect::JUMP_BOOST()) ? $this->effectManager->get(Effect::JUMP_BOOST())->getEffectLevel() : 0)); if($damage > 0){ $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_FALL, $damage); $this->attack($ev); @@ -453,8 +319,8 @@ abstract class Living extends Entity{ } $cause = $source->getCause(); - if($this->hasEffect(Effect::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ - $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->getEffect(Effect::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); + if($this->effectManager->has(Effect::RESISTANCE()) and $cause !== EntityDamageEvent::CAUSE_VOID and $cause !== EntityDamageEvent::CAUSE_SUICIDE){ + $source->setModifier(-$source->getFinalDamage() * min(1, 0.2 * $this->effectManager->get(Effect::RESISTANCE())->getEffectLevel()), EntityDamageEvent::MODIFIER_RESISTANCE); } $totalEpf = 0; @@ -534,7 +400,7 @@ abstract class Living extends Entity{ } } - if($this->hasEffect(Effect::FIRE_RESISTANCE()) and ( + if($this->effectManager->has(Effect::FIRE_RESISTANCE()) and ( $source->getCause() === EntityDamageEvent::CAUSE_FIRE or $source->getCause() === EntityDamageEvent::CAUSE_FIRE_TICK or $source->getCause() === EntityDamageEvent::CAUSE_LAVA @@ -656,7 +522,7 @@ abstract class Living extends Entity{ $hasUpdate = parent::entityBaseTick($tickDiff); if($this->isAlive()){ - if($this->doEffectsTick($tickDiff)){ + if($this->effectManager->tick($tickDiff)){ $hasUpdate = true; } @@ -680,21 +546,6 @@ abstract class Living extends Entity{ return $hasUpdate; } - protected function doEffectsTick(int $tickDiff = 1) : bool{ - foreach($this->effects as $instance){ - $type = $instance->getType(); - if($type->canTick($instance)){ - $type->applyEffect($this, $instance); - } - $instance->decreaseDuration($tickDiff); - if($instance->hasExpired()){ - $this->removeEffect($instance->getType()); - } - } - - return !empty($this->effects); - } - /** * Ticks the entity's air supply, consuming it when underwater and regenerating it when out of water. * @@ -739,7 +590,7 @@ abstract class Living extends Entity{ * @return bool */ public function canBreathe() : bool{ - return $this->hasEffect(Effect::WATER_BREATHING()) or $this->hasEffect(Effect::CONDUIT_POWER()) or !$this->isUnderwater(); + return $this->effectManager->has(Effect::WATER_BREATHING()) or $this->effectManager->has(Effect::CONDUIT_POWER()) or !$this->isUnderwater(); } /** diff --git a/src/pocketmine/entity/effect/EffectManager.php b/src/pocketmine/entity/effect/EffectManager.php new file mode 100644 index 000000000..906c0d2d0 --- /dev/null +++ b/src/pocketmine/entity/effect/EffectManager.php @@ -0,0 +1,203 @@ +entity = $entity; + } + + /** + * Returns an array of Effects currently active on the mob. + * @return EffectInstance[] + */ + public function all() : array{ + return $this->effects; + } + + /** + * Removes all effects from the mob. + */ + public function clear() : void{ + foreach($this->effects as $effect){ + $this->remove($effect->getType()); + } + } + + /** + * Removes the effect with the specified ID from the mob. + * + * @param Effect $effectType + */ + public function remove(Effect $effectType) : void{ + $index = $effectType->getId(); + if(isset($this->effects[$index])){ + $effect = $this->effects[$index]; + $hasExpired = $effect->hasExpired(); + $ev = new EntityEffectRemoveEvent($this->entity, $effect); + $ev->call(); + if($ev->isCancelled()){ + if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed + $this->entity->onEffectAdded($ev->getEffect(), true); + } + return; + } + + unset($this->effects[$index]); + $effect->getType()->remove($this->entity, $effect); + $this->entity->onEffectRemoved($effect); + + $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 Effect $effect + * + * @return EffectInstance|null + */ + public function get(Effect $effect) : ?EffectInstance{ + return $this->effects[$effect->getId()] ?? null; + } + + /** + * Returns whether the specified effect is active on the mob. + * + * @param Effect $effect + * + * @return bool + */ + public function has(Effect $effect) : bool{ + return isset($this->effects[$effect->getId()]); + } + + /** + * 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 EffectInstance $effect + * + * @return bool whether the effect has been successfully applied. + */ + public function add(EffectInstance $effect) : bool{ + $oldEffect = null; + $cancelled = false; + + $index = $effect->getType()->getId(); + if(isset($this->effects[$index])){ + $oldEffect = $this->effects[$index]; + if( + abs($effect->getAmplifier()) < $oldEffect->getAmplifier() + or (abs($effect->getAmplifier()) === abs($oldEffect->getAmplifier()) and $effect->getDuration() < $oldEffect->getDuration()) + ){ + $cancelled = true; + } + } + + $ev = new EntityEffectAddEvent($this->entity, $effect, $oldEffect); + $ev->setCancelled($cancelled); + + $ev->call(); + if($ev->isCancelled()){ + return false; + } + + if($oldEffect !== null){ + $oldEffect->getType()->remove($this->entity, $oldEffect); + } + + $effect->getType()->add($this->entity, $effect); + $this->entity->onEffectAdded($effect, $oldEffect !== null); + + $this->effects[$index] = $effect; + + $this->recalculateEffectColor(); + + return true; + } + + /** + * Recalculates the mob's potion bubbles colour based on the active effects. + */ + protected function recalculateEffectColor() : void{ + /** @var Color[] $colors */ + $colors = []; + $ambient = true; + foreach($this->effects as $effect){ + if($effect->isVisible() and $effect->getType()->hasBubbles()){ + $level = $effect->getEffectLevel(); + $color = $effect->getColor(); + for($i = 0; $i < $level; ++$i){ + $colors[] = $color; + } + + if(!$effect->isAmbient()){ + $ambient = false; + } + } + } + + $propManager = $this->entity->getDataPropertyManager(); + if(!empty($colors)){ + $propManager->setInt(EntityMetadataProperties::POTION_COLOR, Color::mix(...$colors)->toARGB()); + $propManager->setByte(EntityMetadataProperties::POTION_AMBIENT, $ambient ? 1 : 0); + }else{ + $propManager->setInt(EntityMetadataProperties::POTION_COLOR, 0); + $propManager->setByte(EntityMetadataProperties::POTION_AMBIENT, 0); + } + } + + public function tick(int $tickDiff = 1) : bool{ + foreach($this->effects as $instance){ + $type = $instance->getType(); + if($type->canTick($instance)){ + $type->applyEffect($this->entity, $instance); + } + $instance->decreaseDuration($tickDiff); + if($instance->hasExpired()){ + $this->remove($instance->getType()); + } + } + + return !empty($this->effects); + } +} diff --git a/src/pocketmine/entity/projectile/SplashPotion.php b/src/pocketmine/entity/projectile/SplashPotion.php index 40c8ef0ba..1b408978c 100644 --- a/src/pocketmine/entity/projectile/SplashPotion.php +++ b/src/pocketmine/entity/projectile/SplashPotion.php @@ -109,7 +109,7 @@ class SplashPotion extends Throwable{ continue; } $effect->setDuration($newDuration); - $entity->addEffect($effect); + $entity->getEffects()->add($effect); }else{ $effect->getType()->applyEffect($entity, $effect, $distanceMultiplier, $this); } diff --git a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php index ab0fdf8d7..2793f4673 100644 --- a/src/pocketmine/event/entity/EntityDamageByEntityEvent.php +++ b/src/pocketmine/event/entity/EntityDamageByEntityEvent.php @@ -53,12 +53,13 @@ class EntityDamageByEntityEvent extends EntityDamageEvent{ protected function addAttackerModifiers(Entity $damager) : void{ if($damager instanceof Living){ //TODO: move this to entity classes - if($damager->hasEffect(Effect::STRENGTH())){ - $this->setModifier($this->getBaseDamage() * 0.3 * $damager->getEffect(Effect::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); + $effects = $damager->getEffects(); + if($effects->has(Effect::STRENGTH())){ + $this->setModifier($this->getBaseDamage() * 0.3 * $effects->get(Effect::STRENGTH())->getEffectLevel(), self::MODIFIER_STRENGTH); } - if($damager->hasEffect(Effect::WEAKNESS())){ - $this->setModifier(-($this->getBaseDamage() * 0.2 * $damager->getEffect(Effect::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); + if($effects->has(Effect::WEAKNESS())){ + $this->setModifier(-($this->getBaseDamage() * 0.2 * $effects->get(Effect::WEAKNESS())->getEffectLevel()), self::MODIFIER_WEAKNESS); } } } diff --git a/src/pocketmine/item/MilkBucket.php b/src/pocketmine/item/MilkBucket.php index d0851d2e9..592308f63 100644 --- a/src/pocketmine/item/MilkBucket.php +++ b/src/pocketmine/item/MilkBucket.php @@ -40,6 +40,6 @@ class MilkBucket extends Item implements Consumable{ } public function onConsume(Living $consumer) : void{ - $consumer->removeAllEffects(); + $consumer->getEffects()->clear(); } } diff --git a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php index 9aa3ac0a5..066a37b36 100644 --- a/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php +++ b/src/pocketmine/network/mcpe/handler/PreSpawnPacketHandler.php @@ -86,7 +86,7 @@ class PreSpawnPacketHandler extends PacketHandler{ $this->session->syncAttributes($this->player, true); $this->session->syncAvailableCommands(); $this->session->syncAdventureSettings($this->player); - foreach($this->player->getEffects() as $effect){ + foreach($this->player->getEffects()->all() as $effect){ $this->session->onEntityEffectAdded($this->player, $effect, false); } $this->player->sendData($this->player); diff --git a/src/pocketmine/player/Player.php b/src/pocketmine/player/Player.php index c4515c11c..570254d16 100644 --- a/src/pocketmine/player/Player.php +++ b/src/pocketmine/player/Player.php @@ -1543,11 +1543,11 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, return $this->isCreative() or parent::canBreathe(); } - protected function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ + public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{ $this->networkSession->onEntityEffectAdded($this, $effect, $replacesOldEffect); } - protected function onEffectRemoved(EffectInstance $effect) : void{ + public function onEffectRemoved(EffectInstance $effect) : void{ $this->networkSession->onEntityEffectRemoved($this, $effect); } @@ -1911,7 +1911,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, } $ev->setModifier($meleeEnchantmentDamage, EntityDamageEvent::MODIFIER_WEAPON_ENCHANTMENTS); - if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->hasEffect(Effect::BLINDNESS()) and !$this->isUnderwater()){ + if(!$this->isSprinting() and !$this->isFlying() and $this->fallDistance > 0 and !$this->effectManager->has(Effect::BLINDNESS()) and !$this->isUnderwater()){ $ev->setModifier($ev->getFinalDamage() / 2, EntityDamageEvent::MODIFIER_CRITICAL); } @@ -2426,7 +2426,7 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener, $this->deadTicks = 0; $this->noDamageTicks = 60; - $this->removeAllEffects(); + $this->effectManager->clear(); $this->setHealth($this->getMaxHealth()); foreach($this->attributeMap->getAll() as $attr){