mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-14 22:01:59 +00:00
Refactored entity metadata handling into its own class, with type-safe methods (#1876)
This includes several other changes, including: - SLOT data properties now accept items directly - POS data properties now accept floored Vector3s (in future this will be block positions) or null for 0,0,0 - VECTOR3F data properties now accept Vector3s or null for 0,0,0
This commit is contained in:
parent
8f928915d9
commit
2eb6e075ae
@ -1171,7 +1171,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
|
|
||||||
$this->sleeping = clone $pos;
|
$this->sleeping = clone $pos;
|
||||||
|
|
||||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [$pos->x, $pos->y, $pos->z]);
|
$this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, $pos);
|
||||||
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, true);
|
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, true);
|
||||||
|
|
||||||
$this->setSpawn($pos);
|
$this->setSpawn($pos);
|
||||||
@ -1190,7 +1190,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
|||||||
$this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $b));
|
$this->server->getPluginManager()->callEvent($ev = new PlayerBedLeaveEvent($this, $b));
|
||||||
|
|
||||||
$this->sleeping = null;
|
$this->sleeping = null;
|
||||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0]);
|
$this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null);
|
||||||
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false);
|
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false);
|
||||||
|
|
||||||
$this->level->setSleepTicks(0);
|
$this->level->setSleepTicks(0);
|
||||||
|
303
src/pocketmine/entity/DataPropertyManager.php
Normal file
303
src/pocketmine/entity/DataPropertyManager.php
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* ____ _ _ __ __ _ __ __ ____
|
||||||
|
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
|
||||||
|
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
|
||||||
|
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
|
||||||
|
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* @author PocketMine Team
|
||||||
|
* @link http://www.pocketmine.net/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace pocketmine\entity;
|
||||||
|
|
||||||
|
use pocketmine\math\Vector3;
|
||||||
|
|
||||||
|
class DataPropertyManager{
|
||||||
|
|
||||||
|
private $properties = [];
|
||||||
|
|
||||||
|
private $dirtyProperties = [];
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function getByte(int $key) : ?int{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_BYTE);
|
||||||
|
assert(is_int($value) or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param int $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setByte(int $key, int $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_BYTE, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function getShort(int $key) : ?int{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_SHORT);
|
||||||
|
assert(is_int($value) or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param int $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setShort(int $key, int $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_SHORT, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function getInt(int $key) : ?int{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_INT);
|
||||||
|
assert(is_int($value) or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param int $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setInt(int $key, int $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_INT, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return float|null
|
||||||
|
*/
|
||||||
|
public function getFloat(int $key) : ?float{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_FLOAT);
|
||||||
|
assert(is_float($value) or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param float $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setFloat(int $key, float $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_FLOAT, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public function getString(int $key) : ?string{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_STRING);
|
||||||
|
assert(is_string($value) or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param string $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setString(int $key, string $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_STRING, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return null|\pocketmine\item\Item
|
||||||
|
*/
|
||||||
|
public function getItem(int $key) : ?\pocketmine\item\Item{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_SLOT);
|
||||||
|
assert($value instanceof \pocketmine\item\Item or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param \pocketmine\item\Item $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setItem(int $key, \pocketmine\item\Item $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_SLOT, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return null|Vector3
|
||||||
|
*/
|
||||||
|
public function getBlockPos(int $key) : ?Vector3{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_POS);
|
||||||
|
assert($value instanceof Vector3 or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param null|Vector3 $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setBlockPos(int $key, ?Vector3 $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_POS, $value ? $value->floor() : null, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return int|null
|
||||||
|
*/
|
||||||
|
public function getLong(int $key) : ?int{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_LONG);
|
||||||
|
assert(is_int($value) or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param int $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setLong(int $key, int $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_LONG, $value, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return null|Vector3
|
||||||
|
*/
|
||||||
|
public function getVector3(int $key) : ?Vector3{
|
||||||
|
$value = $this->getPropertyValue($key, Entity::DATA_TYPE_VECTOR3F);
|
||||||
|
assert($value instanceof Vector3 or $value === null);
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param null|Vector3 $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setVector3(int $key, ?Vector3 $value, bool $force = false) : void{
|
||||||
|
$this->setPropertyValue($key, Entity::DATA_TYPE_VECTOR3F, $value ? $value->asVector3() : null, $force);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*/
|
||||||
|
public function removeProperty(int $key) : void{
|
||||||
|
unset($this->properties[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasProperty(int $key) : bool{
|
||||||
|
return isset($this->properties[$key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getPropertyType(int $key) : int{
|
||||||
|
if(isset($this->properties[$key])){
|
||||||
|
return $this->properties[$key][0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkType(int $key, int $type) : void{
|
||||||
|
if(isset($this->properties[$key]) and $this->properties[$key][0] !== $type){
|
||||||
|
throw new \RuntimeException("Expected type $type, but have " . $this->properties[$key][0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param int $type
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getPropertyValue(int $key, int $type){
|
||||||
|
if($type !== -1){
|
||||||
|
$this->checkType($key, $type);
|
||||||
|
}
|
||||||
|
return isset($this->properties[$key]) ? $this->properties[$key][1] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $key
|
||||||
|
* @param int $type
|
||||||
|
* @param mixed $value
|
||||||
|
* @param bool $force
|
||||||
|
*/
|
||||||
|
public function setPropertyValue(int $key, int $type, $value, bool $force = false) : void{
|
||||||
|
if(!$force){
|
||||||
|
$this->checkType($key, $type);
|
||||||
|
}
|
||||||
|
$this->properties[$key] = $this->dirtyProperties[$key] = [$type, $value];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all properties.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAll() : array{
|
||||||
|
return $this->properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns properties that have changed and need to be broadcasted.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getDirty() : array{
|
||||||
|
return $this->dirtyProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears records of dirty properties.
|
||||||
|
*/
|
||||||
|
public function clearDirtyProperties() : void{
|
||||||
|
$this->dirtyProperties = [];
|
||||||
|
}
|
||||||
|
}
|
@ -338,16 +338,8 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
/** @var int */
|
/** @var int */
|
||||||
protected $id;
|
protected $id;
|
||||||
|
|
||||||
protected $dataProperties = [
|
/** @var DataPropertyManager */
|
||||||
self::DATA_FLAGS => [self::DATA_TYPE_LONG, 0],
|
protected $propertyManager;
|
||||||
self::DATA_AIR => [self::DATA_TYPE_SHORT, 400],
|
|
||||||
self::DATA_MAX_AIR => [self::DATA_TYPE_SHORT, 400],
|
|
||||||
self::DATA_NAMETAG => [self::DATA_TYPE_STRING, ""],
|
|
||||||
self::DATA_LEAD_HOLDER_EID => [self::DATA_TYPE_LONG, -1],
|
|
||||||
self::DATA_SCALE => [self::DATA_TYPE_FLOAT, 1]
|
|
||||||
];
|
|
||||||
|
|
||||||
protected $changedDataProperties = [];
|
|
||||||
|
|
||||||
public $passenger = null;
|
public $passenger = null;
|
||||||
public $vehicle = null;
|
public $vehicle = null;
|
||||||
@ -524,12 +516,20 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
|
|
||||||
$this->fallDistance = $this->namedtag->getFloat("FallDistance", 0.0);
|
$this->fallDistance = $this->namedtag->getFloat("FallDistance", 0.0);
|
||||||
|
|
||||||
|
$this->propertyManager = new DataPropertyManager();
|
||||||
|
|
||||||
|
$this->propertyManager->setLong(self::DATA_FLAGS, 0);
|
||||||
|
$this->propertyManager->setShort(self::DATA_MAX_AIR, 400);
|
||||||
|
$this->propertyManager->setString(self::DATA_NAMETAG, "");
|
||||||
|
$this->propertyManager->setLong(self::DATA_LEAD_HOLDER_EID, -1);
|
||||||
|
$this->propertyManager->setFloat(self::DATA_SCALE, 1);
|
||||||
|
|
||||||
$this->fireTicks = $this->namedtag->getShort("Fire", 0);
|
$this->fireTicks = $this->namedtag->getShort("Fire", 0);
|
||||||
if($this->isOnFire()){
|
if($this->isOnFire()){
|
||||||
$this->setGenericFlag(self::DATA_FLAG_ONFIRE);
|
$this->setGenericFlag(self::DATA_FLAG_ONFIRE);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $this->namedtag->getShort("Air", 300), false);
|
$this->propertyManager->setShort(self::DATA_AIR, $this->namedtag->getShort("Air", 300));
|
||||||
$this->onGround = $this->namedtag->getByte("OnGround", 0) !== 0;
|
$this->onGround = $this->namedtag->getByte("OnGround", 0) !== 0;
|
||||||
$this->invulnerable = $this->namedtag->getByte("Invulnerable", 0) !== 0;
|
$this->invulnerable = $this->namedtag->getByte("Invulnerable", 0) !== 0;
|
||||||
|
|
||||||
@ -553,7 +553,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getNameTag(){
|
public function getNameTag(){
|
||||||
return $this->getDataProperty(self::DATA_NAMETAG);
|
return $this->propertyManager->getString(self::DATA_NAMETAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -575,7 +575,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
* @param string $name
|
* @param string $name
|
||||||
*/
|
*/
|
||||||
public function setNameTag($name){
|
public function setNameTag($name){
|
||||||
$this->setDataProperty(self::DATA_NAMETAG, self::DATA_TYPE_STRING, $name);
|
$this->propertyManager->setString(self::DATA_NAMETAG, $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -596,7 +596,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
* @return float
|
* @return float
|
||||||
*/
|
*/
|
||||||
public function getScale() : float{
|
public function getScale() : float{
|
||||||
return $this->getDataProperty(self::DATA_SCALE);
|
return $this->propertyManager->getFloat(self::DATA_SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -611,7 +611,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
|
|
||||||
$this->recalculateBoundingBox();
|
$this->recalculateBoundingBox();
|
||||||
|
|
||||||
$this->setDataProperty(self::DATA_SCALE, self::DATA_TYPE_FLOAT, $value);
|
$this->propertyManager->setFloat(self::DATA_SCALE, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBoundingBox(){
|
public function getBoundingBox(){
|
||||||
@ -706,7 +706,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
* @return int|null
|
* @return int|null
|
||||||
*/
|
*/
|
||||||
public function getOwningEntityId(){
|
public function getOwningEntityId(){
|
||||||
return $this->getDataProperty(self::DATA_OWNER_EID);
|
return $this->propertyManager->getLong(self::DATA_OWNER_EID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -731,11 +731,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
*/
|
*/
|
||||||
public function setOwningEntity(Entity $owner = null){
|
public function setOwningEntity(Entity $owner = null){
|
||||||
if($owner === null){
|
if($owner === null){
|
||||||
$this->removeDataProperty(self::DATA_OWNER_EID);
|
$this->propertyManager->removeProperty(self::DATA_OWNER_EID);
|
||||||
}elseif($owner->closed){
|
}elseif($owner->closed){
|
||||||
throw new \InvalidArgumentException("Supplied owning entity is garbage and cannot be used");
|
throw new \InvalidArgumentException("Supplied owning entity is garbage and cannot be used");
|
||||||
}else{
|
}else{
|
||||||
$this->setDataProperty(self::DATA_OWNER_EID, self::DATA_TYPE_LONG, $owner->getId());
|
$this->propertyManager->setLong(self::DATA_OWNER_EID, $owner->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,7 +744,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
* @return int|null
|
* @return int|null
|
||||||
*/
|
*/
|
||||||
public function getTargetEntityId(){
|
public function getTargetEntityId(){
|
||||||
return $this->getDataProperty(self::DATA_TARGET_EID);
|
return $this->propertyManager->getLong(self::DATA_TARGET_EID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -771,11 +771,11 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
*/
|
*/
|
||||||
public function setTargetEntity(Entity $target = null){
|
public function setTargetEntity(Entity $target = null){
|
||||||
if($target === null){
|
if($target === null){
|
||||||
$this->removeDataProperty(self::DATA_TARGET_EID);
|
$this->propertyManager->removeProperty(self::DATA_TARGET_EID);
|
||||||
}elseif($target->closed){
|
}elseif($target->closed){
|
||||||
throw new \InvalidArgumentException("Supplied target entity is garbage and cannot be used");
|
throw new \InvalidArgumentException("Supplied target entity is garbage and cannot be used");
|
||||||
}else{
|
}else{
|
||||||
$this->setDataProperty(self::DATA_TARGET_EID, self::DATA_TYPE_LONG, $target->getId());
|
$this->propertyManager->setLong(self::DATA_TARGET_EID, $target->getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,7 +841,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
|
|
||||||
$this->namedtag->setFloat("FallDistance", $this->fallDistance);
|
$this->namedtag->setFloat("FallDistance", $this->fallDistance);
|
||||||
$this->namedtag->setShort("Fire", $this->fireTicks);
|
$this->namedtag->setShort("Fire", $this->fireTicks);
|
||||||
$this->namedtag->setShort("Air", $this->getDataProperty(self::DATA_AIR));
|
$this->namedtag->setShort("Air", $this->propertyManager->getShort(self::DATA_AIR));
|
||||||
$this->namedtag->setByte("OnGround", $this->onGround ? 1 : 0);
|
$this->namedtag->setByte("OnGround", $this->onGround ? 1 : 0);
|
||||||
$this->namedtag->setByte("Invulnerable", $this->invulnerable ? 1 : 0);
|
$this->namedtag->setByte("Invulnerable", $this->invulnerable ? 1 : 0);
|
||||||
}
|
}
|
||||||
@ -971,9 +971,10 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
|
|
||||||
$this->justCreated = false;
|
$this->justCreated = false;
|
||||||
|
|
||||||
if(count($this->changedDataProperties) > 0){
|
$changedProperties = $this->propertyManager->getDirty();
|
||||||
$this->sendData($this->hasSpawned, $this->changedDataProperties);
|
if(!empty($changedProperties)){
|
||||||
$this->changedDataProperties = [];
|
$this->sendData($this->hasSpawned, $changedProperties);
|
||||||
|
$this->propertyManager->clearDirtyProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
$hasUpdate = false;
|
$hasUpdate = false;
|
||||||
@ -1899,7 +1900,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
$pk->yaw = $this->yaw;
|
$pk->yaw = $this->yaw;
|
||||||
$pk->pitch = $this->pitch;
|
$pk->pitch = $this->pitch;
|
||||||
$pk->attributes = $this->attributeMap->getAll();
|
$pk->attributes = $this->attributeMap->getAll();
|
||||||
$pk->metadata = $this->dataProperties;
|
$pk->metadata = $this->propertyManager->getAll();
|
||||||
|
|
||||||
$player->dataPacket($pk);
|
$player->dataPacket($pk);
|
||||||
}
|
}
|
||||||
@ -2001,49 +2002,6 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $id
|
|
||||||
* @param int $type
|
|
||||||
* @param mixed $value
|
|
||||||
* @param bool $send
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function setDataProperty(int $id, int $type, $value, bool $send = true) : bool{
|
|
||||||
if($this->getDataProperty($id) !== $value){
|
|
||||||
$this->dataProperties[$id] = [$type, $value];
|
|
||||||
if($send){
|
|
||||||
$this->changedDataProperties[$id] = $this->dataProperties[$id]; //This will be sent on the next tick
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $id
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getDataProperty(int $id){
|
|
||||||
return isset($this->dataProperties[$id]) ? $this->dataProperties[$id][1] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function removeDataProperty(int $id){
|
|
||||||
unset($this->dataProperties[$id]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $id
|
|
||||||
*
|
|
||||||
* @return int|null
|
|
||||||
*/
|
|
||||||
public function getDataPropertyType(int $id){
|
|
||||||
return isset($this->dataProperties[$id]) ? $this->dataProperties[$id][0] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $propertyId
|
* @param int $propertyId
|
||||||
* @param int $flagId
|
* @param int $flagId
|
||||||
@ -2052,9 +2010,9 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
*/
|
*/
|
||||||
public function setDataFlag(int $propertyId, int $flagId, bool $value = true, int $propertyType = self::DATA_TYPE_LONG){
|
public function setDataFlag(int $propertyId, int $flagId, bool $value = true, int $propertyType = self::DATA_TYPE_LONG){
|
||||||
if($this->getDataFlag($propertyId, $flagId) !== $value){
|
if($this->getDataFlag($propertyId, $flagId) !== $value){
|
||||||
$flags = (int) $this->getDataProperty($propertyId);
|
$flags = (int) $this->propertyManager->getPropertyValue($propertyId, $propertyType);
|
||||||
$flags ^= 1 << $flagId;
|
$flags ^= 1 << $flagId;
|
||||||
$this->setDataProperty($propertyId, $propertyType, $flags);
|
$this->propertyManager->setPropertyValue($propertyId, $propertyType, $flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2065,7 +2023,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getDataFlag(int $propertyId, int $flagId) : bool{
|
public function getDataFlag(int $propertyId, int $flagId) : bool{
|
||||||
return (((int) $this->getDataProperty($propertyId)) & (1 << $flagId)) > 0;
|
return (((int) $this->propertyManager->getPropertyValue($propertyId, -1)) & (1 << $flagId)) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2099,7 +2057,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
|||||||
|
|
||||||
$pk = new SetEntityDataPacket();
|
$pk = new SetEntityDataPacket();
|
||||||
$pk->entityRuntimeId = $this->getId();
|
$pk->entityRuntimeId = $this->getId();
|
||||||
$pk->metadata = $data ?? $this->dataProperties;
|
$pk->metadata = $data ?? $this->propertyManager->getAll();
|
||||||
|
|
||||||
foreach($player as $p){
|
foreach($player as $p){
|
||||||
if($p === $this){
|
if($p === $this){
|
||||||
|
@ -71,7 +71,7 @@ class FallingSand extends Entity{
|
|||||||
|
|
||||||
$this->block = BlockFactory::get($blockId, $damage);
|
$this->block = BlockFactory::get($blockId, $damage);
|
||||||
|
|
||||||
$this->setDataProperty(self::DATA_VARIANT, self::DATA_TYPE_INT, $this->block->getId() | ($this->block->getDamage() << 8));
|
$this->propertyManager->setInt(self::DATA_VARIANT, $this->block->getId() | ($this->block->getDamage() << 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function canCollideWith(Entity $entity) : bool{
|
public function canCollideWith(Entity $entity) : bool{
|
||||||
|
@ -496,7 +496,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
protected function initEntity(){
|
protected function initEntity(){
|
||||||
|
|
||||||
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false);
|
$this->setPlayerFlag(self::DATA_PLAYER_FLAG_SLEEP, false);
|
||||||
$this->setDataProperty(self::DATA_PLAYER_BED_POSITION, self::DATA_TYPE_POS, [0, 0, 0], false);
|
$this->propertyManager->setBlockPos(self::DATA_PLAYER_BED_POSITION, null);
|
||||||
|
|
||||||
$this->inventory = new PlayerInventory($this);
|
$this->inventory = new PlayerInventory($this);
|
||||||
$this->enderChestInventory = new EnderChestInventory($this);
|
$this->enderChestInventory = new EnderChestInventory($this);
|
||||||
@ -705,7 +705,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
|||||||
$pk->yaw = $this->yaw;
|
$pk->yaw = $this->yaw;
|
||||||
$pk->pitch = $this->pitch;
|
$pk->pitch = $this->pitch;
|
||||||
$pk->item = $this->getInventory()->getItemInHand();
|
$pk->item = $this->getInventory()->getItemInHand();
|
||||||
$pk->metadata = $this->dataProperties;
|
$pk->metadata = $this->propertyManager->getAll();
|
||||||
$player->dataPacket($pk);
|
$player->dataPacket($pk);
|
||||||
|
|
||||||
$this->inventory->sendArmorContents($player);
|
$this->inventory->sendArmorContents($player);
|
||||||
|
@ -200,7 +200,7 @@ class Item extends Entity{
|
|||||||
$pk->position = $this->asVector3();
|
$pk->position = $this->asVector3();
|
||||||
$pk->motion = $this->getMotion();
|
$pk->motion = $this->getMotion();
|
||||||
$pk->item = $this->getItem();
|
$pk->item = $this->getItem();
|
||||||
$pk->metadata = $this->dataProperties;
|
$pk->metadata = $this->propertyManager->getAll();
|
||||||
|
|
||||||
$player->dataPacket($pk);
|
$player->dataPacket($pk);
|
||||||
}
|
}
|
||||||
|
@ -297,11 +297,11 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($colors)){
|
if(!empty($colors)){
|
||||||
$this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, Color::mix(...$colors)->toARGB());
|
$this->propertyManager->setInt(Entity::DATA_POTION_COLOR, Color::mix(...$colors)->toARGB());
|
||||||
$this->setDataProperty(Entity::DATA_POTION_AMBIENT, Entity::DATA_TYPE_BYTE, $ambient ? 1 : 0);
|
$this->propertyManager->setByte(Entity::DATA_POTION_AMBIENT, $ambient ? 1 : 0);
|
||||||
}else{
|
}else{
|
||||||
$this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, 0);
|
$this->propertyManager->setInt(Entity::DATA_POTION_COLOR, 0);
|
||||||
$this->setDataProperty(Entity::DATA_POTION_AMBIENT, Entity::DATA_TYPE_BYTE, 0);
|
$this->propertyManager->setByte(Entity::DATA_POTION_AMBIENT, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,7 +619,7 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getAirSupplyTicks() : int{
|
public function getAirSupplyTicks() : int{
|
||||||
return $this->getDataProperty(self::DATA_AIR);
|
return $this->propertyManager->getShort(self::DATA_AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -627,7 +627,7 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
* @param int $ticks
|
* @param int $ticks
|
||||||
*/
|
*/
|
||||||
public function setAirSupplyTicks(int $ticks){
|
public function setAirSupplyTicks(int $ticks){
|
||||||
$this->setDataProperty(self::DATA_AIR, self::DATA_TYPE_SHORT, $ticks);
|
$this->propertyManager->setShort(self::DATA_AIR, $ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -635,7 +635,7 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function getMaxAirSupplyTicks() : int{
|
public function getMaxAirSupplyTicks() : int{
|
||||||
return $this->getDataProperty(self::DATA_MAX_AIR);
|
return $this->propertyManager->getShort(self::DATA_MAX_AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -643,7 +643,7 @@ abstract class Living extends Entity implements Damageable{
|
|||||||
* @param int $ticks
|
* @param int $ticks
|
||||||
*/
|
*/
|
||||||
public function setMaxAirSupplyTicks(int $ticks){
|
public function setMaxAirSupplyTicks(int $ticks){
|
||||||
$this->setDataProperty(self::DATA_MAX_AIR, self::DATA_TYPE_SHORT, $ticks);
|
$this->propertyManager->setShort(self::DATA_MAX_AIR, $ticks);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +61,7 @@ class PrimedTNT extends Entity implements Explosive{
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->setGenericFlag(self::DATA_FLAG_IGNITED, true);
|
$this->setGenericFlag(self::DATA_FLAG_IGNITED, true);
|
||||||
$this->setDataProperty(self::DATA_FUSE_LENGTH, self::DATA_TYPE_INT, $this->fuse);
|
$this->propertyManager->setInt(self::DATA_FUSE_LENGTH, $this->fuse);
|
||||||
|
|
||||||
$this->level->broadcastLevelEvent($this, LevelEventPacket::EVENT_SOUND_IGNITE);
|
$this->level->broadcastLevelEvent($this, LevelEventPacket::EVENT_SOUND_IGNITE);
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ class PrimedTNT extends Entity implements Explosive{
|
|||||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||||
|
|
||||||
if($this->fuse % 5 === 0){ //don't spam it every tick, it's not necessary
|
if($this->fuse % 5 === 0){ //don't spam it every tick, it's not necessary
|
||||||
$this->setDataProperty(self::DATA_FUSE_LENGTH, self::DATA_TYPE_INT, $this->fuse);
|
$this->propertyManager->setInt(self::DATA_FUSE_LENGTH, $this->fuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$this->isFlaggedForDespawn()){
|
if(!$this->isFlaggedForDespawn()){
|
||||||
|
@ -63,11 +63,11 @@ class Villager extends Creature implements NPC, Ageable{
|
|||||||
* @param int $profession
|
* @param int $profession
|
||||||
*/
|
*/
|
||||||
public function setProfession(int $profession){
|
public function setProfession(int $profession){
|
||||||
$this->setDataProperty(self::DATA_VARIANT, self::DATA_TYPE_INT, $profession);
|
$this->propertyManager->setInt(self::DATA_VARIANT, $profession);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getProfession() : int{
|
public function getProfession() : int{
|
||||||
return $this->getDataProperty(self::DATA_VARIANT);
|
return $this->propertyManager->getInt(self::DATA_VARIANT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isBaby() : bool{
|
public function isBaby() : bool{
|
||||||
|
@ -153,23 +153,17 @@ class NetworkBinaryStream extends BinaryStream{
|
|||||||
$value = $this->getString();
|
$value = $this->getString();
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_SLOT:
|
case Entity::DATA_TYPE_SLOT:
|
||||||
//TODO: use objects directly
|
$value = $this->getSlot();
|
||||||
$value = [];
|
|
||||||
$item = $this->getSlot();
|
|
||||||
$value[0] = $item->getId();
|
|
||||||
$value[1] = $item->getCount();
|
|
||||||
$value[2] = $item->getDamage();
|
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_POS:
|
case Entity::DATA_TYPE_POS:
|
||||||
$value = [0, 0, 0];
|
$value = new Vector3();
|
||||||
$this->getSignedBlockPosition(...$value);
|
$this->getSignedBlockPosition($value->x, $value->y, $value->z);
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_LONG:
|
case Entity::DATA_TYPE_LONG:
|
||||||
$value = $this->getVarLong();
|
$value = $this->getVarLong();
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_VECTOR3F:
|
case Entity::DATA_TYPE_VECTOR3F:
|
||||||
$value = [0.0, 0.0, 0.0];
|
$value = $this->getVector3Obj();
|
||||||
$this->getVector3f(...$value);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$value = [];
|
$value = [];
|
||||||
@ -211,19 +205,21 @@ class NetworkBinaryStream extends BinaryStream{
|
|||||||
$this->putString($d[1]);
|
$this->putString($d[1]);
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_SLOT:
|
case Entity::DATA_TYPE_SLOT:
|
||||||
//TODO: change this implementation (use objects)
|
$this->putSlot($d[1]);
|
||||||
$this->putSlot(ItemFactory::get($d[1][0], $d[1][2], $d[1][1])); //ID, damage, count
|
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_POS:
|
case Entity::DATA_TYPE_POS:
|
||||||
//TODO: change this implementation (use objects)
|
$v = $d[1];
|
||||||
$this->putSignedBlockPosition(...$d[1]);
|
if($v !== null){
|
||||||
|
$this->putSignedBlockPosition($v->x, $v->y, $v->z);
|
||||||
|
}else{
|
||||||
|
$this->putSignedBlockPosition(0, 0, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_LONG:
|
case Entity::DATA_TYPE_LONG:
|
||||||
$this->putVarLong($d[1]);
|
$this->putVarLong($d[1]);
|
||||||
break;
|
break;
|
||||||
case Entity::DATA_TYPE_VECTOR3F:
|
case Entity::DATA_TYPE_VECTOR3F:
|
||||||
//TODO: change this implementation (use objects)
|
$this->putVector3ObjNullable($d[1]);
|
||||||
$this->putVector3f(...$d[1]); //x, y, z
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,6 @@ use pocketmine\network\mcpe\NetworkBinaryStream;
|
|||||||
use pocketmine\network\mcpe\NetworkSession;
|
use pocketmine\network\mcpe\NetworkSession;
|
||||||
use pocketmine\utils\Utils;
|
use pocketmine\utils\Utils;
|
||||||
|
|
||||||
|
|
||||||
abstract class DataPacket extends NetworkBinaryStream{
|
abstract class DataPacket extends NetworkBinaryStream{
|
||||||
|
|
||||||
public const NETWORK_ID = 0;
|
public const NETWORK_ID = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user