Esempio n. 1
0
 public function onEntityCollide(Entity $entity)
 {
     $entity->resetFallDistance();
     if ($entity->fireTicks > 0) {
         $entity->extinguish();
     }
     $entity->resetFallDistance();
 }
 protected function addAttackerModifiers(Entity $damager)
 {
     if ($damager->hasEffect(Effect::STRENGTH)) {
         $this->setDamage($this->getDamage(self::MODIFIER_BASE) * 0.3 * ($damager->getEffect(Effect::STRENGTH)->getAmplifier() + 1), self::MODIFIER_STRENGTH);
     }
     if ($damager->hasEffect(Effect::WEAKNESS)) {
         $this->setDamage(-($this->getDamage(self::MODIFIER_BASE) * 0.2 * ($damager->getEffect(Effect::WEAKNESS)->getAmplifier() + 1)), self::MODIFIER_WEAKNESS);
     }
 }
Esempio n. 3
0
 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 EntityCombustByBlockEvent($this, $entity, 8);
     Server::getInstance()->getPluginManager()->callEvent($ev);
     if (!$ev->isCancelled()) {
         $entity->setOnFire($ev->getDuration());
     }
 }
Esempio n. 4
0
 /**
  * @param Entity    $entity
  * @param int       $cause
  * @param int|int[] $damage
  *
  * @throws \Exception
  */
 public function __construct(Entity $entity, $cause, $damage)
 {
     $this->entity = $entity;
     $this->cause = $cause;
     if (is_array($damage)) {
         $this->modifiers = $damage;
     } else {
         $this->modifiers = [self::MODIFIER_BASE => $damage];
     }
     $this->originals = $this->modifiers;
     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.2 * ($entity->getEffect(Effect::DAMAGE_RESISTANCE)->getAmplifier() + 1)), self::MODIFIER_RESISTANCE);
     }
 }
Esempio n. 5
0
 public function onUpdate($type)
 {
     if ($type === Level::BLOCK_UPDATE_NORMAL) {
         $down = $this->getSide(Vector3::SIDE_DOWN);
         if ($down->getId() === self::AIR or $down instanceof Liquid) {
             $fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", ["Pos" => new Enum("Pos", [new Double("", $this->x + 0.5), new Double("", $this->y), new Double("", $this->z + 0.5)]), "Motion" => new Enum("Motion", [new Double("", 0), new Double("", 0), new Double("", 0)]), "Rotation" => new Enum("Rotation", [new Float("", 0), new Float("", 0)]), "TileID" => new Int("TileID", $this->getId()), "Data" => new Byte("Data", $this->getDamage())]));
             $fall->spawnToAll();
         }
     }
 }
