New direct block method, better block placement sending

This commit is contained in:
Shoghi Cervantes 2013-06-01 00:32:23 +02:00
parent 722eb6d1f9
commit 24ba7cbbd1
7 changed files with 72 additions and 46 deletions

View File

@ -25,17 +25,6 @@ the Free Software Foundation, either version 3 of the License, or
*/ */
define("BLOCK_UPDATE_NORMAL", 0);
define("BLOCK_UPDATE_RANDOM", 1);
define("BLOCK_UPDATE_SCHEDULED", 2);
define("BLOCK_UPDATE_WEAK", 3);
define("BLOCK_UPDATE_TOUCH", 4);
class BlockAPI{ class BlockAPI{
private $server; private $server;
private $scheduledUpdates = array(); private $scheduledUpdates = array();

View File

@ -37,10 +37,18 @@ define("VIEWER", 3);
define("PLAYER_RECOVERY_BUFFER", 2048); define("PLAYER_RECOVERY_BUFFER", 2048);
//Entities //Block Updates
define("ENTITY_PLAYER", 0); define("BLOCK_UPDATE_NORMAL", 1);
define("BLOCK_UPDATE_RANDOM", 2);
define("BLOCK_UPDATE_SCHEDULED", 3);
define("BLOCK_UPDATE_WEAK", 4);
define("BLOCK_UPDATE_TOUCH", 5);
define("ENTITY_MOB", 1);
//Entities
define("ENTITY_PLAYER", 1);
define("ENTITY_MOB", 2);
define("MOB_CHICKEN", 10); define("MOB_CHICKEN", 10);
define("MOB_COW", 11); define("MOB_COW", 11);
define("MOB_PIG", 12); define("MOB_PIG", 12);
@ -52,10 +60,10 @@ define("ENTITY_MOB", 1);
define("MOB_SPIDER", 35); define("MOB_SPIDER", 35);
define("MOB_PIGMAN", 36); define("MOB_PIGMAN", 36);
define("ENTITY_OBJECT", 2); define("ENTITY_OBJECT", 3);
define("OBJECT_PAINTING", 83); define("OBJECT_PAINTING", 83);
define("ENTITY_ITEM", 3); define("ENTITY_ITEM", 4);
define("ENTITY_FALLING", 4); define("ENTITY_FALLING", 4);
define("FALLING_SAND", 66); define("FALLING_SAND", 66);

View File

@ -31,6 +31,12 @@ class FallableBlock extends SolidBlock{
$this->hasPhysics = true; $this->hasPhysics = true;
} }
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
$ret = $this->level->setBlock($this, $this, true, false, true);
ServerAPI::request()->api->block->blockUpdate($this, BLOCK_UPDATE_NORMAL);
return $ret;
}
public function onUpdate($type){ public function onUpdate($type){
if($this->getSide(0)->getID() === AIR){ if($this->getSide(0)->getID() === AIR){
$data = array( $data = array(
@ -40,9 +46,11 @@ class FallableBlock extends SolidBlock{
"Tile" => $this->id, "Tile" => $this->id,
); );
$server = ServerAPI::request(); $server = ServerAPI::request();
$this->level->setBlock($this, new AirBlock()); $this->level->setBlock($this, new AirBlock(), false, false, true);
$e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data); $e = $server->api->entity->add($this->level, ENTITY_FALLING, FALLING_SAND, $data);
$server->api->entity->spawnToAll($this->level, $e->eid); $server->api->entity->spawnToAll($this->level, $e->eid);
return BLOCK_UPDATE_NORMAL;
} }
return false;
} }
} }

View File

