add a more flexible hook system to EffectManager

This commit is contained in:
Dylan K. Taylor 2019-08-01 19:36:13 +01:00
parent d09e79e682
commit 7e4236a3ec
4 changed files with 32 additions and 29 deletions

View File

@ -212,24 +212,6 @@ abstract class Living extends Entity{
return $this->effectManager; return $this->effectManager;
} }
/**
* @internal
*
* @param EffectInstance $effect
* @param bool $replacesOldEffect
*/
public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{
}
/**
* @internal
* @param EffectInstance $effect
*/
public function onEffectRemoved(EffectInstance $effect) : void{
}
/** /**
* Causes the mob to consume the given Consumable object, applying applicable effects, health bonuses, food bonuses, * Causes the mob to consume the given Consumable object, applying applicable effects, health bonuses, food bonuses,
* etc. * etc.

View File

@ -27,7 +27,9 @@ use pocketmine\entity\Living;
use pocketmine\event\entity\EntityEffectAddEvent; use pocketmine\event\entity\EntityEffectAddEvent;
use pocketmine\event\entity\EntityEffectRemoveEvent; use pocketmine\event\entity\EntityEffectRemoveEvent;
use pocketmine\utils\Color; use pocketmine\utils\Color;
use pocketmine\utils\Utils;
use function abs; use function abs;
use function spl_object_id;
class EffectManager{ class EffectManager{
@ -42,6 +44,11 @@ class EffectManager{
/** @var bool */ /** @var bool */
protected $onlyAmbientEffects = false; protected $onlyAmbientEffects = false;
/** @var \Closure[] */
protected $effectAddHooks = [];
/** @var \Closure[] */
protected $effectRemoveHooks = [];
public function __construct(Living $entity){ public function __construct(Living $entity){
$this->entity = $entity; $this->entity = $entity;
$this->bubbleColor = new Color(0, 0, 0, 0); $this->bubbleColor = new Color(0, 0, 0, 0);
@ -78,14 +85,18 @@ class EffectManager{
$ev->call(); $ev->call();
if($ev->isCancelled()){ if($ev->isCancelled()){
if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed if($hasExpired and !$ev->getEffect()->hasExpired()){ //altered duration of an expired effect to make it not get removed
$this->entity->onEffectAdded($ev->getEffect(), true); foreach($this->effectAddHooks as $hook){
$hook($ev->getEffect(), true);
}
} }
return; return;
} }
unset($this->effects[$index]); unset($this->effects[$index]);
$effect->getType()->remove($this->entity, $effect); $effect->getType()->remove($this->entity, $effect);
$this->entity->onEffectRemoved($effect); foreach($this->effectRemoveHooks as $hook){
$hook($effect);
}
$this->recalculateEffectColor(); $this->recalculateEffectColor();
} }
@ -151,7 +162,9 @@ class EffectManager{
} }
$effect->getType()->add($this->entity, $effect); $effect->getType()->add($this->entity, $effect);
$this->entity->onEffectAdded($effect, $oldEffect !== null); foreach($this->effectAddHooks as $hook){
$hook($effect, $oldEffect !== null);
}
$this->effects[$index] = $effect; $this->effects[$index] = $effect;
@ -218,4 +231,14 @@ class EffectManager{
return !empty($this->effects); return !empty($this->effects);
} }
public function onEffectAdd(\Closure $closure) : void{
Utils::validateCallableSignature(function(EffectInstance $effect, bool $replacesOldEffect) : void{}, $closure);
$this->effectAddHooks[spl_object_id($closure)] = $closure;
}
public function onEffectRemove(\Closure $closure) : void{
Utils::validateCallableSignature(function(EffectInstance $effect) : void{}, $closure);
$this->effectRemoveHooks[spl_object_id($closure)] = $closure;
}
} }

View File

@ -184,6 +184,12 @@ class NetworkSession{
$this->player = new $class($this->server, $this, $this->info, $this->authenticated); $this->player = new $class($this->server, $this, $this->info, $this->authenticated);
$this->invManager = new InventoryManager($this->player, $this); $this->invManager = new InventoryManager($this->player, $this);
$this->player->getEffects()->onEffectAdd(function(EffectInstance $effect, bool $replacesOldEffect) : void{
$this->onEntityEffectAdded($this->player, $effect, $replacesOldEffect);
});
$this->player->getEffects()->onEffectRemove(function(EffectInstance $effect) : void{
$this->onEntityEffectRemoved($this->player, $effect);
});
} }
public function getPlayer() : ?Player{ public function getPlayer() : ?Player{

View File

@ -1453,14 +1453,6 @@ class Player extends Human implements CommandSender, ChunkLoader, ChunkListener,
return $this->isCreative() or parent::canBreathe(); return $this->isCreative() or parent::canBreathe();
} }
public function onEffectAdded(EffectInstance $effect, bool $replacesOldEffect) : void{
$this->networkSession->onEntityEffectAdded($this, $effect, $replacesOldEffect);
}
public function onEffectRemoved(EffectInstance $effect) : void{
$this->networkSession->onEntityEffectRemoved($this, $effect);
}
/** /**
* Returns whether the player can interact with the specified position. This checks distance and direction. * Returns whether the player can interact with the specified position. This checks distance and direction.
* *