PageRenderTime 52ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/API/BlockAPI.php

https://github.com/domanicYL/PocketMine-MP
PHP | 863 lines | 808 code | 31 blank | 24 comment | 83 complexity | 6a2e2803a1d73382507d2f3596f18b41 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. /*
  3. -
  4. / \
  5. / \
  6. / PocketMine \
  7. / MP \
  8. |\ @shoghicp /|
  9. |. \ / .|
  10. | .. \ / .. |
  11. | .. | .. |
  12. | .. | .. |
  13. \ | /
  14. \ | /
  15. \ | /
  16. \ | /
  17. This program is free software: you can redistribute it and/or modify
  18. it under the terms of the GNU Lesser General Public License as published by
  19. the Free Software Foundation, either version 3 of the License, or
  20. (at your option) any later version.
  21. */
  22. define("BLOCK_UPDATE_NORMAL", 0);
  23. define("BLOCK_UPDATE_RANDOM", 1);
  24. define("BLOCK_UPDATE_SCHEDULED", 2);
  25. define("BLOCK_UPDATE_WEAK", 3);
  26. class BlockAPI{
  27. private $server;
  28. function __construct(PocketMinecraftServer $server){
  29. $this->server = $server;
  30. }
  31. public function init(){
  32. $this->server->addHandler("world.block.update", array($this, "updateBlockRemote"), 1);
  33. $this->server->addHandler("player.block.break", array($this, "blockBreak"), 1);
  34. $this->server->addHandler("player.block.action", array($this, "blockAction"), 1);
  35. $this->server->api->console->register("give", "Give items to a player", array($this, "commandHandler"));
  36. }
  37. public function commandHandler($cmd, $params){
  38. switch($cmd){
  39. case "give":
  40. if(!isset($params[0]) or !isset($params[1])){
  41. console("[INFO] Usage: /give <username> <item> [amount] [damage]");
  42. break;
  43. }
  44. $username = $params[0];
  45. $b = explode(":", $params[1]);
  46. if(!isset($b[1])){
  47. $meta = 0;
  48. }else{
  49. $meta = (int) $b[1];
  50. }
  51. $block = ((int) $b[0]) & 0xFFFF;
  52. if(!isset($params[2])){
  53. $amount = 64;
  54. }else{
  55. $amount = (int) $params[2];
  56. }
  57. if(isset($params[3])){
  58. $meta = (int) $params[3];
  59. }
  60. if(($player = $this->server->api->player->get($username)) !== false){
  61. $this->drop($player->entity->x, $player->entity->y, $player->entity->z, $block, $meta, $amount);
  62. console("[INFO] Giving ".$amount." of ".$block.":".$meta." to ".$username);
  63. }else{
  64. console("[INFO] Unknown player");
  65. }
  66. break;
  67. }
  68. }
  69. private function cancelAction($block){
  70. $this->server->api->dhandle("world.block.change", array(
  71. "x" => $block[2][0],
  72. "y" => $block[2][1],
  73. "z" => $block[2][2],
  74. "block" => $block[0],
  75. "meta" => $block[1],
  76. "fake" => true,
  77. ));
  78. return false;
  79. }
  80. public function blockBreak($data, $event){
  81. if($event !== "player.block.break"){
  82. return;
  83. }
  84. $target = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"]);
  85. if(isset(Material::$unbreakable[$target[0]])){
  86. return $this->cancelAction($target);
  87. }
  88. $drop = array(
  89. $target[0], //Block
  90. $target[1], //Meta
  91. 1, //Count
  92. );
  93. switch($target[0]){
  94. case 16:
  95. $drop = array(263, 0, 1);
  96. break;
  97. case 21:
  98. $drop = array(351, 4, mt_rand(4, 8));
  99. break;
  100. case 56:
  101. $drop = array(264, 0, 1);
  102. break;
  103. case 73:
  104. case 74:
  105. $drop = array(351, 4, mt_rand(4, 5));
  106. break;
  107. case 18:
  108. $drop = false;
  109. if(mt_rand(1,20) === 1){ //Saplings
  110. $drop = array(6, $target[1], 1);
  111. }
  112. if($target[1] === 0 and mt_rand(1,200) === 1){ //Apples
  113. $this->drop($data["x"], $data["y"], $data["z"], 260, 0, 1);
  114. }
  115. break;
  116. case 59:
  117. if($target[1] >= 0x07){ //Seeds
  118. $drop = array(296, 0, 1);
  119. $this->drop($data["x"], $data["y"], $data["z"], 295, 0, mt_rand(0,3));
  120. }else{
  121. $drop = array(295, 0, 1);
  122. }
  123. break;
  124. case 31:
  125. $drop = false;
  126. if(mt_rand(1,10) === 1){ //Seeds
  127. $drop = array(295, 0, 1);
  128. }
  129. break;
  130. case 20:
  131. $drop = false;
  132. break;
  133. case 30:
  134. $drop = false;
  135. break;
  136. case 51:
  137. $drop = false;
  138. break;
  139. case 52:
  140. $drop = false;
  141. break;
  142. case 43:
  143. $drop = array(
  144. 44,
  145. $target[1],
  146. 2,
  147. );
  148. break;
  149. case 60:
  150. case 2:
  151. $drop = array(3, 0, 1);
  152. break;
  153. case 64: //Door
  154. $drop = array(324, 0, 1);
  155. if(($target[1] & 0x08) === 0x08){
  156. $down = $this->server->api->level->getBlock($data["x"], $data["y"] - 1, $data["z"]);
  157. if($down[0] === 64){
  158. $data2 = $data;
  159. --$data2["y"];
  160. $this->server->trigger("player.block.break", $data2);
  161. }
  162. }else{
  163. $up = $this->server->api->level->getBlock($data["x"], $data["y"] + 1, $data["z"]);
  164. if($up[0] === 64){
  165. $data2 = $data;
  166. ++$data2["y"];
  167. $this->server->trigger("player.block.break", $data2);
  168. }
  169. }
  170. break;
  171. }
  172. if($drop !== false and $drop[0] !== 0 and $drop[2] > 0){
  173. $this->drop($data["x"], $data["y"], $data["z"], $drop[0], $drop[1] & 0x0F, $drop[2] & 0xFF);
  174. }
  175. $this->server->trigger("player.block.break", $data);
  176. return false;
  177. }
  178. public function drop($x, $y, $z, $block, $meta, $stack = 1){
  179. if($block === 0 or $stack <= 0 or $this->server->gamemode === 1){
  180. return;
  181. }
  182. $data = array(
  183. "x" => $x,
  184. "y" => $y,
  185. "z" => $z,
  186. "meta" => $meta,
  187. "stack" => $stack,
  188. );
  189. $data["x"] += mt_rand(2, 8) / 10;
  190. $data["y"] += 0.19;
  191. $data["z"] += mt_rand(2, 8) / 10;
  192. if($this->server->api->handle("item.drop", $data) !== false){
  193. for($count = $stack; $count > 0; ){
  194. $data["stack"] = min(64, $count);
  195. $count -= $data["stack"];
  196. $e = $this->server->api->entity->add(ENTITY_ITEM, $block, $data);
  197. $this->server->api->entity->spawnToAll($e->eid);
  198. }
  199. }
  200. }
  201. public function blockAction($data, $event){
  202. if($event !== "player.block.action"){
  203. return;
  204. }
  205. if($data["face"] < 0 or $data["face"] > 5){
  206. return false;
  207. }
  208. $target = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"]);
  209. if($target[0] === 0){ //If no block exists
  210. $this->cancelAction($target);
  211. $block = $this->server->api->level->getBlockFace($target, $data["face"]);
  212. return $this->cancelAction($block);
  213. }
  214. $cancelPlace = false;
  215. if(isset(Material::$activable[$target[0]])){
  216. switch($target[0]){
  217. case 6:
  218. if($data["block"] === 351 and $data["meta"] === 0x0F){ //Bonemeal
  219. Sapling::growTree($this->server->api->level, $target, $target[1] & 0x03);
  220. $cancelPlace = true;
  221. }
  222. break;
  223. case 2:
  224. case 3:
  225. if($data["block"] === 292){ //Hoe
  226. $data["block"] = 60;
  227. $data["meta"] = 0;
  228. $this->server->handle("player.block.place", $data);
  229. $cancelPlace = true;
  230. }
  231. case 59:
  232. case 105:
  233. if($data["block"] === 351 and $data["meta"] === 0x0F){ //Bonemeal
  234. $data["block"] = $target[0];
  235. $data["meta"] = 0x07;
  236. $this->server->handle("player.block.place", $data);
  237. $cancelPlace = true;
  238. }
  239. break;
  240. case 64: //Door
  241. if(($target[1] & 0x08) === 0x08){
  242. $down = $this->server->api->level->getBlock($data["x"], $data["y"] - 1, $data["z"]);
  243. if($down[0] === 64){
  244. $down[1] = $down[1] ^ 0x04;
  245. $data2 = array(
  246. "x" => $data["x"],
  247. "z" => $data["z"],
  248. "y" => $data["y"] - 1,
  249. "block" => $down[0],
  250. "meta" => $down[1],
  251. "eid" => $data["eid"],
  252. );
  253. if($this->server->handle("player.block.update", $data2) !== false){
  254. $this->updateBlocksAround($data["x"], $data["y"], $data["z"], BLOCK_UPDATE_NORMAL);
  255. }
  256. }
  257. }else{
  258. $data["block"] = $target[0];
  259. $data["meta"] = $target[1] ^ 0x04;
  260. if($this->server->handle("player.block.update", $data) !== false){
  261. $up = $this->server->api->level->getBlock($data["x"], $data["y"] + 1, $data["z"]);
  262. if($up[0] === 64){
  263. $data2 = $data;
  264. $data2["meta"] = $up[1];
  265. ++$data2["y"];
  266. $this->updateBlocksAround($data2["x"], $data2["y"], $data2["z"], BLOCK_UPDATE_NORMAL);
  267. }
  268. $this->updateBlocksAround($data["x"], $data["y"], $data["z"], BLOCK_UPDATE_NORMAL);
  269. }
  270. }
  271. $cancelPlace = true;
  272. break;
  273. case 96: //Trapdoor
  274. case 107: //Fence gates
  275. $data["block"] = $target[0];
  276. $data["meta"] = $target[1] ^ 0x04;
  277. $this->server->handle("player.block.update", $data);
  278. $cancelPlace = true;
  279. break;
  280. default:
  281. $cancelPlace = true;
  282. break;
  283. }
  284. }
  285. if($cancelPlace === true){
  286. return false;
  287. }
  288. $replace = false;
  289. switch($target[0]){
  290. case 44: //Slabs
  291. if($data["face"] !== 1){
  292. break;
  293. }
  294. if(($target[1] & 0x07) === ($data["meta"] & 0x07)){
  295. $replace = true;
  296. $data["block"] = 43;
  297. $data["meta"] = $data["meta"] & 0x07;
  298. }
  299. break;
  300. }
  301. if($replace === false){
  302. BlockFace::setPosition($data, $data["face"]);
  303. }
  304. if($data["y"] >= 127){
  305. return false;
  306. }
  307. $block = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"]);
  308. if($replace === false and !isset(Material::$replaceable[$block[0]])){
  309. return $this->cancelAction($block);
  310. }
  311. if(isset(Material::$placeable[$data["block"]])){
  312. $data["block"] = Material::$placeable[$data["block"]] === true ? $data["block"]:Material::$placeable[$data["block"]];
  313. }else{
  314. return $this->cancelAction($block);
  315. }
  316. $direction = $this->server->api->entity->get($data["eid"])->getDirection();
  317. switch($data["block"]){
  318. case 6:
  319. if($target[0] === 60){
  320. break;
  321. }
  322. case 37:
  323. case 38:
  324. if(($target[0] !== 2 and $target[0] !== 3) or $data["face"] !== 1){
  325. return false;
  326. }
  327. break;
  328. case 39://Mushrooms
  329. case 40:
  330. $blockDown = $this->server->api->level->getBlock($data["x"], $data["y"] - 1, $data["z"]);
  331. if(isset(Material::$transparent[$blockDown[0]])){
  332. return false;
  333. }
  334. break;
  335. case 83: //Sugarcane
  336. $blockDown = $this->server->api->level->getBlock($data["x"], $data["y"] - 1, $data["z"]);
  337. if($blockDown[0] !== 2 and $blockDown[0] !== 3 and $blockDown[0] !== 12){
  338. return false;
  339. }
  340. $block0 = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"] + 1);
  341. $block1 = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"] - 1);
  342. $block2 = $this->server->api->level->getBlock($data["x"] + 1, $data["y"], $data["z"]);
  343. $block3 = $this->server->api->level->getBlock($data["x"] - 1, $data["y"], $data["z"]);
  344. if($block0[0] === 9 or $block0[0] === 8 or $block1[0] === 9 or $block1[0] === 8 or $block2[0] === 9 or $block2[0] === 8 or $block3[0] === 9 or $block3[0] === 8){
  345. }else{
  346. return false;
  347. }
  348. break;
  349. case 50: //Torch
  350. if(isset(Material::$transparent[$target[0]])){
  351. return false;
  352. }
  353. $faces = array(
  354. 0 => 6,
  355. 1 => 5,
  356. 2 => 4,
  357. 3 => 3,
  358. 4 => 2,
  359. 5 => 1,
  360. );
  361. if(!isset($faces[$data["face"]])){
  362. return false;
  363. }
  364. $data["meta"] = $faces[$data["face"]];
  365. break;
  366. case 53://Stairs
  367. case 67:
  368. case 108:
  369. $faces = array(
  370. 0 => 0,
  371. 1 => 2,
  372. 2 => 1,
  373. 3 => 3,
  374. );
  375. $data["meta"] = $faces[$direction] & 0x03;
  376. break;
  377. case 96: //trapdoor
  378. if(isset(Material::$transparent[$target[0]])){
  379. return false;
  380. }
  381. $faces = array(
  382. 2 => 0,
  383. 3 => 1,
  384. 4 => 2,
  385. 5 => 3,
  386. );
  387. if(!isset($faces[$data["face"]])){
  388. return false;
  389. }
  390. $data["meta"] = $faces[$data["face"]] & 0x03;
  391. break;
  392. case 107: //Fence gate
  393. $faces = array(
  394. 0 => 3,
  395. 1 => 0,
  396. 2 => 1,
  397. 3 => 2,
  398. );
  399. $data["meta"] = $faces[$direction] & 0x03;
  400. break;
  401. case 64://Door placing
  402. $blockUp = $this->server->api->level->getBlock($data["x"], $data["y"] + 1, $data["z"]);
  403. $blockDown = $this->server->api->level->getBlock($data["x"], $data["y"] - 1, $data["z"]);
  404. if(!isset(Material::$replaceable[$blockUp[0]]) or isset(Material::$transparent[$blockDown[0]])){
  405. return false;
  406. }else{
  407. $data2 = $data;
  408. $data2["meta"] = 0x08;
  409. $data["meta"] = $direction & 0x03;
  410. ++$data2["y"];
  411. $this->server->handle("player.block.place", $data2);
  412. }
  413. break;
  414. case 54:
  415. case 61:
  416. $faces = array(
  417. 0 => 4,
  418. 1 => 2,
  419. 2 => 5,
  420. 3 => 3,
  421. );
  422. $data["meta"] = $faces[$direction];
  423. break;
  424. case 26: //bed
  425. $face = array(
  426. 0 => 3,
  427. 1 => 4,
  428. 2 => 2,
  429. 3 => 5,
  430. );
  431. $next = $this->server->api->level->getBlockFace($block, $face[(($direction + 3) % 4)]);
  432. if(!isset(Material::$replaceable[$next[0]])){
  433. return false;
  434. }
  435. $data["meta"] = (($direction + 3) % 4) & 0x3;
  436. $data2 = $data;
  437. $data2["meta"] = $data2["meta"] | 0x08;
  438. $data2["x"] = $next[2][0];
  439. $data2["y"] = $next[2][1];
  440. $data2["z"] = $next[2][2];
  441. $this->server->handle("player.block.place", $data2);
  442. break;
  443. case 65: //Ladder
  444. if(isset(Material::$transparent[$target[0]])){
  445. return false;
  446. }
  447. $faces = array(
  448. 2 => 2,
  449. 3 => 3,
  450. 4 => 4,
  451. 5 => 5,
  452. );
  453. if(!isset($faces[$data["face"]])){
  454. return false;
  455. }
  456. $data["meta"] = $faces[$data["face"]];
  457. break;
  458. case 59://Seeds
  459. case 105:
  460. $blockDown = $this->server->api->level->getBlock($data["x"], $data["y"] - 1, $data["z"]);
  461. if($blockDown[0] !== 60){
  462. return false;
  463. }
  464. $data["meta"] = 0;
  465. break;
  466. case 81: //Cactus
  467. $blockDown = $this->server->api->level->getBlock($data["x"], $data["y"] - 1, $data["z"]);
  468. $block0 = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"] + 1);
  469. $block1 = $this->server->api->level->getBlock($data["x"], $data["y"], $data["z"] - 1);
  470. $block2 = $this->server->api->level->getBlock($data["x"] + 1, $data["y"], $data["z"]);
  471. $block3 = $this->server->api->level->getBlock($data["x"] - 1, $data["y"], $data["z"]);
  472. if($blockDown[0] !== 12 or !isset(Material::$transparent[$block0[0]]) or !isset(Material::$transparent[$block1[0]]) or !isset(Material::$transparent[$block2[0]]) or !isset(Material::$transparent[$block3[0]])){
  473. return false;
  474. }
  475. break;
  476. }
  477. $this->server->handle("player.block.place", $data);
  478. return false;
  479. }
  480. public function blockScheduler($data){
  481. $this->updateBlock($data["x"], $data["y"], $data["z"], BLOCK_UPDATE_SCHEDULED);
  482. }
  483. public function updateBlockRemote($data, $event){
  484. if($event !== "world.block.update"){
  485. return;
  486. }
  487. $this->updateBlock($data["x"], $data["y"], $data["z"], isset($data["type"]) ? $data["type"]:BLOCK_UPDATE_RANDOM);
  488. }
  489. public function flowLavaOn($source, $face){
  490. $down = 0;
  491. if($face === BlockFace::BOTTOM){
  492. $level = 0;
  493. $down = 1;
  494. }else{
  495. $level = ($source[1] & 0x07) + 2;
  496. if($level > 0x07){
  497. return false;
  498. }
  499. }
  500. $spread = $this->server->api->level->getBlockFace($source, $face);
  501. if(($source[0] === 10 or $source[0] === 11) and $spread[0] === 10){
  502. if($level < ($spread[1] & 0x07)){
  503. $this->server->schedule(20, array($this, "blockScheduler"), array(
  504. "x" => $spread[2][0],
  505. "y" => $spread[2][1],
  506. "z" => $spread[2][2],
  507. "type" => BLOCK_UPDATE_NORMAL,
  508. ));
  509. $this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
  510. return true;
  511. }
  512. }elseif(isset(Material::$flowable[$spread[0]])){
  513. $this->server->schedule(20, array($this, "blockScheduler"), array(
  514. "x" => $spread[2][0],
  515. "y" => $spread[2][1],
  516. "z" => $spread[2][2],
  517. "type" => BLOCK_UPDATE_NORMAL,
  518. ));
  519. $this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 10, $level | $down, false);
  520. return true;
  521. }elseif(($source[1] & 0x08) === 0x08){
  522. $this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
  523. return true;
  524. }
  525. return false;
  526. }
  527. public function flowWaterOn($source, $face){
  528. $down = 0;
  529. if($face === BlockFace::BOTTOM){
  530. $level = 0;
  531. $down = 1;
  532. }else{
  533. $level = ($source[1] & 0x07) + 1;
  534. if($level > 0x07){
  535. return false;
  536. }
  537. }
  538. $spread = $this->server->api->level->getBlockFace($source, $face);
  539. if(($source[0] === 8 or $source[0] === 9) and $spread[0] === 8){
  540. if($level < ($spread[1] & 0x07)){
  541. $this->server->schedule(10, array($this, "blockScheduler"), array(
  542. "x" => $spread[2][0],
  543. "y" => $spread[2][1],
  544. "z" => $spread[2][2],
  545. "type" => BLOCK_UPDATE_NORMAL,
  546. ));
  547. $this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $spread[0], $level | $down, false);
  548. return true;
  549. }
  550. }elseif(isset(Material::$flowable[$spread[0]])){
  551. $this->server->schedule(10, array($this, "blockScheduler"), array(
  552. "x" => $spread[2][0],
  553. "y" => $spread[2][1],
  554. "z" => $spread[2][2],
  555. "type" => BLOCK_UPDATE_NORMAL,
  556. ));
  557. $this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], 8, $level | $down, false);
  558. return true;
  559. }elseif(($source[1] & 0x08) === 0x08){
  560. $this->server->api->level->setBlock($spread[2][0], $spread[2][1], $spread[2][2], $source[0], $source[1] & 0x07, false);
  561. return true;
  562. }
  563. return false;
  564. }
  565. public function updateBlock($x, $y, $z, $type = BLOCK_UPDATE_NORMAL){
  566. $block = $this->server->api->level->getBlock($x, $y, $z);
  567. $changed = false;
  568. switch($block[0]){
  569. case 8:
  570. case 9:
  571. if(!$this->flowWaterOn($block, 0) or $block[0] === 9){
  572. $this->flowWaterOn($block, 2);
  573. $this->flowWaterOn($block, 3);
  574. $this->flowWaterOn($block, 4);
  575. $this->flowWaterOn($block, 5);
  576. }
  577. if($block[0] === 8){
  578. $drained = true;
  579. $level = $block[1] & 0x07;
  580. $up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
  581. if($up[0] === 8 or $up[0] === 9){
  582. $drained = false;
  583. }else{
  584. $b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
  585. if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  586. $drained = false;
  587. }else{
  588. $b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
  589. if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  590. $drained = false;
  591. }else{
  592. $b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
  593. if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  594. $drained = false;
  595. }else{
  596. $b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
  597. if($b[0] === 9 or ($b[0] === 8 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  598. $drained = false;
  599. }
  600. }
  601. }
  602. }
  603. }
  604. if($drained === true){
  605. ++$level;
  606. if($level > 0x07){
  607. $this->server->schedule(10, array($this, "blockScheduler"), array(
  608. "x" => $block[2][0] + 1,
  609. "y" => $block[2][1],
  610. "z" => $block[2][2],
  611. "type" => BLOCK_UPDATE_NORMAL,
  612. ));
  613. $this->server->schedule(10, array($this, "blockScheduler"), array(
  614. "x" => $block[2][0] - 1,
  615. "y" => $block[2][1],
  616. "z" => $block[2][2],
  617. "type" => BLOCK_UPDATE_NORMAL,
  618. ));
  619. $this->server->schedule(10, array($this, "blockScheduler"), array(
  620. "x" => $block[2][0],
  621. "y" => $block[2][1],
  622. "z" => $block[2][2] + 1,
  623. "type" => BLOCK_UPDATE_NORMAL,
  624. ));
  625. $this->server->schedule(10, array($this, "blockScheduler"), array(
  626. "x" => $block[2][0],
  627. "y" => $block[2][1],
  628. "z" => $block[2][2] - 1,
  629. "type" => BLOCK_UPDATE_NORMAL,
  630. ));
  631. $this->server->schedule(10, array($this, "blockScheduler"), array(
  632. "x" => $block[2][0],
  633. "y" => $block[2][1] - 1,
  634. "z" => $block[2][2],
  635. "type" => BLOCK_UPDATE_NORMAL,
  636. ));
  637. $this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
  638. }else{
  639. $block[1] = ($block[1] & 0x08) | $level;
  640. $this->server->schedule(10, array($this, "blockScheduler"), array(
  641. "x" => $block[2][0] + 1,
  642. "y" => $block[2][1],
  643. "z" => $block[2][2],
  644. "type" => BLOCK_UPDATE_NORMAL,
  645. ));
  646. $this->server->schedule(10, array($this, "blockScheduler"), array(
  647. "x" => $block[2][0] - 1,
  648. "y" => $block[2][1],
  649. "z" => $block[2][2],
  650. "type" => BLOCK_UPDATE_NORMAL,
  651. ));
  652. $this->server->schedule(10, array($this, "blockScheduler"), array(
  653. "x" => $block[2][0],
  654. "y" => $block[2][1],
  655. "z" => $block[2][2] + 1,
  656. "type" => BLOCK_UPDATE_NORMAL,
  657. ));
  658. $this->server->schedule(10, array($this, "blockScheduler"), array(
  659. "x" => $block[2][0],
  660. "y" => $block[2][1],
  661. "z" => $block[2][2] - 1,
  662. "type" => BLOCK_UPDATE_NORMAL,
  663. ));
  664. $this->server->schedule(10, array($this, "blockScheduler"), array(
  665. "x" => $block[2][0],
  666. "y" => $block[2][1] - 1,
  667. "z" => $block[2][2],
  668. "type" => BLOCK_UPDATE_NORMAL,
  669. ));
  670. $this->server->schedule(10, array($this, "blockScheduler"), array(
  671. "x" => $block[2][0],
  672. "y" => $block[2][1],
  673. "z" => $block[2][2],
  674. "type" => BLOCK_UPDATE_NORMAL,
  675. ));
  676. $this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
  677. }
  678. }
  679. }
  680. break;
  681. case 10:
  682. case 11:
  683. if(!$this->flowLavaOn($block, 0) or $block[0] === 11){
  684. $this->flowLavaOn($block, 2);
  685. $this->flowLavaOn($block, 3);
  686. $this->flowLavaOn($block, 4);
  687. $this->flowLavaOn($block, 5);
  688. }
  689. if($block[0] === 10){
  690. $drained = true;
  691. $level = $block[1] & 0x07;
  692. $up = $this->server->api->level->getBlockFace($block, BlockFace::UP);
  693. if($up[0] === 10 or $up[0] === 11){
  694. $drained = false;
  695. }else{
  696. $b = $this->server->api->level->getBlockFace($block, BlockFace::NORTH);
  697. if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  698. $drained = false;
  699. }else{
  700. $b = $this->server->api->level->getBlockFace($block, BlockFace::SOUTH);
  701. if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  702. $drained = false;
  703. }else{
  704. $b = $this->server->api->level->getBlockFace($block, BlockFace::EAST);
  705. if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  706. $drained = false;
  707. }else{
  708. $b = $this->server->api->level->getBlockFace($block, BlockFace::WEST);
  709. if($b[0] === 11 or ($b[0] === 10 and ($b[1] & 0x08) === 0 and ($b[1] & 0x07) < $level)){
  710. $drained = false;
  711. }
  712. }
  713. }
  714. }
  715. }
  716. if($drained === true){
  717. ++$level;
  718. if($level > 0x07){
  719. $this->server->schedule(20, array($this, "blockScheduler"), array(
  720. "x" => $block[2][0] + 1,
  721. "y" => $block[2][1],
  722. "z" => $block[2][2],
  723. "type" => BLOCK_UPDATE_NORMAL,
  724. ));
  725. $this->server->schedule(20, array($this, "blockScheduler"), array(
  726. "x" => $block[2][0] - 1,
  727. "y" => $block[2][1],
  728. "z" => $block[2][2],
  729. "type" => BLOCK_UPDATE_NORMAL,
  730. ));
  731. $this->server->schedule(20, array($this, "blockScheduler"), array(
  732. "x" => $block[2][0],
  733. "y" => $block[2][1],
  734. "z" => $block[2][2] + 1,
  735. "type" => BLOCK_UPDATE_NORMAL,
  736. ));
  737. $this->server->schedule(20, array($this, "blockScheduler"), array(
  738. "x" => $block[2][0],
  739. "y" => $block[2][1],
  740. "z" => $block[2][2] - 1,
  741. "type" => BLOCK_UPDATE_NORMAL,
  742. ));
  743. $this->server->schedule(20, array($this, "blockScheduler"), array(
  744. "x" => $block[2][0],
  745. "y" => $block[2][1] - 1,
  746. "z" => $block[2][2],
  747. "type" => BLOCK_UPDATE_NORMAL,
  748. ));
  749. $this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], 0, 0, false);
  750. }else{
  751. $block[1] = ($block[1] & 0x08) | $level;
  752. $this->server->schedule(20, array($this, "blockScheduler"), array(
  753. "x" => $block[2][0] + 1,
  754. "y" => $block[2][1],
  755. "z" => $block[2][2],
  756. "type" => BLOCK_UPDATE_NORMAL,
  757. ));
  758. $this->server->schedule(20, array($this, "blockScheduler"), array(
  759. "x" => $block[2][0] - 1,
  760. "y" => $block[2][1],
  761. "z" => $block[2][2],
  762. "type" => BLOCK_UPDATE_NORMAL,
  763. ));
  764. $this->server->schedule(20, array($this, "blockScheduler"), array(
  765. "x" => $block[2][0],
  766. "y" => $block[2][1],
  767. "z" => $block[2][2] + 1,
  768. "type" => BLOCK_UPDATE_NORMAL,
  769. ));
  770. $this->server->schedule(20, array($this, "blockScheduler"), array(
  771. "x" => $block[2][0],
  772. "y" => $block[2][1],
  773. "z" => $block[2][2] - 1,
  774. "type" => BLOCK_UPDATE_NORMAL,
  775. ));
  776. $this->server->schedule(20, array($this, "blockScheduler"), array(
  777. "x" => $block[2][0],
  778. "y" => $block[2][1] - 1,
  779. "z" => $block[2][2],
  780. "type" => BLOCK_UPDATE_NORMAL,
  781. ));
  782. $this->server->schedule(20, array($this, "blockScheduler"), array(
  783. "x" => $block[2][0],
  784. "y" => $block[2][1],
  785. "z" => $block[2][2],
  786. "type" => BLOCK_UPDATE_NORMAL,
  787. ));
  788. $this->server->api->level->setBlock($block[2][0], $block[2][1], $block[2][2], $block[0], $block[1], false);
  789. }
  790. }
  791. }
  792. break;
  793. case 74:
  794. if($type === BLOCK_UPDATE_SCHEDULED or $type === BLOCK_UPDATE_RANDOM){
  795. $changed = true;
  796. $this->server->api->level->setBlock($x, $y, $z, 73, $block[1], false);
  797. $type = BLOCK_UPDATE_WEAK;
  798. }
  799. break;
  800. case 73:
  801. if($type === BLOCK_UPDATE_NORMAL){
  802. $changed = true;
  803. $this->server->api->level->setBlock($x, $y, $z, 74, $block[1], false);
  804. $this->server->schedule(mt_rand(40, 100), array($this, "blockScheduler"), array(
  805. "x" => $x,
  806. "y" => $y,
  807. "z" => $z,
  808. ));
  809. $type = BLOCK_UPDATE_WEAK;
  810. }
  811. break;
  812. }
  813. if($type === BLOCK_TYPE_SCHEDULED){
  814. $type = BLOCK_UPDATE_WEAK;
  815. }
  816. if($changed === true){
  817. $this->updateBlocksAround($x, $y, $z, $type);
  818. }
  819. }
  820. public function updateBlocksAround($x, $y, $z, $type){
  821. $this->updateBlock($x + 1, $y, $z, $type);
  822. $this->updateBlock($x, $y + 1, $z, $type);
  823. $this->updateBlock($x, $y, $z + 1, $type);
  824. $this->updateBlock($x - 1, $y, $z, $type);
  825. $this->updateBlock($x, $y - 1, $z, $type);
  826. $this->updateBlock($x, $y, $z - 1, $type);
  827. }
  828. }