From 275e27f7a947292658c661c936029a30e8345f39 Mon Sep 17 00:00:00 2001 From: Shoghi Cervantes Date: Sun, 8 Sep 2013 01:21:40 +0200 Subject: [PATCH] Low level PMF level interface --- src/API/BlockAPI.php | 3 +- src/pmf/Level.php | 91 ++++++++++++++++++++++++++++++++++++++++++-- src/world/Level.php | 12 +++--- 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/src/API/BlockAPI.php b/src/API/BlockAPI.php index 6a44ba457..e0927f854 100644 --- a/src/API/BlockAPI.php +++ b/src/API/BlockAPI.php @@ -167,12 +167,11 @@ class BlockAPI{ } public static function get($id, $meta = 0, $v = false){ - $id = (int) $id; if(isset(Block::$class[$id])){ $classname = Block::$class[$id]; $b = new $classname($meta); }else{ - $b = new GenericBlock($id, $meta); + $b = new GenericBlock((int) $id, $meta); } if($v instanceof Position){ $b->position($v); diff --git a/src/pmf/Level.php b/src/pmf/Level.php index 160ac8abc..3cf41471a 100644 --- a/src/pmf/Level.php +++ b/src/pmf/Level.php @@ -304,6 +304,91 @@ class PMFLevel extends PMF{ return true; } + public function getBlockID($x, $y, $z){ + $X = $x >> 4; + $Z = $z >> 4; + $Y = $y >> 4; + $index = $this->getIndex($X, $Z); + $aX = $x - ($X << 4); + $aZ = $z - ($Z << 4); + $aY = $y - ($Y << 4); + $b = ord($this->chunks[$index][$Y]{(int) ($aY + ($aX << 5) + ($aZ << 9))}); + return $b; + } + + public function setBlockID($x, $y, $z, $block){ + $X = $x >> 4; + $Z = $z >> 4; + $Y = $y >> 4; + $block &= 0xFF; + $meta &= 0x0F; + if($X >= 32 or $Z >= 32 or $Y >= $this->levelData["height"] or $y < 0){ + return false; + } + $index = $this->getIndex($X, $Z); + $aX = $x - ($X << 4); + $aZ = $z - ($Z << 4); + $aY = $y - ($Y << 4); + $this->chunks[$index][$Y]{(int) ($aY + ($aX << 5) + ($aZ << 9))} = chr($block); + if(!isset($this->chunkChange[$index][$Y])){ + $this->chunkChange[$index][$Y] = 1; + }else{ + ++$this->chunkChange[$index][$Y]; + } + $this->chunkChange[$index][-1] = true; + return true; + } + + public function getBlockDamage($x, $y, $z){ + $X = $x >> 4; + $Z = $z >> 4; + $Y = $y >> 4; + $index = $this->getIndex($X, $Z); + $aX = $x - ($X << 4); + $aZ = $z - ($Z << 4); + $aY = $y - ($Y << 4); + $m = ord($this->chunks[$index][$Y]{(int) (($aY >> 1) + 16 + ($aX << 5) + ($aZ << 9))}); + if(($y & 1) === 0){ + $m = $m & 0x0F; + }else{ + $m = $m >> 4; + } + return $m; + } + + public function setBlockDamage($x, $y, $z, $damage){ + $X = $x >> 4; + $Z = $z >> 4; + $Y = $y >> 4; + $damage &= 0x0F; + if($X >= 32 or $Z >= 32 or $Y >= $this->levelData["height"] or $y < 0){ + return false; + } + $index = $this->getIndex($X, $Z); + $aX = $x - ($X << 4); + $aZ = $z - ($Z << 4); + $aY = $y - ($Y << 4); + $mindex = (int) (($aY >> 1) + 16 + ($aX << 5) + ($aZ << 9)); + $old_m = ord($this->chunks[$index][$Y]{$mindex}); + if(($y & 1) === 0){ + $m = ($old_m & 0xF0) | $meta; + }else{ + $m = ($meta << 4) | ($old_m & 0x0F); + } + + if($old_m != $m){ + $this->chunks[$index][$Y]{$mindex} = chr($m); + if(!isset($this->chunkChange[$index][$Y])){ + $this->chunkChange[$index][$Y] = 1; + }else{ + ++$this->chunkChange[$index][$Y]; + } + $this->chunkChange[$index][-1] = true; + return true; + } + return false; + } + public function getBlock($x, $y, $z){ $X = $x >> 4; $Z = $z >> 4; @@ -322,10 +407,8 @@ class PMFLevel extends PMF{ $aX = $x - ($X << 4); $aZ = $z - ($Z << 4); $aY = $y - ($Y << 4); - $bindex = (int) ($aY + ($aX << 5) + ($aZ << 9)); - $mindex = (int) (($aY >> 1) + 16 + ($aX << 5) + ($aZ << 9)); - $b = ord($this->chunks[$index][$Y]{$bindex}); - $m = ord($this->chunks[$index][$Y]{$mindex}); + $b = ord($this->chunks[$index][$Y]{(int) ($aY + ($aX << 5) + ($aZ << 9))}); + $m = ord($this->chunks[$index][$Y]{(int) (($aY >> 1) + 16 + ($aX << 5) + ($aZ << 9))}); if(($y & 1) === 0){ $m = $m & 0x0F; }else{ diff --git a/src/world/Level.php b/src/world/Level.php index 1d8605c16..497ce8b86 100644 --- a/src/world/Level.php +++ b/src/world/Level.php @@ -20,8 +20,8 @@ */ class Level{ - public $entities, $tiles, $blockUpdates, $nextSave, $players = array(); - private $level, $time, $startCheck, $startTime, $server, $name, $usedChunks, $changedBlocks, $changedCount; + public $entities, $tiles, $blockUpdates, $nextSave, $players = array(), $level; + private $time, $startCheck, $startTime, $server, $name, $usedChunks, $changedBlocks, $changedCount; public function __construct(PMFLevel $level, Config $entities, Config $tiles, Config $blockUpdates, $name){ $this->server = ServerAPI::request(); @@ -263,6 +263,11 @@ class Level{ $this->nextSave = microtime(true) + 45; } + public function getBlockRaw(Vector3 $pos){ + $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)); + } + public function getBlock(Vector3 $pos){ if(!isset($this->level) or ($pos instanceof Position) and $pos->level !== $this){ return false; @@ -272,9 +277,6 @@ class Level{ } public function setBlockRaw(Vector3 $pos, Block $block, $direct = true, $send = true){ - if(!isset($this->level)){ - return false; - } if(($ret = $this->level->setBlock($pos->x, $pos->y, $pos->z, $block->getID(), $block->getMetadata())) === true and $send !== false){ if($direct === true){ $this->server->api->player->broadcastPacket($this->players, MC_UPDATE_BLOCK, array(