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