public function generateChunk($chunkX, $chunkZ) { if ($this->emptyChunk !== null) { //Use the cached empty chunk instead of generating a new one $this->chunk = clone $this->emptyChunk; } else { $this->chunk = clone $this->level->getChunk($chunkX, $chunkZ); $this->chunk->setGenerated(); $c = Biome::getBiome(1)->getColor(); $R = $c >> 16; $G = $c >> 8 & 0xff; $B = $c & 0xff; for ($Z = 0; $Z < 16; ++$Z) { for ($X = 0; $X < 16; ++$X) { $this->chunk->setBiomeId($X, $Z, 1); $this->chunk->setBiomeColor($X, $Z, $R, $G, $B); for ($y = 0; $y < 128; ++$y) { $this->chunk->setBlockId($X, $y, $Z, Block::AIR); } } } $spawn = $this->getSpawn(); if ($spawn->getX() >> 4 === $chunkX and $spawn->getZ() >> 4 === $chunkZ) { $this->chunk->setBlockId(0, 64, 0, Block::GRASS); } else { $this->emptyChunk = $this->chunk; } } $chunk = clone $this->chunk; $chunk->setX($chunkX); $chunk->setZ($chunkZ); $this->level->setChunk($chunkX, $chunkZ, $chunk); }
private function pop(ChunkManager $level, $x, $z, $chunkX, $chunkZ, Random $random) { $c = $level->getChunk($x, $z); $oC = $level->getChunk($chunkX, $chunkZ); if ($c == null or $oC == null or $c != null and !$c->isGenerated() or $oC != null and !$oC->isGenerated()) { return; } $chunk = new Vector3($x << 4, 0, $z << 4); $originChunk = new Vector3($chunkX << 4, 0, $chunkZ << 4); if ($random->nextBoundedInt(15) != 0) { return; } $numberOfCaves = $random->nextBoundedInt($random->nextBoundedInt($random->nextBoundedInt(40) + 1) + 1); for ($caveCount = 0; $caveCount < $numberOfCaves; $caveCount++) { $target = new Vector3($chunk->getX() + $random->nextBoundedInt(16), $random->nextBoundedInt($random->nextBoundedInt(120) + 8), $chunk->getZ() + $random->nextBoundedInt(16)); $numberOfSmallCaves = 1; if ($random->nextBoundedInt(4) == 0) { $this->generateLargeCaveBranch($level, $originChunk, $target, new Random($random->nextInt())); $numberOfSmallCaves += $random->nextBoundedInt(4); } for ($count = 0; $count < $numberOfSmallCaves; $count++) { $randomHorizontalAngle = $random->nextFloat() * pi() * 2; $randomVerticalAngle = ($random->nextFloat() - 0.5) * 2 / 8; $horizontalScale = $random->nextFloat() * 2 + $random->nextFloat(); if ($random->nextBoundedInt(10) == 0) { $horizontalScale *= $random->nextFloat() * $random->nextFloat() * 3 + 1; } $this->generateCaveBranch($level, $originChunk, $target, $horizontalScale, 1, $randomHorizontalAngle, $randomVerticalAngle, 0, 0, new Random($random->nextInt())); } } }
protected function parsePreset($preset, $chunkX, $chunkZ) { $this->preset = $preset; $preset = explode(";", $preset); $version = (int) $preset[0]; $blocks = isset($preset[1]) ? $preset[1] : ""; $biome = isset($preset[2]) ? $preset[2] : 1; $options = isset($preset[3]) ? $preset[3] : ""; preg_match_all('#^(([0-9]*x|)([0-9]{1,3})(|:[0-9]{0,2}))$#m', str_replace(",", "\n", $blocks), $matches); $y = 0; $this->structure = []; $this->chunks = []; foreach ($matches[3] as $i => $b) { $b = Item::fromString($b . $matches[4][$i]); $cnt = $matches[2][$i] === "" ? 1 : intval($matches[2][$i]); for ($cY = $y, $y += $cnt; $cY < $y; ++$cY) { $this->structure[$cY] = [$b->getId(), $b->getDamage()]; } } $this->floorLevel = $y; for (; $y < 0xff; ++$y) { $this->structure[$y] = [0, 0]; } $this->chunk = clone $this->level->getChunk($chunkX, $chunkZ); $this->chunk->setGenerated(); $c = Biome::getBiome($biome)->getColor(); $R = $c >> 16; $G = $c >> 8 & 0xff; $B = $c & 0xff; for ($Z = 0; $Z < 16; ++$Z) { for ($X = 0; $X < 16; ++$X) { $this->chunk->setBiomeId($X, $Z, $biome); $this->chunk->setBiomeColor($X, $Z, $R, $G, $B); for ($y = 0; $y < 128; ++$y) { $this->chunk->setBlock($X, $y, $Z, ...$this->structure[$y]); } } } preg_match_all('#(([0-9a-z_]{1,})\\(?([0-9a-z_ =:]{0,})\\)?),?#', $options, $matches); foreach ($matches[2] as $i => $option) { $params = true; if ($matches[3][$i] !== "") { $params = []; $p = explode(" ", $matches[3][$i]); foreach ($p as $k) { $k = explode("=", $k); if (isset($k[1])) { $params[$k[0]] = $k[1]; } } } $this->options[$option] = $params; } }
public function populate(ChunkManager $level, $chunkX, $chunkZ, Random $random) { $chunk = $level->getChunk($chunkX, $chunkZ); for ($x = 0; $x < 16; ++$x) { for ($z = 0; $z < 16; ++$z) { $biome = Biome::getBiome($chunk->getBiomeId($x, $z)); $cover = $biome->getGroundCover(); if (count($cover) > 0) { $diffY = 0; if (!$cover[0]->isSolid()) { $diffY = 1; } $column = $chunk->getBlockIdColumn($x, $z); for ($y = 127; $y > 0; --$y) { if ($column[$y] !== "" and !Block::get(ord($column[$y]))->isTransparent()) { break; } } $startY = min(127, $y + $diffY); $endY = $startY - count($cover); for ($y = $startY; $y > $endY and $y >= 0; --$y) { $b = $cover[$startY - $y]; if ($column[$y] === "" and $b->isSolid()) { break; } if ($b->getDamage() === 0) { $chunk->setBlockId($x, $y, $z, $b->getId()); } else { $chunk->setBlock($x, $y, $z, $b->getId(), $b->getDamage()); } } } } } }
public function populateChunk($chunkX, $chunkZ) { $this->random->setSeed(0xdeadbeef ^ $chunkX << 8 ^ $chunkZ ^ $this->level->getSeed()); foreach ($this->populators as $populator) { $populator->populate($this->level, $chunkX, $chunkZ, $this->random); } $chunk = $this->level->getChunk($chunkX, $chunkZ); $biome = Biome::getBiome($chunk->getBiomeId(7, 7)); $biome->populateChunk($this->level, $chunkX, $chunkZ, $this->random); }
public function generateChunk($chunkX, $chunkZ) { $spawn = $this->getSpawn(); // Adjust spawn so it is relative to current chunk... $spawn->x = $spawn->x - ($chunkX << 4); $spawn->z = $spawn->z - ($chunkZ << 4); $inSpawn = -$this->radius <= $spawn->x && $spawn->x < 16 + $this->radius && -$this->radius <= $spawn->z && $spawn->z < 16 + $this->radius; if ($inSpawn || $this->chunk === null) { $chunk = $this->level->getChunk($chunkX, $chunkZ); $chunk->setGenerated(); $c = Biome::getBiome($this->biome)->getColor(); $R = $c >> 16; $G = $c >> 8 & 0xff; $B = $c & 0xff; $rad2 = $this->radius * $this->radius; for ($Z = 0; $Z < 16; ++$Z) { for ($X = 0; $X < 16; ++$X) { $chunk->setBiomeId($X, $Z, $biome); $chunk->setBiomeColor($X, $Z, $R, $G, $B); $chunk->setBlock($X, 0, $Z, $this->baseFloor, 0); for ($y = 1; $y < 128; ++$y) { $chunk->setBlock($X, $y, $Z, Block::AIR, 0); } if (self::inSpawn($rad2, $spawn->x, $spawn->z, $X, $Z)) { $chunk->setBlock($X, $this->floorLevel, $Z, $this->block); } } } if (!$inSpawn) { $this->chunk = clone $chunk; } } else { $chunk = clone $this->chunk; } $chunk->setX($chunkX); $chunk->setZ($chunkZ); $this->level->setChunk($chunkX, $chunkZ, $chunk); }
public function generateChunk($chunkX, $chunkZ) { $this->chunk = clone $this->level->getChunk($chunkX, $chunkZ); $this->chunk->setGenerated(); $c = Biome::getBiome(1)->getColor(); $R = $c >> 16; $G = $c >> 8 & 0xff; $B = $c & 0xff; for ($Z = 0; $Z < 16; ++$Z) { for ($X = 0; $X < 16; ++$X) { $this->chunk->setBiomeId($X, $Z, 1); $this->chunk->setBiomeColor($X, $Z, $R, $G, $B); for ($y = 0; $y < 128; ++$y) { $this->chunk->setBlockId($X, $y, $Z, Block::AIR); } } } $this->chunk->setBlockId(8, 64, 8, Block::GRASS); $chunk = clone $this->chunk; $chunk->setX($chunkX); $chunk->setZ($chunkZ); $this->level->setChunk($chunkX, $chunkZ, $chunk); }
private function lavaSpread($x, $y, $z) { if ($this->level->getChunk($x >> 4, $z >> 4) == null) { return; } $decay = $this->getFlowDecay($x, $y, $z, $x, $y, $z); $multiplier = 2; if ($decay > 0) { $smallestFlowDecay = -100; $smallestFlowDecay = $this->getSmallestFlowDecay($x, $y, $z, $x, $y, $z - 1, $smallestFlowDecay); $smallestFlowDecay = $this->getSmallestFlowDecay($x, $y, $z, $x, $y, $z + 1, $smallestFlowDecay); $smallestFlowDecay = $this->getSmallestFlowDecay($x, $y, $z, $x - 1, $y, $z, $smallestFlowDecay); $smallestFlowDecay = $this->getSmallestFlowDecay($x, $y, $z, $x + 1, $y, $z, $smallestFlowDecay); $k = $smallestFlowDecay + $multiplier; if ($k >= 8 or $smallestFlowDecay < 0) { $k = -1; } if (($topFlowDecay = $this->getFlowDecay($x, $y, $z, $x, $y + 1, $z)) >= 0) { if ($topFlowDecay >= 8) { $k = $topFlowDecay; } else { $k = $topFlowDecay | 0x8; } } if ($decay < 8 and $k < 8 and $k > 1 and mt_rand(0, 4) !== 0) { $k = $decay; } if ($k !== $decay) { $decay = $k; if ($decay < 0) { $this->level->setBlockIdAt($x, $y, $z, 0); } else { $this->level->setBlockIdAt($x, $y, $z, Block::LAVA); $this->level->setBlockDataAt($x, $y, $z, $decay); $this->level->updateBlockLight($x, $y, $z); $this->lavaSpread($x, $y, $z); return; } } } if ($this->canFlowInto($x, $y - 1, $z)) { if ($decay >= 8) { $this->flowIntoBlock($x, $y - 1, $z, $decay); } else { $this->flowIntoBlock($x, $y - 1, $z, $decay | 0x8); } } elseif ($decay >= 0 and ($decay === 0 or !$this->canFlowInto($x, $y - 1, $z))) { $flags = $this->getOptimalFlowDirections($x, $y, $z); $l = $decay + $multiplier; if ($decay >= 8) { $l = 1; } if ($l >= 8) { return; } if ($flags[0]) { $this->flowIntoBlock($x - 1, $y, $z, $l); } if ($flags[1]) { $this->flowIntoBlock($x + 1, $y, $z, $l); } if ($flags[2]) { $this->flowIntoBlock($x, $y, $z - 1, $l); } if ($flags[3]) { $this->flowIntoBlock($x, $y, $z + 1, $l); } } }