Esempio n. 6
0
 public function onActivate(Item $item, Player $player = null)
 {
     if ($item->getId() === Item::FLINT_STEEL) {
         $item->useOn($this);
         $this->getLevel()->setBlock($this, new Air(), true);
         $mot = (new Random())->nextSignedFloat() * M_PI * 2;
         $tnt = Entity::createEntity("PrimedTNT", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", ["Pos" => new Enum("Pos", [new Double("", $this->x + 0.5), new Double("", $this->y), new Double("", $this->z + 0.5)]), "Motion" => new Enum("Motion", [new Double("", -sin($mot) * 0.02), new Double("", 0.2), new Double("", -cos($mot) * 0.02)]), "Rotation" => new Enum("Rotation", [new Float("", 0), new Float("", 0)]), "Fuse" => new Byte("Fuse", 80)]));
         $tnt->spawnToAll();
         return true;
     }
     return false;
 }
Esempio n. 7
0
 /**
  * TODO: Move this to each item
  *
  * @param Entity|Block $object
  *
  * @return bool
  */
 public function useOn($object)
 {
     if ($this->isUnbreakable()) {
         return true;
     }
     if ($object instanceof Block) {
         if ($object->getToolType() === Tool::TYPE_PICKAXE and $this->isPickaxe() or $object->getToolType() === Tool::TYPE_SHOVEL and $this->isShovel() or $object->getToolType() === Tool::TYPE_AXE and $this->isAxe() or $object->getToolType() === Tool::TYPE_SWORD and $this->isSword() or $object->getToolType() === Tool::TYPE_SHEARS and $this->isShears()) {
             $this->meta++;
         } elseif (!$this->isShears() and $object->getBreakTime($this) > 0) {
             $this->meta += 2;
         }
     } elseif ($this->isHoe()) {
         if ($object instanceof Block and ($object->getId() === self::GRASS or $object->getId() === self::DIRT)) {
             $this->meta++;
         }
     } elseif ($object instanceof Entity and !$this->isSword()) {
         $this->meta += 2;
     } else {
         $this->meta++;
     }
     return true;
 }
Esempio n. 8
0
 public function launch(Player $player)
 {
     $dir = $player->getDirectionVector();
     $frontPos = $player->add($dir->multiply(1.1));
     $nbt = new Compound("", ["Pos" => new Enum("Pos", [new Double("", $frontPos->x), new Double("", $frontPos->y + $player->getEyeHeight()), new Double("", $frontPos->z)]), "Motion" => new Enum("Motion", [new Double("", $dir->x), new Double("", $dir->y), new Double("", $dir->z)]), "Rotation" => new Enum("Rotation", [new Float("", 0), new Float("", 0)]), "Data" => new Byte("Data", $this->getDamage())]);
     $f = $this->f;
     $launched = Entity::createEntity($this->getEntityName(), $player->chunk, $nbt);
     $launched->setMotion($launched->getMotion()->multiply($f));
     if ($launched instanceof Projectile) {
         $player->server->getPluginManager()->callEvent($projectileEv = new ProjectileLaunchEvent($launched));
         if ($projectileEv->isCancelled()) {
             $launched->kill();
         } else {
             $launched->spawnToAll();
             $player->level->addSound(new LaunchSound($player), $player->getViewers());
         }
     } else {
         $launched->spawnToAll();
     }
 }
Esempio n. 9
0
 public function onActivate(Level $level, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz)
 {
     $entity = null;
     $chunk = $level->getChunk($block->getX() >> 4, $block->getZ() >> 4);
     if (!$chunk instanceof FullChunk) {
         return false;
     }
     $nbt = new Compound("", ["Pos" => new Enum("Pos", [new Double("", $block->getX() + 0.5), new Double("", $block->getY()), new Double("", $block->getZ() + 0.5)]), "Motion" => new Enum("Motion", [new Double("", 0), new Double("", 0), new Double("", 0)]), "Rotation" => new Enum("Rotation", [new Float("", lcg_value() * 360), new Float("", 0)])]);
     if ($this->hasCustomName()) {
         $nbt->CustomName = new String("CustomName", $this->getCustomName());
     }
     $entity = Entity::createEntity($this->meta, $chunk, $nbt);
     if ($entity instanceof Entity) {
         $entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_NO_AI, true);
         $entity->getLevel()->getServer()->broadcastPopup(TextFormat::RED . "Mob AI isn't implemented yet!");
         if ($player->isSurvival()) {
             --$this->count;
         }
         $entity->spawnToAll();
         return true;
     }
     return false;
 }
Esempio n. 10
0
 /**
  * @param Entity $entity
  *
  * @throws LevelException
  */
 public function addEntity(Entity $entity)
 {
     if ($entity->getLevel() !== $this) {
         throw new LevelException("Invalid Entity level");
     }
     if ($entity instanceof Player) {
         $this->players[$entity->getId()] = $entity;
     }
     $this->entities[$entity->getId()] = $entity;
 }
Esempio n. 11
0
 public function spawnTo(Player $player)
 {
     $pk = new AddItemEntityPacket();
     $pk->eid = $this->getId();
     $pk->x = $this->x;
     $pk->y = $this->y;
     $pk->z = $this->z;
     $pk->speedX = $this->motionX;
     $pk->speedY = $this->motionY;
     $pk->speedZ = $this->motionZ;
     $pk->item = $this->getItem();
     $player->dataPacket($pk);
     $this->sendData($player);
     parent::spawnTo($player);
 }
Esempio n. 12
0
 public function onEntityCollide(Entity $entity)
 {
     $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1);
     $entity->attack($ev->getFinalDamage(), $ev);
 }
Esempio n. 13
0
 public function spawnTo(Player $player)
 {
     $pk = $this->addEntityDataPacket($player);
     $pk->type = FallingSand::NETWORK_ID;
     $player->dataPacket($pk);
     parent::spawnTo($player);
 }
