mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 16:51:42 +00:00
Ore Generation
This commit is contained in:
parent
808f5473d0
commit
579175b3bc
@ -30,9 +30,9 @@ interface LevelGenerator{
|
||||
|
||||
public function init(Level $level, Random $random);
|
||||
|
||||
public function generateChunk($chunkX, $chunkY, $chunkZ);
|
||||
public function generateChunk($chunkX, $chunkZ);
|
||||
|
||||
public function populateChunk($chunkX, $chunkY, $chunkZ);
|
||||
public function populateChunk($chunkX, $chunkZ);
|
||||
|
||||
public function populateLevel();
|
||||
|
||||
|
30
src/world/generator/Populator.php
Normal file
30
src/world/generator/Populator.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
abstract class Populator{
|
||||
public abstract function populate(Level $level, $chunkX, $chunkZ, Random $random);
|
||||
}
|
@ -30,7 +30,7 @@ require_once("LevelGenerator.php");
|
||||
/***REM_END***/
|
||||
|
||||
class SuperflatGenerator implements LevelGenerator{
|
||||
private $level, $random, $structure, $chunks, $options, $floorLevel;
|
||||
private $level, $random, $structure, $chunks, $options, $floorLevel, $populators = array();
|
||||
|
||||
public function __construct(array $options = array()){
|
||||
$this->preset = "2;7,59x1,3x3,2;1;spawn(radius=10 block=89),decoration(treecount=80 grasscount=120)";
|
||||
@ -40,6 +40,24 @@ class SuperflatGenerator implements LevelGenerator{
|
||||
}else{
|
||||
$this->parsePreset($this->preset);
|
||||
}
|
||||
if(isset($this->options["decoration"])){
|
||||
$ores = new OrePopulator();
|
||||
$ores->setOreTypes(array(
|
||||
new OreType(new DirtBlock(), 20, 32, 0, 128),
|
||||
new OreType(new GravelBlock(), 10, 16, 0, 128),
|
||||
new OreType(new CoalOreBlock(), 20, 16, 0, 128),
|
||||
new OreType(New IronOreBlock(), 20, 8, 0, 64),
|
||||
new OreType(new RedstoneOreBlock(), 8, 7, 0, 16),
|
||||
new OreType(new LapisOreBlock(), 1, 6, 0, 32),
|
||||
new OreType(new GoldOreBlock(), 2, 8, 0, 32),
|
||||
new OreType(new DiamondOreBlock(), 1, 7, 0, 16),
|
||||
));
|
||||
$this->populators[] = $ores;
|
||||
}
|
||||
|
||||
/*if(isset($this->options["mineshaft"])){
|
||||
$this->populators[] = new MineshaftPopulator(isset($this->options["mineshaft"]["chance"]) ? floatval($this->options["mineshaft"]["chance"]) : 0.01);
|
||||
}*/
|
||||
}
|
||||
|
||||
public function parsePreset($preset){
|
||||
@ -107,48 +125,16 @@ class SuperflatGenerator implements LevelGenerator{
|
||||
$this->random = $random;
|
||||
}
|
||||
|
||||
public function generateChunk($chunkX, $chunkY, $chunkZ){
|
||||
$this->level->setMiniChunk($chunkX, $chunkZ, $chunkY, $this->chunks[$chunkY]);
|
||||
public function generateChunk($chunkX, $chunkZ){
|
||||
for($Y = 0; $Y < 8; ++$Y){
|
||||
$this->level->setMiniChunk($chunkX, $chunkZ, $Y, $this->chunks[$Y]);
|
||||
}
|
||||
}
|
||||
|
||||
public function populateChunk($chunkX, $chunkY, $chunkZ){
|
||||
$this->random->setSeed((int) ($chunkX * 0xdead + $chunkZ * 0xbeef));
|
||||
if(isset($this->options["decoration"])){
|
||||
//Ore spawning algorithm
|
||||
$ores = array(
|
||||
array(new CoalOreBlock(), 1, 70, 143),
|
||||
array(new IronOreBlock(), 1, 64, 77),
|
||||
array(new LapisOreBlock(), 1, 31, 3),
|
||||
array(new GoldOreBlock(), 1, 32, 8),
|
||||
array(new DiamondOreBlock(), 1, 14, 3),
|
||||
array(new RedstoneOreBlock(), 1, 14, 25),
|
||||
);
|
||||
$minX = $chunkX << 4;
|
||||
$maxX = $minX + 16;
|
||||
$minZ = $chunkZ << 4;
|
||||
$maxZ = $minZ + 16;
|
||||
$y = $chunkY << 4;
|
||||
|
||||
foreach($ores as $data){
|
||||
$minY = max($y, $data[1]);
|
||||
$maxY = min($y + 16, min($this->floorLevel - 1, $data[2]));
|
||||
if($minY > ($y + 16) or $maxY < $y){
|
||||
continue;
|
||||
}
|
||||
$nRange = $data[2] - $data[1] + 1;
|
||||
$factor = ($maxY - $minY + 1) / $nRange;
|
||||
$count = (int) ($this->random->nextRange($data[3] - 1, $data[3] + 1) * $factor);
|
||||
for($c = 0; $c < $count; ++$c){
|
||||
$block = $this->level->getBlock(new Vector3(
|
||||
$this->random->nextRange($minX, $maxX),
|
||||
$this->random->nextRange($minY, $maxY),
|
||||
$this->random->nextRange($minZ, $maxZ)
|
||||
));
|
||||
if($block->getID() === STONE){
|
||||
$this->level->setBlockRaw($block, $data[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
public function populateChunk($chunkX, $chunkZ){
|
||||
foreach($this->populators as $populator){
|
||||
$this->random->setSeed((int) ($chunkX * 0xdead + $chunkZ * 0xbeef));
|
||||
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,11 +52,11 @@ class TemporalGenerator implements LevelGenerator{
|
||||
$this->level->setSeed(TemporalGenerator::$levels[$this->index][0]);
|
||||
}
|
||||
|
||||
public function generateChunk($chunkX, $chunkY, $chunkZ){
|
||||
public function generateChunk($chunkX, $chunkZ){
|
||||
|
||||
}
|
||||
|
||||
public function populateChunk($chunkX, $chunkY, $chunkZ){
|
||||
public function populateChunk($chunkX, $chunkZ){
|
||||
|
||||
}
|
||||
|
||||
|
@ -55,15 +55,19 @@ class WorldGenerator{
|
||||
$this->generator->init($this->level, $this->random);
|
||||
for($Z = 0; $Z < $this->width; ++$Z){
|
||||
for($X = 0; $X < $this->width; ++$X){
|
||||
for($Y = 0; $Y < $this->height; ++$Y){
|
||||
$this->generator->generateChunk($X, $Y, $Z);
|
||||
$this->generator->populateChunk($X, $Y, $Z);
|
||||
}
|
||||
$this->generator->generateChunk($X, $Z);
|
||||
}
|
||||
console("[NOTICE] Generating level ".ceil((($Z + 1)/$this->width) * 100)."%");
|
||||
}
|
||||
console("[NOTICE] Populating level");
|
||||
$this->generator->populateLevel();
|
||||
for($Z = 0; $Z < $this->width; ++$Z){
|
||||
for($X = 0; $X < $this->width; ++$X){
|
||||
$this->generator->populateChunk($X, $Z);
|
||||
}
|
||||
console("[NOTICE] Populating level ".ceil((($Z + 1)/$this->width) * 100)."%");
|
||||
}
|
||||
|
||||
$this->level->setSpawn($this->generator->getSpawn());
|
||||
$this->level->save(true, true);
|
||||
}
|
||||
|
88
src/world/generator/object/OreObject.php
Normal file
88
src/world/generator/object/OreObject.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class OreObject{
|
||||
private $random;
|
||||
public $type;
|
||||
|
||||
public function __construct(Random $random, OreType $type){
|
||||
$this->type = $type;
|
||||
$this->random = $random;
|
||||
}
|
||||
|
||||
public function getType(){
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function canPlaceObject(Level $level, Vector3 $pos){
|
||||
return ($level->getBlock($pos)->getID() !== AIR);
|
||||
}
|
||||
|
||||
public function placeObject(Level $level, Vector3 $pos){
|
||||
$clusterSize = (int) $this->type->clusterSize;
|
||||
$angle = $this->random->nextFloat() * pi();
|
||||
$offset = VectorMath::getDirection2D($angle)->multiply($clusterSize)->divide(8);
|
||||
$x1 = $pos->x + 8 + $offset->x;
|
||||
$x2 = $pos->x + 8 - $offset->x;
|
||||
$z1 = $pos->z + 8 + $offset->y;
|
||||
$z2 = $pos->z + 8 - $offset->y;
|
||||
$y1 = $pos->y + $this->random->nextRange(0, 3) + 2;
|
||||
$y2 = $pos->y + $this->random->nextRange(0, 3) + 2;
|
||||
for($count = 0; $count <= $clusterSize; ++$count){
|
||||
$seedX = $x1 + ($x2 - $x1) * $count / $clusterSize;
|
||||
$seedY = $y1 + ($y2 - $y1) * $count / $clusterSize;
|
||||
$seedZ = $z1 + ($z2 - $z1) * $count / $clusterSize;
|
||||
$size = ((sin($count * (pi() / $clusterSize)) + 1) * $this->random->nextFloat() * $clusterSize / 16 + 1) / 2;
|
||||
|
||||
$startX = (int) ($seedX - $size);
|
||||
$startY = (int) ($seedY - $size);
|
||||
$startZ = (int) ($seedZ - $size);
|
||||
$endX = (int) ($seedX + $size);
|
||||
$endY = (int) ($seedY + $size);
|
||||
$endZ = (int) ($seedZ + $size);
|
||||
|
||||
for($x = $startX; $x <= $endX; ++$x){
|
||||
$sizeX = pow(($x + 0.5 - $seedX) / $size, 2);
|
||||
if($sizeX < 1){
|
||||
for($y = $startY; $y <= $endY; ++$y){
|
||||
$sizeY = pow(($y + 0.5 - $seedY) / $size, 2);
|
||||
if($y > 0 and ($sizeX + $sizeY) < 1){
|
||||
for($z = $startZ; $z <= $endZ; ++$z){
|
||||
$sizeZ = pow(($z + 0.5 - $seedZ) / $size, 2);
|
||||
$v = new Vector3($x, $y, $z);
|
||||
if(($sizeX + $sizeY + $sizeZ) < 1 and $level->getBlock($v)->getID() === STONE){
|
||||
$level->setBlockRaw($v, $this->type->material);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
38
src/world/generator/object/OreType.php
Normal file
38
src/world/generator/object/OreType.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class OreType{
|
||||
public $material, $clusterCount, $clusterSize, $maxHeight, $minHeight;
|
||||
|
||||
public function __construct(Block $material, $clusterCount, $clusterSize, $minHeight, $maxHeight){
|
||||
$this->material = $material;
|
||||
$this->clusterCount = (int) $clusterCount;
|
||||
$this->clusterSize = (int) $clusterSize;
|
||||
$this->maxHeight = (int) $maxHeight;
|
||||
$this->minHeight = (int) $minHeight;
|
||||
}
|
||||
}
|
43
src/world/generator/object/PondObject.php
Normal file
43
src/world/generator/object/PondObject.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class PondObject{
|
||||
private $random;
|
||||
public $type;
|
||||
|
||||
public function __construct(Random $random, Block $type){
|
||||
$this->type = $type;
|
||||
$this->random = $random;
|
||||
}
|
||||
|
||||
public function canPlaceObject(Level $level, Vector3 $pos){
|
||||
}
|
||||
|
||||
public function placeObject(Level $level, Vector3 $pos){
|
||||
}
|
||||
|
||||
}
|
@ -26,7 +26,7 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
*/
|
||||
|
||||
/***REM_START***/
|
||||
require_once("src/world/generator/object/tree/TreeObject.php");
|
||||
require_once("TreeObject.php");
|
||||
/***REM_END***/
|
||||
|
||||
class SmallTreeObject extends TreeObject{
|
||||
|
41
src/world/generator/populator/MineshaftPopulator.php
Normal file
41
src/world/generator/populator/MineshaftPopulator.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class MineshaftPopulator extends Populator{
|
||||
private static $DISTANCE = 256;
|
||||
private static $VARIATION = 16;
|
||||
private static $ODD = 3;
|
||||
private static $BASE_Y = 35;
|
||||
private static $RAND_Y = 11;
|
||||
|
||||
public function populate(Level $level, $chunkX, $chunkZ, Random $random){
|
||||
if($random->nextRange(0, MineshaftPopulator::$ODD) === 0){
|
||||
//$mineshaft = new Mineshaft($random);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
49
src/world/generator/populator/OrePopulator.php
Normal file
49
src/world/generator/populator/OrePopulator.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class OrePopulator extends Populator{
|
||||
private $oreTypes = array();
|
||||
public function populate(Level $level, $chunkX, $chunkZ, Random $random){
|
||||
foreach($this->oreTypes as $type){
|
||||
$ore = new OreObject($random, $type);
|
||||
for($i = 0; $i < $ore->type->clusterCount; ++$i){
|
||||
$v = new Vector3(
|
||||
$random->nextRange($chunkX << 4, ($chunkX << 4) + 16),
|
||||
$random->nextRange($ore->type->minHeight, $ore->type->maxHeight),
|
||||
$random->nextRange($chunkZ << 4, ($chunkZ << 4) + 16)
|
||||
);
|
||||
if($ore->canPlaceObject($level, $v)){
|
||||
$ore->placeObject($level, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setOreTypes(array $types){
|
||||
$this->oreTypes = $types;
|
||||
}
|
||||
}
|
57
src/world/generator/populator/PondPopulator.php
Normal file
57
src/world/generator/populator/PondPopulator.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|
||||
-
|
||||
/ \
|
||||
/ \
|
||||
/ PocketMine \
|
||||
/ MP \
|
||||
|\ @shoghicp /|
|
||||
|. \ / .|
|
||||
| .. \ / .. |
|
||||
| .. | .. |
|
||||
| .. | .. |
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
\ | /
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
class PondPopulator extends Populator{
|
||||
private $waterOdd = 4;
|
||||
private $lavaOdd = 4;
|
||||
private $lavaSurfaceOdd = 4;
|
||||
public function populate(Level $level, $chunkX, $chunkZ, Random $random){
|
||||
if($random->nextRange(0, $this->waterOdd) === 0){
|
||||
$v = new Vector3(
|
||||
$random->nextRange($chunkX << 4, ($chunkX << 4) + 16),
|
||||
$random->nextRange(0, 128),
|
||||
$random->nextRange($chunkZ << 4, ($chunkZ << 4) + 16),
|
||||
);
|
||||
$pond = new PondObject($random, new WaterBlock());
|
||||
if($pond->canPlaceObject($level, $v)){
|
||||
$pond->placeObject($level, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function setWaterOdd($waterOdd){
|
||||
$this->waterOdd = $waterOdd;
|
||||
}
|
||||
|
||||
public function setLavaOdd($lavaOdd){
|
||||
$this->lavaOdd = $lavaOdd;
|
||||
}
|
||||
|
||||
public function setLavaSurfaceOdd($lavaSurfaceOdd){
|
||||
$this->lavaSurfaceOdd = $lavaSurfaceOdd;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user