id = $id; $this->name = $name; $this->bad = (bool) $isBad; $this->setColor($r, $g, $b); } public function getName(){ return $this->name; } public function getId(){ return $this->id; } public function setDuration($ticks){ $this->duration = $ticks; return $this; } public function getDuration(){ return $this->duration; } public function isVisible(){ return $this->show; } public function setVisible($bool){ $this->show = (bool) $bool; return $this; } /** * @return int */ public function getAmplifier(){ return $this->amplifier; } /** * @param int $amplifier * * @return $this */ public function setAmplifier(int $amplifier){ $this->amplifier = $amplifier & 0xff; return $this; } public function isAmbient(){ return $this->ambient; } public function setAmbient($ambient = true){ $this->ambient = (bool) $ambient; return $this; } public function isBad(){ return $this->bad; } public function canTick(){ switch($this->id){ case Effect::POISON: if(($interval = (25 >> $this->amplifier)) > 0){ return ($this->duration % $interval) === 0; } return true; case Effect::WITHER: if(($interval = (50 >> $this->amplifier)) > 0){ return ($this->duration % $interval) === 0; } return true; case Effect::REGENERATION: if(($interval = (40 >> $this->amplifier)) > 0){ return ($this->duration % $interval) === 0; } return true; case Effect::HUNGER: if($this->amplifier < 0){ // prevents hacking with amplifier -1 return false; } if(($interval = 20) > 0){ return ($this->duration % $interval) === 0; } return true; } return false; } public function applyEffect(Entity $entity){ switch($this->id){ case Effect::POISON: if($entity->getHealth() > 1){ $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, 1); $entity->attack($ev->getFinalDamage(), $ev); } break; case Effect::WITHER: $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, 1); $entity->attack($ev->getFinalDamage(), $ev); break; case Effect::REGENERATION: if($entity->getHealth() < $entity->getMaxHealth()){ $ev = new EntityRegainHealthEvent($entity, 1, EntityRegainHealthEvent::CAUSE_MAGIC); $entity->heal($ev->getAmount(), $ev); } break; case Effect::HUNGER: if($entity instanceof Human){ $entity->exhaust(0.5 * $this->amplifier, PlayerExhaustEvent::CAUSE_POTION); } } } public function getColor(){ return [$this->color >> 16, ($this->color >> 8) & 0xff, $this->color & 0xff]; } public function setColor($r, $g, $b){ $this->color = (($r & 0xff) << 16) + (($g & 0xff) << 8) + ($b & 0xff); } public function add(Entity $entity, $modify = false, Effect $oldEffect = null){ $entity->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityEffectAddEvent($entity, $this, $modify, $oldEffect)); if($ev->isCancelled()){ return; } if($entity instanceof Player){ $pk = new MobEffectPacket(); $pk->eid = $entity->getId(); $pk->effectId = $this->getId(); $pk->amplifier = $this->getAmplifier(); $pk->particles = $this->isVisible(); $pk->duration = $this->getDuration(); if($ev->willModify()){ $pk->eventId = MobEffectPacket::EVENT_MODIFY; }else{ $pk->eventId = MobEffectPacket::EVENT_ADD; } $entity->dataPacket($pk); } if($this->id === Effect::INVISIBILITY){ $entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, true); $entity->setNameTagVisible(false); }elseif($this->id === Effect::SPEED){ $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); if($ev->willModify() and $oldEffect !== null){ $speed = $attr->getValue() / (1 + 0.2 * $oldEffect->getAmplifier()); }else{ $speed = $attr->getValue(); } $speed *= (1 + 0.2 * $this->amplifier); $attr->setValue($speed); }elseif($this->id === Effect::SLOWNESS){ $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); if($ev->willModify() and $oldEffect !== null){ $speed = $attr->getValue() / (1 - 0.15 * $oldEffect->getAmplifier()); }else{ $speed = $attr->getValue(); } $speed *= (1 - 0.15 * $this->amplifier); $attr->setValue($speed); } } public function remove(Entity $entity){ $entity->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityEffectRemoveEvent($entity, $this)); if($ev->isCancelled()){ return; } if($entity instanceof Player){ $pk = new MobEffectPacket(); $pk->eid = $entity->getId(); $pk->eventId = MobEffectPacket::EVENT_REMOVE; $pk->effectId = $this->getId(); $entity->dataPacket($pk); } if($this->id === Effect::INVISIBILITY){ $entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, false); $entity->setNameTagVisible(true); }elseif($this->id === Effect::SPEED){ $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); $attr->setValue($attr->getValue() / (1 + 0.2 * $this->amplifier)); }elseif($this->id === Effect::SLOWNESS){ $attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED); $attr->setValue($attr->getValue() / (1 - 0.15 * $this->amplifier)); } } }