@ -31,7 +31,7 @@ class GenericBlock extends Block{
parent::__construct($id, $meta, $name); parent::__construct($id, $meta, $name);
} }
public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){ public function place(Item $item, Player $player, Block $block, Block $target, $face, $fx, $fy, $fz){
return $this->level->setBlock($block, $this); return $this->level->setBlock($this, $this, true, false, true);
} }
public function isBreakable(Item $item, Player $player){ public function isBreakable(Item $item, Player $player){

View File

@ -400,7 +400,7 @@ class Entity extends Position{
if($fall->isFullBlock === false or $down->isFullBlock === false){ if($fall->isFullBlock === false or $down->isFullBlock === false){
$this->server->api->entity->drop($this, BlockAPI::getItem($this->data["Tile"] & 0xFFFF, 0, 1), true); $this->server->api->entity->drop($this, BlockAPI::getItem($this->data["Tile"] & 0xFFFF, 0, 1), true);
}else{ }else{
$this->level->setBlock($fall, BlockAPI::get($this->data["Tile"])); $this->level->setBlock($fall, BlockAPI::get($this->data["Tile"]), true, false, true);
} }
$this->server->api->handle("entity.motion", $this); $this->server->api->handle("entity.motion", $this);
$this->close(); $this->close();

View File

@ -26,7 +26,7 @@ the Free Software Foundation, either version 3 of the License, or
*/ */
class Level{ class Level{
public $entities, $tileEntities, $nextSave; public $entities, $tileEntities, $nextSave, $players = array();
private $level, $time, $startCheck, $startTime, $server, $name, $usedChunks, $changedBlocks, $changedCount; private $level, $time, $startCheck, $startTime, $server, $name, $usedChunks, $changedBlocks, $changedCount;
public function __construct(PMFLevel $level, Config $entities, Config $tileEntities, $name){ public function __construct(PMFLevel $level, Config $entities, Config $tileEntities, $name){
@ -63,12 +63,12 @@ class Level{
} }
public function checkThings(){ public function checkThings(){
$players = $this->server->api->player->getAll($this); $this->players = $this->server->api->player->getAll($this);
$now = microtime(true); $now = microtime(true);
$time = $this->startTime + ($now - $this->startCheck) * 20; $time = $this->startTime + ($now - $this->startCheck) * 20;
if($this->server->api->dhandle("time.change", array("level" => $this, "time" => $time)) !== false){ if($this->server->api->dhandle("time.change", array("level" => $this, "time" => $time)) !== false){
$this->time = $time; $this->time = $time;
$this->server->api->player->broadcastPacket($players, MC_SET_TIME, array( $this->server->api->player->broadcastPacket($this->players, MC_SET_TIME, array(
"time" => $this->time, "time" => $this->time,
)); ));
} }
@ -80,7 +80,7 @@ class Level{
if($count < 582){//Optimal value, calculated using the relation between minichunks and single packets if($count < 582){//Optimal value, calculated using the relation between minichunks and single packets
break; break;
} }
foreach($players as $p){ foreach($this->players as $p){
unset($p->chunksLoaded[$index]); unset($p->chunksLoaded[$index]);
} }
unset($this->changedBlocks[$index]); unset($this->changedBlocks[$index]);
@ -90,7 +90,7 @@ class Level{
if(count($this->changedBlocks) > 0){ if(count($this->changedBlocks) > 0){
foreach($this->changedBlocks as $blocks){ foreach($this->changedBlocks as $blocks){
foreach($blocks as $b){ foreach($blocks as $b){
$this->server->api->player->broadcastPacket($players, MC_UPDATE_BLOCK, array( $this->server->api->player->broadcastPacket($this->players, MC_UPDATE_BLOCK, array(
"x" => $b->x, "x" => $b->x,
"y" => $b->y, "y" => $b->y,
"z" => $b->z, "z" => $b->z,
@ -205,8 +205,20 @@ class Level{
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));
} }
public function setBlockRaw(Vector3 $pos, Block $block){ public function setBlockRaw(Vector3 $pos, Block $block, $direct = true){
if(($ret = $this->level->setBlock($pos->x, $pos->y, $pos->z, $block->getID(), $block->getMetadata())) === true){ if(($ret = $this->level->setBlock($pos->x, $pos->y, $pos->z, $block->getID(), $block->getMetadata())) === true){
if($direct === true){
$this->server->api->player->broadcastPacket($this->players, MC_UPDATE_BLOCK, array(
"x" => $pos->x,
"y" => $pos->y,
"z" => $pos->z,
"block" => $block->getID(),
"meta" => $block->getMetadata(),
));
}elseif($direct === false){
if(!($block->level instanceof Level)){
$block->position($pos);
}
$i = ($pos->x >> 4).":".($pos->y >> 4).":".($pos->z >> 4); $i = ($pos->x >> 4).":".($pos->y >> 4).":".($pos->z >> 4);
if(!isset($this->changedBlocks[$i])){ if(!isset($this->changedBlocks[$i])){
$this->changedBlocks[$i] = array(); $this->changedBlocks[$i] = array();
@ -215,10 +227,11 @@ class Level{
$this->changedBlocks[$i][] = $block; $this->changedBlocks[$i][] = $block;
++$this->changedCount[$i]; ++$this->changedCount[$i];
} }
}
return $ret; return $ret;
} }
public function setBlock(Vector3 $pos, Block $block, $update = true, $tiles = false){ public function setBlock(Vector3 $pos, Block $block, $update = true, $tiles = false, $direct = false){
if((($pos instanceof Position) and $pos->level !== $this) or $pos->x < 0 or $pos->y < 0 or $pos->z < 0){ if((($pos instanceof Position) and $pos->level !== $this) or $pos->x < 0 or $pos->y < 0 or $pos->z < 0){
return false; return false;
} }
@ -228,8 +241,18 @@ class Level{
if(!($pos instanceof Position)){ if(!($pos instanceof Position)){
$pos = new Position($pos->x, $pos->y, $pos->z, $this); $pos = new Position($pos->x, $pos->y, $pos->z, $this);
} }
$block = $this->getBlock($pos); if(!($block->level instanceof Level)){
$block->position($pos);
}
if($direct === true){
$this->server->api->player->broadcastPacket($this->players, MC_UPDATE_BLOCK, array(
"x" => $pos->x,
"y" => $pos->y,
"z" => $pos->z,
"block" => $block->getID(),
"meta" => $block->getMetadata(),
));
}else{
$i = ($pos->x >> 4).":".($pos->y >> 4).":".($pos->z >> 4); $i = ($pos->x >> 4).":".($pos->y >> 4).":".($pos->z >> 4);
if(!isset($this->changedBlocks[$i])){ if(!isset($this->changedBlocks[$i])){
$this->changedBlocks[$i] = array(); $this->changedBlocks[$i] = array();
@ -237,12 +260,10 @@ class Level{
} }
$this->changedBlocks[$i][] = $block; $this->changedBlocks[$i][] = $block;
++$this->changedCount[$i]; ++$this->changedCount[$i];
/*$this->server->trigger("block.change", array( }
"position" => $pos,
"block" => $block,
));*/
if($update === true){ if($update === true){
$this->server->api->block->scheduleBlockUpdate($block, 1, BLOCK_UPDATE_NORMAL); //????? water?
$this->server->api->block->blockUpdateAround($pos, BLOCK_UPDATE_NORMAL, 1); $this->server->api->block->blockUpdateAround($pos, BLOCK_UPDATE_NORMAL, 1);
} }
if($tiles === true){ if($tiles === true){

View File

@ -134,7 +134,7 @@ class SuperflatGenerator implements LevelGenerator{
for($x = $start; $x <= $end; ++$x){ for($x = $start; $x <= $end; ++$x){
for($z = $start; $z <= $end; ++$z){ for($z = $start; $z <= $end; ++$z){
if(floor(sqrt(pow($x - 128, 2) + pow($z - 128, 2))) <= $spawn[0]){ if(floor(sqrt(pow($x - 128, 2) + pow($z - 128, 2))) <= $spawn[0]){
$this->level->setBlockRaw(new Vector3($x, $this->floorLevel - 1, $z), $spawn[1]); $this->level->setBlockRaw(new Vector3($x, $this->floorLevel - 1, $z), $spawn[1], null);
} }
} }
} }