The same blocks, simply better. For PocketMine & forks.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
12 KiB

  1. <?php
  2. # ____ _ _ ____ _ _
  3. # | __ ) ___ | |_ | |_ ___ _ __ | __ ) | | ___ ___ | | __ ___
  4. # | _ \ / _ \ | __| | __| / _ \ | '__| | _ \ | | / _ \ / __| | |/ / / __|
  5. # | |_) | | __/ | |_ | |_ | __/ | | | |_) | | | | (_) | | (__ | < \__ \
  6. # |____/ \___| \__| \__| \___| |_| |____/ |_| \___/ \___| |_|\_\ |___/
  7. #
  8. # Extends your Minecraft PE blocks palette ! For PocketMine.
  9. namespace Ad5001\BetterBlocks;
  10. use pocketmine\event\Listener;
  11. use pocketmine\plugin\PluginBase;
  12. use pocketmine\Server;
  13. use pocketmine\Player;
  14. use pocketmine\tile\Tile;
  15. use pocketmine\item\Item;
  16. use pocketmine\inventory\ShapedRecipe;
  17. use pocketmine\math\Vector3;
  18. use pocketmine\block\Block;
  19. use pocketmine\event\block\BlockBreakEvent;
  20. use pocketmine\nbt\NBT;
  21. use pocketmine\nbt\tag\ListTag;
  22. use Ad5001\BetterBlocks\CustomBlockData\FallableTile;
  23. use Ad5001\BetterBlocks\CustomBlockData\GraveTile;
  24. use Ad5001\BetterBlocks\CustomBlockData\RedstonePoweringTile;
  25. use Ad5001\BetterBlocks\CustomBlockData\SoundHolderTile;
  26. use Ad5001\BetterBlocks\CustomBlockData\StickTile;
  27. use Ad5001\BetterBlocks\CustomBlockData\VacuumTile;
  28. use Ad5001\BetterBlocks\tasks\AttractTask;
  29. use Ad5001\BetterBlocks\tasks\BlockRegenerateTask;
  30. use Ad5001\BetterBlocks\tasks\Drop2CraftTask;
  31. class Main extends PluginBase implements Listener {
  32. static $instance;
  33. public function onEnable(){
  34. self::$instance = $this;
  35. // Registering recipes
  36. $ep = Item::get(368, 0);
  37. // Sticky Slime block
  38. $ssb = Item::get(165, 0);
  39. $ssb->setCustomName("§rSticky Slime Block");
  40. $ssb->setNamedTag(NBT::parseJSON('{"isStickable":"true"}'));
  41. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($ssb, 3, 3))->addIngredient(1, 1, $ep)->addIngredient(1, 2, Item::get(165, 0)));
  42. // Vacuum Hopper
  43. $vh = Item::get(410, 0);
  44. $vh->setNamedTag(NBT::parseJSON('{"isVacuum":"true"}'));
  45. $vh->setCustomName("§rVacuum Item Hopper");
  46. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($vh, 3, 3))->addIngredient(1, 0, $ep)->addIngredient(0, 0, Item::get(410, 0))->addIngredient(0, 1, Item::get(49, 0)));
  47. // Trappers (used to create trap blocks)
  48. $vh = Item::get(69, 0);
  49. $vh->setNamedTag(NBT::parseJSON('{"isTrapper":"true"}'));
  50. $vh->setCustomName("§rTrapper");
  51. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($vh, 3, 3))->addIngredient(1, 1, Item::get(70, 0))->addIngredient(0, 0, Item::get(331, 0)));
  52. // Hammes (for fallable blocks)
  53. // Wooden
  54. $wt = Item::get(271, 0);
  55. $wt->setNamedTag(NBT::parseJSON('{"isHammer":"true"}'));
  56. $wt->setCustomName("§rWooden Hammer");
  57. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($wt, 3, 3))->addIngredient(2, 0, Item::get(280, 0))->addIngredient(1, 1, Item::get(280, 0))->addIngredient(0, 1, Item::get(5, 0))->addIngredient(0, 2, Item::get(5, 0))->addIngredient(1, 2, Item::get(5, 0)));
  58. // Stone
  59. $wt = Item::get(275, 0);
  60. $wt->setNamedTag(NBT::parseJSON('{"isHammer":"true"}'));
  61. $wt->setCustomName("§rStone Hammer");
  62. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($wt, 3, 3))->addIngredient(2, 0, Item::get(280, 0))->addIngredient(1, 1, Item::get(280, 0))->addIngredient(0, 1, Item::get(4, 0))->addIngredient(0, 2, Item::get(4, 0))->addIngredient(1, 2, Item::get(4, 0)));
  63. // Iron
  64. $wt = Item::get(258, 0);
  65. $wt->setNamedTag(NBT::parseJSON('{"isHammer":"true"}'));
  66. $wt->setCustomName("§rIron Hammer");
  67. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($wt, 3, 3))->addIngredient(2, 0, Item::get(280, 0))->addIngredient(1, 1, Item::get(280, 0))->addIngredient(0, 1, Item::get(265, 0))->addIngredient(0, 2, Item::get(265, 0))->addIngredient(1, 2, Item::get(265, 0)));
  68. // Gold
  69. $wt = Item::get(286, 0);
  70. $wt->setNamedTag(NBT::parseJSON('{"isHammer":"true"}'));
  71. $wt->setCustomName("§rGold Hammer");
  72. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($wt, 3, 3))->addIngredient(2, 0, Item::get(280, 0))->addIngredient(1, 1, Item::get(280, 0))->addIngredient(0, 1, Item::get(266, 0))->addIngredient(0, 2, Item::get(266, 0))->addIngredient(1, 2, Item::get(266, 0)));
  73. // Diamond
  74. $wt = Item::get(279, 0);
  75. $wt->setNamedTag(NBT::parseJSON('{"isHammer":"true"}'));
  76. $wt->setCustomName("§rDiamond Hammer");
  77. $this->getServer()->getCraftingManager()->registerRecipe((new ShapedRecipe($wt, 3, 3))->addIngredient(2, 0, Item::get(280, 0))->addIngredient(1, 1, Item::get(280, 0))->addIngredient(0, 1, Item::get(264, 0))->addIngredient(0, 2, Item::get(264, 0))->addIngredient(1, 2, Item::get(264, 0)));
  78. // Registering tiles
  79. Tile::registerTile(FallableTile::class);
  80. Tile::registerTile(GraveTile::class);
  81. Tile::registerTile(RedstonePoweringTile::class);
  82. Tile::registerTile(SoundHolderTile::class);
  83. Tile::registerTile(StickTile::class);
  84. Tile::registerTile(VacuumTile::class);
  85. $this->getServer()->getPluginManager()->registerEvents($this, $this);
  86. $this->saveDefaultConfig();
  87. }
  88. /*
  89. When a custom block item is placed (Sticcky Slime Blocks, Vaccum hoppers and for Trap Blocks)
  90. @param $event \pocketmine\event\block\BlockPlaceEvent
  91. @retu
  92. */
  93. public function onBlockPlace(\pocketmine\event\block\BlockPlaceEvent $event) {
  94. if(isset($event->getItem()->getNamedTag()->isStickable) && $event->getItem()->getNamedTag()->isStickable->getValue() == "true") {
  95. Tile::createTile("StickTile", $event->getBlock()->getLevel()->getChunk($event->getBlock()->x >> 4, $event->getBlock()->z >> 4), NBT::parseJSON(json_encode([$event->getBlock()->x, $event->getBlock()->y, $event->getBlock()->z], JSON_FORCE_OBJECT)));
  96. } elseif(isset($event->getItem()->getNamedTag()->isVacuum) && $event->getItem()->getNamedTag()->isVacuum->getValue() == "true") {
  97. Tile::createTile("VacuumTile", $event->getBlock()->getLevel()->getChunk($event->getBlock()->x >> 4, $event->getBlock()->z >> 4), NBT::parseJSON(json_encode([$event->getBlock()->x, $event->getBlock()->y, $event->getBlock()->z], JSON_FORCE_OBJECT)));
  98. } elseif(isset($event->getItem()->getNamedTag()->isTrapper) && $event->getItem()->getNamedTag()->isTrapper->getValue() == "true") {
  99. Tile::createTile("TrapTile", $event->getBlock()->getLevel()->getChunk($event->getBlock()->x >> 4, $event->getBlock()->z >> 4), NBT::parseJSON(json_encode([$event->getBlock()->x, $event->getBlock()->y - 1, $event->getBlock()->z], JSON_FORCE_OBJECT)));
  100. $this->getServer()->getScheduler()->scheduleDelayedTask(new BlockRegenerateTask($this, Block::get(0, 0), $event->getBlock()->getLevel()), 30); // Clears the lever
  101. }
  102. }
  103. /*
  104. Checks when a block breaks to drop the item if custom block.
  105. @param $event BlockBreakEvent
  106. */
  107. public function onBlockBreak(BlockBreakEvent $event) {
  108. //1
  109. $block = $event->getBlock();
  110. if($event->getBlock()->getLevel()->getTile($block) instanceof CustomBlockData && !$event->isCancelled()) {
  111. switch(substr(get_class($event->getBlock()->getLevel()->getTile($block)), 36)) {
  112. case "GraveTile":
  113. $event->getBlock()->getLevel()->getTile($block)->drop();
  114. break;
  115. case "RedstonePoweringTile":
  116. $redstoneblock = Item::get(152, 0);
  117. $event->setDrops(array_merge([$redstoneblock], $event->getDrops()));
  118. break;
  119. case "SoundHolderTile":
  120. $noteblock = Item::get(25, 0);
  121. $event->setDrops(array_merge([$noteblock], $event->getDrops()));
  122. break;
  123. case "StickTile":
  124. $ssb = Item::get(165, 0);
  125. $ssb->setCustomName("§rSticky Slime Block");
  126. $ssb->setNamedTag(NBT::parseJSON('{"isStickable":"true"}'));
  127. $event->setDrops([$ssb]);
  128. break;
  129. case "TrapTile":
  130. break;
  131. case "VacuumTile":
  132. $vh = Item::get(410, 0);
  133. $vh->setNamedTag(NBT::parseJSON('{"isVacuum":"true"}'));
  134. $vh->setCustomName("§rVacuum Item Hopper");
  135. $event->setDrops([$vh]);
  136. break;
  137. }
  138. }
  139. }
  140. /*
  141. Check if a player touches a block. Check if he right clicks ill a hammer.
  142. @param $event \pocketmine\event\player\PlayerInteractEvent
  143. */
  144. public function onInteract(\pocketmine\event\player\PlayerInteractEvent $event) {
  145. if(isset($event->getItem()->getNamedTag()->isHammer) && $event->getItem()->getNamedTag()->isHammer == "true" && !($event->getBlock() instanceof \pocketmine\block\Fallable) && !($event->getBlock()->getLevel()->getTile($event->getBlock()) instanceof Tile)) {
  146. Tile::createTile("FallableTile", $event->getBlock()->getLevel()->getChunk($event->getBlock()->x >> 4, $event->getBlock()->z >> 4), NBT::parseJSON('{"x":"'.$event->getBlock()->x.'","y":"' .$event->getBlock()->y.'","z":"'. $event->getBlock()->z . '"}'));
  147. $event->getPlayer()->sendPopup("This block seems now unstable... You shouldn't walk on it...");
  148. }
  149. }
  150. /*
  151. Detects when a player drops an item to set it as "Droped by the player" to build some custom blocks.
  152. @param $event \pocketmine\event\player\PlayerDropItemEvent
  153. */
  154. public function onPlayerItemDrop(\pocketmine\event\player\PlayerDropItemEvent $event) {
  155. $event->getItem()->setNamedTag(NBT::parseJSON('{"isDropedByPlayer":"true"}'));
  156. }
  157. /*
  158. Checks when a player death to set up a grave.
  159. @param $event \pocketmine\event\player\PlayerDeathEvent
  160. */
  161. public function onPlayerDeath(\pocketmine\event\player\PlayerDeathEvent $event) {
  162. $player = $event->getPlayer();
  163. $cause = $player->getLastDamageCause();
  164. $nbt = NBT::parseJSON(json_encode([
  165. "x" => $player->x,
  166. "y" => $player->y,
  167. "z" => $player->z,
  168. "Player" => $player->getName(),
  169. "DeathCause" => $cause == null ? 14 : $cause->getCause(),
  170. "Params" => $event->getDeathMessage()->getParameters()
  171. ], JSON_FORCE_OBJECT));
  172. $nbt->Items = new ListTag("Items", []);
  173. $nbt->Items->setTagType(NBT::TAG_Compound);
  174. foreach($event->getDrops() as $index => $content) {
  175. $nbt->Items[$index] = $content->nbtSerialize();
  176. }
  177. $event->setDrops([]);
  178. Tile::createTile("GraveTile", $player->getLevel()->getChunk($player->x >> 4, $player->z >> 4), $nbt);
  179. }
  180. /*
  181. Checks when a player moves to 1) Trigger traps blocks, 2) Set person as sticky 3) Makes fallable block fall if a player walks on it.
  182. @param $event \pocketmine\event\player\PlayerMoveEvent
  183. */
  184. public function onPlayerMove(\pocketmine\event\player\PlayerMoveEvent $event) {
  185. $v3Under = $event->getPlayer()->round();
  186. $v3Under->y--;
  187. $v3Upper = $event->getPlayer()->round();
  188. $v3Upper->y += 2;
  189. $tileUnder = $event->getPlayer()->getLevel()->getTile($v3Under);
  190. $tileUpper = $event->getPlayer()->getLevel()->getTile($v3Upper);
  191. // 1)
  192. if($tileUnder instanceof TrapTile) {
  193. $block = clone $event->getPlayer()->getLevel()->getBlock($v3Under);
  194. $event->getPlayer()->getLevel()->setBlock($v3Under, Block::get(0, 0));
  195. $this->getServer()->getScheduler()->scheduleDelayedTask(new BlockRegenerateTask($this, $block, $event->getPlayer()->getLevel()), 30);
  196. }
  197. // 2)
  198. if($tileUnder instanceof StickTile || $tileUpper instanceof StickTile) {
  199. $event->getPlayer()->setMotion($event->getPlayer()->getMotion()->x, 0, $event->getPlayer()->getMotion()->z);
  200. }
  201. // 3)
  202. if($tileUnder instanceof FallableTile) {
  203. $tileUnder->fall();
  204. }
  205. }
  206. }