From dad2f2188859c15a7a94c79f80fdb6f0722b461e Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sat, 1 Mar 2014 18:23:38 +0100 Subject: [PATCH] Players are fully spawnable and can see each other! --- src/Entity.php | 58 ++++++++++++++---- src/Player.php | 23 ++++---- src/entity/HumanEntity.php | 113 +++++++++++++++++++++++------------- src/entity/PlayerEntity.php | 2 + 4 files changed, 132 insertions(+), 64 deletions(-) diff --git a/src/Entity.php b/src/Entity.php index 8caf0b38f..d49ac1abf 100644 --- a/src/Entity.php +++ b/src/Entity.php @@ -23,7 +23,10 @@ abstract class Entity extends Position{ public static $entityCount = 1; public static $list = array(); public static $needUpdate = array(); - private $id; + + protected $hasSpawned = array(); + + protected $id; public $passenger = null; public $vehicle = null; @@ -86,7 +89,15 @@ abstract class Entity extends Position{ $this->level = $level; $this->boundingBox = new AxisAlignedBB(0, 0, 0, 0, 0, 0); - $this->setPosition(new Vector3($this->namedtag->Pos[0], $this->namedtag->Pos[1], $this->namedtag->Pos[2])); + $this->setPositionAndRotation(new Vector3($this->namedtag->Pos[0], $this->namedtag->Pos[1], $this->namedtag->Pos[2]), $this->namedtag->Rotation[0], $this->namedtag->Rotation[1]); + $this->setMotion(new Vector3($this->namedtag->Motion[0], $this->namedtag->Motion[1], $this->namedtag->Motion[2])); + + $this->fallDistance = $this->namedtag->FallDistance; + $this->fireTicks = $this->namedtag->Fire; + $this->airTicks = $this->namedtag->Air; + $this->onGround = $this->namedtag->OnGround > 0 ? true:false; + $this->invulnerable = $this->namedtag->Invulnerable > 0 ? true:false; + $index = PMFLevel::getIndex($this->x >> 4, $this->z >> 4); $this->chunkIndex = $index; Entity::$list[$this->id] = $this; @@ -118,12 +129,19 @@ abstract class Entity extends Position{ protected abstract function initEntity(); - public abstract function spawnTo(Player $player); + public function spawnTo(Player $player){ + if(!isset($this->hasSpawned[$player->getID()]) and $player->chunksLoaded[$this->chunkIndex] !== 0xff){ + $this->hasSpawned[$player->getID()] = $player; + } + } public function despawnFrom(Player $player){ - $pk = new RemoveEntityPacket; - $pk->eid = $this->id; - $player->dataPacket($pk); + if(isset($this->hasSpawned[$player->getID()])){ + $pk = new RemoveEntityPacket; + $pk->eid = $this->id; + $player->dataPacket($pk); + unset($this->hasSpawned[$player->getID()]); + } } abstract function attack($damage, $source = "generic"); @@ -310,6 +328,28 @@ abstract class Entity extends Position{ $this->level->chunkEntities[$this->chunkIndex][$this->id] = $this; } $this->boundingBox->setBounds($pos->x - $radius, $pos->y, $pos->z - $radius, $pos->x + $radius, $pos->y + $this->height, $pos->z + $radius); + + if($this instanceof HumanEntity){ + $pk = new MovePlayerPacket; + $pk->eid = $this->id; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->yaw = $this->yaw; + $pk->pitch = $this->pitch; + $pk->bodyYaw = $this->yaw; + }else{ + $pk = new MoveEntityPacket_PosRot; + $pk->eid = $this->id; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->yaw = $this->yaw; + $pk->pitch = $this->pitch; + } + foreach($this->hasSpawned as $p){ + $p->dataPacket(clone $pk); + } return true; } @@ -376,10 +416,8 @@ abstract class Entity extends Position{ } public function despawnFromAll(){ - foreach($this->level->getPlayers() as $player){ - if($player->eid !== false or $player->spawned !== true){ - $this->despawnFrom($player); - } + foreach($this->hasSpawned as $player){ + $this->despawnFrom($player); } } diff --git a/src/Player.php b/src/Player.php index effea7fa4..10e4e5e8c 100644 --- a/src/Player.php +++ b/src/Player.php @@ -1355,7 +1355,7 @@ class Player extends PlayerEntity{ $this->hotbar = array(-1, -1, -1, -1, -1, -1, -1, -1, -1); } - parent::__construct($this->level, new NBTTag_Compound(false, array( + $nbt = new NBTTag_Compound(false, array( "Pos" => new NBTTag_List("Pos", array( 0 => new NBTTag_Double(0, $this->data->get("position")["x"]), 1 => new NBTTag_Double(1, $this->data->get("position")["y"]), @@ -1377,10 +1377,13 @@ class Player extends PlayerEntity{ "Invulnerable" => new NBTTag_Byte("Invulnerable", 0), "NameTag" => new NBTTag_String("NameTag", $this->username), - ))); - $this->namedtag->Pos->setTagType(NBTTag::TAG_Double); - $this->namedtag->Motion->setTagType(NBTTag::TAG_Double); - $this->namedtag->Rotation->setTagType(NBTTag::TAG_Float); + )); + $nbt->Pos->setTagType(NBTTag::TAG_Double); + $nbt->Motion->setTagType(NBTTag::TAG_Double); + $nbt->Rotation->setTagType(NBTTag::TAG_Float); + + parent::__construct($this->level, $nbt); + if(($level = $this->server->api->level->get($this->data->get("spawn")["level"])) !== false){ $this->spawnPosition = new Position($this->data->get("spawn")["x"], $this->data->get("spawn")["y"], $this->data->get("spawn")["z"], $level); @@ -1416,14 +1419,7 @@ class Player extends PlayerEntity{ } $this->heal($this->data->get("health"), "spawn", true); $this->spawned = true; - //TODO - //$this->server->api->player->spawnAllPlayers($this); - //TODO - //$this->server->api->player->spawnToAllPlayers($this); - //TODO - //$this->server->api->entity->spawnAll($this); - //$this->spawnToAll(); - //$this->sendArmor(); + $this->spawnToAll(); $this->sendChat($this->server->motd."\n"); if($this->iusername === "steve" or $this->iusername === "stevie"){ @@ -1431,6 +1427,7 @@ class Player extends PlayerEntity{ } $this->sendInventory(); $this->sendSettings(); + $this->sendArmor(); $this->server->schedule(30, array($this, "orderChunks"), array(), true); $this->blocked = false; diff --git a/src/entity/HumanEntity.php b/src/entity/HumanEntity.php index ef4f661e6..829f1705d 100644 --- a/src/entity/HumanEntity.php +++ b/src/entity/HumanEntity.php @@ -32,52 +32,83 @@ class HumanEntity extends CreatureEntity implements ProjectileSourceEntity{ } public function spawnTo(Player $player){ - $pk = new AddPlayerPacket; - $pk->clientID = 0; - $pk->username = $this->nameTag; - $pk->eid = $this->id; - $pk->x = $this->x; - $pk->y = $this->y; - $pk->z = $this->z; - $pk->yaw = 0; - $pk->pitch = 0; - $pk->unknown1 = 0; - $pk->unknown2 = 0; - $pk->metadata = $this->getMetadata(); - $player->dataPacket($pk); - - /* - $pk = new SetEntityMotionPacket; - $pk->eid = $this->id; - $pk->speedX = $this->velocity->x; - $pk->speedY = $this->velocity->y; - $pk->speedZ = $this->velocity->z; - $player->dataPacket($pk);*/ + if($player !== $this and !isset($this->hasSpawned[$player->getID()])){ + $this->hasSpawned[$player->getID()] = $player; - $this->sendMotion($player); - - /* - $pk = new PlayerEquipmentPacket; - $pk->eid = $this->id; - $pk->item = $this->player->getSlot($this->player->slot)->getID(); - $pk->meta = $this->player->getSlot($this->player->slot)->getMetadata(); - $pk->slot = 0; - $player->dataPacket($pk);*/ - - $this->sendEquipment($player); - - $this->sendArmor($player); + $pk = new AddPlayerPacket; + $pk->clientID = 0; + $pk->username = $this->nameTag; + $pk->eid = $this->id; + $pk->x = $this->x; + $pk->y = $this->y; + $pk->z = $this->z; + $pk->yaw = 0; + $pk->pitch = 0; + $pk->unknown1 = 0; + $pk->unknown2 = 0; + $pk->metadata = $this->getMetadata(); + $player->dataPacket($pk); + + /* + $pk = new SetEntityMotionPacket; + $pk->eid = $this->id; + $pk->speedX = $this->velocity->x; + $pk->speedY = $this->velocity->y; + $pk->speedZ = $this->velocity->z; + $player->dataPacket($pk);*/ + + //$this->sendMotion($player); + + /* + $pk = new PlayerEquipmentPacket; + $pk->eid = $this->id; + $pk->item = $this->player->getSlot($this->player->slot)->getID(); + $pk->meta = $this->player->getSlot($this->player->slot)->getMetadata(); + $pk->slot = 0; + $player->dataPacket($pk);*/ + + //$this->sendEquipment($player); + + //$this->sendArmor($player); + } } - public function despawnTo(Player $player){ - $pk = new RemovePlayerPacket; - $pk->eid = $this->id; - $pk->clientID = 0; - $player->dataPacket($pk); + public function despawnFrom(Player $player){ + if(isset($this->hasSpawned[$player->getID()])){ + $pk = new RemovePlayerPacket; + $pk->eid = $this->id; + $pk->clientID = 0; + $player->dataPacket($pk); + unset($this->hasSpawned[$player->getID()]); + } } - public function getMetadata(){ - return array(); + public function getMetadata(){ //TODO + $flags = 0; + $flags |= $this->fireTicks > 0 ? 1:0; + //$flags |= ($this->crouched === true ? 0b10:0) << 1; + //$flags |= ($this->inAction === true ? 0b10000:0); + $d = array( + 0 => array("type" => 0, "value" => $flags), + 1 => array("type" => 1, "value" => $this->airTicks), + 16 => array("type" => 0, "value" => 0), + 17 => array("type" => 6, "value" => array(0, 0, 0)), + ); + /*if($this->class === ENTITY_MOB and $this->type === MOB_SHEEP){ + if(!isset($this->data["Sheared"])){ + $this->data["Sheared"] = 0; + $this->data["Color"] = mt_rand(0,15); + } + $d[16]["value"] = (($this->data["Sheared"] == 1 ? 1:0) << 4) | ($this->data["Color"] & 0x0F); + }elseif($this->type === OBJECT_PRIMEDTNT){ + $d[16]["value"] = (int) max(0, $this->data["fuse"] - (microtime(true) - $this->spawntime) * 20); + }elseif($this->class === ENTITY_PLAYER){ + if($this->player->isSleeping !== false){ + $d[16]["value"] = 2; + $d[17]["value"] = array($this->player->isSleeping->x, $this->player->isSleeping->y, $this->player->isSleeping->z); + } + }*/ + return $d; } public function attack($damage, $source = "generic"){ diff --git a/src/entity/PlayerEntity.php b/src/entity/PlayerEntity.php index 6e8a8cf96..9e8c9bba8 100644 --- a/src/entity/PlayerEntity.php +++ b/src/entity/PlayerEntity.php @@ -23,9 +23,11 @@ class PlayerEntity extends HumanEntity{ protected function initEntity(){ $this->level->players[$this->CID] = $this; + parent::initEntity(); } public function close(){ unset($this->level->players[$this->CID]); + parent::close(); } } \ No newline at end of file