PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/src/pocketmine/command/defaults/CaveCommand.php

https://gitlab.com/kennethgomad01/genisys
PHP | 335 lines | 261 code | 26 blank | 48 comment | 54 complexity | d48765882d1e71d84f7414d9453f39f9 MD5 | raw file
  1. <?php
  2. /**
  3. * Author: boybook
  4. * OpenGenisys Project
  5. */
  6. namespace pocketmine\command\defaults;
  7. use pocketmine\block\Air;
  8. use pocketmine\block\Block;
  9. use pocketmine\block\Lava;
  10. use pocketmine\block\Water;
  11. use pocketmine\command\CommandSender;
  12. use pocketmine\event\TranslationContainer;
  13. use pocketmine\item\Item;
  14. use pocketmine\level\Level;
  15. use pocketmine\level\Position;
  16. use pocketmine\math\Vector3;
  17. use pocketmine\Player;
  18. use pocketmine\utils\TextFormat;
  19. class CaveCommand extends VanillaCommand{
  20. public function __construct($name){
  21. parent::__construct(
  22. $name,
  23. "Generate a cave",
  24. "%commands.cave.usage"
  25. );
  26. $this->setPermission("pocketmine.command.cave");
  27. }
  28. public function execute(CommandSender $sender, $commandLabel, array $args){
  29. if(!$this->testPermission($sender)){
  30. return true;
  31. }
  32. if($sender instanceof Player and $args[0] == "getmypos"){
  33. $sender->sendMessage("You position ({$sender->getX()}, {$sender->getY()}, {$sender->getZ()}, {$sender->getLevel()->getFolderName()})");
  34. return true;
  35. }
  36. //0:旋转角度 1:洞穴长度 2:分叉数 3:洞穴强度
  37. if(count($args) != 8){
  38. $sender->sendMessage(new TranslationContainer("commands.generic.usage", [$this->usageMessage]));
  39. return false;
  40. }
  41. $level = $sender->getServer()->getLevelByName($args[7]);
  42. if(!$level instanceof Level){
  43. $sender->sendMessage(TextFormat::RED ."Wrong LevelName");
  44. return false;
  45. }
  46. $pos = new Position($args[4], $args[5], $args[6], $level);
  47. $caves[0] = isset($args[0]) ? $args[0] : mt_rand(1, 360);
  48. $caves[1] = isset($args[1]) ? $args[1] : mt_rand(10, 300);
  49. $caves[2] = isset($args[2]) ? $args[2] : mt_rand(1, 6);
  50. $caves[4] = isset($args[3]) ? $args[3] : mt_rand(1, 10);
  51. $caves[3] = [false, true, true];
  52. $sender->sendMessage(new TranslationContainer("commands.cave.info", [$caves[0], $caves[1], $caves[2], $caves[3]]));
  53. $sender->sendMessage("[Caves] " . TextFormat::YELLOW . "%commands.cave.start");
  54. $sender->sendMessage($pos->x . " " . $pos->y . " " . $pos->z);
  55. $this->caves($pos, $caves);
  56. $sender->sendMessage("[Caves] " . TextFormat::GREEN . "%commands.cave.success");
  57. return true;
  58. }
  59. public function chu($v1, $v2){
  60. if($v2 == 0) return 0;
  61. return $v1 / $v2;
  62. }
  63. public function getDirectionVector($yaw, $pitch){
  64. $y = -\sin(\deg2rad($pitch));
  65. $xz = \cos(\deg2rad($pitch));
  66. $x = -$xz * \sin(\deg2rad($yaw));
  67. $z = $xz * \cos(\deg2rad($yaw));
  68. $temporalVector = new Vector3($x, $y, $z);
  69. return $temporalVector->normalize();
  70. }
  71. public function caves(Position $pos, $cave, $tt = false){
  72. $x = $pos->x;
  73. $y = $pos->y;
  74. $z = $pos->z;
  75. $level = $pos->getLevel();
  76. $ls = $cave[1]; //长度
  77. $cv = $cave[2]; //分叉数
  78. $lofs = $ls / $cave[2];
  79. $ls2 = $lofs;
  80. $yaw = $cave[0];
  81. if($cave[0] >= 0 || $cave[0] < 0){
  82. }else{
  83. $yaw = mt_rand(0, 100) * 72;
  84. }
  85. $pitch = -45;
  86. //$pi = M_PI / 180;
  87. $s1 = [$x, $y, $z];
  88. $s2 = [$x, $y, $z];
  89. //$i = -10 + mt_rand(0, 100) * 0.2;
  90. //$i = mt_rand(8, 25) / 10;
  91. $i = 1;
  92. for($u = 0; $u <= $ls; $u += $i){
  93. if($pitch > 12) $pitch = -45;
  94. $pitch += 5 + mt_rand(0, 5);
  95. $pos->getLevel()->getServer()->getLogger()->debug("[Caves] ".TextFormat::YELLOW . "yaw: $yaw pitch: $pitch");
  96. if($tt) $pitch = mt_rand(0, 100) * 0.05;
  97. //$s2[0] = $s1[0] -\sin($yaw / 180 * M_PI) * \cos($pitch / 180 * M_PI) * $i;
  98. //$s2[1] = $s1[1] +\sin($pitch / 180 * M_PI) * $i;
  99. //$s2[2] = $s1[2] + \cos($yaw / 180 * M_PI) * \cos($pitch / 180 * M_PI) * $i;
  100. #echo "s1: ";
  101. //var_dump($s1);
  102. $see = $this->getDirectionVector($yaw, $pitch);
  103. $s2[0] = $s1[0] + $see->x * $i;
  104. $s2[1] = $s1[1] - $see->y * $i;
  105. $s2[2] = $s1[2] + $see->z * $i;
  106. //echo "s2: ";
  107. //var_dump($s2);
  108. if($s2[1] < 10){
  109. $s2[1] = 10 + mt_rand(0, 10);
  110. }
  111. if($u > $lofs){
  112. $cv--;
  113. if($cave[3][1] === false) $cv = 0;
  114. $lofs += $ls2;
  115. $newPos = new Position($s2[0], $s2[1], $s2[2], $level);
  116. $this->caves($newPos, [$yaw + 90 * (round(mt_rand(0, 100) / 100) * 2 - 1), $ls - $u, $cv, [false, $cave[3][1], $cave[3][2]], 0], $tt);
  117. }
  118. //$exPos = new Position($s2[0], $s2[1], $s2[2], $level);
  119. //$this->explodeBlocks($exPos, mt_rand(2, 4), mt_rand(1, 4));
  120. if(mt_rand(0, 100) > 80){
  121. $add = mt_rand(-10, 10);
  122. }else{
  123. $add = mt_rand(-45, 45);
  124. }
  125. $yaw = $yaw + $add;
  126. $yaw = $yaw % 360;
  127. $yaw = $yaw >= 0 ? $yaw : 360 + $yaw;
  128. //$i = 5 + mt_rand(0, 100) * 0.05;
  129. $x = $s1[0];
  130. $y = $s1[1];
  131. $z = $s1[2];
  132. $x2 = $s2[0];
  133. $y2 = $s2[1];
  134. $z2 = $s2[2];
  135. $l = max(abs($x - $x2), abs($y - $y2), abs($z - $z2));
  136. for($m = 0; $m <= $l; $m++){
  137. //$v = $level->getBlock(new Vector3(round($this->chu($x + $m, $l * ($x2 - $x))), round($y + $this->chu($m, $l * ($y2 - $y))), round($z + $this->chu($m, $l * ($z2 - $z)))))->getId();
  138. //if ($v != 0 and $v != 95)
  139. $liu = mt_rand(0, 200) == 100;
  140. $this->fdx(round($x + $this->chu($m, $l * ($x2 - $x))), round($y + $this->chu($m, $l * ($y2 - $y))), round($z + $this->chu($m, $l * ($z2 - $z))), $level, $liu);
  141. }
  142. $s1 = [$s2[0], $s2[1], $s2[2]];
  143. }
  144. if(mt_rand(0, 10) >= 5 and $s2[1] <= 40){
  145. $this->lavaSpawn($level, $s2[0], $s2[1], $s2[2]);
  146. }
  147. /*
  148. if ($cave[3][0]) {
  149. $l = $cave[4];
  150. $x = $s2[0];
  151. $y = $s2[1];
  152. $z = $s2[2];
  153. for ($i = -$l; $i <= $l; $i += 2) {
  154. for ($j = -$l; $j <= $l; $j += 2) {
  155. if ($i * $i + $j * $j <= pow($l - 0.3 * $l * mt_rand(0, 1000) / 1000, 2)) {
  156. if ($level->getBlock(new Vector3($x + $i, $y - 1, $z + $j))->getId() != 0) {
  157. $this->fdx($x + $i, $y - 1 + 2 * mt_rand(0, 1000) / 1000, $z + $j, $level);
  158. }
  159. }
  160. if ($i * $i + $j * $j <= pow($l - 0.5 * $l * mt_rand(0, 1000) / 1000, 2)) {
  161. if ($level->getBlock(new Vector3($x + $i, $y + 3, $z + $j))->getId() != 0) {
  162. $this->fdx($x + $i, $y + 3 + 2 * mt_rand(0, 1000) / 1000, $z + $j, $level);
  163. }
  164. }
  165. }
  166. }
  167. //if ($level->getBlock(new Vector3($s2[0], $s2[1] - 4, $s2[2]))->getId() != 0 && $cave[3][2] && mt_rand(0, 100) / 100 > 0.5) $this->tiankengy($level, $s2[0], $s2[1], $s2[2], $l * 0.6, 11, 0);
  168. } else if ($cave[3][2]) {
  169. $l = $cave[4];
  170. if ($pitch < -10 && $pitch > -45 && $level->getBlock(new Vector3($s2[0], $s2[1] - 3, $s2[2]))->getId() != 0) $this->tiankengy($level, $s2[0], $s2[1], $s2[2], $l / 2, 11, 0);
  171. }*/
  172. //echo "\n 矿洞生成完成\n";
  173. }
  174. public function lavaSpawn(Level $level, $x, $y, $z){
  175. $level->getServer()->getLogger()->info("生成岩浆中 " . "floor($x)" . ", " . "floor($y)" . ", " . floor($z));
  176. for($xx = $x - 20; $xx <= $x + 20; $xx++){
  177. for($zz = $z - 20; $zz <= $z + 20; $zz++){
  178. for($yy = $y; $yy > $y - 4; $yy--){
  179. $id = $level->getBlockIdAt($xx, $yy, $zz);
  180. if($id == 0){
  181. $level->setBlockIdAt($xx, $yy, $zz, 10);
  182. $level->setBlockDataAt($xx, $yy, $zz, 0);
  183. }
  184. }
  185. }
  186. }
  187. $level->setBlock(new Vector3($x, $y, $z), new Lava());
  188. }
  189. public function explodeBlocks(Position $source, $rays = 16, $size = 4){
  190. $vector = new Vector3(0, 0, 0);
  191. $vBlock = new Vector3(0, 0, 0);
  192. $stepLen = 0.3;
  193. $mRays = \intval($rays - 1);
  194. $affectedBlocks = array();
  195. for($i = 0; $i < $rays; ++$i){
  196. for($j = 0; $j < $rays; ++$j){
  197. for($k = 0; $k < $rays; ++$k){
  198. if($i === 0 or $i === $mRays or $j === 0 or $j === $mRays or $k === 0 or $k === $mRays){
  199. $vector->setComponents($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1);
  200. $vector->setComponents(($vector->x / ($len = $vector->length())) * $stepLen, ($vector->y / $len) * $stepLen, ($vector->z / $len) * $stepLen);
  201. $pointerX = $source->x;
  202. $pointerY = $source->y;
  203. $pointerZ = $source->z;
  204. for($blastForce = $size * (\mt_rand(700, 1300) / 1000); $blastForce > 0; $blastForce -= $stepLen * 0.75){
  205. $x = (int) $pointerX;
  206. $y = (int) $pointerY;
  207. $z = (int) $pointerZ;
  208. $vBlock->x = $pointerX >= $x ? $x : $x - 1;
  209. $vBlock->y = $pointerY >= $y ? $y : $y - 1;
  210. $vBlock->z = $pointerZ >= $z ? $z : $z - 1;
  211. if($vBlock->y < 0 or $vBlock->y > 127){
  212. break;
  213. }
  214. $block = $source->getLevel()->getBlock($vBlock);
  215. if($block->getId() !== 0){
  216. $blastForce -= (mt_rand(1, 3) / 5 + 0.3) * $stepLen;
  217. if($blastForce > 0){
  218. if(!isset($affectedBlocks[$index = (\PHP_INT_SIZE === 8 ? ((($block->x) & 0xFFFFFFF) << 35) | ((($block->y) & 0x7f) << 28) | (($block->z) & 0xFFFFFFF) : ($block->x) . ":" . ($block->y) . ":" . ($block->z))])){
  219. $affectedBlocks[$index] = $block;
  220. }
  221. }
  222. }
  223. $pointerX += $vector->x;
  224. $pointerY += $vector->y;
  225. $pointerZ += $vector->z;
  226. }
  227. }
  228. }
  229. }
  230. }
  231. foreach($affectedBlocks as $block){
  232. if($block instanceof Block){
  233. $block->getLevel()->setBlock($block, new Air(), false, false);
  234. }
  235. }
  236. }
  237. public function fdx($x, $y, $z, Level $level, $liu = false){
  238. //$this->getLogger()->info(TextFormat::GREEN."fdx!");
  239. for($i = 1; $i < mt_rand(2, 4); $i++){
  240. $level->setBlockIdAt($x + $i - 2, $y - 1, $z + 1, 0);
  241. $level->setBlockIdAt($x + $i - 2, $y - 1, $z, 0);
  242. $level->setBlockIdAt($x + $i - 2, $y - 1, $z - 1, 0);
  243. $level->setBlockIdAt($x + $i - 2, $y - 1, $z - 1, 0);
  244. $level->setBlockIdAt($x + $i - 2, $y - 1, $z + 1, 0);
  245. $level->setBlockIdAt($x + $i - 2, $y + 2, $z + 1, 0);
  246. $level->setBlockIdAt($x + $i - 2, $y + 2, $z, 0);
  247. $level->setBlockIdAt($x + $i - 2, $y + 2, $z - 1, 0);
  248. }
  249. for($i = 1; $i < mt_rand(3, 6); $i++){
  250. $level->setBlockIdAt($x + $i - 3, $y + 1, $z + 2, 0);
  251. $level->setBlockIdAt($x + $i - 3, $y + 1, $z + 1, 0);
  252. $level->setBlockIdAt($x + $i - 3, $y + 1, $z, 0);
  253. $level->setBlockIdAt($x + $i - 3, $y + 1, $z - 1, 0);
  254. $level->setBlockIdAt($x + $i - 3, $y + 1, $z - 2, 0);
  255. $level->setBlockIdAt($x + $i - 3, $y, $z + 2, 0);
  256. $level->setBlockIdAt($x + $i - 3, $y, $z + 1, 0);
  257. $level->setBlockIdAt($x + $i - 3, $y, $z, 0);
  258. $level->setBlockIdAt($x + $i - 3, $y, $z - 1, 0);
  259. $level->setBlockIdAt($x + $i - 3, $y, $z - 2, 0);
  260. }
  261. if($liu){
  262. $l = (mt_rand(0, 1) == 0) ? new Water() : new Lava();
  263. $i = mt_rand(3, 6);
  264. $level->setBlock(new Vector3($x + $i - 3, $y + 1, $z + 3), $l);
  265. }
  266. }
  267. public function ranz($a){
  268. $n = [];
  269. $j = 0;
  270. for($m = 0; $m < $a; $m++){
  271. $n[] = mt_rand(0, 999) / 1000 - 1;
  272. }
  273. for($m = 0; $m < $a; $m++){
  274. foreach($n as $q){
  275. $min = min($n);
  276. if($n[$q] == $min){
  277. $n[$q] = $j;
  278. $j++;
  279. break;
  280. }
  281. }
  282. }
  283. return $n;
  284. }
  285. public function tiankengy(Level $level, $x, $y, $z, $l, $id, $bd){
  286. if($level->getBlock(new Vector3($x, $y, $z))->getId() == 0) $level->setBlock(new Vector3($x, $y, $z), Item::get($id, $bd)->getBlock());
  287. if($l >= 0){
  288. $random = mt_rand(0, 99999) / 100000;
  289. $mz = $this->ranz(4);
  290. foreach($mz as $sss){
  291. switch($mz[$sss]){
  292. case 0:
  293. if($level->getBlock(new Vector3($x, $y, $z - 1))->getId() == 0) $this->tiankengy($level, $x, $y, $z - 1, $l - $random, $id, $bd);
  294. break;
  295. case 1:
  296. if($level->getBlock(new Vector3($x, $y, $z + 1))->getId() == 0) $this->tiankengy($level, $x, $y, $z + 1, $l - $random, $id, $bd);
  297. break;
  298. case 2:
  299. if($level->getBlock(new Vector3($x + 1, $y, $z))->getId() == 0) $this->tiankengy($level, $x + 1, $y, $z, $l - $random, $id, $bd);
  300. break;
  301. case 3:
  302. if($level->getBlock(new Vector3($x - 1, $y, $z))->getId() == 0) $this->tiankengy($level, $x - 1, $y, $z, $l - $random, $id, $bd);
  303. break;
  304. }
  305. }
  306. }
  307. }
  308. }