diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index 4fbe939c0..e047edd0e 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -193,7 +193,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ protected $chunksPerTick; /** @var null|Position */ private $spawnPosition = null; - private $inAction = false; protected $inAirTicks = 0; protected $lastSpeedTick = 0; @@ -251,10 +250,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ return $this->namedtag instanceof Compound; } - protected function initEntity(){ - parent::initEntity(); - } - /** * @param Player $player */ @@ -669,6 +664,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->teleport($ev->getRespawnPosition()); $this->sendSettings(); + $this->sendData($this); + $this->sendPotionEffects($this); $this->inventory->sendContents($this); $this->inventory->sendArmorContents($this); @@ -829,8 +826,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->sleeping = clone $pos; $this->teleport(new Position($pos->x + 0.5, $pos->y + 1, $pos->z + 0.5, $this->level)); - $this->sendMetadata($this->getViewers()); - $this->sendMetadata($this); + $this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [$pos->x, $pos->y, $pos->z]); + $this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, true); $this->setSpawn($pos); $this->tasks[] = $this->server->getScheduler()->scheduleDelayedTask(new CallbackTask([$this, "checkSleep"]), 60); @@ -863,9 +860,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $this->level->getBlock($this->sleeping))); $this->sleeping = null; - - $this->sendMetadata($this->getViewers()); - $this->sendMetadata($this); + $this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, false); + $this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0]); } } @@ -1680,10 +1676,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->inventory->sendHeldItem($this->hasSpawned); - if($this->inAction === true){ - $this->inAction = false; - $this->sendMetadata($this->getViewers()); - } + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false); break; case ProtocolInfo::USE_ITEM_PACKET: if($this->spawned === false or $this->dead === true or $this->blocked){ @@ -1697,10 +1690,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $packet->eid = $this->id; if($packet->face >= 0 and $packet->face <= 5){ //Use Block, place - if($this->inAction === true){ - $this->inAction = false; - $this->sendMetadata($this->getViewers()); - } + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false); if($blockVector->distance($this) > 10){ @@ -1797,9 +1787,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $snowball->spawnToAll(); } } - $this->inAction = true; + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, true); $this->startAction = microtime(true); - $this->sendMetadata($this->getViewers()); } break; case ProtocolInfo::PLAYER_ACTION_PACKET: @@ -1875,8 +1864,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } $this->startAction = false; - $this->inAction = false; - $this->sendMetadata($this->getViewers()); + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false); break; case 6: //get out of the bed $this->stopSleep(); @@ -2080,15 +2068,14 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->teleport($ev->getRespawnPosition()); $this->fireTicks = 0; - $this->airTicks = 300; + $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300); $this->deadTicks = 0; $this->noDamageTicks = 60; $this->setHealth(20); $this->dead = false; - $this->sendMetadata($this->getViewers()); - $this->sendMetadata($this); + $this->sendData($this); $this->sendSettings(); $this->inventory->sendContents($this); @@ -2107,10 +2094,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } $this->craftingType = 0; - if($this->inAction === true){ - $this->inAction = false; - $this->sendMetadata($this->getViewers()); - } + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false); //TODO: check if this should be true + switch($packet->event){ case 9: //Eating $items = [ @@ -2182,10 +2167,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->level->dropItem($this->add(0, 1.3, 0), $item, $motion, 40); - if($this->inAction === true){ - $this->inAction = false; - $this->sendMetadata($this->getViewers()); - } + $this->setDataFlag(self::DATA_FLAGS, self::DATA_FLAG_ACTION, false); break; case ProtocolInfo::MESSAGE_PACKET: if($this->spawned === false or $this->dead === true){ @@ -2701,30 +2683,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ } } - public function getData(){ //TODO - $flags = 0; - $flags |= $this->fireTicks > 0 ? 1 : 0; - $flags |= $this->hasEffect(Effect::INVISIBILITY) ? 1 << 5 : 0; - //$flags |= ($this->crouched === true ? 0b10:0) << 1; - $flags |= ($this->inAction === true ? 0b10000 : 0); - $d = [ - 0 => ["type" => 0, "value" => $flags], - 1 => ["type" => 1, "value" => $this->airTicks], - 3 => ["type" => 0, "value" => $this->hasEffect(Effect::INVISIBILITY) ? 0 : 1], - 16 => ["type" => 0, "value" => 0], - 17 => ["type" => 6, "value" => [0, 0, 0]], - ]; - - - if($this->sleeping instanceof Vector3){ - $d[16]["value"] = 2; - $d[17]["value"] = [$this->sleeping->x, $this->sleeping->y, $this->sleeping->z]; - } - - - return $d; - } - public function teleport(Vector3 $pos, $yaw = null, $pitch = null){ if(parent::teleport($pos, $yaw, $pitch)){ @@ -2735,7 +2693,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{ $this->removeWindow($window); } - $this->airTicks = 300; + $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300); $this->resetFallDistance(); $this->orderChunks(); $this->nextChunkOrderRun = 0; diff --git a/src/pocketmine/entity/Effect.php b/src/pocketmine/entity/Effect.php index 1c78b553a..bea73b385 100644 --- a/src/pocketmine/entity/Effect.php +++ b/src/pocketmine/entity/Effect.php @@ -23,6 +23,9 @@ namespace pocketmine\entity; use pocketmine\event\entity\EntityDamageEvent; use pocketmine\event\entity\EntityRegainHealthEvent; +use pocketmine\network\protocol\MobEffectPacket; +use pocketmine\Player; +use pocketmine\Server; class Effect{ const SPEED = 1; @@ -136,12 +139,20 @@ class Effect{ return $this; } + /** + * @return int + */ public function getAmplifier(){ return $this->amplifier; } + /** + * @param int $amplifier + * + * @return $this + */ public function setAmplifier($amplifier){ - $this->amplifier = $amplifier; + $this->amplifier = (int) $amplifier; return $this; } @@ -188,4 +199,44 @@ class Effect{ break; } } + + public function add(Entity $entity, $modify = false){ + $pk = new MobEffectPacket(); + $pk->eid = $entity->getId(); + $pk->effectId = $this->getId(); + $pk->amplifier = $this->getAmplifier(); + $pk->particles = $this->isVisible(); + $pk->duration = $this->getDuration(); + if($modify){ + $pk->eventId = MobEffectPacket::EVENT_MODIFY; + }else{ + $pk->eventId = MobEffectPacket::EVENT_ADD; + } + + Server::broadcastPacket($entity->getViewers(), $pk); + if($entity instanceof Player){ + $entity->dataPacket($pk); + } + + if($this->id === Effect::INVISIBILITY){ + $entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, true); + $entity->setDataProperty(Entity::DATA_SHOW_NAMETAG, Entity::DATA_TYPE_BYTE, 0); + } + } + + public function remove(Entity $entity){ + $pk = new MobEffectPacket(); + $pk->eid = $entity->getId(); + $pk->eventId = MobEffectPacket::EVENT_REMOVE; + $pk->effectId = $this->getId(); + Server::broadcastPacket($entity->getViewers(), $pk); + if($entity instanceof Player){ + $entity->dataPacket($pk); + } + + 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); + } + } } diff --git a/src/pocketmine/entity/Entity.php b/src/pocketmine/entity/Entity.php index f72339885..124ba5531 100644 --- a/src/pocketmine/entity/Entity.php +++ b/src/pocketmine/entity/Entity.php @@ -48,6 +48,7 @@ use pocketmine\nbt\tag\Compound; use pocketmine\nbt\tag\Double; use pocketmine\nbt\tag\Enum; use pocketmine\nbt\tag\Float; +use pocketmine\nbt\tag\Int; use pocketmine\nbt\tag\Short; use pocketmine\nbt\tag\String; use pocketmine\Network; @@ -66,6 +67,26 @@ abstract class Entity extends Location implements Metadatable{ const NETWORK_ID = -1; + + const DATA_TYPE_BYTE = 0; + const DATA_TYPE_SHORT = 1; + const DATA_TYPE_INT = 2; + const DATA_TYPE_FLOAT = 3; + const DATA_TYPE_STRING = 4; + const DATA_TYPE_SLOT = 5; + const DATA_TYPE_POS = 6; + const DATA_TYPE_ROTATION = 7; + + const DATA_FLAGS = 0; + const DATA_AIR = 1; + const DATA_SHOW_NAMETAG = 3; + + + const DATA_FLAG_ONFIRE = 0; + const DATA_FLAG_ACTION = 4; + const DATA_FLAG_INVISIBLE = 5; + + public static $entityCount = 1; /** @var Entity[] */ private static $knownEntities = []; @@ -81,6 +102,13 @@ abstract class Entity extends Location implements Metadatable{ protected $id; + protected $dataFlags = 0; + protected $dataProperties = [ + self::DATA_FLAGS => [self::DATA_TYPE_BYTE, 0], + self::DATA_SHOW_NAMETAG => [self::DATA_TYPE_BYTE, 1], + self::DATA_AIR => [self::DATA_TYPE_SHORT, 300] + ]; + public $passenger = null; public $vehicle = null; @@ -138,7 +166,6 @@ abstract class Entity extends Location implements Metadatable{ public $lastUpdate; public $maxFireTicks; public $fireTicks; - public $airTicks; public $namedtag; public $canCollide = true; @@ -210,7 +237,7 @@ abstract class Entity extends Location implements Metadatable{ if(!isset($this->namedtag->Air)){ $this->namedtag->Air = new Short("Air", 300); } - $this->airTicks = $this->namedtag["Air"]; + $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $this->namedtag["Air"]); if(!isset($this->namedtag->OnGround)){ $this->namedtag->OnGround = new Byte("OnGround", 0); @@ -239,23 +266,17 @@ abstract class Entity extends Location implements Metadatable{ return $this->effects; } + public function removeAllEffects(){ + foreach($this->effects as $effect){ + $this->removeEffect($effect->getId()); + } + } + public function removeEffect($effectId){ if(isset($this->effects[$effectId])){ - $pk = new MobEffectPacket(); - $pk->eid = $this->getId(); - $pk->eventId = MobEffectPacket::EVENT_REMOVE; - $pk->effectId = $effectId; - Server::broadcastPacket($this->getViewers(), $pk); - if($this instanceof Player){ - $this->dataPacket($pk); - } - + $effect = $this->effects[$effectId]; unset($this->effects[$effectId]); - - $this->sendMetadata($this->hasSpawned); - if($this instanceof Player){ - $this->sendMetadata($this); - } + $effect->remove($this); } } @@ -264,29 +285,21 @@ abstract class Entity extends Location implements Metadatable{ } public function addEffect(Effect $effect){ - $pk = new MobEffectPacket(); - $pk->eid = $this->getId(); - $pk->effectId = $effect->getId(); - $pk->amplifier = $effect->getAmplifier(); - $pk->particles = $effect->isVisible(); - $pk->duration = $effect->getDuration(); if(isset($this->effects[$effect->getId()])){ - $pk->eventId = MobEffectPacket::EVENT_MODIFY; + $oldEffect = $this->effects[$effect->getId()]; + if( + $effect->getAmplifier() <= $oldEffect->getAmplifier() + or ($effect->getAmplifier() === $oldEffect->getAmplifier() + and $effect->getDuration() < $oldEffect->getDuration()) + ){ + return; + } + $effect->add($this, true); }else{ - $pk->eventId = MobEffectPacket::EVENT_ADD; - } - - Server::broadcastPacket($this->getViewers(), $pk); - if($this instanceof Player){ - $this->dataPacket($pk); + $effect->add($this, false); } $this->effects[$effect->getId()] = $effect; - - $this->sendMetadata($this->hasSpawned); - if($this instanceof Player){ - $this->sendMetadata($this); - } } /** @@ -356,12 +369,42 @@ abstract class Entity extends Location implements Metadatable{ $this->namedtag->FallDistance = new Float("FallDistance", $this->fallDistance); $this->namedtag->Fire = new Short("Fire", $this->fireTicks); - $this->namedtag->Air = new Short("Air", $this->airTicks); + $this->namedtag->Air = new Short("Air", $this->getDataProperty(self::DATA_AIR)); $this->namedtag->OnGround = new Byte("OnGround", $this->onGround == true ? 1 : 0); $this->namedtag->Invulnerable = new Byte("Invulnerable", $this->invulnerable == true ? 1 : 0); + + if(count($this->effects) > 0){ + $effects = []; + foreach($this->effects as $effect){ + $effects[$effect->getId()] = new Compound($effect->getId(), [ + "Id" => new Byte("Id", $effect->getId()), + "Amplifier" => new Byte("Amplifier", $effect->getAmplifier()), + "Duration" => new Int("Duration", $effect->getDuration()), + "Ambient" => new Byte("Ambient", 0), + "ShowParticles" => new Byte("ShowParticles", $effect->isVisible() ? 1 : 0) + ]); + } + + $this->namedtag->ActiveEffects = new Enum("ActiveEffects", $effects); + }else{ + unset($this->namedtag->ActiveEffects); + } } - protected abstract function initEntity(); + protected function initEntity(){ + if(isset($this->namedtag->ActiveEffects)){ + foreach($this->namedtag->ActiveEffects->getValue() as $e){ + $effect = Effect::getEffect($e["Id"]); + if($effect === null){ + continue; + } + + $effect->setAmplifier($e["Amplifier"])->setDuration($e["Duration"])->setVisible($e["ShowParticles"] > 0); + + $this->addEffect($effect); + } + } + } /** * @return Player[] @@ -376,31 +419,42 @@ abstract class Entity extends Location implements Metadatable{ public function spawnTo(Player $player){ if(!isset($this->hasSpawned[$player->getId()]) and isset($player->usedChunks[Level::chunkHash($this->chunk->getX(), $this->chunk->getZ())])){ $this->hasSpawned[$player->getId()] = $player; - foreach($this->effects as $effect){ - $pk = new MobEffectPacket(); - $pk->eid = $this->getId(); - $pk->effectId = $effect->getId(); - $pk->amplifier = $effect->getAmplifier(); - $pk->particles = $effect->isVisible(); - $pk->duration = $effect->getDuration(); - $pk->eventId = MobEffectPacket::EVENT_ADD; - - $player->dataPacket($pk); - } + } + } + + public function sendPotionEffects(Player $player){ + foreach($this->effects as $effect){ + $pk = new MobEffectPacket(); + $pk->eid = $this->getId(); + $pk->effectId = $effect->getId(); + $pk->amplifier = $effect->getAmplifier(); + $pk->particles = $effect->isVisible(); + $pk->duration = $effect->getDuration(); + $pk->eventId = MobEffectPacket::EVENT_ADD; + + $player->dataPacket($pk); } } /** - * @param Player[]|Player $player + * @deprecated */ public function sendMetadata($player){ + $this->sendData($player); + } + + /** + * @param Player[]|Player $player + * @param array $data Properly formatted entity data, defaults to everything + */ + public function sendData($player, array $data = null){ if($player instanceof Player){ $player = [$player]; } $pk = new SetEntityDataPacket(); $pk->eid = $this->id; - $pk->metadata = $this->getData(); + $pk->metadata = $data === null ? $this->dataProperties : $data; Server::broadcastPacket($player, $pk); } @@ -588,7 +642,7 @@ abstract class Entity extends Location implements Metadatable{ $isPlayer = $this instanceof Player; if($this->dead === true){ - $this->effects = []; + $this->removeAllEffects(); $this->despawnFromAll(); if(!$isPlayer){ $this->close(); @@ -1380,7 +1434,67 @@ abstract class Entity extends Location implements Metadatable{ } } - abstract public function getData(); + /** + * @param int $id + * @param int $type + * @param mixed $value + */ + public function setDataProperty($id, $type, $value){ + $this->dataProperties[$id] = [$type, $value]; + + $targets = $this->hasSpawned; + if($this instanceof Player){ + $targets[] = $this; + } + + $this->sendData($targets, [$id => $this->dataProperties[$id]]); + } + + /** + * @param int $id + * + * @return mixed + */ + public function getDataProperty($id){ + return isset($this->dataProperties[$id]) ? $this->dataProperties[$id][1] : null; + } + + /** + * @param int $id + * + * @return int + */ + public function getDataPropertyType($id){ + return isset($this->dataProperties[$id]) ? $this->dataProperties[$id][0] : null; + } + + /** + * @param int $propertyId; + * @param int $id + * @param bool $value + */ + public function setDataFlag($propertyId, $id, $value = true, $type = self::DATA_TYPE_BYTE){ + if($this->getDataFlag($propertyId, $id) !== $value){ + $flags = (int) $this->getDataProperty($propertyId); + $flags ^= 1 << $id; + $this->setDataProperty($propertyId, $type, $flags); + } + } + + /** + * @param int $propertyId + * @param int $id + * + * @return bool + */ + public function getDataFlag($propertyId, $id){ + return (((int) $this->getDataProperty($propertyId)) & (1 << $id)) > 0; + } + + /** + * @deprecated + */ + public function getData(){} public function __destruct(){ $this->close(); diff --git a/src/pocketmine/entity/FallingSand.php b/src/pocketmine/entity/FallingSand.php index 51b91a169..fff4229bd 100644 --- a/src/pocketmine/entity/FallingSand.php +++ b/src/pocketmine/entity/FallingSand.php @@ -50,6 +50,7 @@ class FallingSand extends Entity{ public $canCollide = false; protected function initEntity(){ + parent::initEntity(); if(isset($this->namedtag->TileID)){ $this->blockId = $this->namedtag["TileID"]; }elseif(isset($this->namedtag->Tile)){ diff --git a/src/pocketmine/entity/Human.php b/src/pocketmine/entity/Human.php index c2e3bd6a0..dcb28590e 100644 --- a/src/pocketmine/entity/Human.php +++ b/src/pocketmine/entity/Human.php @@ -24,6 +24,7 @@ namespace pocketmine\entity; use pocketmine\inventory\InventoryHolder; use pocketmine\inventory\PlayerInventory; use pocketmine\item\Item as ItemItem; +use pocketmine\math\Vector3; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\Byte; use pocketmine\nbt\tag\Compound; @@ -37,6 +38,11 @@ use pocketmine\utils\TextFormat; class Human extends Creature implements ProjectileSource, InventoryHolder{ + const DATA_PLAYER_FLAG_SLEEP = 1; + + const DATA_PLAYER_FLAGS = 16; + const DATA_PLAYER_BED_POSITION = 17; + protected $nameTag = "TESTIFICATE"; /** @var PlayerInventory */ protected $inventory; @@ -52,6 +58,9 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ protected function initEntity(){ + $this->setDataFlag(self::DATA_PLAYER_FLAGS, self::DATA_PLAYER_FLAG_SLEEP, false); + $this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0]); + $this->inventory = new PlayerInventory($this); if($this instanceof Player){ $this->addWindow($this->inventory, 0); @@ -186,23 +195,6 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{ } } - public function getData(){ //TODO - $flags = 0; - $flags |= $this->fireTicks > 0 ? 1 : 0; - $flags |= $this->hasEffect(Effect::INVISIBILITY) ? 1 << 5 : 0; - //$flags |= ($this->crouched === true ? 0b10:0) << 1; - //$flags |= ($this->inAction === true ? 0b10000:0); - $d = [ - 0 => ["type" => 0, "value" => $flags], - 1 => ["type" => 1, "value" => $this->airTicks], - 3 => ["type" => 0, "value" => $this->hasEffect(Effect::INVISIBILITY) ? 0 : 1], - 16 => ["type" => 0, "value" => 0], - 17 => ["type" => 6, "value" => [0, 0, 0]], - ]; - - return $d; - } - public function close(){ if(!$this->closed){ if(!($this instanceof Player) or $this->loggedIn){ diff --git a/src/pocketmine/entity/Item.php b/src/pocketmine/entity/Item.php index 2fd58b23c..d73f6cc47 100644 --- a/src/pocketmine/entity/Item.php +++ b/src/pocketmine/entity/Item.php @@ -52,6 +52,8 @@ class Item extends Entity{ public $canCollide = false; protected function initEntity(){ + parent::initEntity(); + $this->setMaxHealth(5); $this->setHealth($this->namedtag["Health"]); if(isset($this->namedtag->Age)){ diff --git a/src/pocketmine/entity/Living.php b/src/pocketmine/entity/Living.php index 0370b0c0a..ac2413372 100644 --- a/src/pocketmine/entity/Living.php +++ b/src/pocketmine/entity/Living.php @@ -46,6 +46,8 @@ abstract class Living extends Entity implements Damageable{ protected $invisible = false; protected function initEntity(){ + parent::initEntity(); + if(isset($this->namedtag->HealF)){ $this->namedtag->Health = new Short("Health", (int) $this->namedtag["HealF"]); unset($this->namedtag->HealF); @@ -180,15 +182,16 @@ abstract class Living extends Entity implements Damageable{ if($this->dead !== true and $this->isInsideOfWater()){ $hasUpdate = true; - $this->airTicks -= $tickDiff; - if($this->airTicks <= -20){ - $this->airTicks = 0; + $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{ - $this->airTicks = 300; + $this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, 300); } if($this->attackTime > 0){ diff --git a/src/pocketmine/entity/PrimedTNT.php b/src/pocketmine/entity/PrimedTNT.php index e4df9d954..55f5f97c5 100644 --- a/src/pocketmine/entity/PrimedTNT.php +++ b/src/pocketmine/entity/PrimedTNT.php @@ -45,6 +45,8 @@ class PrimedTNT extends Entity implements Explosive{ public $canCollide = false; protected function initEntity(){ + parent::initEntity(); + if(isset($this->namedtag->Fuse)){ $this->fuse = $this->namedtag["Fuse"]; }else{ diff --git a/src/pocketmine/entity/Projectile.php b/src/pocketmine/entity/Projectile.php index c155f7b73..7c7547767 100644 --- a/src/pocketmine/entity/Projectile.php +++ b/src/pocketmine/entity/Projectile.php @@ -40,6 +40,8 @@ abstract class Projectile extends Entity{ private $hadCollision = false; protected function initEntity(){ + parent::initEntity(); + $this->setMaxHealth(1); $this->setHealth(1); if(isset($this->namedtag->Age)){ @@ -52,17 +54,6 @@ abstract class Projectile extends Entity{ return $entity instanceof Living and !$this->onGround; } - public function getData(){ - $flags = 0; - $flags |= $this->fireTicks > 0 ? 1 : 0; - - return [ - 0 => ["type" => 0, "value" => $flags], - 1 => ["type" => 1, "value" => $this->airTicks], - 16 => ["type" => 0, "value" => 0] //Is critical - ]; - } - public function saveNBT(){ parent::saveNBT(); $this->namedtag->Age = new Short("Age", $this->age); diff --git a/src/pocketmine/entity/Villager.php b/src/pocketmine/entity/Villager.php index 5c6f8b74c..0ba3c4979 100644 --- a/src/pocketmine/entity/Villager.php +++ b/src/pocketmine/entity/Villager.php @@ -68,21 +68,6 @@ class Villager extends Creature implements NPC, Ageable{ parent::spawnTo($player); } - public function getData(){ //TODO - $flags = 0; - $flags |= $this->fireTicks > 0 ? 1 : 0; - //$flags |= ($this->crouched === true ? 0b10:0) << 1; - //$flags |= ($this->inAction === true ? 0b10000:0); - $d = [ - 0 => ["type" => 0, "value" => $flags], - 1 => ["type" => 1, "value" => $this->airTicks], - 16 => ["type" => 0, "value" => 0], - 17 => ["type" => 6, "value" => [0, 0, 0]], - ]; - - return $d; - } - /** * Sets the villager profession * diff --git a/src/pocketmine/entity/Zombie.php b/src/pocketmine/entity/Zombie.php index 1b3d7fb27..a20670578 100644 --- a/src/pocketmine/entity/Zombie.php +++ b/src/pocketmine/entity/Zombie.php @@ -56,21 +56,6 @@ class Zombie extends Monster{ parent::spawnTo($player); } - public function getData(){ //TODO - $flags = 0; - $flags |= $this->fireTicks > 0 ? 1 : 0; - //$flags |= ($this->crouched === true ? 0b10:0) << 1; - //$flags |= ($this->inAction === true ? 0b10000:0); - $d = [ - 0 => ["type" => 0, "value" => $flags], - 1 => ["type" => 1, "value" => $this->airTicks], - 16 => ["type" => 0, "value" => 0], - 17 => ["type" => 6, "value" => [0, 0, 0]], - ]; - - return $d; - } - public function getDrops(){ $drops = [ ItemItem::get(ItemItem::FEATHER, 0, 1) diff --git a/src/pocketmine/utils/Binary.php b/src/pocketmine/utils/Binary.php index a948a4e43..9e6ba28e9 100644 --- a/src/pocketmine/utils/Binary.php +++ b/src/pocketmine/utils/Binary.php @@ -23,6 +23,7 @@ * Various Utilities used around the code */ namespace pocketmine\utils; +use pocketmine\entity\Entity; /** * WARNING: This class is available on the PocketMine-MP Zephir project. @@ -88,32 +89,32 @@ class Binary{ public static function writeMetadata(array $data){ $m = ""; foreach($data as $bottom => $d){ - $m .= chr(($d["type"] << 5) | ($bottom & 0x1F)); - switch($d["type"]){ - case 0: - $m .= self::writeByte($d["value"]); + $m .= chr(($d[0] << 5) | ($bottom & 0x1F)); + switch($d[0]){ + case Entity::DATA_TYPE_BYTE: + $m .= self::writeByte($d[1]); break; - case 1: - $m .= self::writeLShort($d["value"]); + case Entity::DATA_TYPE_SHORT: + $m .= self::writeLShort($d[1]); break; - case 2: - $m .= self::writeLInt($d["value"]); + case Entity::DATA_TYPE_INT: + $m .= self::writeLInt($d[1]); break; - case 3: - $m .= self::writeLFloat($d["value"]); + case Entity::DATA_TYPE_FLOAT: + $m .= self::writeLFloat($d[1]); break; - case 4: - $m .= self::writeLShort(strlen($d["value"])) . $d["value"]; + case Entity::DATA_TYPE_STRING: + $m .= self::writeLShort(strlen($d[1])) . $d[1]; break; - case 5: - $m .= self::writeLShort($d["value"][0]); - $m .= self::writeByte($d["value"][1]); - $m .= self::writeLShort($d["value"][2]); + case Entity::DATA_TYPE_SLOT: + $m .= self::writeLShort($d[1][0]); + $m .= self::writeByte($d[1][1]); + $m .= self::writeLShort($d[1][2]); break; - case 6: - $m .= self::writeLInt($d["value"][0]); - $m .= self::writeLInt($d["value"][1]); - $m .= self::writeLInt($d["value"][2]); + case Entity::DATA_TYPE_POS: + $m .= self::writeLInt($d[1][0]); + $m .= self::writeLInt($d[1][1]); + $m .= self::writeLInt($d[1][2]); break; } } @@ -140,29 +141,29 @@ class Binary{ $bottom = $b & 0x1F; $type = $b >> 5; switch($type){ - case 0: + case Entity::DATA_TYPE_BYTE: $r = self::readByte($value{$offset}); ++$offset; break; - case 1: + case Entity::DATA_TYPE_SHORT: $r = self::readLShort(substr($value, $offset, 2)); $offset += 2; break; - case 2: + case Entity::DATA_TYPE_INT: $r = self::readLInt(substr($value, $offset, 4)); $offset += 4; break; - case 3: + case Entity::DATA_TYPE_FLOAT: $r = self::readLFloat(substr($value, $offset, 4)); $offset += 4; break; - case 4: + case Entity::DATA_TYPE_STRING: $len = self::readLShort(substr($value, $offset, 2)); $offset += 2; $r = substr($value, $offset, $len); $offset += $len; break; - case 5: + case Entity::DATA_TYPE_SLOT: $r = []; $r[] = self::readLShort(substr($value, $offset, 2)); $offset += 2; @@ -171,7 +172,7 @@ class Binary{ $r[] = self::readLShort(substr($value, $offset, 2)); $offset += 2; break; - case 6: + case Entity::DATA_TYPE_POS: $r = []; for($i = 0; $i < 3; ++$i){ $r[] = self::readLInt(substr($value, $offset, 4)); @@ -183,7 +184,7 @@ class Binary{ } if($types === true){ - $m[$bottom] = ["value" => $r, "type" => $type]; + $m[$bottom] = [$r, $type]; }else{ $m[$bottom] = $r; }