Esempio n. 14
0
 public function kill()
 {
     if (!$this->spawned) {
         return;
     }
     $message = "death.attack.generic";
     $params = [$this->getDisplayName()];
     $cause = $this->getLastDamageCause();
     switch ($cause === null ? EntityDamageEvent::CAUSE_CUSTOM : $cause->getCause()) {
         case EntityDamageEvent::CAUSE_ENTITY_ATTACK:
             if ($cause instanceof EntityDamageByEntityEvent) {
                 $e = $cause->getDamager();
                 if ($e instanceof Player) {
                     $message = "death.attack.player";
                     $params[] = $e->getDisplayName();
                     break;
                 } elseif ($e instanceof Living) {
                     $message = "death.attack.mob";
                     $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName();
                     break;
                 } else {
                     $params[] = "Unknown";
                 }
             }
             break;
         case EntityDamageEvent::CAUSE_PROJECTILE:
             if ($cause instanceof EntityDamageByEntityEvent) {
                 $e = $cause->getDamager();
                 if ($e instanceof Player) {
                     $message = "death.attack.arrow";
                     $params[] = $e->getDisplayName();
                 } elseif ($e instanceof Living) {
                     $message = "death.attack.arrow";
                     $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName();
                     break;
                 } else {
                     $params[] = "Unknown";
                 }
             }
             break;
         case EntityDamageEvent::CAUSE_SUICIDE:
             $message = "death.attack.generic";
             break;
         case EntityDamageEvent::CAUSE_VOID:
             $message = "death.attack.outOfWorld";
             break;
         case EntityDamageEvent::CAUSE_FALL:
             if ($cause instanceof EntityDamageEvent) {
                 if ($cause->getFinalDamage() > 2) {
                     $message = "death.fell.accident.generic";
                     break;
                 }
             }
             $message = "death.attack.fall";
             break;
         case EntityDamageEvent::CAUSE_SUFFOCATION:
             $message = "death.attack.inWall";
             break;
         case EntityDamageEvent::CAUSE_LAVA:
             $message = "death.attack.lava";
             break;
         case EntityDamageEvent::CAUSE_FIRE:
             $message = "death.attack.onFire";
             break;
         case EntityDamageEvent::CAUSE_FIRE_TICK:
             $message = "death.attack.inFire";
             break;
         case EntityDamageEvent::CAUSE_DROWNING:
             $message = "death.attack.drown";
             break;
         case EntityDamageEvent::CAUSE_CONTACT:
             if ($cause instanceof EntityDamageByBlockEvent) {
                 if ($cause->getDamager()->getId() === Block::CACTUS) {
                     $message = "death.attack.cactus";
                 }
             }
             break;
         case EntityDamageEvent::CAUSE_BLOCK_EXPLOSION:
         case EntityDamageEvent::CAUSE_ENTITY_EXPLOSION:
             if ($cause instanceof EntityDamageByEntityEvent) {
                 $e = $cause->getDamager();
                 if ($e instanceof Player) {
                     $message = "death.attack.explosion.player";
                     $params[] = $e->getDisplayName();
                 } elseif ($e instanceof Living) {
                     $message = "death.attack.explosion.player";
                     $params[] = $e->getNameTag() !== "" ? $e->getNameTag() : $e->getName();
                     break;
                 }
             } else {
                 $message = "death.attack.explosion";
             }
             break;
         case EntityDamageEvent::CAUSE_MAGIC:
             $message = "death.attack.magic";
             break;
         case EntityDamageEvent::CAUSE_CUSTOM:
             break;
         default:
     }
     Entity::kill();
     $this->server->getPluginManager()->callEvent($ev = new PlayerDeathEvent($this, $this->getDrops(), new TranslationContainer($message, $params)));
     if (!$ev->getKeepInventory()) {
         foreach ($ev->getDrops() as $item) {
             $this->level->dropItem($this, $item);
         }
         if ($this->inventory !== null) {
             $this->inventory->clearAll();
         }
     }
     if ($this->server->getProperty("experience.enable", true) and $this->server->getProperty("experience.player-drop", true)) {
         $DropExp = $this->getExperience();
         $vector = new Vector3(ceil($this->x), ceil($this->y), ceil($this->z));
         $this->getLevel()->spawnExperienceOrb($vector, $DropExp);
         $this->setExperience(0);
     }
     if ($ev->getDeathMessage() != "") {
         $this->server->broadcast($ev->getDeathMessage(), Server::BROADCAST_CHANNEL_USERS);
     }
     $pk = new RespawnPacket();
     $pos = $this->getSpawn();
     $pk->x = $pos->x;
     $pk->y = $pos->y;
     $pk->z = $pos->z;
     $this->dataPacket($pk);
 }
