mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-09 19:24:12 +00:00
Compare commits
158 Commits
Alpha_1.4d
...
1.4-916
Author | SHA1 | Date | |
---|---|---|---|
3de14d8ba6 | |||
5fffabe05b | |||
3128ae9736 | |||
7be4e2fa81 | |||
95b305ce87 | |||
767800662c | |||
fe32e6f5d0 | |||
2cec0d9f36 | |||
d800a21bd4 | |||
8d9fbec4ce | |||
ab72c32769 | |||
346626305c | |||
fafbd500e1 | |||
2db2e8cfc4 | |||
854479180f | |||
902ba81e02 | |||
1ac17abec0 | |||
714ea54121 | |||
aa992684ba | |||
0c58de86b7 | |||
7ecac019a9 | |||
6cb88afe1a | |||
a677bcb331 | |||
2f6007342c | |||
b6c0eb8c96 | |||
afa8496767 | |||
d7be2ce439 | |||
6dcb5da069 | |||
3cf1692c96 | |||
d04af590d1 | |||
d4c43215b1 | |||
a40918aabf | |||
20f9352714 | |||
a605e90dfc | |||
9fc250956f | |||
db2dfc47a6 | |||
408a537001 | |||
922bfb33ac | |||
8e47c93fbc | |||
c175485cd8 | |||
b6981cc31d | |||
1f9cd6a99b | |||
ded7ada7d7 | |||
1b50879823 | |||
1bd9cbd4d3 | |||
96122d3be7 | |||
71d602a4cf | |||
c81bbdaaa9 | |||
2752393c42 | |||
312e064b07 | |||
94f91967f3 | |||
fe900b417e | |||
4c30b6b8a1 | |||
c41ac7b0a2 | |||
b220bd2a45 | |||
04ee94dc91 | |||
ea8f10efa4 | |||
04ecbd1a76 | |||
ddfc9d9ce1 | |||
a4735eaf76 | |||
306f492fc0 | |||
5e5f8bf33d | |||
3bb2f12cde | |||
1041bb0e6a | |||
49e93cee80 | |||
8b6681c56d | |||
9e3d432b9e | |||
841a3d5ee6 | |||
a5294d5ec7 | |||
5373e6be07 | |||
075137bd3c | |||
68da4b5b39 | |||
e4557a2e8e | |||
964bf98ca6 | |||
747f7685e7 | |||
bb82e7be50 | |||
7506f01302 | |||
a98da3bab1 | |||
f0d6128282 | |||
161e7ae7ec | |||
6104c5b5a3 | |||
af82d616c1 | |||
a0d4bff385 | |||
79236c971c | |||
20e63ae543 | |||
add7879720 | |||
1a064d38b1 | |||
294e680d5d | |||
811970e58d | |||
941961f5ef | |||
1963d8fde0 | |||
e44ed4da3b | |||
a72488d41e | |||
3930f379cf | |||
66ba327e62 | |||
329ca62465 | |||
26e47ef694 | |||
61ea149ff0 | |||
b3c3f896a3 | |||
d139e5f342 | |||
3abf36ad07 | |||
0bc9a9bdab | |||
98340522d9 | |||
6d09754ea7 | |||
a3b1d318cc | |||
f866efb622 | |||
b1c4578726 | |||
f4181a6e36 | |||
38089af098 | |||
cd135b39ad | |||
dd3207cbd8 | |||
a7abd5ff9d | |||
a3e50f6337 | |||
441a98e60a | |||
4a90ac270f | |||
a906a2988b | |||
545f68382c | |||
8249cac592 | |||
7b7bbe9105 | |||
05679c7872 | |||
8eb80be691 | |||
f55b0d0b45 | |||
754e0dbb49 | |||
525c8db779 | |||
c7f578f297 | |||
19c030281f | |||
ca9fe1b89a | |||
9fd6a695f6 | |||
c07b0ff35b | |||
00be3f0dd3 | |||
6796fca2b6 | |||
5657cce3db | |||
05ac256cc3 | |||
49977c5410 | |||
ca40bb678c | |||
2068cc9cdf | |||
ea4617cedd | |||
1a5544f68c | |||
0128a7aeb2 | |||
fd954ce708 | |||
d63a82de0a | |||
92143d523c | |||
1818e64c8e | |||
522b75645c | |||
4fba6d7c86 | |||
577a7a1c3d | |||
1fc066fc37 | |||
b565844062 | |||
5cb428e5cc | |||
d2f4a14d66 | |||
5437567e95 | |||
7d9a98ec6b | |||
92facc94b9 | |||
d3327f450c | |||
570cab9c66 | |||
582ba100b0 | |||
4c0daa462d | |||
a879104a6f |
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@ players/*
|
||||
worlds/*
|
||||
plugins/*
|
||||
bin/*
|
||||
timings/*
|
||||
*.log
|
||||
*.txt
|
||||
*.phar
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -9,3 +9,6 @@
|
||||
[submodule "src/spl"]
|
||||
path = src/spl
|
||||
url = https://github.com/PocketMine/PocketMine-SPL.git
|
||||
[submodule "tests/TesterPlugin"]
|
||||
path = tests/TesterPlugin
|
||||
url = https://github.com/PocketMine/TesterPlugin.git
|
||||
|
@ -10,7 +10,7 @@ before_script:
|
||||
- mkdir plugins
|
||||
- wget -O plugins/DevTools.phar https://github.com/PocketMine/DevTools/releases/download/v1.9.0/DevTools_v1.9.0.phar
|
||||
- pecl install channel://pecl.php.net/pthreads-2.0.10
|
||||
- pecl install channel://pecl.php.net/weakref-0.2.4
|
||||
- pecl install channel://pecl.php.net/weakref-0.2.6
|
||||
- echo | pecl install channel://pecl.php.net/yaml-1.1.1
|
||||
|
||||
script:
|
||||
@ -18,4 +18,4 @@ script:
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
#webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0
|
||||
#webhooks: http://n.tkte.ch/h/214/wsNvmG43-ncxUVRrFPwSM-r0
|
||||
|
@ -93,7 +93,10 @@ use pocketmine\network\protocol\FullChunkDataPacket;
|
||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||
use pocketmine\network\protocol\LoginStatusPacket;
|
||||
use pocketmine\network\protocol\MessagePacket;
|
||||
use pocketmine\network\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\network\protocol\SetHealthPacket;
|
||||
use pocketmine\network\protocol\SetSpawnPositionPacket;
|
||||
use pocketmine\network\protocol\SetTimePacket;
|
||||
@ -141,6 +144,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
protected $sendIndex = 0;
|
||||
|
||||
protected $moveToSend = [];
|
||||
protected $motionToSend = [];
|
||||
|
||||
public $blocked = false;
|
||||
public $achievements = [];
|
||||
public $lastCorrect;
|
||||
@ -161,8 +167,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
protected $iusername;
|
||||
protected $displayName;
|
||||
protected $startAction = false;
|
||||
/** @var Vector3|bool */
|
||||
protected $sleeping = false;
|
||||
/** @var Vector3 */
|
||||
protected $sleeping = null;
|
||||
protected $clientID = null;
|
||||
|
||||
protected $stepHeight = 0.6;
|
||||
@ -245,20 +251,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
* @param Player $player
|
||||
*/
|
||||
public function spawnTo(Player $player){
|
||||
if($this->spawned === true and $this->dead !== true and $this !== $player and $player->getLevel() === $this->level and $player->canSee($this)){
|
||||
if($this->spawned === true and $this->dead !== true and $player->dead !== true and $player->getLevel() === $this->level and $player->canSee($this)){
|
||||
parent::spawnTo($player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
*/
|
||||
public function despawnFrom(Player $player){
|
||||
if($this->spawned === true and $this->dead !== true){
|
||||
parent::despawnFrom($player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Server
|
||||
*/
|
||||
@ -520,7 +517,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
* @return bool
|
||||
*/
|
||||
public function isSleeping(){
|
||||
return $this->sleeping instanceof Vector3;
|
||||
return $this->sleeping !== null;
|
||||
}
|
||||
|
||||
public function unloadChunk($x, $z){
|
||||
@ -566,7 +563,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$index = $this->chunkACK[$identifier];
|
||||
unset($this->chunkACK[$identifier]);
|
||||
if(isset($this->usedChunks[$index])){
|
||||
$this->usedChunks[$index][0] = true;
|
||||
$this->usedChunks[$index] = true;
|
||||
$X = null;
|
||||
$Z = null;
|
||||
Level::getXZ($index, $X, $Z);
|
||||
@ -606,21 +603,24 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
if($count >= $this->chunksPerTick){
|
||||
break;
|
||||
}
|
||||
++$count;
|
||||
|
||||
$X = null;
|
||||
$Z = null;
|
||||
Level::getXZ($index, $X, $Z);
|
||||
|
||||
if(!$this->level->isChunkPopulated($X, $Z)){
|
||||
$this->level->generateChunk($X, $Z);
|
||||
if($this->spawned === true){
|
||||
if($this->spawned){
|
||||
continue;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
++$count;
|
||||
|
||||
unset($this->loadQueue[$index]);
|
||||
$this->usedChunks[$index] = [false, 0];
|
||||
$this->usedChunks[$index] = false;
|
||||
|
||||
$this->level->useChunk($X, $Z, $this);
|
||||
$this->level->requestChunk($X, $Z, $this, LevelProvider::ORDER_ZXY);
|
||||
@ -629,7 +629,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
if(count($this->usedChunks) >= 56 and $this->spawned === false){
|
||||
$spawned = 0;
|
||||
foreach($this->usedChunks as $d){
|
||||
if($d[0] === true){
|
||||
if($d === true){
|
||||
$spawned++;
|
||||
}
|
||||
}
|
||||
@ -660,6 +660,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->server->broadcastMessage($ev->getJoinMessage());
|
||||
}
|
||||
|
||||
$this->noDamageTicks = 60;
|
||||
|
||||
$this->spawnToAll();
|
||||
|
||||
if($this->server->getUpdater()->hasUpdate() and $this->hasPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE)){
|
||||
@ -673,7 +675,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->nextChunkOrderRun = 100;
|
||||
$this->nextChunkOrderRun = 200;
|
||||
|
||||
$radiusSquared = $this->viewDistance;
|
||||
$radius = ceil(sqrt($radiusSquared));
|
||||
@ -681,23 +683,41 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
$newOrder = [];
|
||||
$lastChunk = $this->usedChunks;
|
||||
$currentQueue = [];
|
||||
$centerX = $this->x >> 4;
|
||||
$centerZ = $this->z >> 4;
|
||||
$count = 0;
|
||||
for($X = -$side; $X <= $side; ++$X){
|
||||
for($Z = -$side; $Z <= $side; ++$Z){
|
||||
++$count;
|
||||
$chunkX = $X + $centerX;
|
||||
$chunkZ = $Z + $centerZ;
|
||||
if(!isset($this->usedChunks[$index = "$chunkX:$chunkZ"])){
|
||||
if(!isset($this->usedChunks[$index = Level::chunkHash($chunkX, $chunkZ)])){
|
||||
$newOrder[$index] = abs($X) + abs($Z);
|
||||
}else{
|
||||
$currentQueue[$index] = abs($X) + abs($Z);
|
||||
}
|
||||
unset($lastChunk[$index]);
|
||||
}
|
||||
}
|
||||
|
||||
$loadedChunks = max(0, count($this->usedChunks) - count($lastChunk));
|
||||
asort($newOrder);
|
||||
asort($currentQueue);
|
||||
|
||||
|
||||
$limit = $this->viewDistance;
|
||||
foreach($currentQueue as $index => $distance){
|
||||
if($limit-- <= 0){
|
||||
break;
|
||||
}
|
||||
unset($lastChunk[$index]);
|
||||
}
|
||||
|
||||
foreach($lastChunk as $index => $Yndex){
|
||||
$X = null;
|
||||
$Z = null;
|
||||
Level::getXZ($index, $X, $Z);
|
||||
$this->unloadChunk($X, $Z);
|
||||
}
|
||||
|
||||
$loadedChunks = count($this->usedChunks);
|
||||
|
||||
if((count($newOrder) + $loadedChunks) > $this->viewDistance){
|
||||
$count = $loadedChunks;
|
||||
$this->loadQueue = [];
|
||||
@ -711,14 +731,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->loadQueue = $newOrder;
|
||||
}
|
||||
|
||||
|
||||
foreach($lastChunk as $index => $Yndex){
|
||||
$X = null;
|
||||
$Z = null;
|
||||
Level::getXZ($index, $X, $Z);
|
||||
$this->unloadChunk($X, $Z);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -784,7 +796,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
public function sleepOn(Vector3 $pos){
|
||||
foreach($this->level->getNearbyEntities($this->boundingBox->grow(2, 1, 2), $this) as $p){
|
||||
if($p instanceof Player){
|
||||
if($p->sleeping instanceof Vector3){
|
||||
if($p->sleeping !== null){
|
||||
if($pos->distance($p->sleeping) <= 0.1){
|
||||
return false;
|
||||
}
|
||||
@ -853,7 +865,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
if($time >= Level::TIME_NIGHT and $time < Level::TIME_SUNRISE){
|
||||
foreach($this->level->getPlayers() as $p){
|
||||
if($p->sleeping === false){
|
||||
if($p->sleeping === null){
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1032,7 +1044,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
protected function getCreativeBlock(Item $item){
|
||||
foreach(Block::$creative as $i => $d){
|
||||
if($d[0] === $item->getID() and $d[1] === $item->getDamage()){
|
||||
if($d[0] === $item->getId() and $d[1] === $item->getDamage()){
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
@ -1040,6 +1052,14 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public function addEntityMotion($entityId, $x, $y, $z){
|
||||
$this->motionToSend[$entityId] = [$entityId, $x, $y, $z];
|
||||
}
|
||||
|
||||
public function addEntityMovement($entityId, $x, $y, $z, $yaw, $pitch){
|
||||
$this->moveToSend[$entityId] = [$entityId, $x, $y, $z, $yaw, $pitch];
|
||||
}
|
||||
|
||||
protected function processMovement($currentTick){
|
||||
if($this->dead or !$this->spawned or !($this->newPosition instanceof Vector3)){
|
||||
return;
|
||||
@ -1058,6 +1078,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$revert = true;
|
||||
$this->nextChunkOrderRun = 0;
|
||||
}else{
|
||||
if($this->chunk instanceof FullChunk){
|
||||
$this->chunk->removeEntity($this);
|
||||
}
|
||||
$this->chunk = $chunk;
|
||||
}
|
||||
}
|
||||
@ -1069,7 +1092,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$dz = $this->newPosition->z - $this->z;
|
||||
|
||||
//$this->inBlock = $this->checkObstruction($this->x, ($this->boundingBox->minY + $this->boundingBox->maxY) / 2, $this->z);
|
||||
$revert = !$this->move($dx, $dy, $dz);
|
||||
$this->move($dx, $dy, $dz);
|
||||
|
||||
$diffX = $this->x - $this->newPosition->x;
|
||||
$diffZ = $this->z - $this->newPosition->z;
|
||||
@ -1080,17 +1103,25 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
$diff = $diffX ** 2 + $diffY ** 2 + $diffZ ** 2;
|
||||
|
||||
if(!$revert and !$this->isSleeping() and $this->isSurvival()){
|
||||
if($diff > 0.0625){
|
||||
$revert = true;
|
||||
//$this->server->getLogger()->warning($this->getName()." moved wrongly!");
|
||||
}elseif($diff > 0){
|
||||
$this->x = $this->newPosition->x;
|
||||
$this->y = $this->newPosition->y;
|
||||
$this->z = $this->newPosition->z;
|
||||
$radius = $this->width / 2;
|
||||
$this->boundingBox->setBounds($this->x - $radius, $this->y + $this->ySize, $this->z - $radius, $this->x + $radius, $this->y + $this->height + $this->ySize, $this->z + $radius);
|
||||
if($this->isSurvival()){
|
||||
if(!$revert and !$this->isSleeping()){
|
||||
if($diff > 0.0625){
|
||||
$revert = true;
|
||||
$this->server->getLogger()->warning($this->getName()." moved wrongly!");
|
||||
}elseif($diff > 0){
|
||||
$this->x = $this->newPosition->x;
|
||||
$this->y = $this->newPosition->y;
|
||||
$this->z = $this->newPosition->z;
|
||||
$radius = $this->width / 2;
|
||||
$this->boundingBox->setBounds($this->x - $radius, $this->y + $this->ySize, $this->z - $radius, $this->x + $radius, $this->y + $this->height + $this->ySize, $this->z + $radius);
|
||||
}
|
||||
}
|
||||
}elseif($diff > 0){
|
||||
$this->x = $this->newPosition->x;
|
||||
$this->y = $this->newPosition->y;
|
||||
$this->z = $this->newPosition->z;
|
||||
$radius = $this->width / 2;
|
||||
$this->boundingBox->setBounds($this->x - $radius, $this->y + $this->ySize, $this->z - $radius, $this->x + $radius, $this->y + $this->height + $this->ySize, $this->z + $radius);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1101,6 +1132,9 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$deltaAngle = abs($this->lastYaw - $to->yaw) + abs($this->lastPitch - $to->pitch);
|
||||
|
||||
if(!$revert and ($delta > (1 / 16) or $deltaAngle > 10)){
|
||||
|
||||
$isFirst = ($this->lastX === null or $this->lastY === null or $this->lastZ === null);
|
||||
|
||||
$this->lastX = $to->x;
|
||||
$this->lastY = $to->y;
|
||||
$this->lastZ = $to->z;
|
||||
@ -1108,33 +1142,43 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->lastYaw = $to->yaw;
|
||||
$this->lastPitch = $to->pitch;
|
||||
|
||||
$ev = new PlayerMoveEvent($this, $from, $to);
|
||||
if(!$isFirst){
|
||||
$ev = new PlayerMoveEvent($this, $from, $to);
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
|
||||
if(!($revert = $ev->isCancelled())){ //Yes, this is intended
|
||||
if($to->distance($ev->getTo()) > 0.1){ //If plugins modify the destination
|
||||
$this->teleport($ev->getTo());
|
||||
}else{
|
||||
$pk = new MovePlayerPacket();
|
||||
$pk->eid = $this->id;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->yaw = $this->yaw;
|
||||
$pk->pitch = $this->pitch;
|
||||
$pk->bodyYaw = $this->yaw;
|
||||
if(!($revert = $ev->isCancelled())){ //Yes, this is intended
|
||||
if($to->distanceSquared($ev->getTo()) > 0.01){ //If plugins modify the destination
|
||||
$this->teleport($ev->getTo());
|
||||
}else{
|
||||
$pk = new MovePlayerPacket();
|
||||
$pk->eid = $this->id;
|
||||
$pk->x = $this->x;
|
||||
$pk->y = $this->y;
|
||||
$pk->z = $this->z;
|
||||
$pk->yaw = $this->yaw;
|
||||
$pk->pitch = $this->pitch;
|
||||
$pk->bodyYaw = $this->yaw;
|
||||
|
||||
Server::broadcastPacket($this->hasSpawned, $pk);
|
||||
Server::broadcastPacket($this->hasSpawned, $pk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($revert){
|
||||
|
||||
$this->lastX = $from->x;
|
||||
$this->lastY = $from->y;
|
||||
$this->lastZ = $from->z;
|
||||
|
||||
$this->lastYaw = $from->yaw;
|
||||
$this->lastPitch = $from->pitch;
|
||||
|
||||
$pk = new MovePlayerPacket();
|
||||
$pk->eid = 0;
|
||||
$pk->x = $from->x;
|
||||
$pk->y = $from->y + $this->getEyeHeight() + 0.01;
|
||||
$pk->y = $from->y + $this->getEyeHeight();
|
||||
$pk->z = $from->z;
|
||||
$pk->bodyYaw = $from->yaw;
|
||||
$pk->pitch = $from->pitch;
|
||||
@ -1145,7 +1189,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->newPosition = null;
|
||||
}else{
|
||||
$this->forceMovement = null;
|
||||
if($this->nextChunkOrderRun > 20){
|
||||
if($distanceSquared != 0 and $this->nextChunkOrderRun > 20){
|
||||
$this->nextChunkOrderRun = 20;
|
||||
}
|
||||
}
|
||||
@ -1156,8 +1200,12 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
|
||||
public function onUpdate($currentTick){
|
||||
if($this->dead === true){
|
||||
return true;
|
||||
if($this->dead === true and $this->spawned){
|
||||
++$this->deadTicks;
|
||||
if($this->deadTicks >= 10){
|
||||
$this->despawnFromAll();
|
||||
}
|
||||
return $this->deadTicks < 10;
|
||||
}
|
||||
|
||||
$this->timings->startTiming();
|
||||
@ -1199,11 +1247,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
$pk = new TakeItemEntityPacket();
|
||||
$pk->eid = 0;
|
||||
$pk->target = $entity->getID();
|
||||
$pk->target = $entity->getId();
|
||||
$this->dataPacket($pk);
|
||||
$pk = new TakeItemEntityPacket();
|
||||
$pk->eid = $this->getID();
|
||||
$pk->target = $entity->getID();
|
||||
$pk->eid = $this->getId();
|
||||
$pk->target = $entity->getId();
|
||||
Server::broadcastPacket($entity->getViewers(), $pk);
|
||||
$this->inventory->addItem(clone $item, $this);
|
||||
$entity->kill();
|
||||
@ -1222,7 +1270,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch($item->getID()){
|
||||
switch($item->getId()){
|
||||
case Item::WOOD:
|
||||
$this->awardAchievement("mineWood");
|
||||
break;
|
||||
@ -1233,11 +1281,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
$pk = new TakeItemEntityPacket();
|
||||
$pk->eid = 0;
|
||||
$pk->target = $entity->getID();
|
||||
$pk->target = $entity->getId();
|
||||
$this->dataPacket($pk);
|
||||
$pk = new TakeItemEntityPacket();
|
||||
$pk->eid = $this->getID();
|
||||
$pk->target = $entity->getID();
|
||||
$pk->eid = $this->getId();
|
||||
$pk->target = $entity->getId();
|
||||
Server::broadcastPacket($entity->getViewers(), $pk);
|
||||
$this->inventory->addItem(clone $item, $this);
|
||||
$entity->kill();
|
||||
@ -1255,6 +1303,21 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->sendNextChunk();
|
||||
}
|
||||
|
||||
if(count($this->moveToSend) > 0){
|
||||
$pk = new MoveEntityPacket();
|
||||
$pk->entities = $this->moveToSend;
|
||||
$this->dataPacket($pk);
|
||||
$this->moveToSend = [];
|
||||
}
|
||||
|
||||
|
||||
if(count($this->motionToSend) > 0){
|
||||
$pk = new SetEntityMotionPacket();
|
||||
$pk->entities = $this->motionToSend;
|
||||
$this->dataPacket($pk);
|
||||
$this->motionToSend = [];
|
||||
}
|
||||
|
||||
$this->timings->stopTiming();
|
||||
|
||||
return true;
|
||||
@ -1447,6 +1510,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->dead = true;
|
||||
}
|
||||
|
||||
$pk = new SetDifficultyPacket();
|
||||
$pk->difficulty = $this->server->getDifficulty();
|
||||
$this->dataPacket($pk);
|
||||
|
||||
$this->server->getLogger()->info(TextFormat::AQUA . $this->username . TextFormat::WHITE . "[/" . $this->ip . ":" . $this->port . "] logged in with entity id " . $this->id . " at (" . $this->level->getName() . ", " . round($this->x, 4) . ", " . round($this->y, 4) . ", " . round($this->z, 4) . ")");
|
||||
|
||||
|
||||
@ -1469,11 +1536,11 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->forceMovement = new Vector3($this->x, $this->y, $this->z);
|
||||
}
|
||||
|
||||
if($this->forceMovement instanceof Vector3 and ($revert or $newPos->distance($this->forceMovement) > 0.2)){
|
||||
if($this->forceMovement instanceof Vector3 and ($revert or $newPos->distanceSquared($this->forceMovement) > 0.04)){
|
||||
$pk = new MovePlayerPacket();
|
||||
$pk->eid = 0;
|
||||
$pk->x = $this->forceMovement->x;
|
||||
$pk->y = $this->forceMovement->y + $this->getEyeHeight() + 0.01;
|
||||
$pk->y = $this->forceMovement->y + $this->getEyeHeight();
|
||||
$pk->z = $this->forceMovement->z;
|
||||
$pk->bodyYaw = $packet->bodyYaw;
|
||||
$pk->pitch = $packet->pitch;
|
||||
@ -1531,7 +1598,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}else{
|
||||
$this->inventory->setHeldItemSlot($packet->slot); //set Air
|
||||
}
|
||||
}elseif(!isset($item) or $slot === -1 or $item->getID() !== $packet->item or $item->getDamage() !== $packet->meta){ // packet error or not implemented
|
||||
}elseif(!isset($item) or $slot === -1 or $item->getId() !== $packet->item or $item->getDamage() !== $packet->meta){ // packet error or not implemented
|
||||
$this->inventory->sendContents($this);
|
||||
break;
|
||||
}elseif($this->isCreative()){
|
||||
@ -1576,14 +1643,17 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
|
||||
break;
|
||||
}
|
||||
}elseif($this->inventory->getItemInHand()->getID() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
|
||||
}elseif($this->inventory->getItemInHand()->getId() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
|
||||
$this->inventory->sendHeldItem($this);
|
||||
}else{
|
||||
$item = $this->inventory->getItemInHand();
|
||||
$oldItem = clone $item;
|
||||
//TODO: Implement adventure mode checks
|
||||
if($this->level->useItemOn($blockVector, $item, $packet->face, $packet->fx, $packet->fy, $packet->fz, $this) === true){
|
||||
$this->inventory->setItemInHand($item, $this);
|
||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||
if(!$item->equals($oldItem, true) or $item->getCount() !== $oldItem->getCount()){
|
||||
$this->inventory->setItemInHand($item, $this);
|
||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1594,7 +1664,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$pk->x = $target->x;
|
||||
$pk->y = $target->y;
|
||||
$pk->z = $target->z;
|
||||
$pk->block = $target->getID();
|
||||
$pk->block = $target->getId();
|
||||
$pk->meta = $target->getDamage();
|
||||
$this->dataPacket($pk);
|
||||
|
||||
@ -1602,14 +1672,14 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$pk->x = $block->x;
|
||||
$pk->y = $block->y;
|
||||
$pk->z = $block->z;
|
||||
$pk->block = $block->getID();
|
||||
$pk->block = $block->getId();
|
||||
$pk->meta = $block->getDamage();
|
||||
$this->dataPacket($pk);
|
||||
break;
|
||||
}elseif($packet->face === 0xff){
|
||||
if($this->isCreative()){
|
||||
$item = $this->inventory->getItemInHand();
|
||||
}elseif($this->inventory->getItemInHand()->getID() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
|
||||
}elseif($this->inventory->getItemInHand()->getId() !== $packet->item or (($damage = $this->inventory->getItemInHand()->getDamage()) !== $packet->meta and $damage !== null)){
|
||||
$this->inventory->sendHeldItem($this);
|
||||
break;
|
||||
}else{
|
||||
@ -1626,7 +1696,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
break;
|
||||
}
|
||||
|
||||
if($item->getID() === Item::SNOWBALL){
|
||||
if($item->getId() === Item::SNOWBALL){
|
||||
$nbt = new Compound("", [
|
||||
"Pos" => new Enum("Pos", [
|
||||
new Double("", $this->x),
|
||||
@ -1676,7 +1746,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
switch($packet->action){
|
||||
case 5: //Shot arrow
|
||||
if($this->inventory->getItemInHand()->getID() === Item::BOW){
|
||||
if($this->inventory->getItemInHand()->getId() === Item::BOW){
|
||||
$bow = $this->inventory->getItemInHand();
|
||||
if($this->isSurvival()){
|
||||
if(!$this->inventory->contains(Item::get(Item::ARROW, 0, 1))){
|
||||
@ -1688,19 +1758,19 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
$nbt = new Compound("", [
|
||||
"Pos" => new Enum("Pos", [
|
||||
new Double("", $this->x),
|
||||
new Double("", $this->y + $this->getEyeHeight()),
|
||||
new Double("", $this->z)
|
||||
]),
|
||||
new Double("", $this->x),
|
||||
new Double("", $this->y + $this->getEyeHeight()),
|
||||
new Double("", $this->z)
|
||||
]),
|
||||
"Motion" => new Enum("Motion", [
|
||||
new Double("", -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI)),
|
||||
new Double("", -sin($this->pitch / 180 * M_PI)),
|
||||
new Double("", cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI))
|
||||
]),
|
||||
new Double("", -sin($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI)),
|
||||
new Double("", -sin($this->pitch / 180 * M_PI)),
|
||||
new Double("", cos($this->yaw / 180 * M_PI) * cos($this->pitch / 180 * M_PI))
|
||||
]),
|
||||
"Rotation" => new Enum("Rotation", [
|
||||
new Float("", $this->yaw),
|
||||
new Float("", $this->pitch)
|
||||
]),
|
||||
new Float("", $this->yaw),
|
||||
new Float("", $this->pitch)
|
||||
]),
|
||||
]);
|
||||
|
||||
$f = 1.5;
|
||||
@ -1754,13 +1824,17 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
if($this->isCreative()){
|
||||
$item = $this->inventory->getItemInHand();
|
||||
}else{
|
||||
$item = clone $this->inventory->getItemInHand();
|
||||
$item = $this->inventory->getItemInHand();
|
||||
}
|
||||
|
||||
$oldItem = clone $item;
|
||||
|
||||
if($this->level->useBreakOn($vector, $item, $this) === true){
|
||||
if($this->isSurvival()){
|
||||
$this->inventory->setItemInHand($item, $this);
|
||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||
if(!$item->equals($oldItem, true) or $item->getCount() !== $oldItem->getCount()){
|
||||
$this->inventory->setItemInHand($item, $this);
|
||||
$this->inventory->sendHeldItem($this->hasSpawned);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1773,7 +1847,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$pk->x = $target->x;
|
||||
$pk->y = $target->y;
|
||||
$pk->z = $target->z;
|
||||
$pk->block = $target->getID();
|
||||
$pk->block = $target->getId();
|
||||
$pk->meta = $target->getDamage();
|
||||
$this->dataPacket($pk);
|
||||
|
||||
@ -1807,7 +1881,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
if($target instanceof Entity and $this->getGamemode() !== Player::VIEW and $this->dead !== true and $target->dead !== true){
|
||||
if($target instanceof DroppedItem or $target instanceof Arrow){
|
||||
$this->kick("Attempting to attack an invalid entity");
|
||||
$this->server->getLogger()->warning("Player ". $this->getName() ." tried to attack an invalid entity");
|
||||
$this->server->getLogger()->warning("Player " . $this->getName() . " tried to attack an invalid entity");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1839,7 +1913,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
];
|
||||
|
||||
$damage = [
|
||||
EntityDamageEvent::MODIFIER_BASE => isset($damageTable[$item->getID()]) ? $damageTable[$item->getID()] : 1,
|
||||
EntityDamageEvent::MODIFIER_BASE => isset($damageTable[$item->getId()]) ? $damageTable[$item->getId()] : 1,
|
||||
];
|
||||
|
||||
if($this->distance($target) > 8){
|
||||
@ -1875,8 +1949,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
];
|
||||
$points = 0;
|
||||
foreach($target->getInventory()->getArmorContents() as $index => $i){
|
||||
if(isset($armorValues[$i->getID()])){
|
||||
$points += $armorValues[$i->getID()];
|
||||
if(isset($armorValues[$i->getId()])){
|
||||
$points += $armorValues[$i->getId()];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1919,7 +1993,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
|
||||
$pk = new AnimatePacket();
|
||||
$pk->eid = $this->getID();
|
||||
$pk->eid = $this->getId();
|
||||
$pk->action = $ev->getAnimationType();
|
||||
Server::broadcastPacket($this->getViewers(), $pk);
|
||||
break;
|
||||
@ -1933,11 +2007,15 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $this->getSpawn()));
|
||||
|
||||
$this->teleport($ev->getRespawnPosition());
|
||||
|
||||
$this->fireTicks = 0;
|
||||
$this->airTicks = 300;
|
||||
$this->deadTicks = 0;
|
||||
$this->noDamageTicks = 60;
|
||||
|
||||
$this->setHealth(20);
|
||||
$this->dead = false;
|
||||
|
||||
$this->sendMetadata($this->getViewers());
|
||||
$this->sendMetadata($this);
|
||||
|
||||
@ -1945,9 +2023,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->inventory->sendContents($this);
|
||||
$this->inventory->sendArmorContents($this);
|
||||
|
||||
$this->spawnToAll();
|
||||
|
||||
$this->blocked = false;
|
||||
|
||||
$this->spawnToAll();
|
||||
$this->scheduleUpdate();
|
||||
break;
|
||||
case ProtocolInfo::SET_HEALTH_PACKET: //Not used
|
||||
break;
|
||||
@ -1985,7 +2064,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
//Item::RAW_FISH => 2,
|
||||
];
|
||||
$slot = $this->inventory->getItemInHand();
|
||||
if($this->getHealth() < 20 and isset($items[$slot->getID()])){
|
||||
if($this->getHealth() < 20 and isset($items[$slot->getId()])){
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerItemConsumeEvent($this, $slot));
|
||||
if($ev->isCancelled()){
|
||||
$this->inventory->sendContents($this);
|
||||
@ -1996,10 +2075,10 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$pk->eid = 0;
|
||||
$pk->event = 9;
|
||||
$this->dataPacket($pk);
|
||||
$pk->eid = $this->getID();
|
||||
$pk->eid = $this->getId();
|
||||
Server::broadcastPacket($this->getViewers(), $pk);
|
||||
|
||||
$amount = $items[$slot->getID()];
|
||||
$amount = $items[$slot->getId()];
|
||||
$this->server->getPluginManager()->callEvent($ev = new EntityRegainHealthEvent($this, $amount, EntityRegainHealthEvent::CAUSE_EATING));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->heal($ev->getAmount(), $ev);
|
||||
@ -2007,7 +2086,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
|
||||
--$slot->count;
|
||||
$this->inventory->setItemInHand($slot, $this);
|
||||
if($slot->getID() === Item::MUSHROOM_STEW or $slot->getID() === Item::BEETROOT_SOUP){
|
||||
if($slot->getId() === Item::MUSHROOM_STEW or $slot->getId() === Item::BEETROOT_SOUP){
|
||||
$this->inventory->addItem(Item::get(Item::BOWL, 0, 1), $this);
|
||||
}
|
||||
}
|
||||
@ -2114,7 +2193,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
|
||||
|
||||
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() < (microtime(true) - 0.4)){
|
||||
if($this->currentTransaction === null or $this->currentTransaction->getCreationTime() < (microtime(true) - 8)){
|
||||
if($this->currentTransaction instanceof SimpleTransactionGroup){
|
||||
foreach($this->currentTransaction->getInventories() as $inventory){
|
||||
if($inventory instanceof PlayerInventory){
|
||||
@ -2129,19 +2208,16 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->currentTransaction->addTransaction($transaction);
|
||||
|
||||
if($this->currentTransaction->canExecute()){
|
||||
if(!$this->currentTransaction->execute()){
|
||||
$this->currentTransaction = null;
|
||||
break;
|
||||
}
|
||||
|
||||
foreach($this->currentTransaction->getTransactions() as $ts){
|
||||
$inv = $ts->getInventory();
|
||||
if($inv instanceof FurnaceInventory){
|
||||
if($ts->getSlot() === 2){
|
||||
switch($inv->getResult()->getID()){
|
||||
case Item::IRON_INGOT:
|
||||
$this->awardAchievement("acquireIron");
|
||||
break;
|
||||
if($this->currentTransaction->execute()){
|
||||
foreach($this->currentTransaction->getTransactions() as $ts){
|
||||
$inv = $ts->getInventory();
|
||||
if($inv instanceof FurnaceInventory){
|
||||
if($ts->getSlot() === 2){
|
||||
switch($inv->getResult()->getId()){
|
||||
case Item::IRON_INGOT:
|
||||
$this->awardAchievement("acquireIron");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2159,7 +2235,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
|
||||
if($craftingGroup->execute()){
|
||||
switch($craftingGroup->getResult()->getID()){
|
||||
switch($craftingGroup->getResult()->getId()){
|
||||
case Item::WORKBENCH:
|
||||
$this->awardAchievement("buildWorkBench");
|
||||
break;
|
||||
@ -2306,6 +2382,13 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
}
|
||||
}
|
||||
|
||||
foreach($this->server->getOnlinePlayers() as $player){
|
||||
if(!$player->canSee($this)){
|
||||
$player->showPlayer($this);
|
||||
}
|
||||
}
|
||||
$this->hiddenPlayers = [];
|
||||
|
||||
foreach($this->windowIndex as $window){
|
||||
$this->removeWindow($window);
|
||||
}
|
||||
@ -2316,6 +2399,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
foreach($this->usedChunks as $index => $d){
|
||||
Level::getXZ($index, $chunkX, $chunkZ);
|
||||
$this->level->freeChunk($chunkX, $chunkZ, $this);
|
||||
unset($this->usedChunks[$index]);
|
||||
}
|
||||
|
||||
parent::close();
|
||||
@ -2338,9 +2422,14 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
unset($this->buffer);
|
||||
}
|
||||
|
||||
$this->perm->clearPermissions();
|
||||
$this->server->removePlayer($this);
|
||||
}
|
||||
|
||||
public function __debugInfo(){
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles player data saving
|
||||
*/
|
||||
@ -2462,7 +2551,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
case EntityDamageEvent::CAUSE_ENTITY_EXPLOSION:
|
||||
$message = $this->getName() . " blew up";
|
||||
break;
|
||||
|
||||
|
||||
case EntityDamageEvent::CAUSE_MAGIC:
|
||||
case EntityDamageEvent::CAUSE_CUSTOM:
|
||||
|
||||
@ -2491,9 +2580,6 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
if($ev->getDeathMessage() != ""){
|
||||
$this->server->broadcast($ev->getDeathMessage(), Server::BROADCAST_CHANNEL_USERS);
|
||||
}
|
||||
|
||||
$this->despawnFromAll();
|
||||
|
||||
}
|
||||
|
||||
public function setHealth($amount){
|
||||
@ -2509,6 +2595,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
if($this->dead === true){
|
||||
return;
|
||||
}
|
||||
|
||||
if($this->isCreative()){
|
||||
if($source instanceof EntityDamageEvent){
|
||||
$cause = $source->getCause();
|
||||
@ -2547,7 +2634,7 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$flags = 0;
|
||||
$flags |= $this->fireTicks > 0 ? 1 : 0;
|
||||
//$flags |= ($this->crouched === true ? 0b10:0) << 1;
|
||||
$flags |= ($this->inAction === true ? 0b10000:0);
|
||||
$flags |= ($this->inAction === true ? 0b10000 : 0);
|
||||
$d = [
|
||||
0 => ["type" => 0, "value" => $flags],
|
||||
1 => ["type" => 1, "value" => $this->airTicks],
|
||||
@ -2579,8 +2666,8 @@ class Player extends Human implements CommandSender, InventoryHolder, IPlayer{
|
||||
$this->fallDistance = 0;
|
||||
$this->orderChunks();
|
||||
$this->nextChunkOrderRun = 0;
|
||||
$this->forceMovement = $pos;
|
||||
$this->newPosition = $pos;
|
||||
$this->forceMovement = new Vector3($this->x, $this->y, $this->z);
|
||||
$this->newPosition = null;
|
||||
|
||||
$pk = new MovePlayerPacket();
|
||||
$pk->eid = 0;
|
||||
|
@ -70,10 +70,10 @@ namespace pocketmine {
|
||||
use pocketmine\utils\Utils;
|
||||
use pocketmine\wizard\Installer;
|
||||
|
||||
const VERSION = "Alpha_1.4dev";
|
||||
const API_VERSION = "1.7.0";
|
||||
const VERSION = "1.4";
|
||||
const API_VERSION = "1.10.0";
|
||||
const CODENAME = "絶好(Zekkou)ケーキ(Cake)";
|
||||
const MINECRAFT_VERSION = "v0.9.5 alpha";
|
||||
const MINECRAFT_VERSION = "v0.10.4 alpha";
|
||||
|
||||
/*
|
||||
* Startup code. Do not look at it, it may harm you.
|
||||
@ -136,15 +136,15 @@ namespace pocketmine {
|
||||
if(!ini_get("date.timezone")){
|
||||
if(($timezone = detect_system_timezone()) and date_default_timezone_set($timezone)){
|
||||
//Success! Timezone has already been set and validated in the if statement.
|
||||
//This here is just for redundancy just in case some stupid program wants to read timezone data from the ini.
|
||||
//This here is just for redundancy just in case some program wants to read timezone data from the ini.
|
||||
ini_set("date.timezone", $timezone);
|
||||
}else{
|
||||
//If system timezone detection fails or timezone is an invalid value.
|
||||
if($response = Utils::getURL("http://ip-api.com/json")
|
||||
and $ip_geolocation_data = json_decode($response, true)
|
||||
and $ip_geolocation_data['status'] != 'fail'
|
||||
and date_default_timezone_set($ip_geolocation_data['timezone']))
|
||||
{
|
||||
and date_default_timezone_set($ip_geolocation_data['timezone'])
|
||||
){
|
||||
//Again, for redundancy.
|
||||
ini_set("date.timezone", $ip_geolocation_data['timezone']);
|
||||
}else{
|
||||
@ -155,7 +155,8 @@ namespace pocketmine {
|
||||
}
|
||||
}else{
|
||||
/*
|
||||
* This is here so that stupid idiots don't come to us complaining and fill up the issue tracker when they put an incorrect timezone abbreviation in php.ini apparently.
|
||||
* This is here so that people don't come to us complaining and fill up the issue tracker when they put
|
||||
* an incorrect timezone abbreviation in php.ini apparently.
|
||||
*/
|
||||
$default_timezone = date_default_timezone_get();
|
||||
if(strpos($default_timezone, "/") === false){
|
||||
@ -168,17 +169,30 @@ namespace pocketmine {
|
||||
function detect_system_timezone(){
|
||||
switch(Utils::getOS()){
|
||||
case 'win':
|
||||
$regex = '/(?:Time Zone:\s*\()(UTC)(\+*\-*\d*\d*\:*\d*\d*)(?:\))/';
|
||||
$regex = '/(UTC)(\+*\-*\d*\d*\:*\d*\d*)/';
|
||||
|
||||
exec("systeminfo", $output);
|
||||
/*
|
||||
* wmic timezone get Caption
|
||||
* Get the timezone offset
|
||||
*
|
||||
* Sample Output var_dump
|
||||
* array(3) {
|
||||
* [0] =>
|
||||
* string(7) "Caption"
|
||||
* [1] =>
|
||||
* string(20) "(UTC+09:30) Adelaide"
|
||||
* [2] =>
|
||||
* string(0) ""
|
||||
* }
|
||||
*/
|
||||
exec("wmic timezone get Caption", $output);
|
||||
|
||||
$string = trim(implode("\n", $output));
|
||||
|
||||
//Detect the Time Zone string in systeminfo
|
||||
//Detect the Time Zone string
|
||||
preg_match($regex, $string, $matches);
|
||||
|
||||
if(!isset($matches[2]))
|
||||
{
|
||||
if(!isset($matches[2])){
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -236,6 +250,7 @@ namespace pocketmine {
|
||||
|
||||
/**
|
||||
* @param string $offset In the format of +09:00, +02:00, -04:00 etc.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function parse_offset($offset){
|
||||
@ -352,8 +367,8 @@ namespace pocketmine {
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
}
|
||||
if(version_compare($pthreads_version, "2.0.8") < 0){
|
||||
$logger->critical("pthreads >= 2.0.8 is required, while you have $pthreads_version.");
|
||||
if(version_compare($pthreads_version, "2.0.9") < 0){
|
||||
$logger->critical("pthreads >= 2.0.9 is required, while you have $pthreads_version.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ use pocketmine\inventory\InventoryType;
|
||||
use pocketmine\inventory\Recipe;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\format\anvil\Anvil;
|
||||
use pocketmine\level\format\leveldb\LevelDB;
|
||||
use pocketmine\level\format\LevelProviderManager;
|
||||
use pocketmine\level\format\mcregion\McRegion;
|
||||
use pocketmine\level\generator\Flat;
|
||||
@ -149,8 +150,8 @@ class Server{
|
||||
*/
|
||||
private $tickCounter;
|
||||
private $nextTick = 0;
|
||||
private $tickAverage = [20,20,20,20,20];
|
||||
private $useAverage = [20,20,20,20,20];
|
||||
private $tickAverage = [20, 20, 20, 20, 20];
|
||||
private $useAverage = [20, 20, 20, 20, 20];
|
||||
|
||||
/** @var \AttachableThreadedLogger */
|
||||
private $logger;
|
||||
@ -299,7 +300,7 @@ class Server{
|
||||
* @return int
|
||||
*/
|
||||
public function getViewDistance(){
|
||||
return max(56, $this->getProperty("chunk-sending.max-chunks"));
|
||||
return max(56, $this->getProperty("chunk-sending.max-chunks", 256));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,7 +314,7 @@ class Server{
|
||||
* @return string
|
||||
*/
|
||||
public function getServerName(){
|
||||
return $this->getConfigString("motd", "Unknown server");
|
||||
return $this->getConfigString("motd", "Minecraft: PE Server");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -621,6 +622,16 @@ class Server{
|
||||
$this->mainInterface->putRaw($address, $port, $payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks an IP address from the main interface. Setting timeout to -1 will block it forever
|
||||
*
|
||||
* @param string $address
|
||||
* @param int $timeout
|
||||
*/
|
||||
public function blockAddress($address, $timeout = 300){
|
||||
$this->mainInterface->blockAddress($address, $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $address
|
||||
* @param int $port
|
||||
@ -632,9 +643,13 @@ class Server{
|
||||
$this->queryHandler->handle($address, $port, $payload);
|
||||
}
|
||||
}catch(\Exception $e){
|
||||
if($this->logger instanceof MainLogger){
|
||||
$this->logger->logException($e);
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
if($this->logger instanceof MainLogger){
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
}
|
||||
|
||||
$this->blockAddress($address, 600);
|
||||
}
|
||||
//TODO: add raw packet events
|
||||
}
|
||||
@ -681,107 +696,112 @@ class Server{
|
||||
public function getOfflinePlayerData($name){
|
||||
$name = strtolower($name);
|
||||
$path = $this->getDataPath() . "players/";
|
||||
if(!file_exists($path . "$name.dat")){
|
||||
$spawn = $this->getDefaultLevel()->getSafeSpawn();
|
||||
$nbt = new Compound(false, [
|
||||
new Long("firstPlayed", floor(microtime(true) * 1000)),
|
||||
new Long("lastPlayed", floor(microtime(true) * 1000)),
|
||||
new Enum("Pos", [
|
||||
new Double(0, $spawn->x),
|
||||
new Double(1, $spawn->y),
|
||||
new Double(2, $spawn->z)
|
||||
]),
|
||||
new String("Level", $this->getDefaultLevel()->getName()),
|
||||
//new String("SpawnLevel", $this->getDefaultLevel()->getName()),
|
||||
//new Int("SpawnX", (int) $spawn->x),
|
||||
//new Int("SpawnY", (int) $spawn->y),
|
||||
//new Int("SpawnZ", (int) $spawn->z),
|
||||
//new Byte("SpawnForced", 1), //TODO
|
||||
new Enum("Inventory", []),
|
||||
new Compound("Achievements", []),
|
||||
new Int("playerGameType", $this->getGamemode()),
|
||||
new Enum("Motion", [
|
||||
new Double(0, 0.0),
|
||||
new Double(1, 0.0),
|
||||
new Double(2, 0.0)
|
||||
]),
|
||||
new Enum("Rotation", [
|
||||
new Float(0, 0.0),
|
||||
new Float(1, 0.0)
|
||||
]),
|
||||
new Float("FallDistance", 0.0),
|
||||
new Short("Fire", 0),
|
||||
new Short("Air", 0),
|
||||
new Byte("OnGround", 1),
|
||||
new Byte("Invulnerable", 0),
|
||||
new String("NameTag", $name),
|
||||
]);
|
||||
$nbt->Pos->setTagType(NBT::TAG_Double);
|
||||
$nbt->Inventory->setTagType(NBT::TAG_Compound);
|
||||
$nbt->Motion->setTagType(NBT::TAG_Double);
|
||||
$nbt->Rotation->setTagType(NBT::TAG_Float);
|
||||
if(file_exists($path . "$name.dat")){
|
||||
try{
|
||||
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||
$nbt->readCompressed(file_get_contents($path . "$name.dat"));
|
||||
|
||||
if(file_exists($path . "$name.yml")){ //Importing old PocketMine-MP files
|
||||
$data = new Config($path . "$name.yml", Config::YAML, []);
|
||||
$nbt["playerGameType"] = (int) $data->get("gamemode");
|
||||
$nbt["Level"] = $data->get("position")["level"];
|
||||
$nbt["Pos"][0] = $data->get("position")["x"];
|
||||
$nbt["Pos"][1] = $data->get("position")["y"];
|
||||
$nbt["Pos"][2] = $data->get("position")["z"];
|
||||
$nbt["SpawnLevel"] = $data->get("spawn")["level"];
|
||||
$nbt["SpawnX"] = (int) $data->get("spawn")["x"];
|
||||
$nbt["SpawnY"] = (int) $data->get("spawn")["y"];
|
||||
$nbt["SpawnZ"] = (int) $data->get("spawn")["z"];
|
||||
$this->logger->notice("Old Player data found for \"" . $name . "\", upgrading profile");
|
||||
foreach($data->get("inventory") as $slot => $item){
|
||||
if(count($item) === 3){
|
||||
$nbt->Inventory[$slot + 9] = new Compound(false, [
|
||||
new Short("id", $item[0]),
|
||||
new Short("Damage", $item[1]),
|
||||
new Byte("Count", $item[2]),
|
||||
new Byte("Slot", $slot + 9),
|
||||
new Byte("TrueSlot", $slot + 9)
|
||||
]);
|
||||
}
|
||||
}
|
||||
foreach($data->get("hotbar") as $slot => $itemSlot){
|
||||
if(isset($nbt->Inventory[$itemSlot + 9])){
|
||||
$item = $nbt->Inventory[$itemSlot + 9];
|
||||
$nbt->Inventory[$slot] = new Compound(false, [
|
||||
new Short("id", $item["id"]),
|
||||
new Short("Damage", $item["Damage"]),
|
||||
new Byte("Count", $item["Count"]),
|
||||
new Byte("Slot", $slot),
|
||||
new Byte("TrueSlot", $item["TrueSlot"])
|
||||
]);
|
||||
}
|
||||
}
|
||||
foreach($data->get("armor") as $slot => $item){
|
||||
if(count($item) === 2){
|
||||
$nbt->Inventory[$slot + 100] = new Compound(false, [
|
||||
new Short("id", $item[0]),
|
||||
new Short("Damage", $item[1]),
|
||||
new Byte("Count", 1),
|
||||
new Byte("Slot", $slot + 100)
|
||||
]);
|
||||
}
|
||||
}
|
||||
foreach($data->get("achievements") as $achievement => $status){
|
||||
$nbt->Achievements[$achievement] = new Byte($achievement, $status == true ? 1 : 0);
|
||||
}
|
||||
unlink($path . "$name.yml");
|
||||
}else{
|
||||
$this->logger->notice("Player data not found for \"" . $name . "\", creating new profile");
|
||||
return $nbt->getData();
|
||||
}catch(\Exception $e){ //zlib decode error / corrupt data
|
||||
rename($path . "$name.dat", $path . "$name.dat.bak");
|
||||
$this->logger->warning("Corrupted data found for \"" . $name . "\", creating new profile");
|
||||
}
|
||||
$this->saveOfflinePlayerData($name, $nbt);
|
||||
|
||||
return $nbt;
|
||||
}else{
|
||||
$nbt = new NBT(NBT::BIG_ENDIAN);
|
||||
$nbt->readCompressed(file_get_contents($path . "$name.dat"));
|
||||
|
||||
return $nbt->getData();
|
||||
$this->logger->notice("Player data not found for \"" . $name . "\", creating new profile");
|
||||
}
|
||||
$spawn = $this->getDefaultLevel()->getSafeSpawn();
|
||||
$nbt = new Compound(false, [
|
||||
new Long("firstPlayed", floor(microtime(true) * 1000)),
|
||||
new Long("lastPlayed", floor(microtime(true) * 1000)),
|
||||
new Enum("Pos", [
|
||||
new Double(0, $spawn->x),
|
||||
new Double(1, $spawn->y),
|
||||
new Double(2, $spawn->z)
|
||||
]),
|
||||
new String("Level", $this->getDefaultLevel()->getName()),
|
||||
//new String("SpawnLevel", $this->getDefaultLevel()->getName()),
|
||||
//new Int("SpawnX", (int) $spawn->x),
|
||||
//new Int("SpawnY", (int) $spawn->y),
|
||||
//new Int("SpawnZ", (int) $spawn->z),
|
||||
//new Byte("SpawnForced", 1), //TODO
|
||||
new Enum("Inventory", []),
|
||||
new Compound("Achievements", []),
|
||||
new Int("playerGameType", $this->getGamemode()),
|
||||
new Enum("Motion", [
|
||||
new Double(0, 0.0),
|
||||
new Double(1, 0.0),
|
||||
new Double(2, 0.0)
|
||||
]),
|
||||
new Enum("Rotation", [
|
||||
new Float(0, 0.0),
|
||||
new Float(1, 0.0)
|
||||
]),
|
||||
new Float("FallDistance", 0.0),
|
||||
new Short("Fire", 0),
|
||||
new Short("Air", 0),
|
||||
new Byte("OnGround", 1),
|
||||
new Byte("Invulnerable", 0),
|
||||
new String("NameTag", $name),
|
||||
]);
|
||||
$nbt->Pos->setTagType(NBT::TAG_Double);
|
||||
$nbt->Inventory->setTagType(NBT::TAG_Compound);
|
||||
$nbt->Motion->setTagType(NBT::TAG_Double);
|
||||
$nbt->Rotation->setTagType(NBT::TAG_Float);
|
||||
|
||||
if(file_exists($path . "$name.yml")){ //Importing old PocketMine-MP files
|
||||
$data = new Config($path . "$name.yml", Config::YAML, []);
|
||||
$nbt["playerGameType"] = (int) $data->get("gamemode");
|
||||
$nbt["Level"] = $data->get("position")["level"];
|
||||
$nbt["Pos"][0] = $data->get("position")["x"];
|
||||
$nbt["Pos"][1] = $data->get("position")["y"];
|
||||
$nbt["Pos"][2] = $data->get("position")["z"];
|
||||
$nbt["SpawnLevel"] = $data->get("spawn")["level"];
|
||||
$nbt["SpawnX"] = (int) $data->get("spawn")["x"];
|
||||
$nbt["SpawnY"] = (int) $data->get("spawn")["y"];
|
||||
$nbt["SpawnZ"] = (int) $data->get("spawn")["z"];
|
||||
$this->logger->notice("Old Player data found for \"" . $name . "\", upgrading profile");
|
||||
foreach($data->get("inventory") as $slot => $item){
|
||||
if(count($item) === 3){
|
||||
$nbt->Inventory[$slot + 9] = new Compound(false, [
|
||||
new Short("id", $item[0]),
|
||||
new Short("Damage", $item[1]),
|
||||
new Byte("Count", $item[2]),
|
||||
new Byte("Slot", $slot + 9),
|
||||
new Byte("TrueSlot", $slot + 9)
|
||||
]);
|
||||
}
|
||||
}
|
||||
foreach($data->get("hotbar") as $slot => $itemSlot){
|
||||
if(isset($nbt->Inventory[$itemSlot + 9])){
|
||||
$item = $nbt->Inventory[$itemSlot + 9];
|
||||
$nbt->Inventory[$slot] = new Compound(false, [
|
||||
new Short("id", $item["id"]),
|
||||
new Short("Damage", $item["Damage"]),
|
||||
new Byte("Count", $item["Count"]),
|
||||
new Byte("Slot", $slot),
|
||||
new Byte("TrueSlot", $item["TrueSlot"])
|
||||
]);
|
||||
}
|
||||
}
|
||||
foreach($data->get("armor") as $slot => $item){
|
||||
if(count($item) === 2){
|
||||
$nbt->Inventory[$slot + 100] = new Compound(false, [
|
||||
new Short("id", $item[0]),
|
||||
new Short("Damage", $item[1]),
|
||||
new Byte("Count", 1),
|
||||
new Byte("Slot", $slot + 100)
|
||||
]);
|
||||
}
|
||||
}
|
||||
foreach($data->get("achievements") as $achievement => $status){
|
||||
$nbt->Achievements[$achievement] = new Byte($achievement, $status == true ? 1 : 0);
|
||||
}
|
||||
unlink($path . "$name.yml");
|
||||
}
|
||||
$this->saveOfflinePlayerData($name, $nbt);
|
||||
|
||||
return $nbt;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -939,7 +959,7 @@ class Server{
|
||||
*/
|
||||
public function unloadLevel(Level $level, $forceUnload = false){
|
||||
if($level->unload($forceUnload) === true){
|
||||
unset($this->levels[$level->getID()]);
|
||||
unset($this->levels[$level->getId()]);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -986,11 +1006,13 @@ class Server{
|
||||
$level = new Level($this, $name, $path, $provider);
|
||||
}catch(\Exception $e){
|
||||
$this->logger->error("Could not load level \"" . $name . "\": " . $e->getMessage());
|
||||
|
||||
if($this->logger instanceof MainLogger){
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->levels[$level->getID()] = $level;
|
||||
$this->levels[$level->getId()] = $level;
|
||||
|
||||
$level->initLevel();
|
||||
|
||||
@ -1125,7 +1147,7 @@ class Server{
|
||||
$provider::generate($path, $name, $seed, $generator, $options);
|
||||
|
||||
$level = new Level($this, $name, $path, $provider);
|
||||
$this->levels[$level->getID()] = $level;
|
||||
$this->levels[$level->getId()] = $level;
|
||||
|
||||
$level->initLevel();
|
||||
|
||||
@ -1219,24 +1241,9 @@ class Server{
|
||||
* @return mixed
|
||||
*/
|
||||
public function getProperty($variable, $defaultValue = null){
|
||||
$vars = explode(".", $variable);
|
||||
$base = array_shift($vars);
|
||||
if($this->config->exists($base)){
|
||||
$base = $this->config->get($base);
|
||||
}else{
|
||||
return $defaultValue;
|
||||
}
|
||||
$value = $this->config->getNested($variable);
|
||||
|
||||
while(count($vars) > 0){
|
||||
$baseKey = array_shift($vars);
|
||||
if(is_array($base) and isset($base[$baseKey])){
|
||||
$base = $base[$baseKey];
|
||||
}else{
|
||||
return $defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $base;
|
||||
return $value === null ? $defaultValue : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1401,7 +1408,7 @@ class Server{
|
||||
/**
|
||||
* @return Config
|
||||
*/
|
||||
public function getOPs(){
|
||||
public function getOps(){
|
||||
return $this->operators;
|
||||
}
|
||||
|
||||
@ -1439,7 +1446,7 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ClassLoader $autoloader
|
||||
* @param \ClassLoader $autoloader
|
||||
* @param \ThreadedLogger $logger
|
||||
* @param string $filePath
|
||||
* @param string $dataPath
|
||||
@ -1564,8 +1571,8 @@ class Server{
|
||||
|
||||
$this->addInterface($this->mainInterface = new RakLibInterface($this));
|
||||
|
||||
$this->logger->info("This server is running " . $this->getName() . " version " . ($version->isDev() ? TextFormat::YELLOW : "") . $version->get(true) . TextFormat::RESET . " \"" . $this->getCodename() . "\" (API " . $this->getApiVersion() . ")", true, true, 0);
|
||||
$this->logger->info($this->getName() . " is distributed under the LGPL License", true, true, 0);
|
||||
$this->logger->info("This server is running " . $this->getName() . " version " . ($version->isDev() ? TextFormat::YELLOW : "") . $version->get(true) . TextFormat::WHITE . " \"" . $this->getCodename() . "\" (API " . $this->getApiVersion() . ")");
|
||||
$this->logger->info($this->getName() . " is distributed under the LGPL License");
|
||||
|
||||
PluginManager::$pluginParentTimer = new TimingsHandler("** Plugins");
|
||||
Timings::init();
|
||||
@ -1604,20 +1611,17 @@ class Server{
|
||||
|
||||
LevelProviderManager::addProvider($this, Anvil::class);
|
||||
LevelProviderManager::addProvider($this, McRegion::class);
|
||||
if(extension_loaded("leveldb")){
|
||||
$this->logger->debug("Enabling LevelDB support");
|
||||
LevelProviderManager::addProvider($this, LevelDB::class);
|
||||
}
|
||||
|
||||
|
||||
Generator::addGenerator(Flat::class, "flat");
|
||||
Generator::addGenerator(Normal::class, "normal");
|
||||
Generator::addGenerator(Normal::class, "default");
|
||||
|
||||
//Temporal workaround, pthreads static property nullification test
|
||||
if(PluginManager::$pluginParentTimer === null or Timings::$serverTickTimer === null){
|
||||
$this->getLogger()->emergency("You are using an invalid pthreads version. Please update your binaries.");
|
||||
kill(getmypid());
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($this->getProperty("worlds", []) as $name => $worldSetting){
|
||||
foreach((array) $this->getProperty("worlds", []) as $name => $worldSetting){
|
||||
if($this->loadLevel($name) === false){
|
||||
$seed = $this->getProperty("worlds.$name.seed", time());
|
||||
$options = explode(":", $this->getProperty("worlds.$name.generator", Generator::getGenerator("default")));
|
||||
@ -1674,7 +1678,7 @@ class Server{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $message
|
||||
* @param $message
|
||||
* @param Player[]|null $recipients
|
||||
*
|
||||
* @return int
|
||||
@ -1840,6 +1844,9 @@ class Server{
|
||||
$this->reloadWhitelist();
|
||||
$this->operators->reload();
|
||||
|
||||
foreach($this->getIPBans()->getEntries() as $entry){
|
||||
$this->blockAddress($entry->getName(), -1);
|
||||
}
|
||||
|
||||
$this->pluginManager->registerInterface(PharPluginLoader::class);
|
||||
$this->pluginManager->loadPlugins($this->pluginPath);
|
||||
@ -1900,7 +1907,7 @@ class Server{
|
||||
foreach($this->interfaces as $interface){
|
||||
$interface->shutdown();
|
||||
}
|
||||
}catch (\Exception $e){
|
||||
}catch(\Exception $e){
|
||||
$this->logger->emergency("Crashed while crashing, killing process");
|
||||
@kill(getmypid());
|
||||
}
|
||||
@ -1917,6 +1924,9 @@ class Server{
|
||||
|
||||
}
|
||||
|
||||
foreach($this->getIPBans()->getEntries() as $entry){
|
||||
$this->blockAddress($entry->getName(), -1);
|
||||
}
|
||||
|
||||
if($this->getProperty("settings.send-usage", true) !== false){
|
||||
$this->scheduler->scheduleDelayedRepeatingTask(new CallbackTask([$this, "sendUsage"]), 6000, 6000);
|
||||
@ -1980,6 +1990,10 @@ class Server{
|
||||
|
||||
global $lastError;
|
||||
|
||||
if($trace === null){
|
||||
$trace = $e->getTrace();
|
||||
}
|
||||
|
||||
$errstr = $e->getMessage();
|
||||
$errfile = $e->getFile();
|
||||
$errno = $e->getCode();
|
||||
@ -2002,7 +2016,7 @@ class Server{
|
||||
"fullFile" => $e->getFile(),
|
||||
"file" => $errfile,
|
||||
"line" => $errline,
|
||||
"trace" => @getTrace($trace === null ? 3 : 0, $trace)
|
||||
"trace" => @getTrace(1, $trace)
|
||||
];
|
||||
|
||||
global $lastExceptionError, $lastError;
|
||||
@ -2083,7 +2097,14 @@ class Server{
|
||||
|
||||
//Do level ticks
|
||||
foreach($this->getLevels() as $level){
|
||||
$level->doTick($currentTick);
|
||||
try{
|
||||
$level->doTick($currentTick);
|
||||
}catch(\Exception $e){
|
||||
$this->logger->critical("Could not tick level " . $level->getName() . ": " . $e->getMessage());
|
||||
if(\pocketmine\DEBUG > 1 and $this->logger instanceof MainLogger){
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2147,7 +2168,7 @@ class Server{
|
||||
|
||||
private function titleTick(){
|
||||
if(defined("pocketmine\\DEBUG") and \pocketmine\DEBUG >= 0 and \pocketmine\ANSI === true){
|
||||
echo "\x1b]0;". $this->getName() . " " . $this->getPocketMineVersion() . " | Online " . count($this->players) . "/" . $this->getMaxPlayers() . " | RAM " . round((memory_get_usage() / 1024) / 1024, 2) . "/" . round((memory_get_usage(true) / 1024) / 1024, 2) . " MB | U " . round($this->mainInterface->getUploadUsage() / 1024, 2) . " D " . round($this->mainInterface->getDownloadUsage() / 1024, 2) . " kB/s | TPS " . $this->getTicksPerSecond() . " | Load ". $this->getTickUsage() . "%\x07";
|
||||
echo "\x1b]0;" . $this->getName() . " " . $this->getPocketMineVersion() . " | Online " . count($this->players) . "/" . $this->getMaxPlayers() . " | RAM " . round((memory_get_usage() / 1024) / 1024, 2) . "/" . round((memory_get_usage(true) / 1024) / 1024, 2) . " MB | U " . round($this->mainInterface->getUploadUsage() / 1024, 2) . " D " . round($this->mainInterface->getDownloadUsage() / 1024, 2) . " kB/s | TPS " . $this->getTicksPerSecond() . " | Load " . $this->getTickUsage() . "%\x07";
|
||||
}
|
||||
}
|
||||
|
||||
@ -2192,7 +2213,15 @@ class Server{
|
||||
}
|
||||
}
|
||||
|
||||
$this->generationManager->process();
|
||||
Timings::$generationTimer->startTiming();
|
||||
try{
|
||||
$this->generationManager->process();
|
||||
}catch(\Exception $e){
|
||||
if($this->logger instanceof MainLogger){
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
}
|
||||
Timings::$generationTimer->stopTiming();
|
||||
|
||||
if(($this->tickCounter % 100) === 0){
|
||||
foreach($this->levels as $level){
|
||||
|
@ -24,8 +24,15 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class AcaciaWoodStairs extends Stair{
|
||||
|
||||
protected $id = self::ACACIA_WOOD_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::ACACIA_WOOD_STAIRS, $meta, "Acacia Wood Stairs");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Acacia Wood Stairs";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -21,29 +21,45 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
|
||||
|
||||
/**
|
||||
* Air block
|
||||
*/
|
||||
class Air extends Transparent{
|
||||
public $isActivable = false;
|
||||
public $breakable = false;
|
||||
public $isFlowable = true;
|
||||
public $isTransparent = true;
|
||||
public $isReplaceable = true;
|
||||
public $isPlaceable = false;
|
||||
public $hasPhysics = false;
|
||||
public $isSolid = false;
|
||||
public $isFullBlock = true;
|
||||
|
||||
protected $id = self::AIR;
|
||||
protected $meta = 0;
|
||||
protected $name = "Air";
|
||||
protected $hardness = 0;
|
||||
|
||||
public function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Air";
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeFlowedInto(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBePlaced(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
@ -28,11 +28,23 @@ use pocketmine\network\protocol\ChatPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Bed extends Transparent{
|
||||
public function __construct($type = 0){
|
||||
parent::__construct(self::BED_BLOCK, $type, "Bed Block");
|
||||
$this->isActivable = true;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 1;
|
||||
|
||||
protected $id = self::BED_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Bed Block";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -67,13 +79,13 @@ class Bed extends Transparent{
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
$b = $this;
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$b = $blockNorth;
|
||||
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$b = $blockSouth;
|
||||
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$b = $blockEast;
|
||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$b = $blockWest;
|
||||
}else{
|
||||
if($player instanceof Player){
|
||||
@ -97,7 +109,7 @@ class Bed extends Transparent{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent === false){
|
||||
if($down->isTransparent() === false){
|
||||
$faces = [
|
||||
0 => 3,
|
||||
1 => 4,
|
||||
@ -107,7 +119,7 @@ class Bed extends Transparent{
|
||||
$d = $player instanceof Player ? $player->getDirection() : 0;
|
||||
$next = $this->getSide($faces[(($d + 3) % 4)]);
|
||||
$downNext = $this->getSide(0);
|
||||
if($next->isReplaceable === true and $downNext->isTransparent === false){
|
||||
if($next->canBeReplaced() === true and $downNext->isTransparent() === false){
|
||||
$meta = (($d + 3) % 4) & 0x03;
|
||||
$this->getLevel()->setBlock($block, Block::get($this->id, $meta), true, true);
|
||||
$this->getLevel()->setBlock($next, Block::get($this->id, $meta | 0x08), true, true);
|
||||
@ -126,23 +138,23 @@ class Bed extends Transparent{
|
||||
$blockWest = $this->getSide(4);
|
||||
|
||||
if(($this->meta & 0x08) === 0x08){ //This is the Top part of bed
|
||||
if($blockNorth->getID() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
|
||||
if($blockNorth->getId() === $this->id and $blockNorth->meta !== 0x08){ //Checks if the block ID and meta are right
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getID() === $this->id and $blockSouth->meta !== 0x08){
|
||||
}elseif($blockSouth->getId() === $this->id and $blockSouth->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getID() === $this->id and $blockEast->meta !== 0x08){
|
||||
}elseif($blockEast->getId() === $this->id and $blockEast->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getID() === $this->id and $blockWest->meta !== 0x08){
|
||||
}elseif($blockWest->getId() === $this->id and $blockWest->meta !== 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
}else{ //Bottom Part of Bed
|
||||
if($blockNorth->getID() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
if($blockNorth->getId() === $this->id and ($blockNorth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockNorth, new Air(), true, true);
|
||||
}elseif($blockSouth->getID() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
}elseif($blockSouth->getId() === $this->id and ($blockSouth->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockSouth, new Air(), true, true);
|
||||
}elseif($blockEast->getID() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
}elseif($blockEast->getId() === $this->id and ($blockEast->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockEast, new Air(), true, true);
|
||||
}elseif($blockWest->getID() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
}elseif($blockWest->getId() === $this->id and ($blockWest->meta & 0x08) === 0x08){
|
||||
$this->getLevel()->setBlock($blockWest, new Air(), true, true);
|
||||
}
|
||||
}
|
||||
|
@ -24,10 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Bedrock extends Solid{
|
||||
|
||||
protected $id = self::BEDROCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::BEDROCK, 0, "Bedrock");
|
||||
$this->breakable = false;
|
||||
$this->hardness = 18000000;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Bedrock";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
|
@ -24,8 +24,15 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Beetroot extends Crops{
|
||||
|
||||
protected $id = self::BEETROOT_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::BEETROOT_BLOCK, $meta, "Beetroot Block");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Beetroot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -24,8 +24,15 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class BirchWoodStairs extends Stair{
|
||||
|
||||
protected $id = self::BIRCH_WOOD_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::BIRCH_WOOD_STAIRS, $meta, "Birch Wood Stairs");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Birch Wood Stairs";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -144,6 +144,7 @@ class Block extends Position implements Metadatable{
|
||||
const SUGARCANE_BLOCK = 83;
|
||||
|
||||
const FENCE = 85;
|
||||
const FENCE_OAK = 85;
|
||||
const PUMPKIN = 86;
|
||||
const NETHERRACK = 87;
|
||||
const SOUL_SAND = 88;
|
||||
@ -179,7 +180,7 @@ class Block extends Position implements Metadatable{
|
||||
|
||||
const NETHER_BRICKS_STAIRS = 114;
|
||||
|
||||
const END_PORTAL = 120;
|
||||
const END_PORTAL_FRAME = 120;
|
||||
const END_STONE = 121;
|
||||
|
||||
const SANDSTONE_STAIRS = 128;
|
||||
@ -228,6 +229,19 @@ class Block extends Position implements Metadatable{
|
||||
const HARDENED_CLAY = 172;
|
||||
const COAL_BLOCK = 173;
|
||||
|
||||
const DOUBLE_PLANT = 175;
|
||||
|
||||
const FENCE_GATE_SPRUCE = 183;
|
||||
const FENCE_GATE_BIRCH = 184;
|
||||
const FENCE_GATE_JUNGLE = 185;
|
||||
const FENCE_GATE_DARK_OAK = 186;
|
||||
const FENCE_GATE_ACACIA = 187;
|
||||
const FENCE_SPRUCE = 188;
|
||||
const FENCE_BIRCH = 189;
|
||||
const FENCE_JUNGLE = 190;
|
||||
const FENCE_DARK_OAK = 191;
|
||||
const FENCE_ACACIA = 192;
|
||||
|
||||
const PODZOL = 243;
|
||||
const BEETROOT_BLOCK = 244;
|
||||
const STONECUTTER = 245;
|
||||
@ -354,7 +368,16 @@ class Block extends Position implements Metadatable{
|
||||
[Item::WOODEN_DOOR, 0],
|
||||
[Item::TRAPDOOR, 0],
|
||||
[Item::FENCE, 0],
|
||||
[Item::FENCE_SPRUCE, 0],
|
||||
[Item::FENCE_BIRCH, 0],
|
||||
[Item::FENCE_DARK_OAK, 0],
|
||||
[Item::FENCE_JUNGLE, 0],
|
||||
[Item::FENCE_GATE, 0],
|
||||
[Item::FENCE_GATE_BIRCH, 0],
|
||||
[Item::FENCE_GATE_SPRUCE, 0],
|
||||
[Item::FENCE_GATE_DARK_OAK, 0],
|
||||
[Item::FENCE_GATE_JUNGLE, 0],
|
||||
[Item::FENCE_GATE_ACACIA, 0],
|
||||
[Item::IRON_BARS, 0],
|
||||
[Item::BED, 0],
|
||||
[Item::BOOKSHELF, 0],
|
||||
@ -507,170 +530,245 @@ class Block extends Position implements Metadatable{
|
||||
|
||||
/** @var \SplFixedArray */
|
||||
public static $list = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $fullList = null;
|
||||
|
||||
/** @var \SplFixedArray */
|
||||
public static $light = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $lightFilter = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $solid = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $hardness = null;
|
||||
/** @var \SplFixedArray */
|
||||
public static $transparent = null;
|
||||
|
||||
protected $id;
|
||||
protected $meta;
|
||||
protected $name = "Unknown";
|
||||
protected $breakTime = 0.20;
|
||||
protected $hardness = 10;
|
||||
public $hasEntityCollision = false;
|
||||
public $isActivable = false;
|
||||
public $breakable = true;
|
||||
public $isFlowable = false;
|
||||
public $isSolid = true;
|
||||
public $isTransparent = false;
|
||||
public $isReplaceable = false;
|
||||
public $isPlaceable = true;
|
||||
public $hasPhysics = false;
|
||||
public $isLiquid = false;
|
||||
public $isFullBlock = true;
|
||||
public $x = 0;
|
||||
public $y = 0;
|
||||
public $z = 0;
|
||||
public $frictionFactor = 0.6;
|
||||
protected $meta = 0;
|
||||
|
||||
/** @var AxisAlignedBB */
|
||||
protected $boundingBox = null;
|
||||
|
||||
/**
|
||||
* Backwards-compatibility with old way to define block properties
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($key){
|
||||
static $map = [
|
||||
"hardness" => "getHardness",
|
||||
"lightLevel" => "getLightLevel",
|
||||
"frictionFactor" => "getFrictionFactor",
|
||||
"name" => "getName",
|
||||
"isPlaceable" => "canBePlaced",
|
||||
"isReplaceable" => "canBeReplaced",
|
||||
"isTransparent" => "isTransparent",
|
||||
"isSolid" => "isSolid",
|
||||
"isFlowable" => "canBeFlowedInto",
|
||||
"isActivable" => "canBeActivated",
|
||||
"hasEntityCollision" => "hasEntityCollision"
|
||||
];
|
||||
return isset($map[$key]) ? $this->{$map[$key]}() : null;
|
||||
}
|
||||
|
||||
public static function init(){
|
||||
if(self::$list === null){
|
||||
self::$list = new \SplFixedArray(256);
|
||||
self::$list[self::AIR] = Air::class;;
|
||||
self::$list[self::STONE] = Stone::class;;
|
||||
self::$list[self::GRASS] = Grass::class;;
|
||||
self::$list[self::DIRT] = Dirt::class;;
|
||||
self::$list[self::COBBLESTONE] = Cobblestone::class;;
|
||||
self::$list[self::PLANKS] = Planks::class;;
|
||||
self::$list[self::SAPLING] = Sapling::class;;
|
||||
self::$list[self::BEDROCK] = Bedrock::class;;
|
||||
self::$list[self::WATER] = Water::class;;
|
||||
self::$list[self::STILL_WATER] = StillWater::class;;
|
||||
self::$list[self::LAVA] = Lava::class;;
|
||||
self::$list[self::STILL_LAVA] = StillLava::class;;
|
||||
self::$list[self::SAND] = Sand::class;;
|
||||
self::$list[self::GRAVEL] = Gravel::class;;
|
||||
self::$list[self::GOLD_ORE] = GoldOre::class;;
|
||||
self::$list[self::IRON_ORE] = IronOre::class;;
|
||||
self::$list[self::COAL_ORE] = CoalOre::class;;
|
||||
self::$list[self::WOOD] = Wood::class;;
|
||||
self::$list[self::LEAVES] = Leaves::class;;
|
||||
self::$list[self::SPONGE] = Sponge::class;;
|
||||
self::$list[self::GLASS] = Glass::class;;
|
||||
self::$list[self::LAPIS_ORE] = LapisOre::class;;
|
||||
self::$list[self::LAPIS_BLOCK] = Lapis::class;;
|
||||
self::$list[self::SANDSTONE] = Sandstone::class;;
|
||||
self::$list[self::BED_BLOCK] = Bed::class;;
|
||||
self::$list[self::COBWEB] = Cobweb::class;;
|
||||
self::$list[self::TALL_GRASS] = TallGrass::class;;
|
||||
self::$list[self::DEAD_BUSH] = DeadBush::class;;
|
||||
self::$list[self::WOOL] = Wool::class;;
|
||||
self::$list[self::DANDELION] = Dandelion::class;;
|
||||
self::$list[self::POPPY] = CyanFlower::class;;
|
||||
self::$list[self::BROWN_MUSHROOM] = BrownMushroom::class;;
|
||||
self::$list[self::RED_MUSHROOM] = RedMushroom::class;;
|
||||
self::$list[self::GOLD_BLOCK] = Gold::class;;
|
||||
self::$list[self::IRON_BLOCK] = Iron::class;;
|
||||
self::$list[self::DOUBLE_SLAB] = DoubleSlab::class;;
|
||||
self::$list[self::SLAB] = Slab::class;;
|
||||
self::$list[self::BRICKS_BLOCK] = Bricks::class;;
|
||||
self::$list[self::TNT] = TNT::class;;
|
||||
self::$list[self::BOOKSHELF] = Bookshelf::class;;
|
||||
self::$list[self::MOSS_STONE] = MossStone::class;;
|
||||
self::$list[self::OBSIDIAN] = Obsidian::class;;
|
||||
self::$list[self::TORCH] = Torch::class;;
|
||||
self::$list[self::FIRE] = Fire::class;;
|
||||
self::$list[self::MONSTER_SPAWNER] = MonsterSpawner::class;;
|
||||
self::$list[self::WOOD_STAIRS] = WoodStairs::class;;
|
||||
self::$list[self::CHEST] = Chest::class;;
|
||||
self::$fullList = new \SplFixedArray(4096);
|
||||
self::$light = new \SplFixedArray(256);
|
||||
self::$lightFilter = new \SplFixedArray(256);
|
||||
self::$solid = new \SplFixedArray(256);
|
||||
self::$hardness = new \SplFixedArray(256);
|
||||
self::$transparent = new \SplFixedArray(256);
|
||||
self::$list[self::AIR] = Air::class;
|
||||
self::$list[self::STONE] = Stone::class;
|
||||
self::$list[self::GRASS] = Grass::class;
|
||||
self::$list[self::DIRT] = Dirt::class;
|
||||
self::$list[self::COBBLESTONE] = Cobblestone::class;
|
||||
self::$list[self::PLANKS] = Planks::class;
|
||||
self::$list[self::SAPLING] = Sapling::class;
|
||||
self::$list[self::BEDROCK] = Bedrock::class;
|
||||
self::$list[self::WATER] = Water::class;
|
||||
self::$list[self::STILL_WATER] = StillWater::class;
|
||||
self::$list[self::LAVA] = Lava::class;
|
||||
self::$list[self::STILL_LAVA] = StillLava::class;
|
||||
self::$list[self::SAND] = Sand::class;
|
||||
self::$list[self::GRAVEL] = Gravel::class;
|
||||
self::$list[self::GOLD_ORE] = GoldOre::class;
|
||||
self::$list[self::IRON_ORE] = IronOre::class;
|
||||
self::$list[self::COAL_ORE] = CoalOre::class;
|
||||
self::$list[self::WOOD] = Wood::class;
|
||||
self::$list[self::LEAVES] = Leaves::class;
|
||||
self::$list[self::SPONGE] = Sponge::class;
|
||||
self::$list[self::GLASS] = Glass::class;
|
||||
self::$list[self::LAPIS_ORE] = LapisOre::class;
|
||||
self::$list[self::LAPIS_BLOCK] = Lapis::class;
|
||||
self::$list[self::SANDSTONE] = Sandstone::class;
|
||||
self::$list[self::BED_BLOCK] = Bed::class;
|
||||
self::$list[self::COBWEB] = Cobweb::class;
|
||||
self::$list[self::TALL_GRASS] = TallGrass::class;
|
||||
self::$list[self::DEAD_BUSH] = DeadBush::class;
|
||||
self::$list[self::WOOL] = Wool::class;
|
||||
self::$list[self::DANDELION] = Dandelion::class;
|
||||
self::$list[self::POPPY] = Poppy::class;
|
||||
self::$list[self::BROWN_MUSHROOM] = BrownMushroom::class;
|
||||
self::$list[self::RED_MUSHROOM] = RedMushroom::class;
|
||||
self::$list[self::GOLD_BLOCK] = Gold::class;
|
||||
self::$list[self::IRON_BLOCK] = Iron::class;
|
||||
self::$list[self::DOUBLE_SLAB] = DoubleSlab::class;
|
||||
self::$list[self::SLAB] = Slab::class;
|
||||
self::$list[self::BRICKS_BLOCK] = Bricks::class;
|
||||
self::$list[self::TNT] = TNT::class;
|
||||
self::$list[self::BOOKSHELF] = Bookshelf::class;
|
||||
self::$list[self::MOSS_STONE] = MossStone::class;
|
||||
self::$list[self::OBSIDIAN] = Obsidian::class;
|
||||
self::$list[self::TORCH] = Torch::class;
|
||||
self::$list[self::FIRE] = Fire::class;
|
||||
self::$list[self::MONSTER_SPAWNER] = MonsterSpawner::class;
|
||||
self::$list[self::WOOD_STAIRS] = WoodStairs::class;
|
||||
self::$list[self::CHEST] = Chest::class;
|
||||
|
||||
self::$list[self::DIAMOND_ORE] = DiamondOre::class;;
|
||||
self::$list[self::DIAMOND_BLOCK] = Diamond::class;;
|
||||
self::$list[self::WORKBENCH] = Workbench::class;;
|
||||
self::$list[self::WHEAT_BLOCK] = Wheat::class;;
|
||||
self::$list[self::FARMLAND] = Farmland::class;;
|
||||
self::$list[self::FURNACE] = Furnace::class;;
|
||||
self::$list[self::BURNING_FURNACE] = BurningFurnace::class;;
|
||||
self::$list[self::SIGN_POST] = SignPost::class;;
|
||||
self::$list[self::WOOD_DOOR_BLOCK] = WoodDoor::class;;
|
||||
self::$list[self::LADDER] = Ladder::class;;
|
||||
self::$list[self::DIAMOND_ORE] = DiamondOre::class;
|
||||
self::$list[self::DIAMOND_BLOCK] = Diamond::class;
|
||||
self::$list[self::WORKBENCH] = Workbench::class;
|
||||
self::$list[self::WHEAT_BLOCK] = Wheat::class;
|
||||
self::$list[self::FARMLAND] = Farmland::class;
|
||||
self::$list[self::FURNACE] = Furnace::class;
|
||||
self::$list[self::BURNING_FURNACE] = BurningFurnace::class;
|
||||
self::$list[self::SIGN_POST] = SignPost::class;
|
||||
self::$list[self::WOOD_DOOR_BLOCK] = WoodDoor::class;
|
||||
self::$list[self::LADDER] = Ladder::class;
|
||||
|
||||
self::$list[self::COBBLESTONE_STAIRS] = CobblestoneStairs::class;;
|
||||
self::$list[self::WALL_SIGN] = WallSign::class;;
|
||||
self::$list[self::COBBLESTONE_STAIRS] = CobblestoneStairs::class;
|
||||
self::$list[self::WALL_SIGN] = WallSign::class;
|
||||
|
||||
self::$list[self::IRON_DOOR_BLOCK] = IronDoor::class;;
|
||||
self::$list[self::REDSTONE_ORE] = RedstoneOre::class;;
|
||||
self::$list[self::GLOWING_REDSTONE_ORE] = GlowingRedstoneOre::class;;
|
||||
self::$list[self::IRON_DOOR_BLOCK] = IronDoor::class;
|
||||
self::$list[self::REDSTONE_ORE] = RedstoneOre::class;
|
||||
self::$list[self::GLOWING_REDSTONE_ORE] = GlowingRedstoneOre::class;
|
||||
|
||||
self::$list[self::SNOW_LAYER] = SnowLayer::class;;
|
||||
self::$list[self::ICE] = Ice::class;;
|
||||
self::$list[self::SNOW_BLOCK] = Snow::class;;
|
||||
self::$list[self::CACTUS] = Cactus::class;;
|
||||
self::$list[self::CLAY_BLOCK] = Clay::class;;
|
||||
self::$list[self::SUGARCANE_BLOCK] = Sugarcane::class;;
|
||||
self::$list[self::SNOW_LAYER] = SnowLayer::class;
|
||||
self::$list[self::ICE] = Ice::class;
|
||||
self::$list[self::SNOW_BLOCK] = Snow::class;
|
||||
self::$list[self::CACTUS] = Cactus::class;
|
||||
self::$list[self::CLAY_BLOCK] = Clay::class;
|
||||
self::$list[self::SUGARCANE_BLOCK] = Sugarcane::class;
|
||||
|
||||
self::$list[self::FENCE] = Fence::class;;
|
||||
self::$list[self::PUMPKIN] = Pumpkin::class;;
|
||||
self::$list[self::NETHERRACK] = Netherrack::class;;
|
||||
self::$list[self::SOUL_SAND] = SoulSand::class;;
|
||||
self::$list[self::GLOWSTONE_BLOCK] = Glowstone::class;;
|
||||
self::$list[self::FENCE] = Fence::class;
|
||||
self::$list[self::PUMPKIN] = Pumpkin::class;
|
||||
self::$list[self::NETHERRACK] = Netherrack::class;
|
||||
self::$list[self::SOUL_SAND] = SoulSand::class;
|
||||
self::$list[self::GLOWSTONE_BLOCK] = Glowstone::class;
|
||||
|
||||
self::$list[self::LIT_PUMPKIN] = LitPumpkin::class;;
|
||||
self::$list[self::CAKE_BLOCK] = Cake::class;;
|
||||
self::$list[self::LIT_PUMPKIN] = LitPumpkin::class;
|
||||
self::$list[self::CAKE_BLOCK] = Cake::class;
|
||||
|
||||
self::$list[self::TRAPDOOR] = Trapdoor::class;;
|
||||
self::$list[self::TRAPDOOR] = Trapdoor::class;
|
||||
|
||||
self::$list[self::STONE_BRICKS] = StoneBricks::class;;
|
||||
self::$list[self::STONE_BRICKS] = StoneBricks::class;
|
||||
|
||||
self::$list[self::IRON_BARS] = IronBars::class;;
|
||||
self::$list[self::GLASS_PANE] = GlassPane::class;;
|
||||
self::$list[self::MELON_BLOCK] = Melon::class;;
|
||||
self::$list[self::PUMPKIN_STEM] = PumpkinStem::class;;
|
||||
self::$list[self::MELON_STEM] = MelonStem::class;;
|
||||
self::$list[self::VINE] = Vine::class;;
|
||||
self::$list[self::FENCE_GATE] = FenceGate::class;;
|
||||
self::$list[self::BRICK_STAIRS] = BrickStairs::class;;
|
||||
self::$list[self::STONE_BRICK_STAIRS] = StoneBrickStairs::class;;
|
||||
self::$list[self::IRON_BARS] = IronBars::class;
|
||||
self::$list[self::GLASS_PANE] = GlassPane::class;
|
||||
self::$list[self::MELON_BLOCK] = Melon::class;
|
||||
self::$list[self::PUMPKIN_STEM] = PumpkinStem::class;
|
||||
self::$list[self::MELON_STEM] = MelonStem::class;
|
||||
self::$list[self::VINE] = Vine::class;
|
||||
self::$list[self::FENCE_GATE] = FenceGate::class;
|
||||
self::$list[self::BRICK_STAIRS] = BrickStairs::class;
|
||||
self::$list[self::STONE_BRICK_STAIRS] = StoneBrickStairs::class;
|
||||
|
||||
self::$list[self::MYCELIUM] = Mycelium::class;;
|
||||
self::$list[self::NETHER_BRICKS] = NetherBrick::class;;
|
||||
self::$list[self::MYCELIUM] = Mycelium::class;
|
||||
self::$list[self::NETHER_BRICKS] = NetherBrick::class;
|
||||
|
||||
self::$list[self::NETHER_BRICKS_STAIRS] = NetherBrickStairs::class;;
|
||||
self::$list[self::NETHER_BRICKS_STAIRS] = NetherBrickStairs::class;
|
||||
|
||||
self::$list[self::END_PORTAL] = EndPortal::class;;
|
||||
self::$list[self::END_STONE] = EndStone::class;;
|
||||
self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class;;
|
||||
self::$list[self::EMERALD_ORE] = EmeraldOre::class;;
|
||||
self::$list[self::END_PORTAL_FRAME] = EndPortalFrame::class;
|
||||
self::$list[self::END_STONE] = EndStone::class;
|
||||
self::$list[self::SANDSTONE_STAIRS] = SandstoneStairs::class;
|
||||
self::$list[self::EMERALD_ORE] = EmeraldOre::class;
|
||||
|
||||
self::$list[self::EMERALD_BLOCK] = Emerald::class;;
|
||||
self::$list[self::SPRUCE_WOOD_STAIRS] = SpruceWoodStairs::class;;
|
||||
self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class;;
|
||||
self::$list[self::JUNGLE_WOOD_STAIRS] = JungleWoodStairs::class;;
|
||||
self::$list[self::STONE_WALL] = StoneWall::class;;
|
||||
self::$list[self::EMERALD_BLOCK] = Emerald::class;
|
||||
self::$list[self::SPRUCE_WOOD_STAIRS] = SpruceWoodStairs::class;
|
||||
self::$list[self::BIRCH_WOOD_STAIRS] = BirchWoodStairs::class;
|
||||
self::$list[self::JUNGLE_WOOD_STAIRS] = JungleWoodStairs::class;
|
||||
self::$list[self::STONE_WALL] = StoneWall::class;
|
||||
|
||||
self::$list[self::CARROT_BLOCK] = Carrot::class;;
|
||||
self::$list[self::POTATO_BLOCK] = Potato::class;;
|
||||
self::$list[self::CARROT_BLOCK] = Carrot::class;
|
||||
self::$list[self::POTATO_BLOCK] = Potato::class;
|
||||
|
||||
self::$list[self::QUARTZ_BLOCK] = Quartz::class;;
|
||||
self::$list[self::QUARTZ_STAIRS] = QuartzStairs::class;;
|
||||
self::$list[self::DOUBLE_WOOD_SLAB] = DoubleWoodSlab::class;;
|
||||
self::$list[self::WOOD_SLAB] = WoodSlab::class;;
|
||||
self::$list[self::STAINED_CLAY] = StainedClay::class;;
|
||||
self::$list[self::QUARTZ_BLOCK] = Quartz::class;
|
||||
self::$list[self::QUARTZ_STAIRS] = QuartzStairs::class;
|
||||
self::$list[self::DOUBLE_WOOD_SLAB] = DoubleWoodSlab::class;
|
||||
self::$list[self::WOOD_SLAB] = WoodSlab::class;
|
||||
self::$list[self::STAINED_CLAY] = StainedClay::class;
|
||||
|
||||
self::$list[self::LEAVES2] = Leaves2::class;;
|
||||
self::$list[self::WOOD2] = Wood2::class;;
|
||||
self::$list[self::ACACIA_WOOD_STAIRS] = AcaciaWoodStairs::class;;
|
||||
self::$list[self::DARK_OAK_WOOD_STAIRS] = DarkOakWoodStairs::class;;
|
||||
self::$list[self::LEAVES2] = Leaves2::class;
|
||||
self::$list[self::WOOD2] = Wood2::class;
|
||||
self::$list[self::ACACIA_WOOD_STAIRS] = AcaciaWoodStairs::class;
|
||||
self::$list[self::DARK_OAK_WOOD_STAIRS] = DarkOakWoodStairs::class;
|
||||
|
||||
self::$list[self::HAY_BALE] = HayBale::class;;
|
||||
self::$list[self::CARPET] = Carpet::class;;
|
||||
self::$list[self::HARDENED_CLAY] = HardenedClay::class;;
|
||||
self::$list[self::COAL_BLOCK] = Coal::class;;
|
||||
self::$list[self::HAY_BALE] = HayBale::class;
|
||||
self::$list[self::CARPET] = Carpet::class;
|
||||
self::$list[self::HARDENED_CLAY] = HardenedClay::class;
|
||||
self::$list[self::COAL_BLOCK] = Coal::class;
|
||||
|
||||
self::$list[self::PODZOL] = Podzol::class;;
|
||||
self::$list[self::BEETROOT_BLOCK] = Beetroot::class;;
|
||||
self::$list[self::STONECUTTER] = Stonecutter::class;;
|
||||
self::$list[self::GLOWING_OBSIDIAN] = GlowingObsidian::class;;
|
||||
self::$list[self::NETHER_REACTOR] = NetherReactor::class;;
|
||||
self::$list[self::DOUBLE_PLANT] = DoublePlant::class;
|
||||
|
||||
self::$list[self::FENCE_GATE_SPRUCE] = FenceGateSpruce::class;
|
||||
self::$list[self::FENCE_GATE_BIRCH] = FenceGateBirch::class;
|
||||
self::$list[self::FENCE_GATE_JUNGLE] = FenceGateJungle::class;
|
||||
self::$list[self::FENCE_GATE_DARK_OAK] = FenceGateDarkOak::class;
|
||||
self::$list[self::FENCE_GATE_ACACIA] = FenceGateAcacia::class;
|
||||
self::$list[self::FENCE_SPRUCE] = FenceSpruce::class;
|
||||
self::$list[self::FENCE_BIRCH] = FenceBirch::class;
|
||||
self::$list[self::FENCE_DARK_OAK] = FenceDarkOak::class;
|
||||
self::$list[self::FENCE_JUNGLE] = FenceJungle::class;
|
||||
self::$list[self::FENCE_ACACIA] = FenceAcacia::class;
|
||||
|
||||
self::$list[self::PODZOL] = Podzol::class;
|
||||
self::$list[self::BEETROOT_BLOCK] = Beetroot::class;
|
||||
self::$list[self::STONECUTTER] = Stonecutter::class;
|
||||
self::$list[self::GLOWING_OBSIDIAN] = GlowingObsidian::class;
|
||||
self::$list[self::NETHER_REACTOR] = NetherReactor::class;
|
||||
|
||||
foreach(self::$list as $id => $class){
|
||||
if($class !== null){
|
||||
/** @var Block $block */
|
||||
$block = new $class();
|
||||
|
||||
for($data = 0; $data < 16; ++$data){
|
||||
self::$fullList[($id << 4) | $data] = new $class($data);
|
||||
}
|
||||
|
||||
self::$solid[$id] = $block->isSolid();
|
||||
self::$transparent[$id] = $block->isTransparent();
|
||||
self::$hardness[$id] = $block->getHardness();
|
||||
self::$light[$id] = $block->getLightLevel();
|
||||
|
||||
if($block->isSolid()){
|
||||
if($block->isTransparent()){
|
||||
if($block instanceof Liquid or $block instanceof Ice){
|
||||
self::$lightFilter[$id] = 2;
|
||||
}else{
|
||||
self::$lightFilter[$id] = 1;
|
||||
}
|
||||
}else{
|
||||
self::$lightFilter[$id] = 15;
|
||||
}
|
||||
}else{
|
||||
self::$lightFilter[$id] = 1;
|
||||
}
|
||||
}else{
|
||||
self::$lightFilter[$id] = 1;
|
||||
for($data = 0; $data < 16; ++$data){
|
||||
self::$fullList[($id << 4) | $data] = new Block($id, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -704,14 +802,12 @@ class Block extends Position implements Metadatable{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
* @param string $name
|
||||
* @param int $id
|
||||
* @param int $meta
|
||||
*/
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
public function __construct($id, $meta = 0){
|
||||
$this->id = (int) $id;
|
||||
$this->meta = (int) $meta;
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -740,7 +836,7 @@ class Block extends Position implements Metadatable{
|
||||
* @return bool
|
||||
*/
|
||||
public function isBreakable(Item $item){
|
||||
return $this->breakable;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -774,21 +870,86 @@ class Block extends Position implements Metadatable{
|
||||
* @return bool
|
||||
*/
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
return $this->isActivable;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
final public function getHardness(){
|
||||
return $this->hardness;
|
||||
public function getHardness(){
|
||||
return 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float
|
||||
*/
|
||||
public function getFrictionFactor(){
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int 0-15
|
||||
*/
|
||||
public function getLightLevel(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isPlaceable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBePlaced(){
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->canBeReplaced()
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeReplaced(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isTransparent(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isFlowable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeFlowedInto(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* AKA: Block->isActivable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeActivated(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
final public function getName(){
|
||||
return $this->name;
|
||||
public function getName(){
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -813,7 +974,7 @@ class Block extends Position implements Metadatable{
|
||||
* @param int $meta
|
||||
*/
|
||||
final public function setDamage($meta){
|
||||
$this->meta = $meta & 0x0F;
|
||||
$this->meta = $meta & 0x0f;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -853,7 +1014,7 @@ class Block extends Position implements Metadatable{
|
||||
* @return float
|
||||
*/
|
||||
public function getBreakTime(Item $item){
|
||||
return $this->breakTime;
|
||||
return 0.20;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -865,19 +1026,18 @@ class Block extends Position implements Metadatable{
|
||||
* @return Block
|
||||
*/
|
||||
public function getSide($side, $step = 1){
|
||||
$v = parent::getSide($side, $step);
|
||||
if($this->isValid()){
|
||||
return $this->getLevel()->getBlock($v);
|
||||
return $this->getLevel()->getBlock(Vector3::getSide($side, $step));
|
||||
}
|
||||
|
||||
return Block::get(Item::AIR, 0, $v);
|
||||
return Block::get(Item::AIR, 0, new Position($v->x, $v->y, $v->z, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
final public function __toString(){
|
||||
return "Block " . $this->name . " (" . $this->id . ":" . $this->meta . ")";
|
||||
public function __toString(){
|
||||
return "Block[" . $this->getName() . "] (" . $this->id . ":" . $this->meta . ")";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,9 +23,19 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class Bookshelf extends Solid{
|
||||
|
||||
protected $id = self::BOOKSHELF;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::BOOKSHELF, 0, "Bookshelf");
|
||||
$this->hardness = 7.5;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Bookshelf";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 7.5;
|
||||
}
|
||||
|
||||
}
|
@ -23,8 +23,15 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class BrickStairs extends Stair{
|
||||
|
||||
protected $id = self::BRICK_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::BRICK_STAIRS, $meta, "Brick Stairs");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Brick Stairs";
|
||||
}
|
||||
|
||||
}
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Bricks extends Solid{
|
||||
|
||||
protected $id = self::BRICKS_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::BRICKS_BLOCK, 0, "Bricks");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Bricks";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -26,14 +26,24 @@ use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class BrownMushroom extends Flowable{
|
||||
public function __construct(){
|
||||
parent::__construct(self::BROWN_MUSHROOM, 0, "Brown Mushroom");
|
||||
$this->hardness = 0;
|
||||
|
||||
protected $id = self::BROWN_MUSHROOM;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Brown Mushroom";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
@ -45,7 +55,7 @@ class BrownMushroom extends Flowable{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->isTransparent === false){
|
||||
if($down->isTransparent() === false){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
|
@ -32,10 +32,27 @@ use pocketmine\tile\Furnace;
|
||||
use pocketmine\tile\Tile;
|
||||
|
||||
class BurningFurnace extends Solid{
|
||||
|
||||
protected $id = self::BURNING_FURNACE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::BURNING_FURNACE, $meta, "Burning Furnace");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 17.5;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Burning Furnace";
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 17.5;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 13;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
|
@ -34,12 +34,22 @@ use pocketmine\Server;
|
||||
|
||||
class Cactus extends Transparent{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
protected $id = self::CACTUS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CACTUS, $meta, "Cactus");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 2;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Cactus";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -62,7 +72,7 @@ class Cactus extends Transparent{
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::SAND and $down->getID() !== self::CACTUS){
|
||||
if($down->getId() !== self::SAND and $down->getId() !== self::CACTUS){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
@ -73,11 +83,11 @@ class Cactus extends Transparent{
|
||||
}
|
||||
}
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getID() !== self::CACTUS){
|
||||
if($this->getSide(0)->getId() !== self::CACTUS){
|
||||
if($this->meta == 0x0F){
|
||||
for($y = 1; $y < 3; ++$y){
|
||||
$b = $this->getLevel()->getBlock(new Vector3($this->x, $this->y + $y, $this->z));
|
||||
if($b->getID() === self::AIR){
|
||||
if($b->getId() === self::AIR){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($b, new Cactus()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($b, $ev->getNewState(), true);
|
||||
@ -98,12 +108,12 @@ class Cactus extends Transparent{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::SAND or $down->getID() === self::CACTUS){
|
||||
if($down->getId() === self::SAND or $down->getId() === self::CACTUS){
|
||||
$block0 = $this->getSide(2);
|
||||
$block1 = $this->getSide(3);
|
||||
$block2 = $this->getSide(4);
|
||||
$block3 = $this->getSide(5);
|
||||
if($block0->isTransparent === true and $block1->isTransparent === true and $block2->isTransparent === true and $block3->isTransparent === true){
|
||||
if($block0->isTransparent() === true and $block1->isTransparent() === true and $block2->isTransparent() === true and $block3->isTransparent() === true){
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
return true;
|
||||
|
@ -29,12 +29,23 @@ use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Cake extends Transparent{
|
||||
|
||||
protected $id = self::CAKE_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CAKE_BLOCK, 0, "Cake Block");
|
||||
$this->isFullBlock = false;
|
||||
$this->isActivable = true;
|
||||
$this->meta = $meta & 0x07;
|
||||
$this->hardness = 2.5;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Cake Block";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -53,7 +64,7 @@ class Cake extends Transparent{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::AIR){
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
@ -64,7 +75,7 @@ class Cake extends Transparent{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -27,9 +27,19 @@ use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Carpet extends Flowable{
|
||||
|
||||
protected $id = self::CARPET;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CARPET, $meta, "Carpet");
|
||||
$names = [
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
0 => "White Carpet",
|
||||
1 => "Orange Carpet",
|
||||
2 => "Magenta Carpet",
|
||||
@ -47,10 +57,7 @@ class Carpet extends Flowable{
|
||||
14 => "Red Carpet",
|
||||
15 => "Black Carpet",
|
||||
];
|
||||
$this->name = $names[$this->meta];
|
||||
$this->hardness = 0;
|
||||
$this->isFullBlock = false;
|
||||
$this->isSolid = true;
|
||||
return $names[$this->meta & 0x0f];
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -67,7 +74,7 @@ class Carpet extends Flowable{
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() !== self::AIR){
|
||||
if($down->getId() !== self::AIR){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
@ -78,7 +85,7 @@ class Carpet extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){
|
||||
if($this->getSide(0)->getId() === self::AIR){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -24,8 +24,15 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Carrot extends Crops{
|
||||
|
||||
protected $id = self::CARROT_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CARROT_BLOCK, $meta, "Carrot Block");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Carrot Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -34,16 +34,25 @@ use pocketmine\tile\Tile;
|
||||
|
||||
class Chest extends Transparent{
|
||||
|
||||
const SLOTS = 27;
|
||||
protected $id = self::CHEST;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::CHEST, $meta, "Chest");
|
||||
$this->isActivable = true;
|
||||
$this->hardness = 15;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Chest";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x + 0.0625,
|
||||
$this->y,
|
||||
@ -113,7 +122,7 @@ class Chest extends Transparent{
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($player instanceof Player){
|
||||
$top = $this->getSide(1);
|
||||
if($top->isTransparent !== true){
|
||||
if($top->isTransparent() !== true){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Clay extends Solid{
|
||||
|
||||
protected $id = self::CLAY_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::CLAY_BLOCK, 0, "Clay Block");
|
||||
$this->hardness = 3;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Clay Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Coal extends Solid{
|
||||
|
||||
protected $id = self::COAL_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::COAL_BLOCK, 0, "Coal Block");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Coal Block";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class CoalOre extends Solid{
|
||||
|
||||
protected $id = self::COAL_ORE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::COAL_ORE, 0, "Coal Ore");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Coal Ore";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Cobblestone extends Solid{
|
||||
|
||||
protected $id = self::COBBLESTONE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::COBBLESTONE, 0, "Cobblestone");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Cobblestone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -23,8 +23,15 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class CobblestoneStairs extends Stair{
|
||||
|
||||
protected $id = self::COBBLESTONE_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::COBBLESTONE_STAIRS, $meta, "Cobblestone Stairs");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Cobblestone Stairs";
|
||||
}
|
||||
|
||||
}
|
@ -26,13 +26,22 @@ use pocketmine\item\Item;
|
||||
|
||||
class Cobweb extends Flowable{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
protected $id = self::COBWEB;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::COBWEB, 0, "Cobweb");
|
||||
$this->isSolid = true;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 25;
|
||||
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Cobweb";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 25;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
@ -40,6 +49,7 @@ class Cobweb extends Flowable{
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
//TODO: correct drops
|
||||
return [];
|
||||
}
|
||||
}
|
@ -29,17 +29,13 @@ use pocketmine\Server;
|
||||
|
||||
abstract class Crops extends Flowable{
|
||||
|
||||
public $isActivable = true;
|
||||
public $hardness = 0;
|
||||
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::FARMLAND){
|
||||
if($down->getId() === self::FARMLAND){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
@ -50,7 +46,7 @@ abstract class Crops extends Flowable{
|
||||
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){ //Bonemeal
|
||||
$block = clone $this;
|
||||
$block->meta += mt_rand(2, 5);
|
||||
if($block->meta > 7){
|
||||
@ -73,7 +69,7 @@ abstract class Crops extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
|
@ -26,19 +26,21 @@ use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Dandelion extends Flowable{
|
||||
|
||||
protected $id = self::DANDELION;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::DANDELION, 0, "Dandelion");
|
||||
$this->hardness = 0;
|
||||
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
public function getName(){
|
||||
return "Dandelion";
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
if($down->getId() === 2 or $down->getId() === 3 or $down->getId() === 60){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
@ -49,7 +51,7 @@ class Dandelion extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -24,8 +24,15 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class DarkOakWoodStairs extends Stair{
|
||||
|
||||
protected $id = self::DARK_OAK_WOOD_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::DARK_OAK_WOOD_STAIRS, $meta, "Dark Oak Wood Stairs");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Dark Oak Wood Stairs";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -24,21 +24,22 @@ namespace pocketmine\block;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class DeadBush extends Flowable{
|
||||
public function __construct(){
|
||||
parent::__construct(self::DEAD_BUSH, 0, "Dead Bush");
|
||||
//$this->isReplaceable = true;
|
||||
$this->hardness = 0;
|
||||
|
||||
protected $id = self::DEAD_BUSH;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
public function getName(){
|
||||
return "Dead Bush";
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Diamond extends Solid{
|
||||
|
||||
protected $id = self::DIAMOND_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::DIAMOND_BLOCK, 0, "Diamond Block");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Diamond Block";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class DiamondOre extends Solid{
|
||||
|
||||
protected $id = self::DIAMOND_ORE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::DIAMOND_ORE, 0, "Diamond Ore");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Diamond Ore";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -26,16 +26,24 @@ use pocketmine\Player;
|
||||
|
||||
class Dirt extends Solid{
|
||||
|
||||
public $isActivable = true;
|
||||
protected $hardness = 2.5;
|
||||
protected $id = self::DIRT;
|
||||
protected $meta = 0;
|
||||
protected $name = "Dirt";
|
||||
|
||||
public function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Dirt";
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->isHoe()){
|
||||
$item->useOn($this);
|
||||
|
@ -30,9 +30,13 @@ use pocketmine\Server;
|
||||
|
||||
|
||||
abstract class Door extends Transparent{
|
||||
public function __construct($id, $meta = 0, $name = "Unknown"){
|
||||
parent::__construct($id, $meta, $name);
|
||||
$this->isSolid = false;
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
return false;
|
||||
}
|
||||
|
||||
private function getFullDamage(){
|
||||
@ -201,7 +205,7 @@ abstract class Door extends Transparent{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), false);
|
||||
if($this->getSide(1) instanceof Door){
|
||||
$this->getLevel()->setBlock($this->getSide(1), new Air(), false);
|
||||
@ -218,7 +222,7 @@ abstract class Door extends Transparent{
|
||||
if($face === 1){
|
||||
$blockUp = $this->getSide(1);
|
||||
$blockDown = $this->getSide(0);
|
||||
if($blockUp->isReplaceable === false or $blockDown->isTransparent === true){
|
||||
if($blockUp->canBeReplaced() === false or $blockDown->isTransparent() === true){
|
||||
return false;
|
||||
}
|
||||
$direction = $player instanceof Player ? $player->getDirection() : 0;
|
||||
@ -231,7 +235,7 @@ abstract class Door extends Transparent{
|
||||
$next = $this->getSide($face[(($direction + 2) % 4)]);
|
||||
$next2 = $this->getSide($face[$direction]);
|
||||
$metaUp = 0x08;
|
||||
if($next->getID() === $this->id or ($next2->isTransparent === false and $next->isTransparent === true)){ //Door hinge
|
||||
if($next->getId() === $this->id or ($next2->isTransparent() === false and $next->isTransparent() === true)){ //Door hinge
|
||||
$metaUp |= 0x01;
|
||||
}
|
||||
|
||||
@ -247,12 +251,12 @@ abstract class Door extends Transparent{
|
||||
public function onBreak(Item $item){
|
||||
if(($this->meta & 0x08) === 0x08){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
if($down->getId() === $this->id){
|
||||
$this->getLevel()->setBlock($down, new Air(), true);
|
||||
}
|
||||
}else{
|
||||
$up = $this->getSide(1);
|
||||
if($up->getID() === $this->id){
|
||||
if($up->getId() === $this->id){
|
||||
$this->getLevel()->setBlock($up, new Air(), true);
|
||||
}
|
||||
}
|
||||
@ -264,12 +268,12 @@ abstract class Door extends Transparent{
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if(($this->meta & 0x08) === 0x08){ //Top
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === $this->id){
|
||||
if($down->getId() === $this->id){
|
||||
$meta = $down->getDamage() ^ 0x04;
|
||||
$this->getLevel()->setBlock($down, Block::get($this->id, $meta), true);
|
||||
$players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getID()]);
|
||||
unset($players[$player->getId()]);
|
||||
}
|
||||
$pk = new LevelEventPacket();
|
||||
$pk->x = $this->x;
|
||||
@ -288,7 +292,7 @@ abstract class Door extends Transparent{
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
$players = $this->getLevel()->getUsingChunk($this->x >> 4, $this->z >> 4);
|
||||
if($player instanceof Player){
|
||||
unset($players[$player->getID()]);
|
||||
unset($players[$player->getId()]);
|
||||
}
|
||||
$pk = new LevelEventPacket();
|
||||
$pk->x = $this->x;
|
||||
|
70
src/pocketmine/block/DoublePlant.php
Normal file
70
src/pocketmine/block/DoublePlant.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class DoublePlant extends Flowable{
|
||||
|
||||
protected $id = self::DOUBLE_PLANT;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
0 => "Sunflower",
|
||||
1 => "Lilac",
|
||||
2 => "Double Tallgrass",
|
||||
3 => "Large Fern",
|
||||
4 => "Rose Bush",
|
||||
5 => "Peony"
|
||||
];
|
||||
return $names[$this->meta & 0x07];
|
||||
}
|
||||
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent() === true){ //Replace with common break method
|
||||
$this->getLevel()->setBlock($this, new Air(), false, false, true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
//TODO
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class DoubleSlab extends Solid{
|
||||
|
||||
protected $id = self::DOUBLE_SLAB;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::DOUBLE_SLAB, $meta, "Double Slab");
|
||||
$names = [
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
0 => "Stone",
|
||||
1 => "Sandstone",
|
||||
2 => "Wooden",
|
||||
@ -36,8 +46,7 @@ class DoubleSlab extends Solid{
|
||||
6 => "Quartz",
|
||||
7 => "",
|
||||
];
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||
$this->hardness = 30;
|
||||
return "Double " . $names[$this->meta & 0x07] . " Slab";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,18 +24,29 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class DoubleWoodSlab extends Solid{
|
||||
|
||||
protected $id = self::DOUBLE_WOOD_SLAB;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::DOUBLE_WOOD_SLAB, $meta, "Double Wooden Slab");
|
||||
$names = [
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
0 => "Oak",
|
||||
1 => "Spruce",
|
||||
2 => "Birch",
|
||||
3 => "Jungle",
|
||||
4 => "Acacia",
|
||||
5 => "Dark Oak",
|
||||
6 => "",
|
||||
7 => ""
|
||||
];
|
||||
$this->name = "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
$this->hardness = 15;
|
||||
return "Double " . $names[$this->meta & 0x07] . " Wooden Slab";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Emerald extends Solid{
|
||||
|
||||
protected $id = self::EMERALD_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::EMERALD_BLOCK, 0, "Emerald Block");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Emerald Block";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class EmeraldOre extends Solid{
|
||||
|
||||
protected $id = self::EMERALD_ORE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::EMERALD_ORE, 0, "Emerald Ore");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Emerald Ore";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -21,12 +21,31 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class EndPortal extends Solid{
|
||||
class EndPortalFrame extends Solid{
|
||||
|
||||
protected $id = self::END_PORTAL_FRAME;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::END_PORTAL, $meta, "End Portal");
|
||||
$this->hardness = 18000000;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "End Portal Frame";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 18000000;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class EndStone extends Solid{
|
||||
|
||||
protected $id = self::END_STONE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::END_STONE, 0, "End Stone");
|
||||
$this->hardness = 45;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "End Stone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 45;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -34,8 +34,6 @@ use pocketmine\Player;
|
||||
|
||||
abstract class Fallable extends Solid{
|
||||
|
||||
public $hasPhysics = true;
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$ret = $this->getLevel()->setBlock($this, $this, true, true);
|
||||
|
||||
@ -43,9 +41,9 @@ abstract class Fallable extends Solid{
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($this->hasPhysics === true and $type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === self::AIR or ($down instanceof Liquid)){
|
||||
if($down->getId() === self::AIR or ($down instanceof Liquid)){
|
||||
$fall = Entity::createEntity("FallingSand", $this->getLevel()->getChunk($this->x >> 4, $this->z >> 4), new Compound("", [
|
||||
"Pos" => new Enum("Pos", [
|
||||
new Double("", $this->x + 0.5),
|
||||
@ -61,7 +59,7 @@ abstract class Fallable extends Solid{
|
||||
new Float("", 0),
|
||||
new Float("", 0)
|
||||
]),
|
||||
"TileID" => new Int("TileID", $this->getID()),
|
||||
"TileID" => new Int("TileID", $this->getId()),
|
||||
"Data" => new Byte("Data", $this->getDamage()),
|
||||
]));
|
||||
|
||||
|
@ -25,13 +25,22 @@ use pocketmine\item\Item;
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class Farmland extends Solid{
|
||||
|
||||
protected $id = self::FARMLAND;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::FARMLAND, $meta, "Farmland");
|
||||
$this->hardness = 3;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Farmland";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 3;
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
|
||||
return new AxisAlignedBB(
|
||||
$this->x,
|
||||
$this->y,
|
||||
|
@ -21,14 +21,22 @@
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
use pocketmine\math\AxisAlignedBB;
|
||||
|
||||
class Fence extends Transparent{
|
||||
|
||||
protected $id = self::FENCE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::FENCE, 0, "Fence");
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Oak Fence";
|
||||
}
|
||||
|
||||
protected function recalculateBoundingBox(){
|
||||
@ -38,7 +46,7 @@ class Fence extends Transparent{
|
||||
$flag2 = $this->canConnect($this->getSide(4));
|
||||
$flag3 = $this->canConnect($this->getSide(5));
|
||||
|
||||
$f = $flag2 ? 0 : 0.375;
|
||||
$f = $flag2 ? 0 : 0.375;
|
||||
$f1 = $flag3 ? 1 : 0.625;
|
||||
$f2 = $flag ? 0 : 0.375;
|
||||
$f3 = $flag1 ? 1 : 0.625;
|
||||
@ -48,13 +56,13 @@ class Fence extends Transparent{
|
||||
$this->y,
|
||||
$this->z + $f2,
|
||||
$this->x + $f1,
|
||||
$this->y + 1,
|
||||
$this->y + 1.5,
|
||||
$this->z + $f3
|
||||
);
|
||||
}
|
||||
|
||||
public function canConnect(Block $block){
|
||||
return ($block->getID() !== self::FENCE and $block->getID() !== self::FENCE_GATE) ? $block->isSolid : true;
|
||||
return (!($block instanceof Fence) and !($block instanceof FenceGate)) ? $block->isSolid() : true;
|
||||
}
|
||||
|
||||
}
|
31
src/pocketmine/block/FenceAcacia.php
Normal file
31
src/pocketmine/block/FenceAcacia.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceAcacia extends Fence{
|
||||
|
||||
protected $id = self::FENCE_ACACIA;
|
||||
|
||||
public function getName(){
|
||||
return "Acacia Fence";
|
||||
}
|
||||
}
|
31
src/pocketmine/block/FenceBirch.php
Normal file
31
src/pocketmine/block/FenceBirch.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceBirch extends Fence{
|
||||
|
||||
protected $id = self::FENCE_BIRCH;
|
||||
|
||||
public function getName(){
|
||||
return "Birch Fence";
|
||||
}
|
||||
}
|
31
src/pocketmine/block/FenceDarkOak.php
Normal file
31
src/pocketmine/block/FenceDarkOak.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceDarkOak extends Fence{
|
||||
|
||||
protected $id = self::FENCE_DARK_OAK;
|
||||
|
||||
public function getName(){
|
||||
return "Dark Oak Fence";
|
||||
}
|
||||
}
|
@ -26,15 +26,23 @@ use pocketmine\math\AxisAlignedBB;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FenceGate extends Transparent{
|
||||
|
||||
protected $id = self::FENCE_GATE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::FENCE_GATE, $meta, "Fence Gate");
|
||||
$this->isActivable = true;
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->hardness = 15;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Oak Fence Gate";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +59,7 @@ class FenceGate extends Transparent{
|
||||
$this->y,
|
||||
$this->z + 0.375,
|
||||
$this->x + 1,
|
||||
$this->y + 1,
|
||||
$this->y + 1.5,
|
||||
$this->z + 0.625
|
||||
);
|
||||
}else{
|
||||
@ -60,7 +68,7 @@ class FenceGate extends Transparent{
|
||||
$this->y,
|
||||
$this->z,
|
||||
$this->x + 0.625,
|
||||
$this->y + 1,
|
||||
$this->y + 1.5,
|
||||
$this->z + 1
|
||||
);
|
||||
}
|
||||
@ -93,11 +101,6 @@ class FenceGate extends Transparent{
|
||||
3 => 2,
|
||||
];
|
||||
$this->meta = ($faces[$player instanceof Player ? $player->getDirection() : 0] & 0x03) | ((~$this->meta) & 0x04);
|
||||
if(($this->meta & 0x04) === 0x04){
|
||||
$this->isFullBlock = true;
|
||||
}else{
|
||||
$this->isFullBlock = false;
|
||||
}
|
||||
$this->getLevel()->setBlock($this, $this, true);
|
||||
|
||||
return true;
|
||||
|
32
src/pocketmine/block/FenceGateAcacia.php
Normal file
32
src/pocketmine/block/FenceGateAcacia.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateAcacia extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_ACACIA;
|
||||
|
||||
public function getName(){
|
||||
return "Acacia Fence Gate";
|
||||
}
|
||||
}
|
32
src/pocketmine/block/FenceGateBirch.php
Normal file
32
src/pocketmine/block/FenceGateBirch.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateBirch extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_BIRCH;
|
||||
|
||||
public function getName(){
|
||||
return "Birch Fence Gate";
|
||||
}
|
||||
}
|
32
src/pocketmine/block/FenceGateDarkOak.php
Normal file
32
src/pocketmine/block/FenceGateDarkOak.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateDarkOak extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_DARK_OAK;
|
||||
|
||||
public function getName(){
|
||||
return "Dark Oak Fence Gate";
|
||||
}
|
||||
}
|
32
src/pocketmine/block/FenceGateJungle.php
Normal file
32
src/pocketmine/block/FenceGateJungle.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateJungle extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_JUNGLE;
|
||||
|
||||
public function getName(){
|
||||
return "Jungle Fence Gate";
|
||||
}
|
||||
}
|
32
src/pocketmine/block/FenceGateSpruce.php
Normal file
32
src/pocketmine/block/FenceGateSpruce.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
|
||||
class FenceGateSpruce extends FenceGate{
|
||||
|
||||
protected $id = self::FENCE_GATE_SPRUCE;
|
||||
|
||||
public function getName(){
|
||||
return "Spruce Fence Gate";
|
||||
}
|
||||
}
|
31
src/pocketmine/block/FenceJungle.php
Normal file
31
src/pocketmine/block/FenceJungle.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceJungle extends Fence{
|
||||
|
||||
protected $id = self::FENCE_JUNGLE;
|
||||
|
||||
public function getName(){
|
||||
return "Jungle Fence";
|
||||
}
|
||||
}
|
31
src/pocketmine/block/FenceSpruce.php
Normal file
31
src/pocketmine/block/FenceSpruce.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\block;
|
||||
|
||||
class FenceSpruce extends Fence{
|
||||
|
||||
protected $id = self::FENCE_SPRUCE;
|
||||
|
||||
public function getName(){
|
||||
return "Spruce Fence";
|
||||
}
|
||||
}
|
@ -31,18 +31,30 @@ use pocketmine\Server;
|
||||
|
||||
class Fire extends Flowable{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
protected $id = self::FIRE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::FIRE, $meta, "Fire");
|
||||
$this->isReplaceable = true;
|
||||
$this->breakable = false;
|
||||
$this->isFullBlock = true;
|
||||
$this->hardness = 0;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
public function hasEntityCollision(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Fire Block";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
@ -64,7 +76,7 @@ class Fire extends Flowable{
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
for($s = 0; $s <= 5; ++$s){
|
||||
$side = $this->getSide($s);
|
||||
if($side->getID() !== self::AIR and !($side instanceof Liquid)){
|
||||
if($side->getId() !== self::AIR and !($side instanceof Liquid)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -72,7 +84,7 @@ class Fire extends Flowable{
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}elseif($type === Level::BLOCK_UPDATE_RANDOM){
|
||||
if($this->getSide(0)->getID() !== self::NETHERRACK){
|
||||
if($this->getSide(0)->getId() !== self::NETHERRACK){
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -24,8 +24,19 @@ namespace pocketmine\block;
|
||||
|
||||
abstract class Flowable extends Transparent{
|
||||
|
||||
public $isFlowable = true;
|
||||
public $isFullBlock = false;
|
||||
public $isSolid = false;
|
||||
public function canBeFlowedInto(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -23,10 +23,10 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class Furnace extends BurningFurnace{
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct($meta);
|
||||
$this->id = self::FURNACE;
|
||||
$this->name = "Furnace";
|
||||
$this->isActivable = true;
|
||||
|
||||
protected $id = self::FURNACE;
|
||||
|
||||
public function getName(){
|
||||
return "Furnace";
|
||||
}
|
||||
}
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Glass extends Transparent{
|
||||
|
||||
protected $id = self::GLASS;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GLASS, 0, "Glass");
|
||||
$this->hardness = 1.5;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Glass";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 1.5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -23,8 +23,19 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class GlassPane extends Thin{
|
||||
|
||||
protected $id = self::GLASS_PANE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GLASS_PANE, 0, "Glass Pane");
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Glass Pane";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 1.5;
|
||||
}
|
||||
|
||||
}
|
@ -23,8 +23,19 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class GlowingObsidian extends Solid{
|
||||
|
||||
protected $id = self::GLOWING_OBSIDIAN;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::GLOWING_OBSIDIAN, $meta, "Glowing Obsidian");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Glowing Obsidian";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 12;
|
||||
}
|
||||
|
||||
}
|
@ -25,9 +25,23 @@ use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
|
||||
class GlowingRedstoneOre extends Solid{
|
||||
|
||||
protected $id = self::GLOWING_REDSTONE_ORE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GLOWING_REDSTONE_ORE, 0, "Glowing Redstone Ore");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Glowing Redstone Ore";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 9;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
|
@ -24,9 +24,23 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Glowstone extends Transparent{
|
||||
|
||||
protected $id = self::GLOWSTONE_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GLOWSTONE_BLOCK, 0, "Glowstone");
|
||||
$this->hardness = 1.5;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Glowstone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 1.5;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Gold extends Solid{
|
||||
|
||||
protected $id = self::GOLD_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GOLD_BLOCK, 0, "Gold Block");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Gold Block";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class GoldOre extends Solid{
|
||||
|
||||
protected $id = self::GOLD_ORE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GOLD_ORE, 0, "Gold Ore");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Gold Ore";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -32,16 +32,24 @@ use pocketmine\utils\Random;
|
||||
|
||||
class Grass extends Solid{
|
||||
|
||||
public $isActivable = true;
|
||||
protected $hardness = 3;
|
||||
protected $id = self::GRASS;
|
||||
protected $meta = 0;
|
||||
protected $name = "Grass";
|
||||
|
||||
public function __construct(){
|
||||
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Grass";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [
|
||||
[Item::DIRT, 0, 1],
|
||||
@ -55,7 +63,7 @@ class Grass extends Solid{
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getID() === Block::DIRT){
|
||||
if($block->getId() === Block::DIRT){
|
||||
if($block->getSide(1) instanceof Transparent){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Grass()));
|
||||
if(!$ev->isCancelled()){
|
||||
@ -67,7 +75,7 @@ class Grass extends Solid{
|
||||
}
|
||||
|
||||
public function onActivate(Item $item, Player $player = null){
|
||||
if($item->getID() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
if($item->getId() === Item::DYE and $item->getDamage() === 0x0F){
|
||||
$item->count--;
|
||||
TallGrassObject::growGrass($this->getLevel(), $this, new Random(mt_rand()), 8, 2);
|
||||
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Gravel extends Fallable{
|
||||
|
||||
protected $id = self::GRAVEL;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::GRAVEL, 0, "Gravel");
|
||||
$this->hardness = 3;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Gravel";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 3;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class HardenedClay extends Solid{
|
||||
|
||||
protected $id = self::HARDENED_CLAY;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::HARDENED_CLAY, 0, "Hardened Clay");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Hardened Clay";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -25,9 +25,19 @@ use pocketmine\item\Item;
|
||||
use pocketmine\Player;
|
||||
|
||||
class HayBale extends Solid{
|
||||
|
||||
protected $id = self::HAY_BALE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::HAY_BALE, $meta, "Hay Bale");
|
||||
$this->hardness = 10;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Hay Bale";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 10;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Ice extends Transparent{
|
||||
|
||||
protected $id = self::ICE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::ICE, 0, "Ice");
|
||||
$this->hardness = 2.5;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Ice";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function onBreak(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Iron extends Solid{
|
||||
|
||||
protected $id = self::IRON_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::IRON_BLOCK, 0, "Iron Block");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Iron Block";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -23,8 +23,15 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class IronBars extends Thin{
|
||||
|
||||
protected $id = self::IRON_BARS;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::IRON_BARS, 0, "Iron Bars");
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Iron Bars";
|
||||
}
|
||||
|
||||
}
|
@ -24,10 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class IronDoor extends Door{
|
||||
|
||||
protected $id = self::IRON_DOOR_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::IRON_DOOR_BLOCK, $meta, "Iron Door Block");
|
||||
//$this->isActivable = true;
|
||||
$this->hardness = 25;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Iron Door Block";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 25;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class IronOre extends Solid{
|
||||
|
||||
protected $id = self::IRON_ORE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::IRON_ORE, 0, "Iron Ore");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Iron Ore";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,8 +24,15 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class JungleWoodStairs extends Stair{
|
||||
|
||||
protected $id = self::JUNGLE_WOOD_STAIRS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::JUNGLE_WOOD_STAIRS, $meta, "Jungle Wood Stairs");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Jungle Wood Stairs";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -29,13 +29,26 @@ use pocketmine\Player;
|
||||
|
||||
class Ladder extends Transparent{
|
||||
|
||||
public $hasEntityCollision = true;
|
||||
protected $id = self::LADDER;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::LADDER, $meta, "Ladder");
|
||||
$this->isSolid = false;
|
||||
$this->isFullBlock = false;
|
||||
$this->hardness = 2;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Ladder";
|
||||
}
|
||||
|
||||
public function hasEntityCollision(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
@ -90,7 +103,7 @@ class Ladder extends Transparent{
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
if($target->isTransparent === false){
|
||||
if($target->isTransparent() === false){
|
||||
$faces = [
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
@ -110,7 +123,7 @@ class Ladder extends Transparent{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
/*if($this->getSide(0)->getID() === self::AIR){ //Replace with common break method
|
||||
/*if($this->getSide(0)->getId() === self::AIR){ //Replace with common break method
|
||||
Server::getInstance()->api->entity->drop($this, Item::get(LADDER, 0, 1));
|
||||
$this->getLevel()->setBlock($this, new Air(), true, true, true);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Lapis extends Solid{
|
||||
|
||||
protected $id = self::LAPIS_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::LAPIS_BLOCK, 0, "Lapis Block");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Lapis Block";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class LapisOre extends Solid{
|
||||
|
||||
protected $id = self::LAPIS_ORE;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::LAPIS_ORE, 0, "Lapis Ore");
|
||||
$this->hardness = 15;
|
||||
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Lapis Ore";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -31,9 +31,22 @@ use pocketmine\Server;
|
||||
|
||||
class Lava extends Liquid{
|
||||
|
||||
protected $id = self::LAVA;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::LAVA, $meta, "Lava");
|
||||
$this->hardness = 0;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Lava";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function onEntityCollide(Entity $entity){
|
||||
|
@ -35,16 +35,24 @@ class Leaves extends Transparent{
|
||||
const ACACIA = 0;
|
||||
const DARK_OAK = 1;
|
||||
|
||||
protected $id = self::LEAVES;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::LEAVES, $meta, "Leaves");
|
||||
$names = [
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
self::OAK => "Oak Leaves",
|
||||
self::SPRUCE => "Spruce Leaves",
|
||||
self::BIRCH => "Birch Leaves",
|
||||
self::JUNGLE => "Jungle Leaves",
|
||||
];
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
$this->hardness = 1;
|
||||
return $names[$this->meta & 0x03];
|
||||
}
|
||||
|
||||
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
|
||||
@ -53,11 +61,11 @@ class Leaves extends Transparent{
|
||||
if(isset($visited[$index])){
|
||||
return false;
|
||||
}
|
||||
if($pos->getID() === self::WOOD){
|
||||
if($pos->getId() === self::WOOD){
|
||||
return true;
|
||||
}elseif($pos->getID() === self::LEAVES and $distance < 3){
|
||||
}elseif($pos->getId() === self::LEAVES and $distance < 3){
|
||||
$visited[$index] = true;
|
||||
$down = $pos->getSide(0)->getID();
|
||||
$down = $pos->getSide(0)->getId();
|
||||
if($down === Item::WOOD){
|
||||
return true;
|
||||
}
|
||||
|
@ -29,14 +29,18 @@ use pocketmine\Server;
|
||||
|
||||
class Leaves2 extends Leaves{
|
||||
|
||||
protected $id = self::LEAVES2;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
Transparent::__construct(self::LEAVES, $meta, "Leaves");
|
||||
$names = [
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
self::ACACIA => "Acacia Leaves",
|
||||
self::DARK_OAK => "Dark Oak Leaves",
|
||||
];
|
||||
$this->name = $names[$this->meta & 0x03];
|
||||
$this->hardness = 1;
|
||||
return $names[$this->meta & 0x01];
|
||||
}
|
||||
|
||||
private function findLog(Block $pos, array $visited, $distance, &$check, $fromSide = null){
|
||||
@ -45,11 +49,11 @@ class Leaves2 extends Leaves{
|
||||
if(isset($visited[$index])){
|
||||
return false;
|
||||
}
|
||||
if($pos->getID() === self::WOOD2){
|
||||
if($pos->getId() === self::WOOD2){
|
||||
return true;
|
||||
}elseif($pos->getID() === self::LEAVES2 and $distance < 3){
|
||||
}elseif($pos->getId() === self::LEAVES2 and $distance < 3){
|
||||
$visited[$index] = true;
|
||||
$down = $pos->getSide(0)->getID();
|
||||
$down = $pos->getSide(0)->getId();
|
||||
if($down === Item::WOOD2){
|
||||
return true;
|
||||
}
|
||||
|
@ -28,13 +28,25 @@ use pocketmine\level\Level;
|
||||
use pocketmine\math\Vector3;
|
||||
|
||||
abstract class Liquid extends Transparent{
|
||||
public $hasEntityCollision = true;
|
||||
|
||||
public $isLiquid = true;
|
||||
public $breakable = false;
|
||||
public $isReplaceable = true;
|
||||
public $isSolid = false;
|
||||
public $isFullBlock = true;
|
||||
/** @var Vector3 */
|
||||
private $temporalVector = null;
|
||||
|
||||
public function hasEntityCollision(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isBreakable(Item $item){
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeReplaced(){
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isSolid(){
|
||||
return false;
|
||||
}
|
||||
|
||||
public $adjacentSources = 0;
|
||||
public $isOptimalFlowDirection = [0, 0, 0, 0];
|
||||
@ -54,7 +66,7 @@ abstract class Liquid extends Transparent{
|
||||
$pos = $this->getLevel()->getBlock($pos);
|
||||
}
|
||||
|
||||
if($pos->getID() !== $this->getID()){
|
||||
if($pos->getId() !== $this->getId()){
|
||||
return -1;
|
||||
}else{
|
||||
return $pos->getDamage();
|
||||
@ -66,7 +78,7 @@ abstract class Liquid extends Transparent{
|
||||
$pos = $this->getLevel()->getBlock($pos);
|
||||
}
|
||||
|
||||
if($pos->getID() !== $this->getID()){
|
||||
if($pos->getId() !== $this->getId()){
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -82,6 +94,10 @@ abstract class Liquid extends Transparent{
|
||||
public function getFlowVector(){
|
||||
$vector = new Vector3(0, 0, 0);
|
||||
|
||||
if($this->temporalVector === null){
|
||||
$this->temporalVector = new Vector3(0, 0, 0);
|
||||
}
|
||||
|
||||
$decay = $this->getEffectiveFlowDecay($this);
|
||||
|
||||
for($j = 0; $j < 4; ++$j){
|
||||
@ -99,46 +115,50 @@ abstract class Liquid extends Transparent{
|
||||
}elseif($j === 3){
|
||||
++$z;
|
||||
}
|
||||
$sideBlock = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
$sideBlock = $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z));
|
||||
$blockDecay = $this->getEffectiveFlowDecay($sideBlock);
|
||||
|
||||
if($blockDecay < 0){
|
||||
if(!$sideBlock->isFlowable){
|
||||
if(!$sideBlock->canBeFlowedInto()){
|
||||
continue;
|
||||
}
|
||||
|
||||
$blockDecay = $this->getEffectiveFlowDecay($sideBlock->getSide(0));
|
||||
$blockDecay = $this->getEffectiveFlowDecay($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z)));
|
||||
|
||||
if($blockDecay >= 0){
|
||||
$realDecay = $blockDecay - ($decay - 8);
|
||||
$vector = $vector->add(($sideBlock->x - $this->x) * $realDecay, ($sideBlock->y - $this->y) * $realDecay, ($sideBlock->z - $this->z) * $realDecay);
|
||||
$vector->x += ($sideBlock->x - $this->x) * $realDecay;
|
||||
$vector->y += ($sideBlock->y - $this->y) * $realDecay;
|
||||
$vector->z += ($sideBlock->z - $this->z) * $realDecay;
|
||||
}
|
||||
|
||||
continue;
|
||||
}else{
|
||||
$realDecay = $blockDecay - $decay;
|
||||
$vector = $vector->add(($sideBlock->x - $this->x) * $realDecay, ($sideBlock->y - $this->y) * $realDecay, ($sideBlock->z - $this->z) * $realDecay);
|
||||
$vector->x += ($sideBlock->x - $this->x) * $realDecay;
|
||||
$vector->y += ($sideBlock->y - $this->y) * $realDecay;
|
||||
$vector->z += ($sideBlock->z - $this->z) * $realDecay;
|
||||
}
|
||||
}
|
||||
|
||||
if($this->getDamage() >= 8){
|
||||
$falling = false;
|
||||
|
||||
if(!$this->getLevel()->getBlock($this->add(0, 0, -1))->isFlowable){
|
||||
if(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(0, 0, 1))->isFlowable){
|
||||
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(-1, 0, 0))->isFlowable){
|
||||
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(1, 0, 0))->isFlowable){
|
||||
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(0, 1, -1))->isFlowable){
|
||||
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z - 1))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(0, 1, 1))->isFlowable){
|
||||
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z + 1))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(-1, 1, 0))->isFlowable){
|
||||
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y + 1, $this->z))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}elseif(!$this->getLevel()->getBlock($this->add(1, 1, 0))->isFlowable){
|
||||
}elseif(!$this->getLevel()->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y + 1, $this->z))->canBeFlowedInto()){
|
||||
$falling = true;
|
||||
}
|
||||
|
||||
@ -172,6 +192,10 @@ abstract class Liquid extends Transparent{
|
||||
$this->checkForHarden();
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
}elseif($type === Level::BLOCK_UPDATE_SCHEDULED){
|
||||
if($this->temporalVector === null){
|
||||
$this->temporalVector = new Vector3(0, 0, 0);
|
||||
}
|
||||
|
||||
$decay = $this->getFlowDecay($this);
|
||||
$multiplier = $this instanceof Lava ? 2 : 1;
|
||||
|
||||
@ -180,10 +204,10 @@ abstract class Liquid extends Transparent{
|
||||
if($decay > 0){
|
||||
$smallestFlowDecay = -100;
|
||||
$this->adjacentSources = 0;
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(4), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(5), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(2), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->getSide(3), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1)), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1)), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z)), $smallestFlowDecay);
|
||||
$smallestFlowDecay = $this->getSmallestFlowDecay($this->level->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z)), $smallestFlowDecay);
|
||||
|
||||
$k = $smallestFlowDecay + $multiplier;
|
||||
|
||||
@ -191,7 +215,7 @@ abstract class Liquid extends Transparent{
|
||||
$k = -1;
|
||||
}
|
||||
|
||||
if(($topFlowDecay = $this->getFlowDecay($this->getSide(1))) >= 0){
|
||||
if(($topFlowDecay = $this->getFlowDecay($this->level->getBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y + 1, $this->z))))) >= 0){
|
||||
if($topFlowDecay >= 8){
|
||||
$k = $topFlowDecay;
|
||||
}else{
|
||||
@ -200,8 +224,8 @@ abstract class Liquid extends Transparent{
|
||||
}
|
||||
|
||||
if($this->adjacentSources >= 2 and $this instanceof Water){
|
||||
$bottomBlock = $this->getSide(0);
|
||||
if($bottomBlock->isSolid){
|
||||
$bottomBlock = $this->level->getBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y - 1, $this->z)));
|
||||
if($bottomBlock->isSolid()){
|
||||
$k = 0;
|
||||
}elseif($bottomBlock instanceof Water and $bottomBlock->getDamage() === 0){
|
||||
$k = 0;
|
||||
@ -216,7 +240,7 @@ abstract class Liquid extends Transparent{
|
||||
if($k !== $decay){
|
||||
$decay = $k;
|
||||
if($decay < 0){
|
||||
$this->getLevel()->setBlock($this, Block::get(Item::AIR), true);
|
||||
$this->getLevel()->setBlock($this, new Air(), true);
|
||||
}else{
|
||||
$this->getLevel()->setBlock($this, Block::get($this->id, $decay), true);
|
||||
$this->getLevel()->scheduleUpdate($this, $this->tickRate());
|
||||
@ -229,9 +253,9 @@ abstract class Liquid extends Transparent{
|
||||
//$this->updateFlow();
|
||||
}
|
||||
|
||||
$bottomBlock = $this->getSide(0);
|
||||
$bottomBlock = $this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y - 1, $this->z));
|
||||
|
||||
if($bottomBlock->isFlowable or $bottomBlock instanceof Liquid){
|
||||
if($bottomBlock->canBeFlowedInto() or $bottomBlock instanceof Liquid){
|
||||
if($this instanceof Lava and $bottomBlock instanceof Water){
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get(Item::STONE), true);
|
||||
return;
|
||||
@ -244,7 +268,7 @@ abstract class Liquid extends Transparent{
|
||||
$this->getLevel()->setBlock($bottomBlock, Block::get($this->id, $decay + 8), true);
|
||||
$this->getLevel()->scheduleUpdate($bottomBlock, $this->tickRate());
|
||||
}
|
||||
}elseif($decay >= 0 and ($decay === 0 or !$bottomBlock->isFlowable)){
|
||||
}elseif($decay >= 0 and ($decay === 0 or !$bottomBlock->canBeFlowedInto())){
|
||||
$flags = $this->getOptimalFlowDirections();
|
||||
|
||||
$l = $decay + $multiplier;
|
||||
@ -259,19 +283,19 @@ abstract class Liquid extends Transparent{
|
||||
}
|
||||
|
||||
if($flags[0]){
|
||||
$this->flowIntoBlock($this->getSide(4), $l);
|
||||
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x - 1, $this->y, $this->z)), $l);
|
||||
}
|
||||
|
||||
if($flags[1]){
|
||||
$this->flowIntoBlock($this->getSide(5), $l);
|
||||
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x + 1, $this->y, $this->z)), $l);
|
||||
}
|
||||
|
||||
if($flags[2]){
|
||||
$this->flowIntoBlock($this->getSide(2), $l);
|
||||
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z - 1)), $l);
|
||||
}
|
||||
|
||||
if($flags[3]){
|
||||
$this->flowIntoBlock($this->getSide(3), $l);
|
||||
$this->flowIntoBlock($this->level->getBlock($this->temporalVector->setComponents($this->x, $this->y, $this->z + 1)), $l);
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,8 +305,8 @@ abstract class Liquid extends Transparent{
|
||||
}
|
||||
|
||||
private function flowIntoBlock(Block $block, $newFlowDecay){
|
||||
if($block->isFlowable){
|
||||
if($block->getID() > 0){
|
||||
if($block->canBeFlowedInto()){
|
||||
if($block->getId() > 0){
|
||||
$this->getLevel()->useBreakOn($block);
|
||||
}
|
||||
|
||||
@ -314,13 +338,13 @@ abstract class Liquid extends Transparent{
|
||||
}elseif($j === 3){
|
||||
++$z;
|
||||
}
|
||||
$blockSide = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
$blockSide = $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z));
|
||||
|
||||
if(!$blockSide->isFlowable and !($blockSide instanceof Liquid)){
|
||||
if(!$blockSide->canBeFlowedInto() and !($blockSide instanceof Liquid)){
|
||||
continue;
|
||||
}elseif($blockSide instanceof Liquid and $blockSide->getDamage() === 0){
|
||||
continue;
|
||||
}elseif($blockSide->getSide(0)->isFlowable){
|
||||
}elseif($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z))->canBeFlowedInto()){
|
||||
return $accumulatedCost;
|
||||
}
|
||||
|
||||
@ -340,6 +364,10 @@ abstract class Liquid extends Transparent{
|
||||
}
|
||||
|
||||
private function getOptimalFlowDirections(){
|
||||
if($this->temporalVector === null){
|
||||
$this->temporalVector = new Vector3(0, 0, 0);
|
||||
}
|
||||
|
||||
for($j = 0; $j < 4; ++$j){
|
||||
$this->flowCost[$j] = 1000;
|
||||
|
||||
@ -356,13 +384,13 @@ abstract class Liquid extends Transparent{
|
||||
}elseif($j === 3){
|
||||
++$z;
|
||||
}
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
$block = $this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y, $z));
|
||||
|
||||
if(!$block->isFlowable and !($block instanceof Liquid)){
|
||||
if(!$block->canBeFlowedInto() and !($block instanceof Liquid)){
|
||||
continue;
|
||||
}elseif($block instanceof Liquid and $block->getDamage() === 0){
|
||||
continue;
|
||||
}elseif($block->getSide(0)->isFlowable){
|
||||
}elseif($this->getLevel()->getBlock($this->temporalVector->setComponents($x, $y - 1, $z))->canBeFlowedInto()){
|
||||
$this->flowCost[$j] = 0;
|
||||
}else{
|
||||
$this->flowCost[$j] = $this->calculateFlowCost($block, 1, $j);
|
||||
|
@ -25,9 +25,23 @@ use pocketmine\item\Item;
|
||||
use pocketmine\Player;
|
||||
|
||||
class LitPumpkin extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::LIT_PUMPKIN, "Jack o'Lantern");
|
||||
$this->hardness = 5;
|
||||
|
||||
protected $id = self::LIT_PUMPKIN;
|
||||
|
||||
public function getLightLevel(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Jack o'Lantern";
|
||||
}
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Melon extends Transparent{
|
||||
|
||||
protected $id = self::MELON_BLOCK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::MELON_BLOCK, 0, "Melon Block");
|
||||
$this->hardness = 5;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Melon Block";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
@ -27,13 +27,20 @@ use pocketmine\level\Level;
|
||||
use pocketmine\Server;
|
||||
|
||||
class MelonStem extends Crops{
|
||||
|
||||
protected $id = self::MELON_STEM;
|
||||
|
||||
public function getName(){
|
||||
return "Melon Stem";
|
||||
}
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::MELON_STEM, $meta, "Melon Stem");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
||||
}
|
||||
@ -51,13 +58,13 @@ class MelonStem extends Crops{
|
||||
}else{
|
||||
for($side = 2; $side <= 5; ++$side){
|
||||
$b = $this->getSide($side);
|
||||
if($b->getID() === self::MELON_BLOCK){
|
||||
if($b->getId() === self::MELON_BLOCK){
|
||||
return Level::BLOCK_UPDATE_RANDOM;
|
||||
}
|
||||
}
|
||||
$side = $this->getSide(mt_rand(2, 5));
|
||||
$d = $side->getSide(0);
|
||||
if($side->getID() === self::AIR and ($d->getID() === self::FARMLAND or $d->getID() === self::GRASS or $d->getID() === self::DIRT)){
|
||||
if($side->getId() === self::AIR and ($d->getId() === self::FARMLAND or $d->getId() === self::GRASS or $d->getId() === self::DIRT)){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockGrowEvent($side, new Melon()));
|
||||
if(!$ev->isCancelled()){
|
||||
$this->getLevel()->setBlock($side, $ev->getNewState(), true);
|
||||
|
@ -24,29 +24,39 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class MonsterSpawner extends Solid{
|
||||
public function __construct(){
|
||||
parent::__construct(self::MONSTER_SPAWNER, 0, "Monster Spawner");
|
||||
$this->hardness = 25;
|
||||
|
||||
protected $id = self::MONSTER_SPAWNER;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.95;
|
||||
case 4:
|
||||
return 1.25;
|
||||
case 3:
|
||||
return 1.9;
|
||||
case 2:
|
||||
return 0.65;
|
||||
case 1:
|
||||
return 3.75;
|
||||
default:
|
||||
return 25;
|
||||
}
|
||||
}
|
||||
public function getHardness(){
|
||||
return 25;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [];
|
||||
}
|
||||
public function getName(){
|
||||
return "Monster Spawner";
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
switch($item->isPickaxe()){
|
||||
case 5:
|
||||
return 0.95;
|
||||
case 4:
|
||||
return 1.25;
|
||||
case 3:
|
||||
return 1.9;
|
||||
case 2:
|
||||
return 0.65;
|
||||
case 1:
|
||||
return 3.75;
|
||||
default:
|
||||
return 25;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
return [];
|
||||
}
|
||||
}
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class MossStone extends Solid{
|
||||
|
||||
protected $id = self::MOSS_STONE;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::MOSS_STONE, $meta, "Moss Stone");
|
||||
$this->hardness = 30;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Moss Stone";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -28,9 +28,19 @@ use pocketmine\math\Vector3;
|
||||
use pocketmine\Server;
|
||||
|
||||
class Mycelium extends Solid{
|
||||
|
||||
protected $id = self::MYCELIUM;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::MYCELIUM, 0, "Mycelium");
|
||||
$this->hardness = 2.5;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Mycelium";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2.5;
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
@ -46,7 +56,7 @@ class Mycelium extends Solid{
|
||||
$y = mt_rand($this->y - 2, $this->y + 2);
|
||||
$z = mt_rand($this->z - 1, $this->z + 1);
|
||||
$block = $this->getLevel()->getBlock(new Vector3($x, $y, $z));
|
||||
if($block->getID() === Block::DIRT){
|
||||
if($block->getId() === Block::DIRT){
|
||||
if($block->getSide(1) instanceof Transparent){
|
||||
Server::getInstance()->getPluginManager()->callEvent($ev = new BlockSpreadEvent($block, $this, new Mycelium()));
|
||||
if(!$ev->isCancelled()){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class NetherBrick extends Solid{
|
||||
|
||||
protected $id = self::NETHER_BRICKS;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::NETHER_BRICKS, 0, "Nether Bricks");
|
||||
$this->hardness = 30;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Nether Bricks";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 30;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -23,8 +23,15 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class NetherBrickStairs extends Stair{
|
||||
|
||||
protected $id = self::NETHER_BRICKS_STAIRS;
|
||||
|
||||
public function getName(){
|
||||
return "Nether Bricks Stairs";
|
||||
}
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::NETHER_BRICKS_STAIRS, $meta, "Nether Bricks Stairs");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
}
|
@ -23,9 +23,19 @@ namespace pocketmine\block;
|
||||
|
||||
|
||||
class NetherReactor extends Solid{
|
||||
|
||||
protected $id = self::NETHER_REACTOR;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::NETHER_REACTOR, $meta, "Nether Reactor");
|
||||
$this->isActivable = true;
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Nether Reactor";
|
||||
}
|
||||
|
||||
public function canBeActivated(){
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Netherrack extends Solid{
|
||||
|
||||
protected $id = self::NETHERRACK;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::NETHERRACK, 0, "Netherrack");
|
||||
$this->hardness = 2;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Netherrack";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -24,9 +24,19 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Obsidian extends Solid{
|
||||
|
||||
protected $id = self::OBSIDIAN;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::OBSIDIAN, 0, "Obsidian");
|
||||
$this->hardness = 6000;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Obsidian";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 6000;
|
||||
}
|
||||
|
||||
public function getBreakTime(Item $item){
|
||||
|
@ -30,18 +30,28 @@ class Planks extends Solid{
|
||||
const ACACIA = 4;
|
||||
const DARK_OAK = 5;
|
||||
|
||||
protected $id = self::WOODEN_PLANKS;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::PLANKS, $meta, "Wood Planks");
|
||||
$names = [
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 15;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
static $names = [
|
||||
self::OAK => "Oak Wood Planks",
|
||||
self::SPRUCE => "Spruce Wood Planks",
|
||||
self::BIRCH => "Birch Wood Planks",
|
||||
self::JUNGLE => "Jungle Wood Planks",
|
||||
self::ACACIA => "Acacia Wood Planks",
|
||||
self::DARK_OAK => "Jungle Wood Planks",
|
||||
"",
|
||||
""
|
||||
];
|
||||
$this->name = $names[$this->meta & 0x07];
|
||||
$this->hardness = 15;
|
||||
return $names[$this->meta & 0x07];
|
||||
}
|
||||
|
||||
}
|
@ -22,8 +22,18 @@
|
||||
namespace pocketmine\block;
|
||||
|
||||
class Podzol extends Solid{
|
||||
|
||||
protected $id = self::PODZOL;
|
||||
|
||||
public function __construct(){
|
||||
parent::__construct(self::PODZOL, 0, "Podzol");
|
||||
$this->hardness = 2.5;
|
||||
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Podzol";
|
||||
}
|
||||
|
||||
public function getHardness(){
|
||||
return 2.5;
|
||||
}
|
||||
}
|
@ -25,20 +25,22 @@ use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\Player;
|
||||
|
||||
class CyanFlower extends Flowable{
|
||||
public function __construct(){
|
||||
parent::__construct(self::POPPY, 0, "Cyan Flower");
|
||||
$this->hardness = 0;
|
||||
class Poppy extends Flowable{
|
||||
|
||||
protected $id = self::POPPY;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getBoundingBox(){
|
||||
return null;
|
||||
public function getName(){
|
||||
return "Poppy";
|
||||
}
|
||||
|
||||
|
||||
public function place(Item $item, Block $block, Block $target, $face, $fx, $fy, $fz, Player $player = null){
|
||||
$down = $this->getSide(0);
|
||||
if($down->getID() === 2 or $down->getID() === 3 or $down->getID() === 60){
|
||||
if($down->getId() === 2 or $down->getId() === 3 or $down->getId() === 60){
|
||||
$this->getLevel()->setBlock($block, $this, true, true);
|
||||
|
||||
return true;
|
||||
@ -49,7 +51,7 @@ class CyanFlower extends Flowable{
|
||||
|
||||
public function onUpdate($type){
|
||||
if($type === Level::BLOCK_UPDATE_NORMAL){
|
||||
if($this->getSide(0)->isTransparent === true){
|
||||
if($this->getSide(0)->isTransparent() === true){
|
||||
$this->getLevel()->useBreakOn($this);
|
||||
|
||||
return Level::BLOCK_UPDATE_NORMAL;
|
@ -24,8 +24,15 @@ namespace pocketmine\block;
|
||||
use pocketmine\item\Item;
|
||||
|
||||
class Potato extends Crops{
|
||||
|
||||
protected $id = self::POTATO_BLOCK;
|
||||
|
||||
public function __construct($meta = 0){
|
||||
parent::__construct(self::POTATO_BLOCK, $meta, "Potato Block");
|
||||
$this->meta = $meta;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
return "Potato Block";
|
||||
}
|
||||
|
||||
public function getDrops(Item $item){
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user