Updated Levels :D

This commit is contained in:
Shoghi Cervantes
2014-06-09 11:35:52 +02:00
parent 920e2a7c7e
commit 115b4cf4ac
41 changed files with 1492 additions and 270 deletions

View File

@ -21,27 +21,46 @@
namespace pocketmine\level\format\generic;
use pocketmine\entity\DroppedItem;
use pocketmine\entity\Entity;
use pocketmine\level\format\Chunk;
use pocketmine\level\format\ChunkSection;
use pocketmine\level\format\LevelProvider;
use pocketmine\level\Level;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\String;
use pocketmine\tile\Chest;
use pocketmine\tile\Furnace;
use pocketmine\tile\Sign;
use pocketmine\tile\Tile;
abstract class BaseChunk implements Chunk{
/** @var ChunkSection[] */
protected $sections = [];
/** @var Entity[] */
protected $entities = [];
/** @var Tile[] */
protected $tiles = [];
/** @var \WeakRef<LevelProvider> */
protected $level;
protected $x;
protected $z;
/**
* @param Level $level
* @param LevelProvider $level
* @param int $x
* @param int $z
* @param ChunkSection[] $sections
* @param Compound[] $entities
* @param Compound[] $tiles
*/
public function __construct(Level $level, $x, $z, array $sections){
$this->level = $level;
protected function __construct(LevelProvider $level, $x, $z, array $sections, array $entities = [], array $tiles = []){
$this->level = new \WeakRef($level);
$this->x = (int) $x;
$this->z = (int) $z;
foreach($sections as $Y => $section){
@ -59,6 +78,44 @@ abstract class BaseChunk implements Chunk{
return;
}
}
foreach($entities as $nbt){
if($nbt instanceof Compound){
if(!isset($nbt->id)){
continue;
}
if($nbt->id instanceof String){ //New format
switch($nbt["id"]){
case "Item":
(new DroppedItem($this, $nbt))->spawnToAll();
break;
}
}else{ //Old format
}
}
}
foreach($tiles as $nbt){
if($nbt instanceof Compound){
if(!isset($nbt->id)){
continue;
}
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;
}
}
}
}
public function getX(){
@ -69,8 +126,11 @@ abstract class BaseChunk implements Chunk{
return $this->z;
}
/**
* @return LevelProvider
*/
public function getLevel(){
return $this->level;
return $this->level->valid() ? $this->level->get() : null;
}
public function getBlock($x, $y, $z, &$blockId, &$meta = null){
@ -140,6 +200,59 @@ abstract class BaseChunk implements Chunk{
$this->sections[(int) $fY] = $section;
}
public function addEntity(Entity $entity){
$this->entities[$entity->getID()] = $entity;
}
public function removeEntity(Entity $entity){
unset($this->entities[$entity->getID()]);
}
public function addTile(Tile $tile){
$this->tiles[$tile->getID()] = $tile;
}
public function removeTile(Tile $tile){
unset($this->tiles[$tile->getID()]);
}
public function getEntities(){
return $this->entities;
}
public function getTiles(){
return $this->tiles;
}
public function isLoaded(){
return $this->getLevel() === null ? false : $this->getLevel()->isChunkLoaded($this->getX(), $this->getZ());
}
public function load($generate = true){
return $this->getLevel() === null ? false : $this->getLevel()->getChunk($this->getX(), $this->getZ(), true) instanceof Chunk;
}
public function unload($save = true, $safe = true){
$level = $this->getLevel();
if($level === null){
return true;
}
if($save === true){
$level->saveChunk($this->getX(), $this->getZ());
}
if($this->getLevel()->unloadChunk($this->getX(), $this->getZ(), $safe)){
foreach($this->getEntities() as $entity){
$entity->close();
}
foreach($this->getTiles() as $tile){
$tile->close();
}
}
}
/**
* @return ChunkSection[]
*/
public function getSections(){
return $this->sections;
}

View File

@ -21,16 +21,83 @@
namespace pocketmine\level\format\generic;
use pocketmine\level\format\LevelProvider;
use pocketmine\Server;
use pocketmine\level\Level;
use pocketmine\math\Vector3;
use pocketmine\nbt\NBT;
use pocketmine\nbt\tag\Compound;
use pocketmine\nbt\tag\Int;
abstract class BaseLevelProvider implements LevelProvider{
/** @var Server */
protected $server;
/** @var Level */
protected $level;
/** @var string */
protected $path;
/** @var Compound */
protected $levelData;
public function __construct(Server $server, $path){
$this->server = $server;
public function __construct(Level $level, $path){
$this->level = $level->getServer();
$this->path = $path;
@mkdir($this->path, 0777, true);
$nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->readCompressed(file_get_contents($this->getPath() . "level.dat"));
$levelData = $nbt->getData();
if($levelData->Data instanceof Compound){
$this->levelData = $levelData->Data;
}else{
throw new \Exception("Invalid level.dat");
}
}
public function getPath(){
return $this->path;
}
public function getServer(){
return $this->level->getServer();
}
public function getLevel(){
return $this->level;
}
public function getName(){
return $this->levelData["LevelName"];
}
public function getTime(){
return $this->levelData["Time"];
}
public function setTime($value){
$this->levelData->Time = new Int("Time", (int) $value);
}
public function getSpawn(){
return new Vector3($this->levelData["SpawnX"], $this->levelData["SpawnY"], $this->levelData["SpawnZ"]);
}
public function setSpawn(Vector3 $pos){
$this->levelData->SpawnX = new Int("SpawnX", $pos->x);
$this->levelData->SpawnY = new Int("SpawnY", $pos->y);
$this->levelData->SpawnZ = new Int("SpawnZ", $pos->z);
}
/**
* @return Compound
*/
public function getLevelData(){
return $this->levelData;
}
public function saveLevelData(){
$nbt = new NBT(NBT::BIG_ENDIAN);
$nbt->setData(new Compound(null, [
"Data" => $this->levelData
]));
$buffer = $nbt->writeCompressed();
@file_put_contents($this->getPath() . "level.dat", $buffer);
}
}