Esempio n. 15
0
 public function removeEntity(Entity $entity)
 {
     unset($this->entities[$entity->getId()]);
     if (!$entity instanceof Player and $this->isInit) {
         $this->hasChanged = true;
     }
 }
Esempio n. 16
0
 public function saveNBT()
 {
     parent::saveNBT();
     $this->namedtag->Age = new Short("Age", $this->age);
 }
Esempio n. 17
0
 public function explodeB()
 {
     $send = [];
     $updateBlocks = [];
     $source = (new Vector3($this->source->x, $this->source->y, $this->source->z))->floor();
     $yield = 1 / $this->size * 100;
     if ($this->what instanceof Entity) {
         $this->level->getServer()->getPluginManager()->callEvent($ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield));
         if ($ev->isCancelled()) {
             return false;
         } else {
             $yield = $ev->getYield();
             $this->affectedBlocks = $ev->getBlockList();
         }
     }
     $explosionSize = $this->size * 2;
     $minX = Math::floorFloat($this->source->x - $explosionSize - 1);
     $maxX = Math::ceilFloat($this->source->x + $explosionSize + 1);
     $minY = Math::floorFloat($this->source->y - $explosionSize - 1);
     $maxY = Math::ceilFloat($this->source->y + $explosionSize + 1);
     $minZ = Math::floorFloat($this->source->z - $explosionSize - 1);
     $maxZ = Math::ceilFloat($this->source->z + $explosionSize + 1);
     $explosionBB = new AxisAlignedBB($minX, $minY, $minZ, $maxX, $maxY, $maxZ);
     $list = $this->level->getNearbyEntities($explosionBB, $this->what instanceof Entity ? $this->what : null);
     foreach ($list as $entity) {
         $distance = $entity->distance($this->source) / $explosionSize;
         if ($distance <= 1) {
             $motion = $entity->subtract($this->source)->normalize();
             $impact = (1 - $distance) * ($exposure = 1);
             $damage = (int) (($impact * $impact + $impact) / 2 * 8 * $explosionSize + 1);
             if ($this->what instanceof Entity) {
                 $ev = new EntityDamageByEntityEvent($this->what, $entity, EntityDamageEvent::CAUSE_ENTITY_EXPLOSION, $damage);
             } elseif ($this->what instanceof Block) {
                 $ev = new EntityDamageByBlockEvent($this->what, $entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage);
             } else {
                 $ev = new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_BLOCK_EXPLOSION, $damage);
             }
             $entity->attack($ev->getFinalDamage(), $ev);
             $entity->setMotion($motion->multiply($impact));
         }
     }
     $air = Item::get(Item::AIR);
     foreach ($this->affectedBlocks as $block) {
         if ($block->getId() === Block::TNT) {
             $mot = (new Random())->nextSignedFloat() * M_PI * 2;
             $tnt = Entity::createEntity("PrimedTNT", $this->level->getChunk($block->x >> 4, $block->z >> 4), new Compound("", ["Pos" => new Enum("Pos", [new Double("", $block->x + 0.5), new Double("", $block->y), new Double("", $block->z + 0.5)]), "Motion" => new Enum("Motion", [new Double("", -sin($mot) * 0.02), new Double("", 0.2), new Double("", -cos($mot) * 0.02)]), "Rotation" => new Enum("Rotation", [new Float("", 0), new Float("", 0)]), "Fuse" => new Byte("Fuse", mt_rand(10, 30))]));
             $tnt->spawnToAll();
         } elseif (mt_rand(0, 100) < $yield) {
             foreach ($block->getDrops($air) as $drop) {
                 $this->level->dropItem($block->add(0.5, 0.5, 0.5), Item::get(...$drop));
             }
         }
         $this->level->setBlockIdAt($block->x, $block->y, $block->z, 0);
         $pos = new Vector3($block->x, $block->y, $block->z);
         for ($side = 0; $side < 5; $side++) {
             $sideBlock = $pos->getSide($side);
             if (!isset($this->affectedBlocks[$index = Level::blockHash($sideBlock->x, $sideBlock->y, $sideBlock->z)]) and !isset($updateBlocks[$index])) {
                 $this->level->getServer()->getPluginManager()->callEvent($ev = new BlockUpdateEvent($this->level->getBlock($sideBlock)));
                 if (!$ev->isCancelled()) {
                     $ev->getBlock()->onUpdate(Level::BLOCK_UPDATE_NORMAL);
                 }
                 $updateBlocks[$index] = true;
             }
         }
         $send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z);
     }
     $pk = new ExplodePacket();
     $pk->x = $this->source->x;
     $pk->y = $this->source->y;
     $pk->z = $this->source->z;
     $pk->radius = $this->size;
     $pk->records = $send;
     $this->level->addChunkPacket($source->x >> 4, $source->z >> 4, $pk);
     return true;
 }
