mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
New way to spawn entities/tiles using a global register table, allow overriding default entity/tile classes via classes
This commit is contained in:
parent
a5b85c549a
commit
34ae760def
@ -24,7 +24,7 @@ namespace pocketmine;
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\DroppedItem;
|
||||
use pocketmine\entity\Item as DroppedItem;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\Living;
|
||||
@ -1650,7 +1650,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
]);
|
||||
|
||||
$f = 1.5;
|
||||
$snowball = new Snowball($this->chunk, $nbt, $this);
|
||||
$snowball = Entity::createEntity("Snowball", $this->chunk, $nbt, $this);
|
||||
$snowball->setMotion($snowball->getMotion()->multiply($f));
|
||||
if($this->isSurvival()){
|
||||
$this->inventory->removeItem(Item::get(Item::SNOWBALL, 0, 1));
|
||||
@ -1709,7 +1709,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
]);
|
||||
|
||||
$f = 1.5;
|
||||
$ev = EntityShootBowEvent::createEvent($this, $bow, new Arrow($this->chunk, $nbt, $this), $f);
|
||||
$ev = EntityShootBowEvent::createEvent($this, $bow, Entity::createEntity("Arrow", $this->chunk, $nbt, $this), $f);
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
|
||||
|
@ -31,12 +31,21 @@ use pocketmine\command\CommandSender;
|
||||
use pocketmine\command\ConsoleCommandSender;
|
||||
use pocketmine\command\PluginIdentifiableCommand;
|
||||
use pocketmine\command\SimpleCommandMap;
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\FallingSand;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\PrimedTNT;
|
||||
use pocketmine\entity\Snowball;
|
||||
use pocketmine\entity\Villager;
|
||||
use pocketmine\entity\Zombie;
|
||||
use pocketmine\event\Event;
|
||||
use pocketmine\event\HandlerList;
|
||||
use pocketmine\event\level\LevelInitEvent;
|
||||
use pocketmine\event\level\LevelLoadEvent;
|
||||
use pocketmine\event\server\ServerCommandEvent;
|
||||
use pocketmine\event\Timings;
|
||||
use pocketmine\entity\Item as DroppedItem;
|
||||
use pocketmine\event\TimingsHandler;
|
||||
use pocketmine\inventory\CraftingManager;
|
||||
use pocketmine\inventory\InventoryType;
|
||||
@ -82,6 +91,10 @@ use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\scheduler\CallbackTask;
|
||||
use pocketmine\scheduler\SendUsageTask;
|
||||
use pocketmine\scheduler\ServerScheduler;
|
||||
use pocketmine\tile\Chest;
|
||||
use pocketmine\tile\Furnace;
|
||||
use pocketmine\tile\Sign;
|
||||
use pocketmine\tile\Tile;
|
||||
use pocketmine\updater\AutoUpdater;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\Cache;
|
||||
@ -1553,6 +1566,9 @@ class Server{
|
||||
$this->consoleSender = new ConsoleCommandSender();
|
||||
$this->commandMap = new SimpleCommandMap($this);
|
||||
|
||||
$this->registerEntities();
|
||||
$this->registerTiles();
|
||||
|
||||
InventoryType::init();
|
||||
Block::init();
|
||||
Item::init();
|
||||
@ -2142,4 +2158,22 @@ class Server{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function registerEntities(){
|
||||
Entity::registerEntity(Arrow::class);
|
||||
Entity::registerEntity(DroppedItem::class);
|
||||
Entity::registerEntity(FallingSand::class);
|
||||
Entity::registerEntity(PrimedTNT::class);
|
||||
Entity::registerEntity(Snowball::class);
|
||||
Entity::registerEntity(Villager::class);
|
||||
Entity::registerEntity(Zombie::class);
|
||||
|
||||
Entity::registerEntity(Human::class, true);
|
||||
}
|
||||
|
||||
private function registerTiles(){
|
||||
Tile::registerTile(Chest::class);
|
||||
Tile::registerTile(Furnace::class);
|
||||
Tile::registerTile(Sign::class);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ class BurningFurnace extends Solid{
|
||||
new Int("z", $this->z)
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
new Furnace($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -81,7 +81,7 @@ class BurningFurnace extends Solid{
|
||||
new Int("z", $this->z)
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$furnace = new Furnace($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$furnace = Tile::createTile("Furnace", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
}
|
||||
|
||||
if(($player->getGamemode() & 0x01) === 0x01){
|
||||
|
@ -90,9 +90,9 @@ class Chest extends Transparent{
|
||||
new Int("z", $this->z)
|
||||
]);
|
||||
$nbt->Items->setTagType(NBT::TAG_Compound);
|
||||
$tile = new TileChest($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
$tile = Tile::createTile("Chest", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), $nbt);
|
||||
|
||||
if($chest instanceof TileChest){
|
||||
if($chest instanceof TileChest and $tile instanceof TileChest){
|
||||
$chest->pairWith($tile);
|
||||
$tile->pairWith($chest);
|
||||
}
|
||||
|
@ -21,7 +21,8 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\FallingBlock;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\FallingSand;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
@ -46,7 +47,7 @@ abstract class Fallable extends Solid{
|
||||
if($this->hasPhysics === true and $type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::AIR or ($down instanceof Liquid)){
|
||||
$fall = new FallingBlock($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
|
||||
$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),
|
||||
@ -67,8 +68,6 @@ abstract class Fallable extends Solid{
|
||||
|
||||
$fall->spawnToAll();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\PrimedTNT;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
@ -44,7 +45,7 @@ class TNT extends Solid{
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
|
||||
$mot = (new Random())->nextSignedFloat() * M_PI * 2;
|
||||
$tnt = new PrimedTNT($this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
|
||||
$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),
|
||||
|
@ -62,9 +62,12 @@ use pocketmine\Server;
|
||||
|
||||
abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
|
||||
const NETWORK_ID = -1;
|
||||
|
||||
public static $entityCount = 1;
|
||||
/** @var Entity[] */
|
||||
private static $knownEntities = [];
|
||||
|
||||
/**
|
||||
* @var Player[]
|
||||
@ -219,6 +222,39 @@ abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $type
|
||||
* @param FullChunk $chunk
|
||||
* @param Compound $nbt
|
||||
* @param $args
|
||||
*
|
||||
* @return Entity
|
||||
*/
|
||||
public static function createEntity($type, FullChunk $chunk, Compound $nbt, ...$args){
|
||||
if(isset(self::$knownEntities[$type])){
|
||||
$class = self::$knownEntities[$type];
|
||||
return new $class($chunk, $nbt, ...$args);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function registerEntity($className, $force = false){
|
||||
$class = new \ReflectionClass($className);
|
||||
if(is_a($className, Entity::class, true) and !$class->isAbstract()){
|
||||
if($className::NETWORK_ID !== -1){
|
||||
self::$knownEntities[$className::NETWORK_ID] = $className;
|
||||
}elseif(!$force){
|
||||
return false;
|
||||
}
|
||||
|
||||
self::$knownEntities[$class->getShortName()] = $className;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function saveNBT(){
|
||||
$this->namedtag->Pos = new Enum("Pos", [
|
||||
new Double(0, $this->x),
|
||||
|
@ -35,8 +35,7 @@ use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FallingBlock extends Entity{
|
||||
|
||||
class FallingSand extends Entity{
|
||||
const NETWORK_ID = 66;
|
||||
|
||||
public $width = 0.98;
|
||||
@ -54,8 +53,7 @@ class FallingBlock extends Entity{
|
||||
$this->namedtag->id = new String("id", "FallingSand");
|
||||
if(isset($this->namedtag->TileID)){
|
||||
$this->blockId = $this->namedtag["TileID"];
|
||||
}
|
||||
elseif(isset($this->namedtag->Tile)){
|
||||
}elseif(isset($this->namedtag->Tile)){
|
||||
$this->blockId = $this->namedtag["Tile"];
|
||||
$this->namedtag["TileID"] = new Int("TileID", $this->blockId);
|
||||
}
|
||||
@ -151,7 +149,7 @@ class FallingBlock extends Entity{
|
||||
|
||||
public function spawnTo(Player $player){
|
||||
$pk = AddEntityPacket::getFromPool();
|
||||
$pk->type = FallingBlock::NETWORK_ID;
|
||||
$pk->type = FallingSand::NETWORK_ID;
|
||||
$pk->eid = $this->getID();
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
@ -25,7 +25,7 @@ use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\EntityRegainHealthEvent;
|
||||
use pocketmine\event\entity\ItemDespawnEvent;
|
||||
use pocketmine\event\entity\ItemSpawnEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\Byte;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
@ -35,12 +35,13 @@ use pocketmine\network\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class DroppedItem extends Entity{
|
||||
class Item extends Entity{
|
||||
const NETWORK_ID = 64;
|
||||
|
||||
protected $owner = null;
|
||||
protected $thrower = null;
|
||||
protected $pickupDelay = 0;
|
||||
/** @var Item */
|
||||
/** @var ItemItem */
|
||||
protected $item;
|
||||
|
||||
public $width = 0.25;
|
||||
@ -67,7 +68,7 @@ class DroppedItem extends Entity{
|
||||
if(isset($this->namedtag->Thrower)){
|
||||
$this->thrower = $this->namedtag["Thrower"];
|
||||
}
|
||||
$this->item = Item::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]);
|
||||
$this->item = ItemItem::get($this->namedtag->Item["id"], $this->namedtag->Item["Damage"], $this->namedtag->Item["Count"]);
|
||||
|
||||
|
||||
$this->server->getPluginManager()->callEvent(ItemSpawnEvent::createEvent($this));
|
||||
@ -166,7 +167,7 @@ class DroppedItem extends Entity{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Item
|
||||
* @return ItemItem
|
||||
*/
|
||||
public function getItem(){
|
||||
return $this->item;
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\event\entity;
|
||||
|
||||
use pocketmine\entity\Creature;
|
||||
use pocketmine\entity\DroppedItem;
|
||||
use pocketmine\entity\Item;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\Projectile;
|
||||
@ -85,7 +85,7 @@ class EntityDespawnEvent extends EntityEvent{
|
||||
* @return bool
|
||||
*/
|
||||
public function isItem(){
|
||||
return $this->entity instanceof DroppedItem;
|
||||
return $this->entity instanceof Item;
|
||||
}
|
||||
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\event\entity;
|
||||
|
||||
use pocketmine\entity\Creature;
|
||||
use pocketmine\entity\DroppedItem;
|
||||
use pocketmine\entity\Item;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\entity\Projectile;
|
||||
@ -92,7 +92,7 @@ class EntitySpawnEvent extends EntityEvent{
|
||||
* @return bool
|
||||
*/
|
||||
public function isItem(){
|
||||
return $this->entity instanceof DroppedItem;
|
||||
return $this->entity instanceof Item;
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
|
||||
namespace pocketmine\event\entity;
|
||||
|
||||
use pocketmine\entity\DroppedItem;
|
||||
use pocketmine\entity\Item;
|
||||
use pocketmine\event\Cancellable;
|
||||
|
||||
class ItemDespawnEvent extends EntityEvent implements Cancellable{
|
||||
@ -30,15 +30,15 @@ class ItemDespawnEvent extends EntityEvent implements Cancellable{
|
||||
public static $nextEvent = 0;
|
||||
|
||||
/**
|
||||
* @param DroppedItem $item
|
||||
* @param Item $item
|
||||
*/
|
||||
public function __construct(DroppedItem $item){
|
||||
public function __construct(Item $item){
|
||||
$this->entity = $item;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DroppedItem
|
||||
* @return Item
|
||||
*/
|
||||
public function getEntity(){
|
||||
return $this->entity;
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
namespace pocketmine\event\entity;
|
||||
|
||||
use pocketmine\entity\DroppedItem;
|
||||
use pocketmine\entity\Item;
|
||||
|
||||
class ItemSpawnEvent extends EntityEvent{
|
||||
public static $handlerList = null;
|
||||
@ -29,15 +29,15 @@ class ItemSpawnEvent extends EntityEvent{
|
||||
public static $nextEvent = 0;
|
||||
|
||||
/**
|
||||
* @param DroppedItem $item
|
||||
* @param Item $item
|
||||
*/
|
||||
public function __construct(DroppedItem $item){
|
||||
public function __construct(Item $item){
|
||||
$this->entity = $item;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DroppedItem
|
||||
* @return Item
|
||||
*/
|
||||
public function getEntity(){
|
||||
return $this->entity;
|
||||
|
@ -66,37 +66,10 @@ class SpawnEgg extends Item{
|
||||
]),
|
||||
]);
|
||||
|
||||
switch($this->meta){
|
||||
case Villager::NETWORK_ID:
|
||||
$nbt->Health = new Short("Health", 20);
|
||||
$entity = new Villager($chunk, $nbt);
|
||||
break;
|
||||
case Zombie::NETWORK_ID:
|
||||
$nbt->Health = new Short("Health", 20);
|
||||
$entity = new Zombie($chunk, $nbt);
|
||||
break;
|
||||
/*
|
||||
//TODO: use entity constants
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
$data = array(
|
||||
"x" => $block->x + 0.5,
|
||||
"y" => $block->y,
|
||||
"z" => $block->z + 0.5,
|
||||
);
|
||||
//$e = Server::getInstance()->api->entity->add($block->level, ENTITY_MOB, $this->meta, $data);
|
||||
//Server::getInstance()->api->entity->spawnToAll($e);
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
--$this->count;
|
||||
}
|
||||
|
||||
return true;*/
|
||||
}
|
||||
$entity = Entity::createEntity($this->meta, $chunk, $nbt);
|
||||
|
||||
if($entity instanceof Entity){
|
||||
if(($player->gamemode & 0x01) === 0){
|
||||
if($player->isSurvival()){
|
||||
--$this->count;
|
||||
}
|
||||
$entity->spawnToAll();
|
||||
|
@ -191,7 +191,7 @@ class Explosion{
|
||||
|
||||
if($block instanceof TNT){
|
||||
$mot = (new Random())->nextSignedFloat() * M_PI * 2;
|
||||
$tnt = new PrimedTNT($this->level->getChunk($block->x >> 4, $block->z >> 4), new Compound("", [
|
||||
$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),
|
||||
|
@ -45,7 +45,7 @@ use pocketmine\block\SnowLayer;
|
||||
use pocketmine\block\Sugarcane;
|
||||
use pocketmine\block\Wheat;
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\DroppedItem;
|
||||
use pocketmine\entity\Item as DroppedItem;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\event\block\BlockBreakEvent;
|
||||
use pocketmine\event\block\BlockPlaceEvent;
|
||||
@ -1000,7 +1000,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
public function dropItem(Vector3 $source, Item $item, Vector3 $motion = null, $delay = 10){
|
||||
$motion = $motion === null ? Vector3::createVector(lcg_value() * 0.2 - 0.1, 0.2, lcg_value() * 0.2 - 0.1) : $motion;
|
||||
if($item->getID() > 0 and $item->getCount() > 0){
|
||||
$itemEntity = new DroppedItem($this->getChunk($source->getX() >> 4, $source->getZ() >> 4), new Compound("", [
|
||||
$itemEntity = Entity::createEntity("Item", $this->getChunk($source->getX() >> 4, $source->getZ() >> 4), new Compound("", [
|
||||
"Pos" => new Enum("Pos", [
|
||||
new Double("", $source->getX()),
|
||||
new Double("", $source->getY()),
|
||||
@ -1233,7 +1233,7 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
if($hand->getID() === Item::SIGN_POST or $hand->getID() === Item::WALL_SIGN){
|
||||
$tile = new Sign($this->getChunk($block->x >> 4, $block->z >> 4), new Compound(false, [
|
||||
$tile = Tile::createTile("Sign", $this->getChunk($block->x >> 4, $block->z >> 4), new Compound(false, [
|
||||
"id" => new String("id", Tile::SIGN),
|
||||
"x" => new Int("x", $block->x),
|
||||
"y" => new Int("y", $block->y),
|
||||
|
@ -21,10 +21,7 @@
|
||||
|
||||
namespace pocketmine\level\format\generic;
|
||||
|
||||
use pocketmine\entity\Arrow;
|
||||
use pocketmine\entity\DroppedItem;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\FallingBlock;
|
||||
use pocketmine\level\format\FullChunk;
|
||||
use pocketmine\level\format\LevelProvider;
|
||||
use pocketmine\nbt\tag\Compound;
|
||||
@ -116,27 +113,20 @@ abstract class BaseFullChunk implements FullChunk{
|
||||
foreach($this->NBTentities as $nbt){
|
||||
if($nbt instanceof Compound){
|
||||
if(!isset($nbt->id)){
|
||||
$this->setChanged();
|
||||
continue;
|
||||
}
|
||||
|
||||
if(($nbt["Pos"][0] >> 4) !== $this->x or ($nbt["Pos"][2] >> 4) !== $this->z){
|
||||
$this->setChanged();
|
||||
continue; //Fixes entities allocated in wrong chunks.
|
||||
}
|
||||
|
||||
//TODO: add all entities
|
||||
switch($nbt["id"]){
|
||||
case DroppedItem::NETWORK_ID:
|
||||
case "Item":
|
||||
(new DroppedItem($this, $nbt))->spawnToAll();
|
||||
break;
|
||||
case Arrow::NETWORK_ID:
|
||||
case "Arrow":
|
||||
(new Arrow($this, $nbt))->spawnToAll();
|
||||
break;
|
||||
case FallingBlock::NETWORK_ID:
|
||||
case "FallingSand":
|
||||
(new FallingBlock($this, $nbt))->spawnToAll();
|
||||
break;
|
||||
if(($entity = Entity::createEntity($nbt["id"], $this, $nbt)) instanceof Entity){
|
||||
$entity->spawnToAll();
|
||||
}else{
|
||||
$this->setChanged();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -155,16 +145,9 @@ abstract class BaseFullChunk implements FullChunk{
|
||||
continue; //Fixes tiles allocated in wrong chunks.
|
||||
}
|
||||
|
||||
switch($nbt["id"]){
|
||||
case Tile::CHEST:
|
||||
new Chest($this, $nbt);
|
||||
break;
|
||||
case Tile::FURNACE:
|
||||
new Furnace($this, $nbt);
|
||||
break;
|
||||
case Tile::SIGN:
|
||||
new Sign($this, $nbt);
|
||||
break;
|
||||
if(Tile::createTile($nbt["id"], $this, $nbt) === null){
|
||||
$this->setChanged();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,9 @@ abstract class Tile extends Position{
|
||||
|
||||
public static $tileCount = 1;
|
||||
|
||||
/** @var Tile[] */
|
||||
private static $knownTiles = [];
|
||||
|
||||
/** @var Chunk */
|
||||
public $chunk;
|
||||
public $name;
|
||||
@ -58,6 +61,38 @@ abstract class Tile extends Position{
|
||||
/** @var \pocketmine\event\TimingsHandler */
|
||||
public $tickTimer;
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param FullChunk $chunk
|
||||
* @param Compound $nbt
|
||||
* @param $args
|
||||
*
|
||||
* @return Tile
|
||||
*/
|
||||
public static function createTile($type, FullChunk $chunk, Compound $nbt, ...$args){
|
||||
if(isset(self::$knownTiles[$type])){
|
||||
$class = self::$knownTiles[$type];
|
||||
return new $class($chunk, $nbt, ...$args);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $className
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function registerTile($className){
|
||||
$class = new \ReflectionClass($className);
|
||||
if(is_a($className, Tile::class, true) and !$class->isAbstract()){
|
||||
self::$knownTiles[$class->getShortName()] = $className;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __construct(FullChunk $chunk, Compound $nbt){
|
||||
if($chunk === null or $chunk->getProvider() === null){
|
||||
throw new \Exception("Invalid garbage Chunk given to Tile");
|
||||
|
Loading…
x
Reference in New Issue
Block a user