Compare commits

...

158 Commits

Author SHA1 Message Date
3de14d8ba6 Preparing release 2015-01-02 01:37:33 +01:00
5fffabe05b Fixed players not calculating onGround correctly 2015-01-02 01:22:33 +01:00
3128ae9736 Improved exception handling and trace creation 2015-01-01 22:50:45 +01:00
7be4e2fa81 Merge pull request #2438 from PocketMine/new-version-format
New release version format
2014-12-31 17:53:12 +01:00
95b305ce87 Detect really big corrupted chunks, closes #2471 2014-12-31 12:40:11 +01:00
767800662c Added chunk check on Level 2014-12-30 15:54:12 +01:00
fe32e6f5d0 Merge branch 'master' into new-version-format 2014-12-29 12:43:15 +01:00
2cec0d9f36 Improved Simplex 2D noise 2014-12-28 03:51:08 +01:00
d800a21bd4 Higher chunk defaults 2014-12-28 02:58:17 +01:00
8d9fbec4ce Fixed memory leak issues on chunk generation under 32-bit hosts, fixed issue with generated chunks not having a provider. Closes #2419, fixes #2308, closes #2421 2014-12-28 02:22:13 +01:00
ab72c32769 Improved Normal generator speed 2014-12-28 02:12:48 +01:00
346626305c Corrected fence crafting recipes, closes #2457 2014-12-28 01:49:42 +01:00
fafbd500e1 Added typehints to HelpCommand 2014-12-28 01:49:10 +01:00
2db2e8cfc4 Block IP addresses on ban-ip 2014-12-26 13:56:35 +01:00
854479180f Move Query exceptions to debug level > 1 2014-12-26 13:47:15 +01:00
902ba81e02 Added automatic/manual RakLib IP address, block addresses when exceptions are thrown 2014-12-26 13:33:41 +01:00
1ac17abec0 Fixed #2446 2014-12-24 23:00:11 +01:00
714ea54121 Players won't take damage 60 ticks after spawning / respawning. 2014-12-24 20:44:22 +01:00
aa992684ba Possible workaround for some PHP bug 2014-12-24 00:55:23 +01:00
0c58de86b7 New version format 2014-12-23 14:02:35 +01:00
7ecac019a9 Bitmask block state 2014-12-23 13:58:30 +01:00
6cb88afe1a Improved block breaking time and event handling 2014-12-22 23:49:17 +01:00
a677bcb331 Increased transaction timeout, not needed anymore due to packet ordering 2014-12-22 23:38:47 +01:00
2f6007342c Fixed server.log created in two different places on path changed 2014-12-22 23:00:28 +01:00
b6c0eb8c96 Added optional parameter for multiple NBT read 2014-12-22 16:25:12 +01:00
afa8496767 Fixed possible memory leak when hiding players from each other 2014-12-21 20:03:39 +01:00
d7be2ce439 Added Chest recreation on imported levels 2014-12-21 14:29:18 +01:00
6dcb5da069 Added Double Plant block, fixes damage walking inside it. 2014-12-21 14:28:45 +01:00
3cf1692c96 Possible fix for #2424 2014-12-21 13:59:04 +01:00
d04af590d1 Updated RakLib
* Fixes issues with packets without messageIndex
* Workarounds possible CPU-hog DoS attack over ACK/NACK packets
2014-12-21 13:45:28 +01:00
d4c43215b1 Fixed typo about async chunk generation 2014-12-19 16:10:01 +01:00
a40918aabf LevelDB load/write fixes 2014-12-19 10:35:16 +01:00
20f9352714 Merge branch 'master' of github.com:PocketMine/PocketMine-MP 2014-12-19 01:07:13 +01:00
a605e90dfc Added experimental LevelDB support, fixed a few issues with NBT, spawning and Binary R/W 2014-12-19 00:28:50 +01:00
9fc250956f Merge pull request #2395 from PEMapModder/patch-6
Allow $base in knockback() to be dynamic and getters/setters in EntityDa...
2014-12-18 20:39:48 +09:00
db2dfc47a6 Update RakLib 2014-12-18 03:33:33 +01:00
408a537001 Added TesterPlugin submodule, updated RakLib to fix packet loop issues 2014-12-17 23:29:57 +01:00
922bfb33ac Updated .gitignore 2014-12-16 18:50:57 +01:00
8e47c93fbc Fixed some issues with chunks being generated on a loop 2014-12-16 02:57:44 +01:00
c175485cd8 Added World Generation timings 2014-12-15 17:52:07 +01:00
b6981cc31d Merge branch 'master' of github.com:PocketMine/PocketMine-MP 2014-12-15 01:05:55 +01:00
1f9cd6a99b Added default parameter to Config getters, implements and closes #2398 2014-12-15 01:05:32 +01:00
ded7ada7d7 Merge pull request #2399 from PEMapModder/patch-7
Update documentation of PluginBase::getCommand() for IDEs' auto completion
2014-12-15 00:52:43 +01:00
1b50879823 Snow layer recipe added: Fix for #2400 2014-12-13 17:10:17 +01:00
1bd9cbd4d3 Update documentation of PluginBase::getCommand() for IDEs' auto completion 2014-12-13 20:42:23 +08:00
96122d3be7 Allow $base in knockback() to be dynamic and getters/setters in EntityDamageByEntityEvent
This change is backwards-compatible.
2014-12-12 23:01:31 +08:00
71d602a4cf Faster chunk setting on provider 2014-12-12 15:51:31 +01:00
c81bbdaaa9 Possible fix for #2394 2014-12-12 12:05:36 +01:00
2752393c42 Fixed #2392 2014-12-12 12:05:15 +01:00
312e064b07 Updated RakLib, changed some Entity move AABB calls 2014-12-11 17:39:59 +01:00
94f91967f3 Updated RakLib: Implemented packet reordering, fixed packet recovery in both sides, errors are now debug level 2014-12-11 03:13:44 +01:00
fe900b417e Less calls! 2014-12-10 02:42:02 +01:00
4c30b6b8a1 Optimized Liquid spreading, optimized light updates, improved side block get/update, fixed raw set not cleaning Block cache (TNT explosions) 2014-12-10 00:37:04 +01:00
c41ac7b0a2 Updated PocketMine-SPL, added trait autoloading 2014-12-09 16:33:42 +01:00
b220bd2a45 Updated chunk indexes on generator 2014-12-09 15:14:11 +01:00
04ee94dc91 Fixed #2388 2014-12-09 15:05:36 +01:00
ea8f10efa4 Limited death animation to Living entities 2014-12-09 14:57:28 +01:00
04ecbd1a76 Level optimization, added new chunk/block hashes 2014-12-09 14:55:21 +01:00
ddfc9d9ce1 Fixed players not getting sound when they are harmed 2014-12-09 02:22:42 +01:00
a4735eaf76 Replaced some instanceof to null checks 2014-12-09 02:22:18 +01:00
306f492fc0 Added Player death animations, improved spawning behavior to correct invisible players, fixed players getting stuck when dead, closes #2304 2014-12-09 01:36:46 +01:00
5e5f8bf33d Better block creation on Level 2014-12-08 22:02:36 +01:00
3bb2f12cde Improved block reading
* Created global block states array
* Improved Level->getBlock() using block states
* Improved Level->getBlock() for 64-bit systems
* Added Level->getFullBlock()
* Added FullChunk->getFullBlock()
* Added Chunk->getFullBlock()
* Added ChunkSection->getFullBlock()
* Deprecated FullChunk->getBlock()
* Deprecated Chunk->getBlock()
* Deprecated ChunkSection->getBlock()
2014-12-08 20:54:47 +01:00
1041bb0e6a Do not quiet error messages when parsing config files 2014-12-07 23:21:47 +01:00
49e93cee80 Merge branch 'master' of github.com:PocketMine/PocketMine-MP 2014-12-07 22:05:58 +01:00
8b6681c56d FIxed some preprocessor includes 2014-12-07 22:05:45 +01:00
9e3d432b9e Faster Level provider chunk unloading 2014-12-07 21:51:57 +01:00
841a3d5ee6 Merge pull request #2381 from PocketMine/revert-2379-master
Revert "Fixed small possible error in permission"
2014-12-07 20:54:46 +01:00
a5294d5ec7 Revert "Fixed small possible error in permission" 2014-12-07 20:54:38 +01:00
5373e6be07 Merge pull request #2379 from sudoku173/master
Fixed small possible error in permission
2014-12-07 20:41:08 +01:00
075137bd3c Fixed small possible error in permission
Changed permission to "pocketmine.command.deop" from "pocketmine.command.op.take"
2014-12-07 11:38:44 -08:00
68da4b5b39 Collect unallocated chunks from the Level provider 2014-12-07 18:27:11 +01:00
e4557a2e8e Added HeightMap get/set methods on chunks, Level 2014-12-07 18:02:07 +01:00
964bf98ca6 Added Config->getNested(key) and Config->setNested(key, value) 2014-12-07 16:41:43 +01:00
747f7685e7 Fix formatting issues due to bad IDE settings 2014-12-07 16:30:04 +01:00
bb82e7be50 Handle a hotbar queue to allow using more than the first slot (won't save order due to the protocol) 2014-12-07 16:01:45 +01:00
7506f01302 Improved Item property handling 2014-12-07 15:51:00 +01:00
a98da3bab1 Renamed old getID() calls to getId() 2014-12-07 15:21:32 +01:00
f0d6128282 Use squared distance on movement handling 2014-12-07 15:18:14 +01:00
161e7ae7ec Fix CPU issue when starting without STDIN 2014-12-07 02:42:38 +01:00
6104c5b5a3 API 1.9.0, backwards-compatible 2014-12-07 02:24:45 +01:00
af82d616c1 Block creating and property handling rewrite, part2 2014-12-07 02:20:26 +01:00
a0d4bff385 Block creating and property handling rewrite, part1 2014-12-07 01:53:27 +01:00
79236c971c Possibly fix issues related to new lines on different operating systems and event listeners modifiers 2014-12-05 22:43:31 +01:00
20e63ae543 Force player setting their new position 2014-12-05 02:24:34 +01:00
add7879720 Implemented no damage ticks 2014-12-05 02:24:08 +01:00
1a064d38b1 Merge remote-tracking branch 'origin/master' 2014-12-04 00:04:18 +01:00
294e680d5d Added armor items and max stack size for them. 2014-12-04 00:04:09 +01:00
811970e58d Merge pull request #2352 from PEMapModder/patch-3
Added internal use warning for TaskHandler::cancel()
2014-12-01 12:07:30 +01:00
941961f5ef Added internal use warning for TaskHandler::cancel()
It is confusing for some developers to whether to use this function or `ServerScheduler::cancelTask($taskId)`. It is better to add warning in the documentation.
2014-12-01 16:25:37 +08:00
1963d8fde0 Change last X/Y/Z/Yaw/Pitch on teleport 2014-11-30 12:49:35 +01:00
e44ed4da3b Enabled batch block sending again 2014-11-29 12:58:31 +01:00
a72488d41e Updated player movement processing and event handling 2014-11-29 12:43:34 +01:00
3930f379cf Updated light filter values 2014-11-29 11:58:50 +01:00
66ba327e62 Improved light spread algorithm even more 2014-11-29 11:27:22 +01:00
329ca62465 Improved light spread algorithm 2014-11-28 19:54:25 +01:00
26e47ef694 Removed old revert flag from Player->processMovement() 2014-11-28 14:49:06 +01:00
61ea149ff0 API 1.8.0 2014-11-28 14:44:56 +01:00
b3c3f896a3 Implemented light population, added Level->getFullLight() 2014-11-28 14:44:27 +01:00
d139e5f342 Removed temporal pthreads workaround 2014-11-28 13:01:25 +01:00
3abf36ad07 Fixed invalid worlds property being set by users 2014-11-28 12:47:28 +01:00
0bc9a9bdab Fixed armor dropping twice 2014-11-27 23:19:46 +01:00
98340522d9 Fixed items getting added on the same empty slot 2014-11-27 20:49:18 +01:00
6d09754ea7 Improved Inventory->addItem(), fixed breaking containers duplicating the last slot, removed not necessary slot changes 2014-11-27 20:10:55 +01:00
a3b1d318cc Fixed ladder crafting recipe 2014-11-27 20:02:38 +01:00
f866efb622 Removed unused Block->isLiquid property 2014-11-27 17:26:43 +01:00
b1c4578726 Fixed #2340 2014-11-27 16:18:43 +01:00
f4181a6e36 Bump Minecraft: PE version 2014-11-27 14:37:44 +01:00
38089af098 Improved global entity motion encoding using per-player queues 2014-11-27 14:26:36 +01:00
cd135b39ad Improved player spawn item in hand sending 2014-11-27 13:59:32 +01:00
dd3207cbd8 Possible fix for #2267, #2314 2014-11-27 13:47:17 +01:00
a7abd5ff9d Catch exceptions when chunks are unloaded 2014-11-27 13:35:54 +01:00
a3e50f6337 Properly close inventory windows from Players 2014-11-27 13:32:07 +01:00
441a98e60a Removed old trigger_error() calls, closes #2335 2014-11-27 13:16:39 +01:00
4a90ac270f Improved exception handling and debugging 2014-11-22 13:52:36 +01:00
a906a2988b Bumped Minecraft: PE version string 2014-11-22 13:44:34 +01:00
545f68382c Increased Fence, Fence Gate and Stone Wall Y bounding box 2014-11-22 13:44:05 +01:00
8249cac592 Catch corrupted chunk data errors 2014-11-20 22:02:00 +01:00
7b7bbe9105 Regenerate corrupt player data if invalid data is found 2014-11-20 21:58:27 +01:00
05679c7872 Merge branch 'master' of github.com:PocketMine/PocketMine-MP 2014-11-20 21:46:14 +01:00
8eb80be691 Remove duplicated tiles from chunk table automatically 2014-11-20 21:45:52 +01:00
f55b0d0b45 Merge pull request #2295 from LukeDarling/patch-1
Fixed Server->getOps() capitalization
2014-11-19 13:10:03 +01:00
754e0dbb49 Protect permission removal against bad plugins 2014-11-18 18:43:30 +01:00
525c8db779 Improved chunk loading/unloading 2014-11-18 18:33:24 +01:00
c7f578f297 Possible fix for #2297 2014-11-18 13:57:03 +01:00
19c030281f Fixed #1969 2014-11-18 13:53:38 +01:00
ca9fe1b89a Improved and fixed command exception message, closes #2301 2014-11-18 13:46:00 +01:00
9fd6a695f6 Fixed permission-related memory leak 2014-11-18 13:42:24 +01:00
c07b0ff35b Fixed tile entities not being placed in the correct array 2014-11-15 11:49:09 +01:00
00be3f0dd3 Fixed Server->getOps() capitalization
I'm not 100% sure, but I believe this is how it's supposed to be.
2014-11-15 00:01:57 -05:00
6796fca2b6 Merge pull request #2294 from LukeDarling/patch-1
fixed version message color
2014-11-15 14:20:14 +10:30
5657cce3db fixed version message color 2014-11-14 15:52:38 -05:00
05ac256cc3 Fixed Acacia / Dark Oak logs crafting recipes 2014-11-14 15:58:31 +01:00
49977c5410 Bumped weakref version, fixes travis builds 2014-11-14 10:30:06 +01:00
ca40bb678c Merge pull request #2288 from sekjun9878/master
Get timezone directly. Fixes #2287.
2014-11-13 23:08:22 +10:30
2068cc9cdf Merge pull request #2243 from PEMapModder/patch-1
cmd files comment syntax should be like this.
2014-11-13 21:42:25 +10:30
ea4617cedd Get timezone directly. Fixes #2287. 2014-11-13 21:13:12 +10:30
1a5544f68c Fixed Chunk tile indexes 2014-11-08 15:00:18 +01:00
0128a7aeb2 API version 1.7.1 (fixes) 2014-11-07 09:45:30 +01:00
fd954ce708 Fixed PlayerInventory->setItem() with null items 2014-11-07 09:43:36 +01:00
d63a82de0a MCPE protocol 20 2014-11-06 19:08:32 +01:00
92143d523c Added SetDifficultyPacket 2014-11-06 19:07:24 +01:00
1818e64c8e Merge branch 'master' into 0.10 2014-11-06 18:56:47 +01:00
522b75645c Merge branch 'master' into 0.10 2014-11-05 19:04:36 +01:00
4fba6d7c86 Merge branch 'master' into 0.10 2014-10-30 23:20:59 +01:00
577a7a1c3d cmd files comment syntax should be like this. 2014-10-29 17:20:36 +08:00
1fc066fc37 Updated time steps from x2.5 to x1.25 2014-10-24 12:12:01 +02:00
b565844062 Merge branch 'master' into 0.10 2014-10-24 12:07:35 +02:00
5cb428e5cc Updated build number 2014-10-23 17:23:59 +02:00
d2f4a14d66 Merge branch 'master' into 0.10 2014-10-23 17:21:24 +02:00
5437567e95 Merge branch 'master' into 0.10 2014-10-20 12:53:14 +02:00
7d9a98ec6b Updated UseItemPacket 2014-10-18 23:42:41 +02:00
92facc94b9 Added new fences and fence gates to fuel types 2014-10-18 18:02:39 +02:00
d3327f450c Added different Fence Gates, new Fence Gate crafting recipes 2014-10-18 17:56:18 +02:00
570cab9c66 Added different Fences, new Fence crafting recipes 2014-10-18 17:44:24 +02:00
582ba100b0 Bumped protocol version to 19 2014-10-18 17:01:36 +02:00
4c0daa462d Merge branch 'master' into 0.10 2014-10-18 16:54:03 +02:00
a879104a6f Minecraft: PE version bump 2014-10-17 14:43:10 +02:00
277 changed files with 5477 additions and 1879 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@ players/*
worlds/*
plugins/*
bin/*
timings/*
*.log
*.txt
*.phar

3
.gitmodules vendored
View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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){

View File

@ -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){

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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 . ")";
}
/**

View File

@ -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;
}
}

View File

@ -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";
}
}

View File

@ -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){

View File

@ -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;

View File

@ -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){

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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){

View File

@ -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;
}

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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";
}
}

View File

@ -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 [];
}
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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){

View File

@ -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;
}

View File

@ -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){

View File

@ -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){

View File

@ -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);

View File

@ -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;

View 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 [];
}
}

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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(){

View File

@ -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){

View File

@ -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()),
]));

View File

@ -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,

View File

@ -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;
}
}

View 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";
}
}

View 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";
}
}

View 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";
}
}

View File

@ -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;

View 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";
}
}

View 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";
}
}

View 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";
}
}

View 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";
}
}

View 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";
}
}

View 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";
}
}

View 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";
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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";
}
}

View File

@ -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){

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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);

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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";
}
}

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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;

View File

@ -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){

View File

@ -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){

View File

@ -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){

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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){

View File

@ -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){

View File

@ -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);

View File

@ -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 [];
}
}

View File

@ -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){

View File

@ -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()){

View File

@ -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){

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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){

View File

@ -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){

View File

@ -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];
}
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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