Esempio n. 18
0
 public function onEntityCollide(Entity $entity)
 {
     $entity->resetFallDistance();
 }
Esempio n. 19
0
 public function unlinkEntity(Entity $entity)
 {
     if ($this->linkedTarget instanceof Entity) {
         $this->linkedTarget = null;
         $entity->islinked = false;
     }
     $pk = new SetEntityLinkPacket();
     $pk->from = $entity->getId();
     $pk->to = 0;
     $pk->type = 0;
     $this->dataPacket($pk);
     $this->islinked = false;
 }
Esempio n. 20
0
 public function spawnTo(Player $player)
 {
     $pk = $this->addEntityDataPacket($player);
     $this->setDataProperty(self::DATA_NO_AI, self::DATA_TYPE_BYTE, 1);
     $pk->type = self::NETWORK_ID;
     $player->dataPacket($pk);
     parent::spawnTo($player);
 }
Esempio n. 21
0
 public function entityBaseTick($tickDiff = 1)
 {
     Timings::$timerLivingEntityBaseTick->startTiming();
     $hasUpdate = parent::entityBaseTick($tickDiff);
     if ($this->isAlive()) {
         if ($this->isInsideOfSolid()) {
             $hasUpdate = true;
             $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 1);
             $this->attack($ev->getFinalDamage(), $ev);
         }
         if (!$this->hasEffect(Effect::WATER_BREATHING) and $this->isInsideOfWater()) {
             if ($this instanceof WaterAnimal) {
                 $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300);
             } else {
                 $hasUpdate = true;
                 $airTicks = $this->getDataProperty(self::DATA_AIR) - $tickDiff;
                 if ($airTicks <= -20) {
                     $airTicks = 0;
                     $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_DROWNING, 2);
                     $this->attack($ev->getFinalDamage(), $ev);
                 }
                 $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $airTicks);
             }
         } else {
             if ($this instanceof WaterAnimal) {
                 $hasUpdate = true;
                 $airTicks = $this->getDataProperty(self::DATA_AIR) - $tickDiff;
                 if ($airTicks <= -20) {
                     $airTicks = 0;
                     $ev = new EntityDamageEvent($this, EntityDamageEvent::CAUSE_SUFFOCATION, 2);
                     $this->attack($ev->getFinalDamage(), $ev);
                 }
                 $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $airTicks);
             } else {
                 $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300);
             }
         }
     }
     if ($this->attackTime > 0) {
         $this->attackTime -= $tickDiff;
     }
     Timings::$timerLivingEntityBaseTick->stopTiming();
     return $hasUpdate;
 }
Esempio n. 22
0
 public function onEntityCollide(Entity $entity)
 {
     $entity->resetFallDistance();
     $entity->onGround = true;
 }
Esempio n. 23
0
 public function remove(Entity $entity)
 {
     if ($entity instanceof Player) {
         $pk = new MobEffectPacket();
         $pk->eid = 0;
         $pk->eventId = MobEffectPacket::EVENT_REMOVE;
         $pk->effectId = $this->getId();
         $entity->dataPacket($pk->setChannel(Network::CHANNEL_WORLD_EVENTS));
     }
     if ($this->id === Effect::INVISIBILITY) {
         $entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, false);
         $entity->setDataProperty(Entity::DATA_SHOW_NAMETAG, Entity::DATA_TYPE_BYTE, 1);
     }
 }