public function isInside(Vector3 $v) { if (!$this->isValid()) { return false; } return min($this->x1, $this->x2) <= $v->x and min($this->y1, $this->y2) <= $v->y and min($this->z1, $this->z2) <= $v->z and max($this->x1, $this->x2) >= $v->x and max($this->y1, $this->y2) >= $v->y and max($this->z1, $this->z2) >= $v->z and !$v instanceof Position or $v->getLevel()->getName() === $this->levelName; }
public function isInside(Vector3 $v) { $out = true; $out = ($out and $v->distance($this->centre) <= $this->radius); if ($v instanceof Position) { $out = ($out and $v->getLevel()->getName() === $this->centre->getLevel()->getName()); } return $out; }
public function isInside(Vector3 $v) { if (!$this->isValid()) { return false; } if ($v instanceof Position and $v->getLevel()->getName() !== $this->levelName) { return false; } return $v->distanceSquared($this->center) <= $this->radiusSquared; }
/** * Checks whether the passed {@link Vector3} is included in this {@link Space}.<br> * Floating point vectors are accepted.<br> * <br> * The contents of this function are based on <a * href="http://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html">Wolfram|MathWorld: Point-Lne Distance * (3-Dimensional)</a>, whereas {@code X0 = $v, X1 = $this->baseCenter, X2 = $this->topCenter}. * * @param Vector3 $v the coordinates to check. * * @return bool whether <code> $v</code> is inside the space. */ public function isInside(Vector3 $v) { if (!$this->isValid()) { return false; } if ($v instanceof Position and $v->getLevel()->getName() !== $this->levelName) { return false; } $distSquared = $v->subtract($this->baseCenter)->cross($v->subtract($this->topCenter))->lengthSquared() / $this->topCenter->subtract($this->baseCenter)->lengthSquared(); // |---| return $distSquared <= $this->radiusSquared; // |(X0 - X1) x (X0 - X2)| / |X2 - X1| }
/** * Sets the spawnpoint of the player (and the compass direction) to a Vector3, or set it on another world with a Position object * * @param Vector3|Position $pos */ public function setSpawn(Vector3 $pos) { if (!$pos instanceof Position) { $level = $this->level; } else { $level = $pos->getLevel(); } $this->spawnPosition = new Position($pos->x, $pos->y, $pos->z, $level); $pk = new SetSpawnPositionPacket(); $pk->x = (int) $this->spawnPosition->x; $pk->y = (int) $this->spawnPosition->y; $pk->z = (int) $this->spawnPosition->z; $this->dataPacket($pk); }
/** * Returns the Tile in a position, or false if not found * * @param Vector3 $pos * * @return bool|Tile */ public function getTile(Vector3 $pos) { if ($pos instanceof Position and $pos->getLevel() !== $this) { return false; } $tiles = $this->getChunkTiles($pos->x >> 4, $pos->z >> 4); if (count($tiles) > 0) { foreach ($tiles as $tile) { if ($tile->x === (int) $pos->x and $tile->y === (int) $pos->y and $tile->z === (int) $pos->z) { return $tile; } } } return false; }
public function setPosition(Vector3 $pos) { if ($this->closed) { return \false; } if ($pos instanceof Position and $pos->level !== \null and $pos->level !== $this->level) { if ($this->switchLevel($pos->getLevel()) === \false) { return \false; } } $this->x = $pos->x; $this->y = $pos->y; $this->z = $pos->z; $radius = $this->width / 2; $this->boundingBox->setBounds($pos->x - $radius, $pos->y, $pos->z - $radius, $pos->x + $radius, $pos->y + $this->height, $pos->z + $radius); if ($this->chunk === \null or $this->chunkX !== $this->x >> 4 and $this->chunkZ !== $this->z >> 4) { if ($this->chunk !== \null) { $this->chunk->removeEntity($this); } $this->level->loadChunk($this->x >> 4, $this->z >> 4); $this->chunk = $this->level->getChunk($this->x >> 4, $this->z >> 4, \true); $this->chunkX = $this->chunk->getX(); $this->chunkZ = $this->chunk->getZ(); if (!$this->justCreated) { $newChunk = $this->level->getUsingChunk($this->x >> 4, $this->z >> 4); foreach ($this->hasSpawned as $player) { if (!isset($newChunk[$player->getId()])) { $this->despawnFrom($player); } else { unset($newChunk[$player->getId()]); } } foreach ($newChunk as $player) { $this->spawnTo($player); } } $this->chunk->addEntity($this); } return \true; }
/** * Returns the distance between two points or objects * * @param Vector3 $pos * * @return float */ public function distance(Vector3 $pos) { if ($pos instanceof Position and $pos->getLevel() !== $this->getLevel()) { return PHP_INT_MAX; } return parent::distance($pos); }
public function onUpdate($currentTick) { if (!$this->loggedIn) { return false; } $tickDiff = $currentTick - $this->lastUpdate; if ($tickDiff <= 0) { return true; } $this->messageCounter = 2; $this->lastUpdate = $currentTick; $this->sendAttributes(); if (!$this->isAlive() and $this->spawned) { ++$this->deadTicks; if ($this->deadTicks >= 10) { $this->despawnFromAll(); } return true; } $this->timings->startTiming(); if ($this->spawned) { if ($this->server->netherEnabled) { if (($this->isCreative() or $this->isSurvival() and $this->server->getTick() - $this->portalTime >= 80) and $this->portalTime > 0) { if ($this->server->netherLevel instanceof Level) { if ($this->getLevel() != $this->server->netherLevel) { $this->fromPos = $this->getPosition(); $this->fromPos->x = (int) $this->fromPos->x + 0.5; $this->fromPos->z = (int) $this->fromPos->z + 0.5; $this->teleport($this->shouldResPos = $this->server->netherLevel->getSafeSpawn()); } elseif ($this->fromPos instanceof Position) { if (!$this->getLevel()->isChunkLoaded($this->fromPos->x, $this->fromPos->z)) { $this->getLevel()->loadChunk($this->fromPos->x, $this->fromPos->z); } $add = [1, 0, -1, 0, 0, 1, 0, -1]; $tempos = null; for ($j = 2; $j < 5; $j++) { for ($i = 0; $i < 4; $i++) { if ($this->fromPos->getLevel()->getBlock($this->temporalVector->fromObjectAdd($this->fromPos, $add[$i] * $j, 0, $add[$i + 4] * $j))->getId() === Block::AIR) { if ($this->fromPos->getLevel()->getBlock($this->temporalVector->fromObjectAdd($this->fromPos, $add[$i] * $j, 1, $add[$i + 4] * $j))->getId() === Block::AIR) { $tempos = $this->fromPos->add($add[$i] * $j, 0, $add[$i + 4] * $j); //$this->getLevel()->getServer()->getLogger()->debug($tempos); break; } } } if ($tempos != null) { break; } } if ($tempos == null) { $tempos = $this->fromPos->add(mt_rand(-2, 2), 0, mt_rand(-2, 2)); } $this->teleport($this->shouldResPos = $tempos); $add = null; $tempos = null; $this->fromPos = null; } else { $this->teleport($this->shouldResPos = $this->server->getDefaultLevel()->getSafeSpawn()); } $this->portalTime = 0; } } } if (!$this->isSleeping()) { $this->processMovement($tickDiff); } if (!$this->isSpectator()) { $this->entityBaseTick($tickDiff); } if ($this->isOnFire() or $this->lastUpdate % 10 == 0) { if ($this->isCreative() and !$this->isInsideOfFire()) { $this->extinguish(); } elseif ($this->getLevel()->getWeather()->isRainy()) { if ($this->getLevel()->canBlockSeeSky($this)) { $this->extinguish(); } } } if ($this->server->antiFly) { if (!$this->isSpectator() and $this->speed !== null) { if ($this->onGround) { if ($this->inAirTicks !== 0) { $this->startAirTicks = 5; } $this->inAirTicks = 0; } else { if (!$this->allowFlight and $this->inAirTicks > 10 and !$this->isSleeping() and $this->getDataProperty(self::DATA_NO_AI) !== 1) { //expectedVelocity here is not calculated correctly //This causes players to fall too fast when bouncing on slime when antiFly is enabled $expectedVelocity = -$this->gravity / $this->drag - -$this->gravity / $this->drag * exp(-$this->drag * ($this->inAirTicks - $this->startAirTicks)); $diff = ($this->speed->y - $expectedVelocity) ** 2; if (!$this->hasEffect(Effect::JUMP) and $diff > 0.6 and $expectedVelocity < $this->speed->y and !$this->server->getAllowFlight()) { $this->setMotion($this->temporalVector->setComponents(0, $expectedVelocity, 0)); /*if($this->inAirTicks < 1000){ }elseif($this->kick("Flying is not enabled on this server")){ $this->timings->stopTiming(); return false; }*/ } } ++$this->inAirTicks; } } } if ($this->getTransactionQueue() !== null) { $this->getTransactionQueue()->execute(); } } $this->checkTeleportPosition(); $this->timings->stopTiming(); return true; }
/** * @param Vector3|Position $pos * @param null|Level $level */ public function createTNT(Vector3 $pos, Level $level = null) { if ($level === null) { if ($pos instanceof Position) { $level = $pos->getLevel(); } else { return; } } $mot = (new Random())->nextSignedFloat() * M_PI * 2; $entity = Entity::createEntity("PrimedTNT", $level->getChunk($pos->x >> 4, $pos->z >> 4), new Compound("EssNuke", ["Pos" => new Enum("Pos", [new DoubleTag("", $pos->getFloorX() + 0.5), new DoubleTag("", $pos->getFloorY()), new DoubleTag("", $pos->getFloorZ() + 0.5)]), "Motion" => new Enum("Motion", [new DoubleTag("", -sin($mot) * 0.02), new DoubleTag("", 0.2), new DoubleTag("", -cos($mot) * 0.02)]), "Rotation" => new Enum("Rotation", [new FloatTag("", 0), new FloatTag("", 0)]), "Fuse" => new ByteTag("Fuse", 80)])); $entity->spawnToAll(); }
public function isInside(Vector3 $v) { $out = true; $out = ($out and $this->baked0->getFloorX() <= $v->getX() and $v->getX() <= $this->baked1->getFloorX()); $out = ($out and $this->baked0->getFloorY() <= $v->getY() and $v->getY() <= $this->baked1->getFloorY()); $out = ($out and $this->baked0->getFloorZ() <= $v->getZ() and $v->getZ() <= $this->baked1->getFloorZ()); if ($v instanceof Position) { $out = ($out and $this->baked0->getLevel()->getName() === $v->getLevel()->getName()); } return $out; }
/** * @param Vector3 $v0 * @param Vector3 $v1 * @return bool */ protected final function equals(Vector3 $v0, Vector3 $v1) { $out = true; $out = ($out and $v0->getX() === $v1->getX()); $out = ($out and $v0->getY() === $v1->getY()); $out = ($out and $v0->getZ() === $v1->getZ()); if ($v0 instanceof Position and $v1 instanceof Position) { $out = ($out and $v0->getLevel()->getName() === $v1->getLevel()->getName()); } return $out; }
public function setPosition(Vector3 $pos, $force = false) { if ($pos instanceof Position and $pos->getLevel() instanceof Level and $pos->getLevel() !== $this->getLevel()) { if ($this->switchLevel($pos->getLevel()) === false) { return false; } } if (!$this->justCreated and $force !== true) { $ev = new EntityMoveEvent($this, $pos); $this->server->getPluginManager()->callEvent($ev); if ($ev->isCancelled()) { return false; } } $this->x = $pos->x; $this->y = $pos->y; $this->z = $pos->z; $radius = $this->width / 2; $this->boundingBox->setBounds($pos->x - $radius, $pos->y + $this->ySize, $pos->z - $radius, $pos->x + $radius, $pos->y + $this->height + $this->ySize, $pos->z + $radius); if ($this->chunk === null or $this->chunk->getX() !== $this->x >> 4 and $this->chunk->getZ() !== $this->z >> 4) { if ($this->chunk instanceof FullChunk) { $this->chunk->removeEntity($this); } $this->getLevel()->loadChunk($this->x >> 4, $this->z >> 4); $this->chunk = $this->getLevel()->getChunkAt($this->x >> 4, $this->z >> 4); if (!$this->justCreated) { $newChunk = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4); foreach ($this->hasSpawned as $player) { if (!isset($newChunk[$player->getID()])) { $this->despawnFrom($player); } else { unset($newChunk[$player->getID()]); } } foreach ($newChunk as $player) { $this->spawnTo($player); } } $this->chunk->addEntity($this); } return true; }
public function isInside(Vector3 $v) { $out = true; switch ($this->axis) { case self::X: $out = ($out and $this->base->getX() <= $v->getX() and $v->getX() <= $this->base->getX() + $this->height); $out = ($out and $v->distance(new Vector3($v->getX(), $this->base->getY(), $this->base->getZ())) <= $this->radius); break; case self::Y: $out = ($out and $this->base->getY() <= $v->getY() and $v->getY() <= $this->base->getY() + $this->height); $out = ($out and $v->distance(new Vector3($this->base->getX(), $v->getY(), $this->base->getZ())) <= $this->radius); break; case self::Z: $out = ($out and $this->base->getZ() <= $v->getZ() and $v->getZ() <= $this->base->getZ() + $this->height); $out = ($out and $v->distance(new Vector3($this->base->getX(), $this->base->getY(), $v->getZ())) <= $this->radius); break; } if ($v instanceof Position) { $out = ($out and $v->getLevel()->getName() === $this->base->getLevel()->getName()); } return $out; }
public function set(Block $block, Vector3 $pos, Level $level = null) { if ($pos instanceof Position && $pos->getLevel() !== null) { $level = $pos->getLevel(); } elseif ($block->getLevel() !== null) { $level = $block->getLevel(); } elseif ($level === null) { return; } $tile = $level->getTile($pos); if ($tile instanceof Chest) { $tile->unpair(); } if ($tile instanceof Tile) { $tile->close(); } $level->setBlock($pos, $block, false, false); }
public function setPosition(Vector3 $pos) { if ($this->closed) { return false; } if ($pos instanceof Position and $pos->level !== null and $pos->level !== $this->level) { if ($this->switchLevel($pos->getLevel()) === false) { return false; } } $this->x = $pos->x; $this->y = $pos->y; $this->z = $pos->z; $radius = $this->width / 2; $this->boundingBox->setBounds($pos->x - $radius, $pos->y, $pos->z - $radius, $pos->x + $radius, $pos->y + $this->height, $pos->z + $radius); $this->checkChunks(); return true; }