mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-07 02:08:21 +00:00
Updated Levels :D
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user