Added more features to the World Generator

This commit is contained in:
Shoghi Cervantes 2013-05-26 13:22:22 +02:00
parent 424dba2fdd
commit aefcfad296
10 changed files with 104 additions and 56 deletions

View File

@ -54,7 +54,7 @@ class SaplingBlock extends TransparentBlock{
public function onActivate(Item $item, Player $player){ public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal if($item->getID() === DYE and $item->getMetadata() === 0x0F){ //Bonemeal
TreeObject::growTree($this->level, $this, $this->meta); TreeObject::growTree($this->level, $this, new Random(), $this->meta & 0x03);
return true; return true;
} }
return false; return false;
@ -63,7 +63,7 @@ class SaplingBlock extends TransparentBlock{
public function onUpdate($type){ public function onUpdate($type){
if($type === BLOCK_UPDATE_RANDOM and mt_rand(0,2) === 0){ //Growth if($type === BLOCK_UPDATE_RANDOM and mt_rand(0,2) === 0){ //Growth
if(($this->meta & 0x08) === 0x08){ if(($this->meta & 0x08) === 0x08){
TreeObject::growTree($this->level, $this); TreeObject::growTree($this->level, $this, new Random(), $this->meta & 0x03);
}else{ }else{
$this->meta |= 0x08; $this->meta |= 0x08;
$this->level->setBlock($this, $this); $this->level->setBlock($this, $this);

View File

@ -38,25 +38,7 @@ class GrassBlock extends SolidBlock{
public function onActivate(Item $item, Player $player){ public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){ if($item->getID() === DYE and $item->getMetadata() === 0x0F){
for($c = 0; $c < 15; ++$c){ TallGrassObject::growGrass($this->level, $this, new Random());
$x = mt_rand($this->x - 2, $this->x + 2);
$z = mt_rand($this->z - 2, $this->z + 2);
$b = $this->level->getBlock(new Vector3($x, $this->y + 1, $z));
$d = $this->level->getBlock(new Vector3($x, $this->y, $z));
if($b->getID() === AIR and $d->getID() === GRASS){
$arr = array(
array(DANDELION, 0),
array(CYAN_FLOWER, 0),
array(TALL_GRASS, 1),
array(TALL_GRASS, 1),
array(TALL_GRASS, 1),
array(TALL_GRASS, 1),
array(AIR, 0),
);
$t = $arr[mt_rand(0, count($arr) - 1)];
$this->level->setBlock($b, BlockAPI::get($t[0], $t[1]));
}
}
return true; return true;
}elseif($item->isHoe()){ }elseif($item->isHoe()){
$this->level->setBlock($this, new FarmlandBlock()); $this->level->setBlock($this, new FarmlandBlock());

View File

@ -33,7 +33,7 @@ class SuperflatGenerator implements LevelGenerator{
private $level, $random, $structure, $chunks, $options, $floorLevel; private $level, $random, $structure, $chunks, $options, $floorLevel;
public function __construct(array $options = array()){ public function __construct(array $options = array()){
$this->preset = "2;7,59x1,3x3,2;1;spawn(radius=10 block=89),decoration(treecount=65)"; $this->preset = "2;7,59x1,3x3,2;1;spawn(radius=10 block=89),decoration(treecount=80 grasscount=120)";
$this->options = $options; $this->options = $options;
if(isset($options["preset"])){ if(isset($options["preset"])){
$this->parsePreset($options["preset"]); $this->parsePreset($options["preset"]);
@ -141,16 +141,28 @@ class SuperflatGenerator implements LevelGenerator{
} }
if(isset($this->options["decoration"])){ if(isset($this->options["decoration"])){
$treecount = 32; $treecount = 80;
$grasscount = 120;
if(isset($this->options["spawn"]["treecount"])){ if(isset($this->options["spawn"]["treecount"])){
$treecount = intval($this->options["spawn"]["treecount"]); $treecount = intval($this->options["spawn"]["treecount"]);
} }
if(isset($this->options["spawn"]["grasscount"])){
$grasscount = intval($this->options["spawn"]["grasscount"]);
}
for($t = 0; $t < $treecount; ++$t){ for($t = 0; $t < $treecount; ++$t){
$centerX = $this->random->nextRange(0, 256); $centerX = $this->random->nextRange(0, 256);
$centerZ = $this->random->nextRange(0, 256); $centerZ = $this->random->nextRange(0, 256);
$down = $this->level->getBlock(new Vector3($centerX, $this->floorLevel - 1, $centerZ))->getID(); $down = $this->level->getBlock(new Vector3($centerX, $this->floorLevel - 1, $centerZ))->getID();
if($down === DIRT or $down === GRASS or $down === FARMLAND){ if($down === DIRT or $down === GRASS or $down === FARMLAND){
TreeObject::growTree($this->level, new Vector3($centerX, $this->floorLevel, $centerZ), $this->random->nextRange(0,3)); TreeObject::growTree($this->level, new Vector3($centerX, $this->floorLevel, $centerZ), $this->random, $this->random->nextRange(0,3));
}
}
for($t = 0; $t < $grasscount; ++$t){
$centerX = $this->random->nextRange(0, 256);
$centerZ = $this->random->nextRange(0, 256);
$down = $this->level->getBlock(new Vector3($centerX, $this->floorLevel - 1, $centerZ))->getID();
if($down === GRASS){
TallGrassObject::growGrass($this->level, new Vector3($centerX, $this->floorLevel - 1, $centerZ), $this->random, $this->random->nextRange(8, 40));
} }
} }
} }

View File

@ -61,6 +61,7 @@ class WorldGenerator{
} }
console("[NOTICE] Generating level ".ceil((($Z + 1)/$this->width) * 100)."%"); console("[NOTICE] Generating level ".ceil((($Z + 1)/$this->width) * 100)."%");
} }
console("[NOTICE] Populating level");
$this->generator->populateLevel(); $this->generator->populateLevel();
$this->level->setSpawn($this->generator->getSpawn()); $this->level->setSpawn($this->generator->getSpawn());
$this->level->save(true); $this->level->save(true);

View File

@ -0,0 +1,52 @@
<?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 TallGrassObject{
public static function growGrass(Level $level, Vector3 $pos, Random $random, $count = 15){
$arr = array(
array(DANDELION, 0),
array(CYAN_FLOWER, 0),
array(TALL_GRASS, 1),
array(TALL_GRASS, 1),
array(TALL_GRASS, 1),
array(TALL_GRASS, 1),
array(AIR, 0),
);
$radius = ceil(sqrt($count) / 2);
for($c = 0; $c < $count; ++$c){
$x = $random->nextRange($pos->x - $radius, $pos->x + $radius);
$z = $random->nextRange($pos->z - $radius, $pos->z + $radius);
$b = $level->getBlock(new Vector3($x, $pos->y + 1, $z));
$d = $level->getBlock(new Vector3($x, $pos->y, $z));
if($b->getID() === AIR and $d->getID() === GRASS){
$t = $arr[$random->nextRange(0, count($arr) - 1)];
$level->setBlock($b, BlockAPI::get($t[0], $t[1]));
}
}
}
}

View File

@ -67,7 +67,7 @@ class BigTreeObject extends TreeObject{
generateBranches(w, x, y, z, leaves); generateBranches(w, x, y, z, leaves);
$level->setBlock($x, $pos->y - 1, $z, 3, 0); $level->setBlock($x, $pos->y - 1, $z, 3, 0);
$this->totalHeight += mt_rand(-1, 3); $this->totalHeight += $random->nextRange(0, 2);
$this->leavesHeight += mt_rand(0, 1); $this->leavesHeight += mt_rand(0, 1);
for($yy = ($this->totalHeight - $this->leavesHeight); $yy < ($this->totalHeight + 1); ++$yy){ for($yy = ($this->totalHeight - $this->leavesHeight); $yy < ($this->totalHeight + 1); ++$yy){
$yRadius = ($yy - $this->totalHeight); $yRadius = ($yy - $this->totalHeight);

View File

@ -35,8 +35,8 @@ class PineTreeObject extends TreeObject{
private $leavesSizeY = -1; private $leavesSizeY = -1;
private $leavesAbsoluteMaxRadius = -1; private $leavesAbsoluteMaxRadius = -1;
public function canPlaceObject(Level $level, Vector3 $pos){ public function canPlaceObject(Level $level, Vector3 $pos, Random $random){
$this->findRandomLeavesSize(); $this->findRandomLeavesSize($random);
$checkRadius = 0; $checkRadius = 0;
for($yy = 0; $yy < $this->totalHeight; ++$yy) { for($yy = 0; $yy < $this->totalHeight; ++$yy) {
if($yy === $this->leavesSizeY) { if($yy === $this->leavesSizeY) {
@ -54,18 +54,18 @@ class PineTreeObject extends TreeObject{
return true; return true;
} }
private function findRandomLeavesSize(){ private function findRandomLeavesSize(Random $random){
$this->totalHeight += mt_rand(-1, 2); $this->totalHeight += $random->nextRange(-1, 2);
$this->leavesSizeY = 1 + mt_rand(0,2); $this->leavesSizeY = 1 + $random->nextRange(0, 2);
$this->leavesAbsoluteMaxRadius = 2 + mt_rand(0, 2); $this->leavesAbsoluteMaxRadius = 2 + $random->nextRange(0, 2);
} }
public function placeObject(Level $level, Vector3 $pos){ public function placeObject(Level $level, Vector3 $pos, Random $random){
if($this->leavesSizeY === -1 or $this->leavesAbsoluteMaxRadius === -1) { if($this->leavesSizeY === -1 or $this->leavesAbsoluteMaxRadius === -1) {
$this->findRandomLeavesSize(); $this->findRandomLeavesSize();
} }
$level->setBlock(new Vector3($pos->x, $pos->y - 1, $pos->z), new DirtBlock()); $level->setBlock(new Vector3($pos->x, $pos->y - 1, $pos->z), new DirtBlock());
$leavesRadius = mt_rand(0,2); $leavesRadius = $random->nextRange(0, 2);
$leavesMaxRadius = 1; $leavesMaxRadius = 1;
$leavesBottomY = $this->totalHeight - $this->leavesSizeY; $leavesBottomY = $this->totalHeight - $this->leavesSizeY;
$firstMaxedRadius = false; $firstMaxedRadius = false;
@ -88,7 +88,7 @@ class PineTreeObject extends TreeObject{
++$leavesRadius; ++$leavesRadius;
} }
} }
$trunkHeightReducer = mt_rand(0,3); $trunkHeightReducer = $random->nextRange(0, 3);
for($yy = 0; $yy < ($this->totalHeight - $trunkHeightReducer); ++$yy){ for($yy = 0; $yy < ($this->totalHeight - $trunkHeightReducer); ++$yy){
$level->setBlock(new Vector3($pos->x, $pos->y + $yy, $pos->z), new WoodBlock($this->type)); $level->setBlock(new Vector3($pos->x, $pos->y + $yy, $pos->z), new WoodBlock($this->type));
} }

View File

@ -30,16 +30,16 @@ require_once("src/world/generator/object/tree/TreeObject.php");
/***REM_END***/ /***REM_END***/
class SmallTreeObject extends TreeObject{ class SmallTreeObject extends TreeObject{
var $type = 0; public $type = 0;
private $trunkHeight = 5; private $trunkHeight = 5;
private static $leavesHeight = 4; // All trees appear to be 4 tall private static $leavesHeight = 4; // All trees appear to be 4 tall
private static $leafRadii = array( 1, 1.41, 2.83, 2.24 ); private static $leafRadii = array( 1, 1.41, 2.83, 2.24 );
private $addLeavesVines = false; private $addLeavesVines = false;
private $addLogVines = false; private $addLogVines = false;
private $addCocoaPlants = false; private $addCocoaPlants = false;
public function canPlaceObject(Level $level, Vector3 $pos){ public function canPlaceObject(Level $level, Vector3 $pos, Random $random){
$radiusToCheck = 0; $radiusToCheck = 0;
for ($yy = 0; $yy < $this->trunkHeight + 3; ++$yy) { for ($yy = 0; $yy < $this->trunkHeight + 3; ++$yy) {
if ($yy == 1 or $yy === $this->trunkHeight) { if ($yy == 1 or $yy === $this->trunkHeight) {
@ -57,7 +57,7 @@ class SmallTreeObject extends TreeObject{
return true; return true;
} }
public function placeObject(Level $level, Vector3 $pos){ public function placeObject(Level $level, Vector3 $pos, Random $random){
// The base dirt block // The base dirt block
$dirtpos = new Vector3( $pos->x, $pos->y -1, $pos->z ); $dirtpos = new Vector3( $pos->x, $pos->y -1, $pos->z );
$level->setBlock( $dirtpos, new DirtBlock() ); $level->setBlock( $dirtpos, new DirtBlock() );
@ -67,13 +67,13 @@ class SmallTreeObject extends TreeObject{
// - min=4 (all leaves are 4 tall, some trunk must show) // - min=4 (all leaves are 4 tall, some trunk must show)
// - max=6 (top leaves are within ground-level whacking range // - max=6 (top leaves are within ground-level whacking range
// on all small trees) // on all small trees)
$heightPre = mt_rand( -14, 11 ); // (TODO: seed may apply) $heightPre = $random->nextRange(-14, 11);
$this->trunkHeight = intval( $heightPre / 8 ) + 5; $this->trunkHeight = intval( $heightPre / 8 ) + 5;
// Adjust the starting leaf density using the trunk height as a // Adjust the starting leaf density using the trunk height as a
// starting position (tall trees with skimpy leaves don't look // starting position (tall trees with skimpy leaves don't look
// too good) // too good)
$leafPre = mt_rand( $this->trunkHeight, 10 ) / 20.0; // (TODO: seed may apply) $leafPre = $random->nextRange($this->trunkHeight, 10) / 20; // (TODO: seed may apply)
// Now build the tree (from the top down) // Now build the tree (from the top down)
$leaflevel = 0; $leaflevel = 0;

View File

@ -35,8 +35,8 @@ class SpruceTreeObject extends TreeObject{
private $leavesBottomY = -1; private $leavesBottomY = -1;
private $leavesMaxRadius = -1; private $leavesMaxRadius = -1;
public function canPlaceObject(Level $level, Vector3 $pos){ public function canPlaceObject(Level $level, Vector3 $pos, Random $random){
$this->findRandomLeavesSize(); $this->findRandomLeavesSize($random);
$checkRadius = 0; $checkRadius = 0;
for($yy = 0; $yy < $this->totalHeight + 2; ++$yy) { for($yy = 0; $yy < $this->totalHeight + 2; ++$yy) {
if($yy === $this->leavesBottomY) { if($yy === $this->leavesBottomY) {
@ -54,13 +54,13 @@ class SpruceTreeObject extends TreeObject{
return true; return true;
} }
private function findRandomLeavesSize(){ private function findRandomLeavesSize(Random $random){
$this->totalHeight += mt_rand(-1, 2); $this->totalHeight += $random->nextRange(-1, 2);
$this->leavesBottomY = (int) ($this->totalHeight - mt_rand(1,2) - 3); $this->leavesBottomY = (int) ($this->totalHeight - $random->nextRange(1, 2) - 3);
$this->leavesMaxRadius = 1 + mt_rand(0, 1); $this->leavesMaxRadius = 1 + $random->nextRange(0, 1);
} }
public function placeObject(Level $level, Vector3 $pos){ public function placeObject(Level $level, Vector3 $pos, Random $random){
if($this->leavesBottomY === -1 or $this->leavesMaxRadius === -1) { if($this->leavesBottomY === -1 or $this->leavesMaxRadius === -1) {
$this->findRandomLeavesSize(); $this->findRandomLeavesSize();
} }

View File

@ -27,16 +27,17 @@ the Free Software Foundation, either version 3 of the License, or
class TreeObject{ class TreeObject{
var $overridable = array( public $overridable = array(
0 => true, 0 => true,
6 => true, 6 => true,
17 => true, 17 => true,
18 => true, 18 => true,
); );
public static function growTree(Level $level, Vector3 $pos, $type = 0){
public static function growTree(Level $level, Vector3 $pos, Random $random, $type = 0){
switch($type & 0x03){ switch($type & 0x03){
case SaplingBlock::SPRUCE: case SaplingBlock::SPRUCE:
if(mt_rand(0,1) == 1){ if($random->nextRange(0, 1) === 1){
$tree = new SpruceTreeObject(); $tree = new SpruceTreeObject();
}else{ }else{
$tree = new PineTreeObject(); $tree = new PineTreeObject();
@ -48,15 +49,15 @@ class TreeObject{
break; break;
default: default:
case SaplingBlock::OAK: case SaplingBlock::OAK:
if(mt_rand(0,9) === 0){ /*if($random->nextRange(0, 9) === 0){
$tree = new BigTreeObject(); $tree = new BigTreeObject();
}else{ }else{*/
$tree = new SmallTreeObject(); $tree = new SmallTreeObject();
} //}
break; break;
} }
if($tree->canPlaceObject($level, $pos)){ if($tree->canPlaceObject($level, $pos, $random)){
$tree->placeObject($level, $pos); $tree->placeObject($level, $pos, $random);
} }
} }
} }