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); } }
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()); } }
/** * @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); } }
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(); } } }
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; }
/** * 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; }
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(); } }
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; }
/** * @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; }
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); }
public function onEntityCollide(Entity $entity) { $ev = new EntityDamageByBlockEvent($this, $entity, EntityDamageEvent::CAUSE_CONTACT, 1); $entity->attack($ev->getFinalDamage(), $ev); }
public function spawnTo(Player $player) { $pk = $this->addEntityDataPacket($player); $pk->type = FallingSand::NETWORK_ID; $player->dataPacket($pk); parent::spawnTo($player); }
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); }
public function removeEntity(Entity $entity) { unset($this->entities[$entity->getId()]); if (!$entity instanceof Player and $this->isInit) { $this->hasChanged = true; } }
public function saveNBT() { parent::saveNBT(); $this->namedtag->Age = new Short("Age", $this->age); }
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; }
public function onEntityCollide(Entity $entity) { $entity->resetFallDistance(); }
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; }
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); }
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; }
public function onEntityCollide(Entity $entity) { $entity->resetFallDistance(); $entity->onGround = true; }
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); } }