mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-03 16:49:53 +00:00
Reworked Level things to handle new NBT structure
This commit is contained in:
parent
398fbbfb31
commit
4a2852bb90
@ -128,14 +128,14 @@ class LevelAPI{
|
|||||||
foreach($this->server->api->player->getAll($level) as $player){
|
foreach($this->server->api->player->getAll($level) as $player){
|
||||||
$player->teleport($this->server->spawn);
|
$player->teleport($this->server->spawn);
|
||||||
}
|
}
|
||||||
foreach($this->server->api->entity->getAll($level) as $entity){
|
/*foreach($this->server->api->entity->getAll($level) as $entity){
|
||||||
if($entity->class !== ENTITY_PLAYER){
|
if($entity->class !== ENTITY_PLAYER){
|
||||||
$entity->close();
|
$entity->close();
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
foreach($this->server->api->tile->getAll($level) as $tile){
|
/*foreach($this->server->api->tile->getAll($level) as $tile){
|
||||||
$tile->close();
|
$tile->close();
|
||||||
}
|
}*/
|
||||||
$level->close();
|
$level->close();
|
||||||
unset($this->levels[$name]);
|
unset($this->levels[$name]);
|
||||||
return true;
|
return true;
|
||||||
@ -159,9 +159,8 @@ class LevelAPI{
|
|||||||
if(file_exists($path."tileEntities.yml")){
|
if(file_exists($path."tileEntities.yml")){
|
||||||
@rename($path."tileEntities.yml", $path."tiles.yml");
|
@rename($path."tileEntities.yml", $path."tiles.yml");
|
||||||
}
|
}
|
||||||
$tiles = new Config($path."tiles.yml", Config::YAML);
|
|
||||||
$blockUpdates = new Config($path."bupdates.yml", Config::YAML);
|
$blockUpdates = new Config($path."bupdates.yml", Config::YAML);
|
||||||
$this->levels[$name] = new Level($level, $entities, $tiles, $blockUpdates, $name);
|
$this->levels[$name] = new Level($level, $name);
|
||||||
foreach($entities->getAll() as $entity){
|
foreach($entities->getAll() as $entity){
|
||||||
if(!isset($entity["id"])){
|
if(!isset($entity["id"])){
|
||||||
break;
|
break;
|
||||||
@ -191,11 +190,68 @@ class LevelAPI{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($tiles->getAll() as $tile){
|
if(file_exists($path ."tiles.yml")){
|
||||||
if(!isset($tile["id"])){
|
$tiles = new Config($path."tiles.yml", Config::YAML);
|
||||||
break;
|
foreach($tiles->getAll() as $tile){
|
||||||
|
if(!isset($tile["id"])){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$this->levels[$name]->loadChunk($tile["x"] >> 4, $tile["z"] >> 4);
|
||||||
|
|
||||||
|
$nbt = new NBTTag_Compound(false, array());
|
||||||
|
foreach($tile as $index => $data){
|
||||||
|
switch($index){
|
||||||
|
case "Items":
|
||||||
|
$tag = new NBTTag_List("Items", array());
|
||||||
|
$tag->setTagType(NBTTag::TAG_Compound);
|
||||||
|
foreach($data as $slot => $fields){
|
||||||
|
$tag->{$slot} = new NBTTag_Compound(false, array(
|
||||||
|
"Count" => new NBTTag_Byte("Count", $fields["Count"]),
|
||||||
|
"Slot" => new NBTTag_Short("Slot", $fields["Slot"]),
|
||||||
|
"Damage" => new NBTTag_Short("Damage", $fields["Damage"]),
|
||||||
|
"id" => new NBTTag_String("id", $fields["id"])
|
||||||
|
));
|
||||||
|
}
|
||||||
|
$nbt["Items"] = $tag;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "id":
|
||||||
|
case "Text1":
|
||||||
|
case "Text2":
|
||||||
|
case "Text3":
|
||||||
|
case "Text4":
|
||||||
|
$nbt[$index] = new NBTTag_String($index, $data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "x":
|
||||||
|
case "y":
|
||||||
|
case "z":
|
||||||
|
case "pairx":
|
||||||
|
case "pairz":
|
||||||
|
$nbt[$index] = new NBTTag_Int($index, $data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "BurnTime":
|
||||||
|
case "CookTime":
|
||||||
|
case "MaxTime":
|
||||||
|
$nbt[$index] = new NBTTag_Short($index, $data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch($tile["id"]){
|
||||||
|
case Tile::FURNACE:
|
||||||
|
new FurnaceTile($this->levels[$name], $nbt);
|
||||||
|
break;
|
||||||
|
case Tile::CHEST:
|
||||||
|
new ChestTile($this->levels[$name], $nbt);
|
||||||
|
break;
|
||||||
|
case Tile::SIGN:
|
||||||
|
new SignTile($this->levels[$name], $nbt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$t = $this->server->api->tile->add($this->levels[$name], $tile["id"], $tile["x"], $tile["y"], $tile["z"], $tile);
|
unlink($path ."tiles.yml");
|
||||||
|
$this->levels[$name]->save(true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($blockUpdates->getAll() as $bupdate){
|
foreach($blockUpdates->getAll() as $bupdate){
|
||||||
|
@ -73,11 +73,6 @@ class ServerAPI{
|
|||||||
*/
|
*/
|
||||||
public $player;
|
public $player;
|
||||||
|
|
||||||
/**
|
|
||||||
* @var TileAPI
|
|
||||||
*/
|
|
||||||
public $tile;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return MainServer
|
* @return MainServer
|
||||||
*/
|
*/
|
||||||
@ -211,8 +206,7 @@ class ServerAPI{
|
|||||||
$this->loadAPI("block", "BlockAPI");
|
$this->loadAPI("block", "BlockAPI");
|
||||||
$this->loadAPI("chat", "ChatAPI");
|
$this->loadAPI("chat", "ChatAPI");
|
||||||
$this->loadAPI("ban", "BanAPI");
|
$this->loadAPI("ban", "BanAPI");
|
||||||
$this->loadAPI("entity", "EntityAPI");
|
$this->loadAPI("entity", "EntityAPI");
|
||||||
$this->loadAPI("tile", "TileAPI");
|
|
||||||
$this->loadAPI("player", "PlayerAPI");
|
$this->loadAPI("player", "PlayerAPI");
|
||||||
$this->loadAPI("time", "TimeAPI");
|
$this->loadAPI("time", "TimeAPI");
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ class Player{
|
|||||||
switch($event){
|
switch($event){
|
||||||
case "tile.update":
|
case "tile.update":
|
||||||
if($data->level === $this->level){
|
if($data->level === $this->level){
|
||||||
if($data->class === TILE_FURNACE){
|
if($data->class === Tile::FURNACE){
|
||||||
foreach($this->windows as $id => $w){
|
foreach($this->windows as $id => $w){
|
||||||
if($w === $data){
|
if($w === $data){
|
||||||
$pk = new ContainerSetDataPacket;
|
$pk = new ContainerSetDataPacket;
|
||||||
@ -2058,7 +2058,7 @@ class Player{
|
|||||||
$pk->case2 = 0;
|
$pk->case2 = 0;
|
||||||
$this->server->api->player->broadcastPacket($this->level->players, $pk);
|
$this->server->api->player->broadcastPacket($this->level->players, $pk);
|
||||||
}
|
}
|
||||||
}elseif($this->windows[$packet->windowid]->class === TILE_CHEST){
|
}elseif($this->windows[$packet->windowid]->class === Tile::CHEST){
|
||||||
$pk = new TileEventPacket;
|
$pk = new TileEventPacket;
|
||||||
$pk->x = $this->windows[$packet->windowid]->x;
|
$pk->x = $this->windows[$packet->windowid]->x;
|
||||||
$pk->y = $this->windows[$packet->windowid]->y;
|
$pk->y = $this->windows[$packet->windowid]->y;
|
||||||
@ -2136,14 +2136,14 @@ class Player{
|
|||||||
|
|
||||||
if(is_array($this->windows[$packet->windowid])){
|
if(is_array($this->windows[$packet->windowid])){
|
||||||
$tiles = $this->windows[$packet->windowid];
|
$tiles = $this->windows[$packet->windowid];
|
||||||
if($packet->slot >= 0 and $packet->slot < CHEST_SLOTS){
|
if($packet->slot >= 0 and $packet->slot < ChestTile::SLOTS){
|
||||||
$tile = $tiles[0];
|
$tile = $tiles[0];
|
||||||
$slotn = $packet->slot;
|
$slotn = $packet->slot;
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
}elseif($packet->slot >= CHEST_SLOTS and $packet->slot <= (CHEST_SLOTS << 1)){
|
}elseif($packet->slot >= ChestTile::SLOTS and $packet->slot <= (ChestTile::SLOTS << 1)){
|
||||||
$tile = $tiles[1];
|
$tile = $tiles[1];
|
||||||
$slotn = $packet->slot - CHEST_SLOTS;
|
$slotn = $packet->slot - ChestTile::SLOTS;
|
||||||
$offset = CHEST_SLOTS;
|
$offset = ChestTile::SLOTS;
|
||||||
}else{
|
}else{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2185,7 +2185,7 @@ class Player{
|
|||||||
$tile->setSlot($slotn, $item, true, $offset);
|
$tile->setSlot($slotn, $item, true, $offset);
|
||||||
}else{
|
}else{
|
||||||
$tile = $this->windows[$packet->windowid];
|
$tile = $this->windows[$packet->windowid];
|
||||||
if(($tile->class !== TILE_CHEST and $tile->class !== TILE_FURNACE) or $packet->slot < 0 or ($tile->class === TILE_CHEST and $packet->slot >= CHEST_SLOTS) or ($tile->class === TILE_FURNACE and $packet->slot >= FURNACE_SLOTS)){
|
if(($tile->class !== Tile::CHEST and $tile->class !== Tile::FURNACE) or $packet->slot < 0 or ($tile->class === Tile::CHEST and $packet->slot >= ChestTile::SLOTS) or ($tile->class === Tile::FURNACE and $packet->slot >= FurnaceTile::SLOTS)){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$item = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count);
|
$item = BlockAPI::getItem($packet->item->getID(), $packet->item->getMetadata(), $packet->item->count);
|
||||||
@ -2206,7 +2206,7 @@ class Player{
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($tile->class === TILE_FURNACE and $packet->slot == 2){
|
if($tile->class === Tile::FURNACE and $packet->slot == 2){
|
||||||
switch($slot->getID()){
|
switch($slot->getID()){
|
||||||
case IRON_INGOT:
|
case IRON_INGOT:
|
||||||
AchievementAPI::grantAchievement($this, "acquireIron");
|
AchievementAPI::grantAchievement($this, "acquireIron");
|
||||||
@ -2245,13 +2245,13 @@ class Player{
|
|||||||
$this->craftingItems = array();
|
$this->craftingItems = array();
|
||||||
$this->toCraft = array();
|
$this->toCraft = array();
|
||||||
$t = $this->server->api->tile->get(new Position($packet->x, $packet->y, $packet->z, $this->level));
|
$t = $this->server->api->tile->get(new Position($packet->x, $packet->y, $packet->z, $this->level));
|
||||||
if(($t instanceof Tile) and $t->class === TILE_SIGN){
|
if(($t instanceof Tile) and $t->class === Tile::SIGN){
|
||||||
if($t->data["creator"] !== $this->username){
|
if($t->data["creator"] !== $this->username){
|
||||||
$t->spawn($this);
|
$t->spawn($this);
|
||||||
}else{
|
}else{
|
||||||
$nbt = new NBT();
|
$nbt = new NBT();
|
||||||
$nbt->read($packet->namedtag);
|
$nbt->read($packet->namedtag);
|
||||||
if($nbt->id !== TILE_SIGN){
|
if($nbt->id !== Tile::SIGN){
|
||||||
$t->spawn($this);
|
$t->spawn($this);
|
||||||
}else{
|
}else{
|
||||||
$t->setText($nbt->Text1, $nbt->Text2, $nbt->Text3, $nbt->Text4);
|
$t->setText($nbt->Text1, $nbt->Text2, $nbt->Text3, $nbt->Text4);
|
||||||
|
@ -69,11 +69,3 @@ define("ENTITY_ITEM", 4);
|
|||||||
|
|
||||||
define("ENTITY_FALLING", 5);
|
define("ENTITY_FALLING", 5);
|
||||||
define("FALLING_SAND", 66);
|
define("FALLING_SAND", 66);
|
||||||
|
|
||||||
|
|
||||||
//TileEntities
|
|
||||||
define("TILE_SIGN", "Sign");
|
|
||||||
define("TILE_CHEST", "Chest");
|
|
||||||
define("CHEST_SLOTS", 27);
|
|
||||||
define("TILE_FURNACE", "Furnace");
|
|
||||||
define("FURNACE_SLOTS", 3);
|
|
@ -93,7 +93,7 @@ if($errors > 0){
|
|||||||
$sha1sum = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
$sha1sum = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
|
||||||
/***REM_START***/
|
/***REM_START***/
|
||||||
require_once(FILE_PATH."/src/math/Vector3.php");
|
require_once(FILE_PATH."/src/math/Vector3.php");
|
||||||
require_once(FILE_PATH."/src/world/Position.php");
|
require_once(FILE_PATH."/src/math/Position.php");
|
||||||
require_once(FILE_PATH."/src/pmf/PMF.php");
|
require_once(FILE_PATH."/src/pmf/PMF.php");
|
||||||
|
|
||||||
require_all(FILE_PATH . "src/", array("entity", "Entity.php")); //REMOVE LATER!!!!
|
require_all(FILE_PATH . "src/", array("entity", "Entity.php")); //REMOVE LATER!!!!
|
||||||
|
@ -224,8 +224,10 @@ function getTrace($start = 1){
|
|||||||
$j = 0;
|
$j = 0;
|
||||||
for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){
|
for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){
|
||||||
$params = "";
|
$params = "";
|
||||||
foreach($trace[$i]["args"] as $name => $value){
|
if(isset($trace[$i]["args"])){
|
||||||
$params .= (is_object($value) ? get_class($value)." ".(method_exists($value, "__toString") ? $value->__toString() : "object"):gettype($value)." ".@strval($value)).", ";
|
foreach($trace[$i]["args"] as $name => $value){
|
||||||
|
$params .= (is_object($value) ? get_class($value)." ".(method_exists($value, "__toString") ? $value->__toString() : "object"):gettype($value)." ".@strval($value)).", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$messages[] = "#$j ".(isset($trace[$i]["file"]) ? $trace[$i]["file"]:"")."(".(isset($trace[$i]["line"]) ? $trace[$i]["line"]:"")."): ".(isset($trace[$i]["class"]) ? $trace[$i]["class"].$trace[$i]["type"]:"").$trace[$i]["function"]."(".substr($params, 0, -2).")";
|
$messages[] = "#$j ".(isset($trace[$i]["file"]) ? $trace[$i]["file"]:"")."(".(isset($trace[$i]["line"]) ? $trace[$i]["line"]:"")."): ".(isset($trace[$i]["class"]) ? $trace[$i]["class"].$trace[$i]["type"]:"").$trace[$i]["function"]."(".substr($params, 0, -2).")";
|
||||||
}
|
}
|
||||||
|
@ -176,9 +176,11 @@ class PMFLevel extends PMF{
|
|||||||
console("[NOTICE] Old PMF Level format version #1 detected, upgrading to version #2");
|
console("[NOTICE] Old PMF Level format version #1 detected, upgrading to version #2");
|
||||||
$nbt = new NBT(NBT::BIG_ENDIAN);
|
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||||
$nbt->setData(new NBTTag_Compound("", array(
|
$nbt->setData(new NBTTag_Compound("", array(
|
||||||
new NBTTag_Compound("Entities", array()),
|
"Entities" => new NBTTag_List("Entities", array()),
|
||||||
new NBTTag_Compound("TileEntities", array())
|
"TileEntities" => new NBTTag_List("TileEntities", array())
|
||||||
)));
|
)));
|
||||||
|
$nbt->Entities->setTagType(NBTTag::TAG_Compound);
|
||||||
|
$nbt->TileEntities->setTagType(NBTTag::TAG_Compound);
|
||||||
$namedtag = $nbt->write();
|
$namedtag = $nbt->write();
|
||||||
$namedtag = Utils::writeInt(strlen($namedtag)) . $namedtag;
|
$namedtag = Utils::writeInt(strlen($namedtag)) . $namedtag;
|
||||||
foreach(glob(dirname($this->file)."/chunks/*/*.*.pmc") as $chunkFile){
|
foreach(glob(dirname($this->file)."/chunks/*/*.*.pmc") as $chunkFile){
|
||||||
@ -273,7 +275,7 @@ class PMFLevel extends PMF{
|
|||||||
$offset += 4;
|
$offset += 4;
|
||||||
$nbt = new NBT(NBT::BIG_ENDIAN);
|
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||||
$nbt->read(substr($chunk, $offset, $len));
|
$nbt->read(substr($chunk, $offset, $len));
|
||||||
$this->chunkInfo[2] = $nbt;
|
$this->chunkInfo[$index][2] = $nbt;
|
||||||
$offset += $len;
|
$offset += $len;
|
||||||
$this->chunks[$index] = array();
|
$this->chunks[$index] = array();
|
||||||
$this->chunkChange[$index] = array(-1 => false);
|
$this->chunkChange[$index] = array(-1 => false);
|
||||||
@ -571,14 +573,31 @@ class PMFLevel extends PMF{
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveChunk($X, $Z){
|
public function getChunkNBT($X, $Z){
|
||||||
|
if(!$this->isChunkLoaded($X, $Z) and $this->loadChunk($X, $Z) === false){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$index = self::getIndex($X, $Z);
|
||||||
|
return $this->chunkInfo[$index][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setChunkNBT($X, $Z, NBT $nbt){
|
||||||
|
if(!$this->isChunkLoaded($X, $Z) and $this->loadChunk($X, $Z) === false){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$index = self::getIndex($X, $Z);
|
||||||
|
$this->chunkChange[$index][-1] = true;
|
||||||
|
$this->chunkInfo[$index][2] = $nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function saveChunk($X, $Z, $force = false){
|
||||||
$X = (int) $X;
|
$X = (int) $X;
|
||||||
$Z = (int) $Z;
|
$Z = (int) $Z;
|
||||||
if(!$this->isChunkLoaded($X, $Z)){
|
if(!$this->isChunkLoaded($X, $Z)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$index = self::getIndex($X, $Z);
|
$index = self::getIndex($X, $Z);
|
||||||
if(!isset($this->chunkChange[$index]) or $this->chunkChange[$index][-1] === false){//No changes in chunk
|
if($force !== true and (!isset($this->chunkChange[$index]) or $this->chunkChange[$index][-1] === false)){//No changes in chunk
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -640,10 +659,10 @@ class PMFLevel extends PMF{
|
|||||||
return file_exists($this->getChunkPath($X, $Z));
|
return file_exists($this->getChunkPath($X, $Z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function doSaveRound(){
|
public function doSaveRound($force = false){
|
||||||
foreach($this->chunks as $index => $chunk){
|
foreach($this->chunks as $index => $chunk){
|
||||||
self::getXZ($index, $X, $Z);
|
self::getXZ($index, $X, $Z);
|
||||||
$this->saveChunk($X, $Z);
|
$this->saveChunk($X, $Z, $force);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,21 +24,15 @@ class Level{
|
|||||||
public $chunkEntities = array();
|
public $chunkEntities = array();
|
||||||
|
|
||||||
public $tiles = array();
|
public $tiles = array();
|
||||||
|
public $chunkTiles = array();
|
||||||
public $entitiesConfig;
|
|
||||||
public $tilesConfig;
|
|
||||||
public $blockUpdatesConfig;
|
|
||||||
|
|
||||||
public $nextSave, $players = array(), $level;
|
public $nextSave, $players = array(), $level;
|
||||||
private $time, $startCheck, $startTime, $server, $name, $usedChunks, $changedBlocks, $changedCount, $stopTime, $generator;
|
private $time, $startCheck, $startTime, $server, $name, $usedChunks, $changedBlocks, $changedCount, $stopTime, $generator;
|
||||||
|
|
||||||
public function __construct(PMFLevel $level, Config $entities, Config $tiles, Config $blockUpdates, $name){
|
public function __construct(PMFLevel $level, $name){
|
||||||
$this->server = ServerAPI::request();
|
$this->server = ServerAPI::request();
|
||||||
$this->level = $level;
|
$this->level = $level;
|
||||||
$this->level->level = $this;
|
$this->level->level = $this;
|
||||||
$this->entitiesConfig = $entities;
|
|
||||||
$this->tilesConfig = $tiles;
|
|
||||||
$this->blockUpdatesConfig = $blockUpdates;
|
|
||||||
$this->startTime = $this->time = (int) $this->level->getData("time");
|
$this->startTime = $this->time = (int) $this->level->getData("time");
|
||||||
$this->nextSave = $this->startCheck = microtime(true);
|
$this->nextSave = $this->startCheck = microtime(true);
|
||||||
$this->nextSave += 90;
|
$this->nextSave += 90;
|
||||||
@ -58,8 +52,9 @@ class Level{
|
|||||||
}else{
|
}else{
|
||||||
$this->generator = new NormalGenerator();
|
$this->generator = new NormalGenerator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->generator->init($this, new Random($this->level->levelData["seed"]));
|
$this->generator->init($this, new Random($this->level->levelData["seed"]));
|
||||||
|
$this->loadChunk(8, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function close(){
|
public function close(){
|
||||||
@ -69,12 +64,9 @@ class Level{
|
|||||||
public function useChunk($X, $Z, Player $player){
|
public function useChunk($X, $Z, Player $player){
|
||||||
$index = PMFLevel::getIndex($X, $Z);
|
$index = PMFLevel::getIndex($X, $Z);
|
||||||
if(!isset($this->usedChunks[$index])){
|
if(!isset($this->usedChunks[$index])){
|
||||||
$this->usedChunks[$index] = array();
|
$this->loadChunk($X, $Z);
|
||||||
}
|
}
|
||||||
$this->usedChunks[$index][$player->CID] = true;
|
$this->usedChunks[$index][$player->CID] = true;
|
||||||
if(isset($this->level)){
|
|
||||||
$this->level->loadChunk($X, $Z);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function freeAllChunks(Player $player){
|
public function freeAllChunks(Player $player){
|
||||||
@ -193,16 +185,38 @@ class Level{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($extra !== false){
|
if($extra !== false){
|
||||||
|
$this->doSaveRoundExtra();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->level->setData("time", (int) $this->time);
|
$this->level->setData("time", (int) $this->time);
|
||||||
$this->level->doSaveRound();
|
$this->level->doSaveRound($force);
|
||||||
$this->level->saveData();
|
$this->level->saveData();
|
||||||
$this->nextSave = microtime(true) + 45;
|
$this->nextSave = microtime(true) + 45;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function doSaveRoundExtra(){
|
||||||
|
foreach($this->usedChunks as $index => $d){
|
||||||
|
PMFLevel::getXZ($index, $X, $Z);
|
||||||
|
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||||
|
$nbt->setData(new NBTTag_Compound("", array(
|
||||||
|
"Entities" => new NBTTag_List("Entities", array()),
|
||||||
|
"TileEntities" => new NBTTag_List("TileEntities", array()),
|
||||||
|
)));
|
||||||
|
$nbt->Entities->setTagType(NBTTag::TAG_Compound);
|
||||||
|
$nbt->TileEntities->setTagType(NBTTag::TAG_Compound);
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
foreach($this->chunkTiles[$index] as $tile){
|
||||||
|
if($tile->closed !== true){
|
||||||
|
$nbt->TileEntities[$i] = $tile->namedtag;
|
||||||
|
++$i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->level->setChunkNBT($X, $Z, $nbt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getBlockRaw(Vector3 $pos){
|
public function getBlockRaw(Vector3 $pos){
|
||||||
$b = $this->level->getBlock($pos->x, $pos->y, $pos->z);
|
$b = $this->level->getBlock($pos->x, $pos->y, $pos->z);
|
||||||
return BlockAPI::get($b[0], $b[1], new Position($pos->x, $pos->y, $pos->z, $this));
|
return BlockAPI::get($b[0], $b[1], new Position($pos->x, $pos->y, $pos->z, $this));
|
||||||
@ -310,11 +324,48 @@ class Level{
|
|||||||
return $this->level->setMiniChunk($X, $Z, $Y, $data);
|
return $this->level->setMiniChunk($X, $Z, $Y, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getChunkEntities($X, $Z){
|
||||||
|
$index = PMFLevel::getIndex($X, $Z);
|
||||||
|
if(isset($this->usedChunks[$index]) or $this->level->loadChunk($X, $Z) === true){
|
||||||
|
return $this->chunkEntities[$index];
|
||||||
|
}
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChunkTiles($X, $Z){
|
||||||
|
$index = PMFLevel::getIndex($X, $Z);
|
||||||
|
if(isset($this->usedChunks[$index]) or $this->level->loadChunk($X, $Z) === true){
|
||||||
|
return $this->chunkTiles[$index];
|
||||||
|
}
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
public function loadChunk($X, $Z){
|
public function loadChunk($X, $Z){
|
||||||
if(!isset($this->level)){
|
if(!isset($this->level)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return $this->level->loadChunk($X, $Z);
|
$index = PMFLevel::getIndex($X, $Z);
|
||||||
|
if(isset($this->usedChunks[$index])){
|
||||||
|
return true;
|
||||||
|
}elseif($this->level->loadChunk($X, $Z) !== false){
|
||||||
|
$this->usedChunks[$index] = array();
|
||||||
|
$this->chunkTiles[$index] = array();
|
||||||
|
$this->chunkEntities[$index] = array();
|
||||||
|
foreach($this->level->getChunkNBT($X, $Z)->TileEntities as $nbt){
|
||||||
|
switch($nbt->id){
|
||||||
|
case Tile::CHEST:
|
||||||
|
new ChestTile($this, $nbt);
|
||||||
|
break;
|
||||||
|
case Tile::FURNACE:
|
||||||
|
new FurnaceTile($this, $nbt);
|
||||||
|
break;
|
||||||
|
case Tile::SIGN:
|
||||||
|
new SignTile($this, $nbt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function unloadChunk($X, $Z, $force = false){
|
public function unloadChunk($X, $Z, $force = false){
|
||||||
@ -325,6 +376,9 @@ class Level{
|
|||||||
if($force !== true and $this->isSpawnChunk($X, $Z)){
|
if($force !== true and $this->isSpawnChunk($X, $Z)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
unset($this->usedChunks[$index]);
|
||||||
|
unset($this->chunkEntities[$index]);
|
||||||
|
unset($this->chunkTiles[$index]);
|
||||||
Cache::remove("world:{$this->name}:$X:$Z");
|
Cache::remove("world:{$this->name}:$X:$Z");
|
||||||
return $this->level->unloadChunk($X, $Z, $this->server->saveEnabled);
|
return $this->level->unloadChunk($X, $Z, $this->server->saveEnabled);
|
||||||
}
|
}
|
||||||
|
@ -1,456 +0,0 @@
|
|||||||
<?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/
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Tile extends Position{
|
|
||||||
public $name;
|
|
||||||
public $normal;
|
|
||||||
public $id;
|
|
||||||
public $x;
|
|
||||||
public $y;
|
|
||||||
public $z;
|
|
||||||
public $data;
|
|
||||||
public $class;
|
|
||||||
public $attach;
|
|
||||||
public $metadata;
|
|
||||||
public $closed;
|
|
||||||
private $lastUpdate;
|
|
||||||
private $scheduledUpdate;
|
|
||||||
private $server;
|
|
||||||
function __construct(Level $level, $id, $class, $x, $y, $z, $data = array()){
|
|
||||||
$this->server = ServerAPI::request();
|
|
||||||
$this->level = $level;
|
|
||||||
$this->normal = true;
|
|
||||||
$this->class = $class;
|
|
||||||
$this->data = $data;
|
|
||||||
$this->closed = false;
|
|
||||||
if($class === false){
|
|
||||||
$this->closed = true;
|
|
||||||
}
|
|
||||||
$this->name = "";
|
|
||||||
$this->lastUpdate = microtime(true);
|
|
||||||
$this->scheduledUpdate = false;
|
|
||||||
$this->id = (int) $id;
|
|
||||||
$this->x = (int) $x;
|
|
||||||
$this->y = (int) $y;
|
|
||||||
$this->z = (int) $z;
|
|
||||||
$this->server->query("INSERT OR REPLACE INTO tiles (ID, level, class, x, y, z) VALUES (".$this->id.", '".$this->level->getName()."', '".$this->class."', ".$this->x.", ".$this->y.", ".$this->z.");");
|
|
||||||
switch($this->class){
|
|
||||||
case TILE_CHEST:
|
|
||||||
case TILE_SIGN:
|
|
||||||
$this->server->query("UPDATE tiles SET spawnable = 1 WHERE ID = ".$this->id.";");
|
|
||||||
break;
|
|
||||||
case TILE_FURNACE:
|
|
||||||
if(!isset($this->data["BurnTime"]) or $this->data["BurnTime"] < 0){
|
|
||||||
$this->data["BurnTime"] = 0;
|
|
||||||
}
|
|
||||||
if(!isset($this->data["CookTime"]) or $this->data["CookTime"] < 0 or ($this->data["BurnTime"] === 0 and $this->data["CookTime"] > 0)){
|
|
||||||
$this->data["CookTime"] = 0;
|
|
||||||
}
|
|
||||||
if(!isset($this->data["MaxTime"])){
|
|
||||||
$this->data["MaxTime"] = $this->data["BurnTime"];
|
|
||||||
$this->data["BurnTicks"] = 0;
|
|
||||||
}
|
|
||||||
if($this->data["BurnTime"] > 0){
|
|
||||||
$this->update();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function isPaired(){
|
|
||||||
if($this->class !== TILE_CHEST){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!isset($this->data["pairx"]) or !isset($this->data["pairz"])){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPair(){
|
|
||||||
if($this->isPaired()){
|
|
||||||
return $this->server->api->tile->get(new Position((int) $this->data["pairx"], $this->y, (int) $this->data["pairz"], $this->level));
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function pairWith(Tile $tile){
|
|
||||||
if($this->isPaired()or $tile->isPaired()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->data["pairx"] = $tile->x;
|
|
||||||
$this->data["pairz"] = $tile->z;
|
|
||||||
|
|
||||||
$tile->data["pairx"] = $this->x;
|
|
||||||
$tile->data["pairz"] = $this->z;
|
|
||||||
|
|
||||||
$this->server->api->tile->spawnToAll($this);
|
|
||||||
$this->server->api->tile->spawnToAll($tile);
|
|
||||||
$this->server->handle("tile.update", $this);
|
|
||||||
$this->server->handle("tile.update", $tile);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function unpair(){
|
|
||||||
if(!$this->isPaired()){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$tile = $this->getPair();
|
|
||||||
unset($this->data["pairx"], $this->data["pairz"], $tile->data["pairx"], $tile->data["pairz"]);
|
|
||||||
|
|
||||||
$this->server->api->tile->spawnToAll($this);
|
|
||||||
$this->server->handle("tile.update", $this);
|
|
||||||
if($tile instanceof Tile){
|
|
||||||
$this->server->api->tile->spawnToAll($tile);
|
|
||||||
$this->server->handle("tile.update", $tile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function openInventory(Player $player){
|
|
||||||
if($this->class === TILE_CHEST){
|
|
||||||
$player->windowCnt++;
|
|
||||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
|
||||||
if(($pair = $this->getPair()) !== false){
|
|
||||||
if(($pair->x + ($pair->z << 13)) > ($this->x + ($this->z << 13))){ //Order them correctly
|
|
||||||
$player->windows[$id] = array(
|
|
||||||
$pair,
|
|
||||||
$this
|
|
||||||
);
|
|
||||||
}else{
|
|
||||||
$player->windows[$id] = array(
|
|
||||||
$this,
|
|
||||||
$pair
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
$player->windows[$id] = $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new ContainerOpenPacket;
|
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->type = WINDOW_CHEST;
|
|
||||||
$pk->slots = is_array($player->windows[$id]) ? CHEST_SLOTS << 1:CHEST_SLOTS;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
$slots = array();
|
|
||||||
|
|
||||||
if(is_array($player->windows[$id])){
|
|
||||||
$all = $this->server->api->player->getAll($this->level);
|
|
||||||
foreach($player->windows[$id] as $ob){
|
|
||||||
$pk = new TileEventPacket;
|
|
||||||
$pk->x = $ob->x;
|
|
||||||
$pk->y = $ob->y;
|
|
||||||
$pk->z = $ob->z;
|
|
||||||
$pk->case1 = 1;
|
|
||||||
$pk->case2 = 2;
|
|
||||||
$this->server->api->player->broadcastPacket($all, $pk);
|
|
||||||
for($s = 0; $s < CHEST_SLOTS; ++$s){
|
|
||||||
$slot = $ob->getSlot($s);
|
|
||||||
if($slot->getID() > AIR and $slot->count > 0){
|
|
||||||
$slots[] = $slot;
|
|
||||||
}else{
|
|
||||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
$pk = new TileEventPacket;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$pk->case1 = 1;
|
|
||||||
$pk->case2 = 2;
|
|
||||||
$this->server->api->player->broadcastPacket($this->server->api->player->getAll($this->level), $pk);
|
|
||||||
for($s = 0; $s < CHEST_SLOTS; ++$s){
|
|
||||||
$slot = $this->getSlot($s);
|
|
||||||
if($slot->getID() > AIR and $slot->count > 0){
|
|
||||||
$slots[] = $slot;
|
|
||||||
}else{
|
|
||||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new ContainerSetContentPacket;
|
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->slots = $slots;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
return true;
|
|
||||||
}elseif($this->class === TILE_FURNACE){
|
|
||||||
$player->windowCnt++;
|
|
||||||
$player->windowCnt = $id = max(2, $player->windowCnt % 99);
|
|
||||||
$player->windows[$id] = $this;
|
|
||||||
|
|
||||||
$pk = new ContainerOpenPacket;
|
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->type = WINDOW_FURNACE;
|
|
||||||
$pk->slots = FURNACE_SLOTS;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
|
|
||||||
$slots = array();
|
|
||||||
for($s = 0; $s < FURNACE_SLOTS; ++$s){
|
|
||||||
$slot = $this->getSlot($s);
|
|
||||||
if($slot->getID() > AIR and $slot->count > 0){
|
|
||||||
$slots[] = $slot;
|
|
||||||
}else{
|
|
||||||
$slots[] = BlockAPI::getItem(AIR, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$pk = new ContainerSetContentPacket;
|
|
||||||
$pk->windowid = $id;
|
|
||||||
$pk->slots = $slots;
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function update(){
|
|
||||||
if($this->closed === true){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if($this->class === TILE_FURNACE){
|
|
||||||
$fuel = $this->getSlot(1);
|
|
||||||
$raw = $this->getSlot(0);
|
|
||||||
$product = $this->getSlot(2);
|
|
||||||
$smelt = $raw->getSmeltItem();
|
|
||||||
$canSmelt = ($smelt !== false and $raw->count > 0 and (($product->getID() === $smelt->getID() and $product->getMetadata() === $smelt->getMetadata() and $product->count < $product->getMaxStackSize()) or $product->getID() === AIR));
|
|
||||||
if($this->data["BurnTime"] <= 0 and $canSmelt and $fuel->getFuelTime() !== false and $fuel->count > 0){
|
|
||||||
$this->lastUpdate = microtime(true);
|
|
||||||
$this->data["MaxTime"] = $this->data["BurnTime"] = floor($fuel->getFuelTime() * 20);
|
|
||||||
$this->data["BurnTicks"] = 0;
|
|
||||||
--$fuel->count;
|
|
||||||
if($fuel->count === 0){
|
|
||||||
$fuel = BlockAPI::getItem(AIR, 0, 0);
|
|
||||||
}
|
|
||||||
$this->setSlot(1, $fuel, false);
|
|
||||||
$current = $this->level->getBlock($this);
|
|
||||||
if($current->getID() === FURNACE){
|
|
||||||
$this->level->setBlock($this, BlockAPI::get(BURNING_FURNACE, $current->getMetadata()), true, false, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if($this->data["BurnTime"] > 0){
|
|
||||||
$ticks = (microtime(true) - $this->lastUpdate) * 20;
|
|
||||||
$this->data["BurnTime"] -= $ticks;
|
|
||||||
$this->data["BurnTicks"] = ceil(($this->data["BurnTime"] / $this->data["MaxTime"]) * 200);
|
|
||||||
if($smelt !== false and $canSmelt){
|
|
||||||
$this->data["CookTime"] += $ticks;
|
|
||||||
if($this->data["CookTime"] >= 200){ //10 seconds
|
|
||||||
$product = BlockAPI::getItem($smelt->getID(), $smelt->getMetadata(), $product->count + 1);
|
|
||||||
$this->setSlot(2, $product, false);
|
|
||||||
--$raw->count;
|
|
||||||
if($raw->count === 0){
|
|
||||||
$raw = BlockAPI::getItem(AIR, 0, 0);
|
|
||||||
}
|
|
||||||
$this->setSlot(0, $raw, false);
|
|
||||||
$this->data["CookTime"] -= 200;
|
|
||||||
}
|
|
||||||
}elseif($this->data["BurnTime"] <= 0){
|
|
||||||
$this->data["BurnTime"] = 0;
|
|
||||||
$this->data["CookTime"] = 0;
|
|
||||||
$this->data["BurnTicks"] = 0;
|
|
||||||
}else{
|
|
||||||
$this->data["CookTime"] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->server->schedule(2, array($this, "update"));
|
|
||||||
$this->scheduledUpdate = true;
|
|
||||||
}else{
|
|
||||||
$current = $this->level->getBlock($this);
|
|
||||||
if($current->getID() === BURNING_FURNACE){
|
|
||||||
$this->level->setBlock($this, BlockAPI::get(FURNACE, $current->getMetadata()), true, false, true);
|
|
||||||
}
|
|
||||||
$this->data["CookTime"] = 0;
|
|
||||||
$this->data["BurnTime"] = 0;
|
|
||||||
$this->data["BurnTicks"] = 0;
|
|
||||||
$this->scheduledUpdate = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->server->handle("tile.update", $this);
|
|
||||||
$this->lastUpdate = microtime(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSlotIndex($s){
|
|
||||||
if($this->class !== TILE_CHEST and $this->class !== TILE_FURNACE){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
foreach($this->data["Items"] as $i => $slot){
|
|
||||||
if($slot["Slot"] === $s){
|
|
||||||
return $i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSlot($s){
|
|
||||||
$i = $this->getSlotIndex($s);
|
|
||||||
if($i === false or $i < 0){
|
|
||||||
return BlockAPI::getItem(AIR, 0, 0);
|
|
||||||
}else{
|
|
||||||
return BlockAPI::getItem($this->data["Items"][$i]["id"], $this->data["Items"][$i]["Damage"], $this->data["Items"][$i]["Count"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSlot($s, Item $item, $update = true, $offset = 0){
|
|
||||||
$i = $this->getSlotIndex($s);
|
|
||||||
$d = array(
|
|
||||||
"Count" => $item->count,
|
|
||||||
"Slot" => $s,
|
|
||||||
"id" => $item->getID(),
|
|
||||||
"Damage" => $item->getMetadata(),
|
|
||||||
);
|
|
||||||
if($i === false){
|
|
||||||
return false;
|
|
||||||
}elseif($item->getID() === AIR or $item->count <= 0){
|
|
||||||
if($i >= 0){
|
|
||||||
unset($this->data["Items"][$i]);
|
|
||||||
}
|
|
||||||
}elseif($i < 0){
|
|
||||||
$this->data["Items"][] = $d;
|
|
||||||
}else{
|
|
||||||
$this->data["Items"][$i] = $d;
|
|
||||||
}
|
|
||||||
$this->server->api->dhandle("tile.container.slot", array(
|
|
||||||
"tile" => $this,
|
|
||||||
"slot" => $s,
|
|
||||||
"offset" => $offset,
|
|
||||||
"slotdata" => $item,
|
|
||||||
));
|
|
||||||
|
|
||||||
if($update === true and $this->scheduledUpdate === false){
|
|
||||||
$this->update();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function spawn($player){
|
|
||||||
if($this->closed){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!($player instanceof Player)){
|
|
||||||
$player = $this->server->api->player->get($player);
|
|
||||||
}
|
|
||||||
switch($this->class){
|
|
||||||
case TILE_CHEST:
|
|
||||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
|
||||||
if($this->isPaired()){
|
|
||||||
$nbt->setData(new NBTTag_Compound("", array(
|
|
||||||
new NBTTag_String("id", $this->class),
|
|
||||||
new NBTTag_Int("x", (int) $this->x),
|
|
||||||
new NBTTag_Int("y", (int) $this->y),
|
|
||||||
new NBTTag_Int("z", (int) $this->z),
|
|
||||||
new NBTTag_Int("pairx", (int) $this->data["pairx"]),
|
|
||||||
new NBTTag_Int("pairz", (int) $this->data["pairz"])
|
|
||||||
)));
|
|
||||||
}else{
|
|
||||||
$nbt->setData(new NBTTag_Compound("", array(
|
|
||||||
new NBTTag_String("id", $this->class),
|
|
||||||
new NBTTag_Int("x", (int) $this->x),
|
|
||||||
new NBTTag_Int("y", (int) $this->y),
|
|
||||||
new NBTTag_Int("z", (int) $this->z)
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
|
|
||||||
$pk = new EntityDataPacket;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$pk->namedtag = $nbt->write();
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
break;
|
|
||||||
case TILE_SIGN:
|
|
||||||
$nbt = new NBT(NBT::LITTLE_ENDIAN);
|
|
||||||
$nbt->setData(new NBTTag_Compound("", array(
|
|
||||||
new NBTTag_String("Text1", $this->data["Text1"]),
|
|
||||||
new NBTTag_String("Text2", $this->data["Text2"]),
|
|
||||||
new NBTTag_String("Text3", $this->data["Text3"]),
|
|
||||||
new NBTTag_String("Text4", $this->data["Text4"]),
|
|
||||||
new NBTTag_String("id", $this->class),
|
|
||||||
new NBTTag_Int("x", (int) $this->x),
|
|
||||||
new NBTTag_Int("y", (int) $this->y),
|
|
||||||
new NBTTag_Int("z", (int) $this->z)
|
|
||||||
)));
|
|
||||||
$pk = new EntityDataPacket;
|
|
||||||
$pk->x = $this->x;
|
|
||||||
$pk->y = $this->y;
|
|
||||||
$pk->z = $this->z;
|
|
||||||
$pk->namedtag = $nbt->write();
|
|
||||||
$player->dataPacket($pk);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setText($line1 = "", $line2 = "", $line3 = "", $line4 = ""){
|
|
||||||
if($this->class !== TILE_SIGN){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->data["Text1"] = $line1;
|
|
||||||
$this->data["Text2"] = $line2;
|
|
||||||
$this->data["Text3"] = $line3;
|
|
||||||
$this->data["Text4"] = $line4;
|
|
||||||
$this->server->api->tile->spawnToAll($this);
|
|
||||||
$this->server->handle("tile.update", $this);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getText(){
|
|
||||||
return array(
|
|
||||||
$this->data["Text1"],
|
|
||||||
$this->data["Text2"],
|
|
||||||
$this->data["Text3"],
|
|
||||||
$this->data["Text4"]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function close(){
|
|
||||||
if($this->closed === false){
|
|
||||||
$this->closed = true;
|
|
||||||
$this->server->api->tile->remove($this->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __destruct(){
|
|
||||||
$this->close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName(){
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function setPosition(Vector3 $pos){
|
|
||||||
if($pos instanceof Position){
|
|
||||||
$this->level = $pos->level;
|
|
||||||
$this->server->query("UPDATE tiles SET level = '".$this->level->getName()."' WHERE ID = ".$this->id.";");
|
|
||||||
}
|
|
||||||
$this->x = (int) $pos->x;
|
|
||||||
$this->y = (int) $pos->y;
|
|
||||||
$this->z = (int) $pos->z;
|
|
||||||
$this->server->query("UPDATE tiles SET x = ".$this->x.", y = ".$this->y.", z = ".$this->z." WHERE ID = ".$this->id.";");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user