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){
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 false;
@ -63,7 +63,7 @@ class SaplingBlock extends TransparentBlock{
public function onUpdate($type){
if($type === BLOCK_UPDATE_RANDOM and mt_rand(0,2) === 0){ //Growth
if(($this->meta & 0x08) === 0x08){
TreeObject::growTree($this->level, $this);
TreeObject::growTree($this->level, $this, new Random(), $this->meta & 0x03);
}else{
$this->meta |= 0x08;
$this->level->setBlock($this, $this);

View File

@ -38,25 +38,7 @@ class GrassBlock extends SolidBlock{
public function onActivate(Item $item, Player $player){
if($item->getID() === DYE and $item->getMetadata() === 0x0F){
for($c = 0; $c < 15; ++$c){
$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]));
}
}
TallGrassObject::growGrass($this->level, $this, new Random());
return true;
}elseif($item->isHoe()){
$this->level->setBlock($this, new FarmlandBlock());

View File

@ -33,7 +33,7 @@ class SuperflatGenerator implements LevelGenerator{
private $level, $random, $structure, $chunks, $options, $floorLevel;
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;
if(isset($options["preset"])){
$this->parsePreset($options["preset"]);
@ -141,16 +141,28 @@ class SuperflatGenerator implements LevelGenerator{
}
if(isset($this->options["decoration"])){
$treecount = 32;
$treecount = 80;
$grasscount = 120;
if(isset($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){
$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 === 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] Populating level");
$this->generator->populateLevel();
$this->level->setSpawn($this->generator->getSpawn());
$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);
$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);
for($yy = ($this->totalHeight - $this->leavesHeight); $yy < ($this->totalHeight + 1); ++$yy){
$yRadius = ($yy - $this->totalHeight);

View File

@ -35,8 +35,8 @@ class PineTreeObject extends TreeObject{
private $leavesSizeY = -1;
private $leavesAbsoluteMaxRadius = -1;
public function canPlaceObject(Level $level, Vector3 $pos){
$this->findRandomLeavesSize();
public function canPlaceObject(Level $level, Vector3 $pos, Random $random){
$this->findRandomLeavesSize($random);
$checkRadius = 0;
for($yy = 0; $yy < $this->totalHeight; ++$yy) {
if($yy === $this->leavesSizeY) {
@ -54,18 +54,18 @@ class PineTreeObject extends TreeObject{
return true;
}
private function findRandomLeavesSize(){
$this->totalHeight += mt_rand(-1, 2);
$this->leavesSizeY = 1 + mt_rand(0,2);
$this->leavesAbsoluteMaxRadius = 2 + mt_rand(0, 2);
private function findRandomLeavesSize(Random $random){
$this->totalHeight += $random->nextRange(-1, 2);
$this->leavesSizeY = 1 + $random->nextRange(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) {
$this->findRandomLeavesSize();
}
$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;
$leavesBottomY = $this->totalHeight - $this->leavesSizeY;
$firstMaxedRadius = false;
@ -88,7 +88,7 @@ class PineTreeObject extends TreeObject{
++$leavesRadius;
}
}
$trunkHeightReducer = mt_rand(0,3);
$trunkHeightReducer = $random->nextRange(0, 3);
for($yy = 0; $yy < ($this->totalHeight - $trunkHeightReducer); ++$yy){
$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***/
class SmallTreeObject extends TreeObject{
var $type = 0;
public $type = 0;
private $trunkHeight = 5;
private static $leavesHeight = 4; // All trees appear to be 4 tall
private static $leafRadii = array( 1, 1.41, 2.83, 2.24 );
private static $leavesHeight = 4; // All trees appear to be 4 tall
private static $leafRadii = array( 1, 1.41, 2.83, 2.24 );
private $addLeavesVines = false;
private $addLogVines = false;
private $addCocoaPlants = false;
public function canPlaceObject(Level $level, Vector3 $pos){
public function canPlaceObject(Level $level, Vector3 $pos, Random $random){
$radiusToCheck = 0;
for ($yy = 0; $yy < $this->trunkHeight + 3; ++$yy) {
if ($yy == 1 or $yy === $this->trunkHeight) {
@ -57,7 +57,7 @@ class SmallTreeObject extends TreeObject{
return true;
}
public function placeObject(Level $level, Vector3 $pos){
public function placeObject(Level $level, Vector3 $pos, Random $random){
// The base dirt block
$dirtpos = new Vector3( $pos->x, $pos->y -1, $pos->z );
$level->setBlock( $dirtpos, new DirtBlock() );
@ -67,13 +67,13 @@ class SmallTreeObject extends TreeObject{
// - min=4 (all leaves are 4 tall, some trunk must show)
// - max=6 (top leaves are within ground-level whacking range
// on all small trees)
$heightPre = mt_rand( -14, 11 ); // (TODO: seed may apply)
$heightPre = $random->nextRange(-14, 11);
$this->trunkHeight = intval( $heightPre / 8 ) + 5;
// Adjust the starting leaf density using the trunk height as a
// starting position (tall trees with skimpy leaves don't look
// 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)
$leaflevel = 0;

View File

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

View File

@ -27,16 +27,17 @@ the Free Software Foundation, either version 3 of the License, or
class TreeObject{
var $overridable = array(
public $overridable = array(
0 => true,
6 => true,
17 => 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){
case SaplingBlock::SPRUCE:
if(mt_rand(0,1) == 1){
if($random->nextRange(0, 1) === 1){
$tree = new SpruceTreeObject();
}else{
$tree = new PineTreeObject();
@ -48,15 +49,15 @@ class TreeObject{
break;
default:
case SaplingBlock::OAK:
if(mt_rand(0,9) === 0){
/*if($random->nextRange(0, 9) === 0){
$tree = new BigTreeObject();
}else{
}else{*/
$tree = new SmallTreeObject();
}
//}
break;
}
if($tree->canPlaceObject($level, $pos)){
$tree->placeObject($level, $pos);
if($tree->canPlaceObject($level, $pos, $random)){
$tree->placeObject($level, $pos, $random);
}
}
}