TypePHP 编译器 https://swoole.com/aot/
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.
 
 

154 lines
4.2 KiB

<?php
declare(strict_types=1);
const DEMO_BLOCK_GRASS = 1;
const DEMO_BLOCK_SAND = 2;
const DEMO_BLOCK_STONE = 3;
const DEMO_BLOCK_WOOD = 5;
const DEMO_BLOCK_DIRT = 7;
const DEMO_BLOCK_SNOW = 9;
const DEMO_BLOCK_COBBLE = 11;
const DEMO_BLOCK_LEAF = 15;
const DEMO_BLOCK_WATER = 64;
const DEMO_WATER_LEVEL = 4;
const DEMO_MAX_Y = 22;
function demo_world_height_at(int $x, int $z): int
{
$large = demo_noise2($x, $z, 0.045) * 3.2;
$medium = demo_noise2($x + 917, $z - 431, 0.13) * 1.6;
$small = demo_noise2(-$x, $z + 331, 0.31) * 0.8;
$height = 6 + (int) round($large + $medium + $small);
if ($height < 1) {
$height = 1;
} elseif ($height > 12) {
$height = 12;
}
if (demo_world_is_river($x, $z)) {
$height -= 2;
if ($height < 1) {
$height = 1;
} elseif ($height > DEMO_WATER_LEVEL - 1) {
$height = DEMO_WATER_LEVEL - 1;
}
}
return $height;
}
function demo_noise2(int $x, int $z, float $scale): float
{
$a = sin($x * $scale + $z * $scale * 0.71);
$b = cos($x * $scale * 1.37 - $z * $scale * 0.83);
$c = sin(($x + $z) * $scale * 0.53 + cos($z * $scale));
return ($a + $b + $c) / 3.0;
}
function demo_hash2(int $x, int $z): float
{
$n = sin($x * 127.1 + $z * 311.7) * 43758.5453123;
return $n - floor($n);
}
function demo_world_is_river(int $x, int $z): bool
{
$spawnLake = (($x - 7) * ($x - 7) + ($z - 7) * ($z - 7)) <= 28;
if ($spawnLake) {
return true;
}
$center = sin($z * 0.22) * 5.0 + sin($z * 0.07) * 2.0;
$width = 3.4 + cos($z * 0.13) * 1.0;
return abs($x - $center) <= $width;
}
function demo_world_has_tree(int $x, int $z): bool
{
if (demo_world_is_river($x, $z)) {
return false;
}
if (($x % 6) !== 0 || ($z % 6) !== 0) {
return false;
}
return demo_hash2($x, $z) > 0.58;
}
function demo_world_block_type_at(int $x, int $y, int $z): int
{
if ($y < 0 || $y > DEMO_MAX_Y) {
return -1;
}
$height = demo_world_height_at($x, $z);
$river = demo_world_is_river($x, $z);
if ($river && $y === DEMO_WATER_LEVEL) {
return DEMO_BLOCK_WATER;
}
if ($y <= $height) {
if ($y === $height) {
if ($river || $height <= DEMO_WATER_LEVEL) {
return DEMO_BLOCK_SAND;
}
if ($height >= 10) {
return DEMO_BLOCK_SNOW;
}
if (demo_world_is_steep($x, $z, $height)) {
return DEMO_BLOCK_STONE;
}
return DEMO_BLOCK_GRASS;
}
if ($height >= 9 && $y >= $height - 2) {
return DEMO_BLOCK_STONE;
}
return $y >= $height - 2 ? DEMO_BLOCK_DIRT : DEMO_BLOCK_STONE;
}
for ($tx = $x - 3; $tx <= $x + 3; $tx++) {
for ($tz = $z - 3; $tz <= $z + 3; $tz++) {
if (!demo_world_has_tree($tx, $tz)) {
continue;
}
$base = demo_world_height_at($tx, $tz) + 1;
if ($x === $tx && $z === $tz && $y >= $base && $y <= $base + 5) {
return DEMO_BLOCK_WOOD;
}
$dx = $x - $tx;
$dz = $z - $tz;
$dy = $y - ($base + 4);
if ($y >= $base + 2 && $y <= $base + 6 && ($dx * $dx + $dz * $dz + $dy * $dy) <= 10) {
return DEMO_BLOCK_LEAF;
}
}
}
return -1;
}
function demo_world_is_steep(int $x, int $z, int $height): bool
{
$neighbors = [
demo_world_height_at($x + 1, $z),
demo_world_height_at($x - 1, $z),
demo_world_height_at($x, $z + 1),
demo_world_height_at($x, $z - 1),
];
return $height - min($neighbors) >= 2;
}
/**
* @return list<array{x:int,y:int,z:int,type:int}>
*/
function demo_world_generate(int $radius = 18): array
{
$blocks = [];
for ($x = -$radius; $x <= $radius; $x++) {
for ($z = -$radius; $z <= $radius; $z++) {
for ($y = 0; $y <= DEMO_MAX_Y; $y++) {
$type = demo_world_block_type_at($x, $y, $z);
if ($type >= 0) {
$blocks[] = ['x' => $x, 'y' => $y, 'z' => $z, 'type' => $type];
}
}
}
}
return $blocks;
}