Fixed wrong paths

This commit is contained in:
Shoghi Cervantes
2014-04-01 05:06:12 +02:00
parent 05a42712bf
commit dd17652aca
437 changed files with 41109 additions and 0 deletions

View File

@ -0,0 +1,154 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level;
use pocketmine\block\Block;
use pocketmine\block\TNT;
use pocketmine\entity\Entity;
use pocketmine\event\entity\EntityExplodeEvent;
use pocketmine\item\Item;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\network\protocol\ExplodePacket;
use pocketmine\Player;
use pocketmine\Server;
class Explosion{
public static $specialDrops = array(
Item::GRASS => Item::DIRT,
Item::STONE => Item::COBBLESTONE,
Item::COAL_ORE => Item::COAL,
Item::DIAMOND_ORE => Item::DIAMOND,
Item::REDSTONE_ORE => Item::REDSTONE,
);
private $rays = 16; //Rays
public $level;
public $source;
public $size;
/**
* @var Block[]
*/
public $affectedBlocks = array();
public $stepLen = 0.3;
private $what;
public function __construct(Position $center, $size, $what = null){
$this->level = $center->level;
$this->source = $center;
$this->size = max($size, 0);
$this->what = $what;
}
public function explode(){
if($this->size < 0.1){
return false;
}
$mRays = $this->rays - 1;
for($i = 0; $i < $this->rays; ++$i){
for($j = 0; $j < $this->rays; ++$j){
for($k = 0; $k < $this->rays; ++$k){
if($i == 0 or $i == $mRays or $j == 0 or $j == $mRays or $k == 0 or $k == $mRays){
$vector = new Vector3($i / $mRays * 2 - 1, $j / $mRays * 2 - 1, $k / $mRays * 2 - 1); //($i / $mRays) * 2 - 1
$vector = $vector->normalize()->multiply($this->stepLen);
$pointer = clone $this->source;
for($blastForce = $this->size * (mt_rand(700, 1300) / 1000); $blastForce > 0; $blastForce -= $this->stepLen * 0.75){
$vBlock = $pointer->floor();
$blockID = $this->level->level->getBlockID($vBlock->x, $vBlock->y, $vBlock->z);
if($blockID > 0){
$block = Block::get($blockID, 0);
$block->x = $vBlock->x;
$block->y = $vBlock->y;
$block->z = $vBlock->z;
$blastForce -= ($block->getHardness() / 5 + 0.3) * $this->stepLen;
if($blastForce > 0){
$index = ($block->x << 15) + ($block->z << 7) + $block->y;
if(!isset($this->affectedBlocks[$index])){
$this->affectedBlocks[$index] = $block;
}
}
}
$pointer = $pointer->add($vector);
}
}
}
}
}
$send = array();
$source = $this->source->floor();
$radius = 2 * $this->size;
$yield = (1 / $this->size) * 100;
if($this->what instanceof Entity){
Server::getInstance()->getPluginManager()->callEvent($ev = new EntityExplodeEvent($this->what, $this->source, $this->affectedBlocks, $yield));
if($ev->isCancelled()){
return false;
}else{
$yield = $ev->getYield();
$this->affectedBlocks = $ev->getBlockList();
}
}
//TODO
/*foreach($server->api->entity->getRadius($this->source, $radius) as $entity){
$impact = (1 - $this->source->distance($entity) / $radius) * 0.5; //placeholder, 0.7 should be exposure
$damage = (int) (($impact * $impact + $impact) * 8 * $this->size + 1);
$entity->harm($damage, "explosion");
}*/
foreach($this->affectedBlocks as $block){
if($block instanceof TNT){
$data = array(
"x" => $block->x + 0.5,
"y" => $block->y + 0.5,
"z" => $block->z + 0.5,
"power" => 4,
"fuse" => mt_rand(10, 30), //0.5 to 1.5 seconds
);
//TODO
//$e = $server->api->entity->add($this->level, ENTITY_OBJECT, OBJECT_PRIMEDTNT, $data);
//$e->spawnToAll();
}elseif(mt_rand(0, 100) < $yield){
if(isset(self::$specialDrops[$block->getID()])){
//TODO
//$server->api->entity->drop(new Position($block->x + 0.5, $block->y, $block->z + 0.5, $this->level), Item::get(self::$specialDrops[$block->getID()], 0));
}else{
//TODO
//$server->api->entity->drop(new Position($block->x + 0.5, $block->y, $block->z + 0.5, $this->level), Item::get($block->getID(), $this->level->level->getBlockDamage($block->x, $block->y, $block->z)));
}
}
$this->level->level->setBlockID($block->x, $block->y, $block->z, 0);
$send[] = new Vector3($block->x - $source->x, $block->y - $source->y, $block->z - $source->z);
}
$pk = new ExplodePacket;
$pk->x = $this->source->x;
$pk->y = $this->source->y;
$pk->z = $this->source->z;
$pk->radius = $this->size;
$pk->records = $send;
Player::broadcastPacket($this->level->getPlayers(), $pk);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level;
use pocketmine\nbt\NBT;
use pocketmine\pmf\LevelFormat;
use pocketmine\utils\Config;
class LevelImport{
private $path;
public function __construct($path){
$this->path = $path;
}
public function import(){
if(file_exists($this->path . "tileEntities.dat")){ //OldPM
$level = unserialize(file_get_contents($this->path . "level.dat"));
console("[INFO] Importing OldPM level \"" . $level["LevelName"] . "\" to PMF format");
$entities = new Config($this->path . "entities.yml", Config::YAML, unserialize(file_get_contents($this->path . "entities.dat")));
$entities->save();
$tiles = new Config($this->path . "tiles.yml", Config::YAML, unserialize(file_get_contents($this->path . "tileEntities.dat")));
$tiles->save();
}elseif(file_exists($this->path . "chunks.dat") and file_exists($this->path . "level.dat")){ //Pocket
$nbt = new NBT(NBT::LITTLE_ENDIAN);
$nbt->read(substr(file_get_contents($this->path . "level.dat"), 8));
$level = $nbt->getData();
if($level["LevelName"] == ""){
$level["LevelName"] = "world" . time();
}
console("[INFO] Importing Pocket level \"" . $level->LevelName . "\" to PMF format");
unset($level->Player);
$nbt->read(substr(file_get_contents($this->path . "entities.dat"), 12));
$entities = $nbt->getData();
if(!isset($entities->TileEntities)){
$entities->TileEntities = array();
}
$tiles = $entities->TileEntities;
$entities = $entities->Entities;
$entities = new Config($this->path . "entities.yml", Config::YAML, $entities);
$entities->save();
$tiles = new Config($this->path . "tiles.yml", Config::YAML, $tiles);
$tiles->save();
}else{
return false;
}
$pmf = new LevelFormat($this->path . "level.pmf", array(
"name" => $level->LevelName,
"seed" => $level->RandomSeed,
"time" => $level->Time,
"spawnX" => $level->SpawnX,
"spawnY" => $level->SpawnY,
"spawnZ" => $level->SpawnZ,
"height" => 8,
"generator" => "default",
"generatorSettings" => "",
"extra" => ""
));
$chunks = new PocketChunkParser();
$chunks->loadFile($this->path . "chunks.dat");
$chunks->loadMap();
for($Z = 0; $Z < 16; ++$Z){
for($X = 0; $X < 16; ++$X){
$chunk = array(
0 => "",
1 => "",
2 => "",
3 => "",
4 => "",
5 => "",
6 => "",
7 => ""
);
$pmf->initCleanChunk($X, $Z);
for($z = 0; $z < 16; ++$z){
for($x = 0; $x < 16; ++$x){
$block = $chunks->getChunkColumn($X, $Z, $x, $z, 0);
$meta = $chunks->getChunkColumn($X, $Z, $x, $z, 1);
for($Y = 0; $Y < 8; ++$Y){
$chunk[$Y] .= substr($block, $Y << 4, 16);
$chunk[$Y] .= substr($meta, $Y << 3, 8);
$chunk[$Y] .= "\x00\x00\x00\x00\x00\x00\x00\x00";
}
}
}
foreach($chunk as $Y => $data){
$pmf->setMiniChunk($X, $Z, $Y, $data);
}
$pmf->setPopulated($X, $Z);
$pmf->saveChunk($X, $Z);
}
console("[NOTICE] Importing level " . ceil(($Z + 1) / 0.16) . "%");
}
$chunks->map = null;
$chunks = null;
@unlink($this->path . "level.dat");
@unlink($this->path . "level.dat_old");
@unlink($this->path . "player.dat");
@unlink($this->path . "entities.dat");
@unlink($this->path . "chunks.dat");
@unlink($this->path . "chunks.dat.gz");
@unlink($this->path . "tiles.dat");
unset($chunks, $level, $entities, $tiles, $nbt);
return true;
}
}

View File

@ -0,0 +1,234 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level;
use pocketmine\utils\Utils;
/**
* WARNING: This code is old, and only supports the file format partially (reverse engineering)
* It can break, lock, or hit you in the face in any moment.
*
*/
class PocketChunkParser{
private $location;
private $raw = "";
private $file;
public $sectorLength = 4096; //16 * 16 * 16
public $chunkLength = 86016; //21 * $sectorLength
public $map = array();
public function __construct(){
}
private function loadLocationTable(){
$this->location = array();
console("[DEBUG] Loading Chunk Location table...", true, true, 2);
for($offset = 0; $offset < 0x1000; $offset += 4){
$data = Utils::readLInt(substr($this->raw, $offset, 4));
$sectors = $data & 0xff;
if($sectors === 0){
continue;
}
$sectorLocation = $data >> 8;
$this->location[$offset >> 2] = $sectorLocation * $this->sectorLength; //$this->getOffset($X, $Z, $sectors);
}
}
public function loadFile($file){
if(file_exists($file . ".gz")){
$this->raw = gzinflate(file_get_contents($file . ".gz"));
$r = @gzinflate($this->raw);
if($r !== false and $r != ""){
$this->raw = $r;
}
@unlink($file . ".gz");
file_put_contents($file, $this->raw);
}elseif(!file_exists($file)){
return false;
}else{
$this->raw = file_get_contents($file);
}
$this->file = $file;
$this->chunkLength = $this->sectorLength * ord($this->raw{0});
return true;
}
public function loadRaw($raw, $file){
$this->file = $file;
$this->raw = $raw;
$this->chunkLength = $this->sectorLength * ord($this->raw{0});
return true;
}
private function getOffset($X, $Z){
return $this->location[$X + ($Z << 5)];
}
public function getChunk($X, $Z){
$X = (int) $X;
$Z = (int) $Z;
return substr($this->raw, $this->getOffset($X, $Z), $this->chunkLength);
}
public function writeChunk($X, $Z){
$X = (int) $X;
$Z = (int) $Z;
if(!isset($this->map[$X][$Z])){
return false;
}
$chunk = "";
foreach($this->map[$X][$Z] as $section => $data){
for($i = 0; $i < 256; ++$i){
$chunk .= $data[$i];
}
}
return Utils::writeLInt(strlen($chunk)) . $chunk;
}
public function parseChunk($X, $Z){
$X = (int) $X;
$Z = (int) $Z;
$offset = $this->getOffset($X, $Z);
$len = Utils::readLInt(substr($this->raw, $offset, 4));
$offset += 4;
$chunk = array(
0 => array(), //Block
1 => array(), //Data
2 => array(), //SkyLight
3 => array(), //BlockLight
);
foreach($chunk as $section => &$data){
$l = $section === 0 ? 128 : 64;
for($i = 0; $i < 256; ++$i){
$data[$i] = substr($this->raw, $offset, $l);
$offset += $l;
}
}
return $chunk;
}
public function loadMap(){
if($this->raw == ""){
return false;
}
$this->loadLocationTable();
console("[DEBUG] Loading chunks...", true, true, 2);
for($x = 0; $x < 16; ++$x){
$this->map[$x] = array();
for($z = 0; $z < 16; ++$z){
$this->map[$x][$z] = $this->parseChunk($x, $z);
}
}
$this->raw = "";
console("[DEBUG] Chunks loaded!", true, true, 2);
return true;
}
public function saveMap($final = false){
console("[DEBUG] Saving chunks...", true, true, 2);
$fp = fopen($this->file, "r+b");
flock($fp, LOCK_EX);
foreach($this->map as $x => $d){
foreach($d as $z => $chunk){
fseek($fp, $this->getOffset($x, $z));
fwrite($fp, $this->writeChunk($x, $z), $this->chunkLength);
}
}
flock($fp, LOCK_UN);
fclose($fp);
$original = filesize($this->file);
file_put_contents($this->file . ".gz", gzdeflate(gzdeflate(file_get_contents($this->file), 9), 9)); //Double compression for flat maps
$compressed = filesize($this->file . ".gz");
console("[DEBUG] Saved chunks.dat.gz with " . round(($compressed / $original) * 100, 2) . "% (" . round($compressed / 1024, 2) . "KB) of the original size", true, true, 2);
if($final === true){
@unlink($this->file);
}
}
public function getFloor($x, $z){
$X = $x >> 4;
$Z = $z >> 4;
$aX = $x - ($X << 4);
$aZ = $z - ($Z << 4);
$index = $aZ + ($aX << 4);
for($y = 127; $y <= 0; --$y){
if($this->map[$X][$Z][0][$index]{$y} !== "\x00"){
break;
}
}
return $y;
}
public function getBlock($x, $y, $z){
$x = (int) $x;
$y = (int) $y;
$z = (int) $z;
$X = $x >> 4;
$Z = $z >> 4;
$aX = $x - ($X << 4);
$aZ = $z - ($Z << 4);
$index = $aZ + ($aX << 4);
$block = ord($this->map[$X][$Z][0][$index]{$y});
$meta = ord($this->map[$X][$Z][1][$index]{$y >> 1});
if(($y & 1) === 0){
$meta = $meta & 0x0F;
}else{
$meta = $meta >> 4;
}
return array($block, $meta);
}
public function getChunkColumn($X, $Z, $x, $z, $type = 0){
$index = $z + ($x << 4);
return $this->map[$X][$Z][$type][$index];
}
public function setBlock($x, $y, $z, $block, $meta = 0){
$x = (int) $x;
$y = (int) $y;
$z = (int) $z;
$X = $x >> 4;
$Z = $z >> 4;
$aX = $x - ($X << 4);
$aZ = $z - ($Z << 4);
$index = $aZ + ($aX << 4);
$this->map[$X][$Z][0][$index]{$y} = chr($block);
$old_meta = ord($this->map[$X][$Z][1][$index]{$y >> 1});
if(($y & 1) === 0){
$meta = ($old_meta & 0xF0) | ($meta & 0x0F);
}else{
$meta = (($meta << 4) & 0xF0) | ($old_meta & 0x0F);
}
$this->map[$X][$Z][1][$index]{$y >> 1} = chr($meta);
}
}

View File

@ -0,0 +1,78 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level;
use pocketmine\math\Vector3 as Vector3;
class Position extends Vector3{
/** @var Level */
public $level = null;
/**
* @param int $x
* @param int $y
* @param int $z
* @param Level $level
*/
public function __construct($x = 0, $y = 0, $z = 0, Level $level){
$this->x = $x;
$this->y = $y;
$this->z = $z;
$this->level = $level;
}
public static function fromObject(Vector3 $pos, Level $level){
return new Position($pos->x, $pos->y, $pos->z, $level);
}
/**
* Returns a side Vector
*
* @param $side
*
* @return Position
*/
public function getSide($side){
return Position::fromObject(parent::getSide($side), $this->level);
}
/**
* Returns the distance between two points or objects
*
* @param Vector3 $pos
*
* @return float
*/
public function distance(Vector3 $pos){
if(($pos instanceof Position) and $pos->level !== $this->level){
return PHP_INT_MAX;
}
return parent::distance($pos);
}
public function __toString(){
return "Position(level=" . $this->level->getName() . ",x=" . $this->x . ",y=" . $this->y . ",z=" . $this->z . ")";
}
}

View File

@ -0,0 +1,71 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level;
use pocketmine\level\generator\Generator;
use pocketmine\pmf\LevelFormat;
use pocketmine\utils\Config;
use pocketmine\utils\Random;
use pocketmine\utils\Utils;
class WorldGenerator{
private $seed, $level, $path, $random, $generator, $height;
public function __construct(Generator $generator, $name, $seed = false, $height = 8){
$this->seed = $seed !== false ? (int) $seed : Utils::readInt(Utils::getRandomBytes(4, false));
$this->random = new Random($this->seed);
$this->height = (int) $height;
$this->path = \pocketmine\DATA . "worlds/" . $name . "/";
$this->generator = $generator;
$level = new LevelFormat($this->path . "level.pmf", array(
"name" => $name,
"seed" => $this->seed,
"time" => 0,
"spawnX" => 128,
"spawnY" => 128,
"spawnZ" => 128,
"height" => $this->height,
"generator" => $this->generator->getName(),
"generatorSettings" => $this->generator->getSettings(),
"extra" => ""
));
$blockUpdates = new Config($this->path . "bupdates.yml", Config::YAML);
$this->level = new Level($level, $name);
}
public function generate(){
$this->generator->init($this->level, $this->random);
for($Z = 7; $Z <= 9; ++$Z){
for($X = 7; $X <= 9; ++$X){
$this->level->level->loadChunk($X, $Z);
}
}
$this->level->setSpawn($this->generator->getSpawn());
}
public function close(){
$this->level->close();
}
}

View File

@ -0,0 +1,159 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator;
use pocketmine\block\Air;
use pocketmine\block\CoalOre;
use pocketmine\block\DiamondOre;
use pocketmine\block\Dirt;
use pocketmine\block\GoldOre;
use pocketmine\block\Gravel;
use pocketmine\block\IronOre;
use pocketmine\block\LapisOre;
use pocketmine\block\RedstoneOre;
use pocketmine\item\Item;
use pocketmine\level\generator\populator\Ore;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class Flat extends Generator{
private $level, $random, $structure, $chunks, $options, $floorLevel, $preset, $populators = array();
public function getSettings(){
return $this->options;
}
public function getName(){
return "flat";
}
public function __construct(array $options = array()){
$this->preset = "2;7,59x1,3x3,2;1;spawn(radius=10 block=89),decoration(treecount=80 grasscount=45)";
$this->options = $options;
if(isset($options["preset"])){
$this->parsePreset($options["preset"]);
}else{
$this->parsePreset($this->preset);
}
if(isset($this->options["decoration"])){
$ores = new Ore();
$ores->setOreTypes(array(
new object\OreType(new CoalOre(), 20, 16, 0, 128),
new object\OreType(New IronOre(), 20, 8, 0, 64),
new object\OreType(new RedstoneOre(), 8, 7, 0, 16),
new object\OreType(new LapisOre(), 1, 6, 0, 32),
new object\OreType(new GoldOre(), 2, 8, 0, 32),
new object\OreType(new DiamondOre(), 1, 7, 0, 16),
new object\OreType(new Dirt(), 20, 32, 0, 128),
new object\OreType(new Gravel(), 10, 16, 0, 128),
));
$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){
$this->preset = $preset;
$preset = explode(";", $preset);
$version = (int) $preset[0];
$blocks = @$preset[1];
$biome = isset($preset[2]) ? $preset[2] : 1;
$options = isset($preset[3]) ? $preset[3] : "";
preg_match_all('#(([0-9]{0,})x?([0-9]{1,3}:?[0-9]{0,2})),?#', $blocks, $matches);
$y = 0;
$this->structure = array();
$this->chunks = array();
foreach($matches[3] as $i => $b){
$b = Item::fromString($b);
$cnt = $matches[2][$i] === "" ? 1 : intval($matches[2][$i]);
for($cY = $y, $y += $cnt; $cY < $y; ++$cY){
$this->structure[$cY] = $b;
}
}
$this->floorLevel = $y;
for(; $y < 0xFF; ++$y){
$this->structure[$y] = new Air();
}
for($Y = 0; $Y < 8; ++$Y){
$this->chunks[$Y] = "";
$startY = $Y << 4;
$endY = $startY + 16;
for($Z = 0; $Z < 16; ++$Z){
for($X = 0; $X < 16; ++$X){
$blocks = "";
$metas = "";
for($y = $startY; $y < $endY; ++$y){
$blocks .= chr($this->structure[$y]->getID());
$metas .= substr(dechex($this->structure[$y]->getMetadata()), -1);
}
$this->chunks[$Y] .= $blocks . hex2bin($metas) . "\x00\x00\x00\x00\x00\x00\x00\x00";
}
}
}
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 = array();
$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 init(Level $level, Random $random){
$this->level = $level;
$this->random = $random;
}
public function generateChunk($chunkX, $chunkZ){
for($Y = 0; $Y < 8; ++$Y){
$this->level->setMiniChunk($chunkX, $chunkZ, $Y, $this->chunks[$Y]);
}
}
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);
}
}
public function getSpawn(){
return new Vector3(128, $this->floorLevel, 128);
}
}

View File

@ -0,0 +1,64 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
/**
* Generator classes used in Levels
*/
namespace pocketmine\level\generator;
use pocketmine\level\Level;
use pocketmine\utils\Random;
abstract class Generator{
private static $list = array();
public static function addGenerator($object, $name){
if(is_subclass_of($object, "pocketmine\\level\\generator\\Generator") and !isset(Generator::$list[$name])){
Generator::$list[$name] = $object;
return true;
}
return false;
}
public static function getGenerator($name){
if(isset(Generator::$list[$name])){
return Generator::$list[$name];
}
return "pocketmine\\level\\generator\\Normal";
}
public abstract function __construct(array $settings = array());
public abstract function init(Level $level, Random $random);
public abstract function generateChunk($chunkX, $chunkZ);
public abstract function populateChunk($chunkX, $chunkZ);
public abstract function getSettings();
public abstract function getName();
public abstract function getSpawn();
}

View File

@ -0,0 +1,189 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator;
use pocketmine\block\CoalOre;
use pocketmine\block\DiamondOre;
use pocketmine\block\Dirt;
use pocketmine\block\GoldOre;
use pocketmine\block\Gravel;
use pocketmine\block\IronOre;
use pocketmine\block\LapisOre;
use pocketmine\block\RedstoneOre;
use pocketmine\level\generator\noise\Simplex;
use pocketmine\level\generator\object\OreType;
use pocketmine\level\generator\populator\Ore;
use pocketmine\level\generator\populator\TallGrass;
use pocketmine\level\generator\populator\Tree;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class Normal extends Generator{
private $populators = array();
private $level;
private $random;
private $worldHeight = 65;
private $waterHeight = 63;
private $noiseHills;
private $noisePatches;
private $noisePatchesSmall;
private $noiseBase;
public function __construct(array $options = array()){
}
public function getName(){
return "normal";
}
public function getSettings(){
return array();
}
public function init(Level $level, Random $random){
$this->level = $level;
$this->random = $random;
$this->random->setSeed($this->level->getSeed());
$this->noiseHills = new Simplex($this->random, 3, 0.11, 12);
$this->noisePatches = new Simplex($this->random, 2, 0.03, 16);
$this->noisePatchesSmall = new Simplex($this->random, 2, 0.5, 4);
$this->noiseBase = new Simplex($this->random, 16, 0.7, 16);
$ores = new Ore();
$ores->setOreTypes(array(
new OreType(new CoalOre(), 20, 16, 0, 128),
new OreType(New IronOre(), 20, 8, 0, 64),
new OreType(new RedstoneOre(), 8, 7, 0, 16),
new OreType(new LapisOre(), 1, 6, 0, 32),
new OreType(new GoldOre(), 2, 8, 0, 32),
new OreType(new DiamondOre(), 1, 7, 0, 16),
new OreType(new Dirt(), 20, 32, 0, 128),
new OreType(new Gravel(), 10, 16, 0, 128),
));
$this->populators[] = $ores;
$trees = new Tree();
$trees->setBaseAmount(3);
$trees->setRandomAmount(0);
$this->populators[] = $trees;
$tallGrass = new TallGrass();
$tallGrass->setBaseAmount(5);
$tallGrass->setRandomAmount(0);
$this->populators[] = $tallGrass;
}
public function generateChunk($chunkX, $chunkZ){
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
$hills = array();
$patches = array();
$patchesSmall = array();
$base = array();
for($z = 0; $z < 16; ++$z){
for($x = 0; $x < 16; ++$x){
$i = ($z << 4) + $x;
$hills[$i] = $this->noiseHills->noise2D($x + ($chunkX << 4), $z + ($chunkZ << 4), true);
$patches[$i] = $this->noisePatches->noise2D($x + ($chunkX << 4), $z + ($chunkZ << 4), true);
$patchesSmall[$i] = $this->noisePatchesSmall->noise2D($x + ($chunkX << 4), $z + ($chunkZ << 4), true);
$base[$i] = $this->noiseBase->noise2D($x + ($chunkX << 4), $z + ($chunkZ << 4), true);
if($base[$i] < 0){
$base[$i] *= 0.5;
}
}
}
for($chunkY = 0; $chunkY < 8; ++$chunkY){
$chunk = "";
$startY = $chunkY << 4;
$endY = $startY + 16;
for($z = 0; $z < 16; ++$z){
for($x = 0; $x < 16; ++$x){
$i = ($z << 4) + $x;
$height = $this->worldHeight + $hills[$i] * 14 + $base[$i] * 7;
$height = (int) $height;
for($y = $startY; $y < $endY; ++$y){
$diff = $height - $y;
if($y <= 4 and ($y === 0 or $this->random->nextFloat() < 0.75)){
$chunk .= "\x07"; //bedrock
}elseif($diff > 2){
$chunk .= "\x01"; //stone
}elseif($diff > 0){
if($patches[$i] > 0.7){
$chunk .= "\x01"; //stone
}elseif($patches[$i] < -0.8){
$chunk .= "\x0d"; //gravel
}else{
$chunk .= "\x03"; //dirt
}
}elseif($y <= $this->waterHeight){
if(($this->waterHeight - $y) <= 1 and $diff === 0){
$chunk .= "\x0c"; //sand
}elseif($diff === 0){
if($patchesSmall[$i] > 0.3){
$chunk .= "\x0d"; //gravel
}elseif($patchesSmall[$i] < -0.45){
$chunk .= "\x0c"; //sand
}else{
$chunk .= "\x03"; //dirt
}
}else{
$chunk .= "\x09"; //still_water
}
}elseif($diff === 0){
if($patches[$i] > 0.7){
$chunk .= "\x01"; //stone
}elseif($patches[$i] < -0.8){
$chunk .= "\x0d"; //gravel
}else{
$chunk .= "\x02"; //grass
}
}else{
$chunk .= "\x00";
}
}
$chunk .= "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
}
}
$this->level->setMiniChunk($chunkX, $chunkZ, $chunkY, $chunk);
}
}
public function populateChunk($chunkX, $chunkZ){
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
foreach($this->populators as $populator){
$this->random->setSeed(0xdeadbeef ^ ($chunkX << 8) ^ $chunkZ ^ $this->level->getSeed());
$populator->populate($this->level, $chunkX, $chunkZ, $this->random);
}
}
public function getSpawn(){
return $this->level->getSafeSpawn(new Vector3(127.5, 128, 127.5));
}
}

View File

@ -0,0 +1,104 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
/**
* Different noise generators for level generation
*/
namespace pocketmine\level\generator\noise;
abstract class Generator{
protected $perm = array();
protected $offsetX = 0;
protected $offsetY = 0;
protected $offsetZ = 0;
protected $octaves = 8;
protected $frequency;
protected $amplitude;
public static function floor($x){
return $x >= 0 ? (int) $x : (int) ($x - 1);
}
public static function fade($x){
return $x * $x * $x * ($x * ($x * 6 - 15) + 10);
}
public static function lerp($x, $y, $z){
return $y + $x * ($z - $y);
}
public static function grad($hash, $x, $y, $z){
$hash &= 15;
$u = $hash < 8 ? $x : $y;
$v = $hash < 4 ? $y : (($hash === 12 or $hash === 14) ? $x : $z);
return (($hash & 1) === 0 ? $u : -$u) + (($hash & 2) === 0 ? $v : -$v);
}
abstract public function getNoise2D($x, $z);
abstract public function getNoise3D($x, $y, $z);
public function noise2D($x, $z, $normalized = false){
$result = 0;
$amp = 1;
$freq = 1;
$max = 0;
for($i = 0; $i < $this->octaves; ++$i){
$result += $this->getNoise2D($x * $freq, $z * $freq) * $amp;
$max += $amp;
$freq *= $this->frequency;
$amp *= $this->amplitude;
}
if($normalized === true){
$result /= $max;
}
return $result;
}
public function noise3D($x, $y, $z, $normalized = false){
$result = 0;
$amp = 1;
$freq = 1;
$max = 0;
for($i = 0; $i < $this->octaves; ++$i){
$result += $this->getNoise3D($x * $freq, $y * $freq, $z * $freq) * $amp;
$max += $amp;
$freq *= $this->frequency;
$amp *= $this->amplitude;
}
if($normalized === true){
$result /= $max;
}
return $result;
}
public function setOffset($x, $y, $z){
$this->offsetX = $x;
$this->offsetY = $y;
$this->offsetZ = $z;
}
}

View File

@ -0,0 +1,104 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\noise;
use pocketmine\utils\Random;
class Perlin extends Generator{
public static $grad3 = [
[1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0],
[1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1],
[0, 1, 1], [0, -1, 1], [0, 1, -1], [0, -1, -1]
];
public function __construct(Random $random, $octaves, $frequency, $amplitude){
$this->octaves = $octaves;
$this->frequency = $frequency;
$this->amplitude = $amplitude;
$this->offsetX = $random->nextFloat() * 256;
$this->offsetY = $random->nextFloat() * 256;
$this->offsetZ = $random->nextFloat() * 256;
for($i = 0; $i < 512; ++$i){
$this->perm[$i] = 0;
}
for($i = 0; $i < 256; ++$i){
$this->perm[$i] = $random->nextRange(0, 255);
}
for($i = 0; $i < 256; ++$i){
$pos = $random->nextRange(0, 255 - $i) + $i;
$old = $this->perm[$i];
$this->perm[$i] = $this->perm[$pos];
$this->perm[$pos] = $old;
$this->perm[$i + 256] = $this->perm[$i];
}
}
public function getNoise3D($x, $y, $z){
$x += $this->offsetX;
$y += $this->offsetY;
$z += $this->offsetZ;
$floorX = (int) floor($x);
$floorY = (int) floor($y);
$floorZ = (int) floor($z);
$X = $floorX & 0xFF;
$Y = $floorY & 0xFF;
$Z = $floorZ & 0xFF;
$x -= $floorX;
$y -= $floorY;
$z -= $floorZ;
//Fade curves
$fX = self::fade($x);
$fY = self::fade($y);
$fZ = self::fade($z);
//Cube corners
$A = $this->perm[$X] + $Y;
$AA = $this->perm[$A] + $Z;
$AB = $this->perm[$A + 1] + $Z;
$B = $this->perm[$X + 1] + $Y;
$BA = $this->perm[$B] + $Z;
$BB = $this->perm[$B + 1] + $Z;
return self::lerp($fZ, self::lerp($fY, self::lerp($fX, self::grad($this->perm[$AA], $x, $y, $z),
self::grad($this->perm[$BA], $x - 1, $y, $z)),
self::lerp($fX, self::grad($this->perm[$AB], $x, $y - 1, $z),
self::grad($this->perm[$BB], $x - 1, $y - 1, $z))),
self::lerp($fY, self::lerp($fX, self::grad($this->perm[$AA + 1], $x, $y, $z - 1),
self::grad($this->perm[$BA + 1], $x - 1, $y, $z - 1)),
self::lerp($fX, self::grad($this->perm[$AB + 1], $x, $y - 1, $z - 1),
self::grad($this->perm[$BB + 1], $x - 1, $y - 1, $z - 1))));
}
public function getNoise2D($x, $y){
return $this->getNoise3D($x, $y, 0);
}
}

View File

@ -0,0 +1,461 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\noise;
use pocketmine\utils\Random;
/**
* Generates simplex-based noise.
* <p>
* This is a modified version of the freely published version in the paper by
* Stefan Gustavson at
* <a href="http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf">
* http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf</a>
*/
class Simplex extends Perlin{
protected static $SQRT_3;
protected static $SQRT_5;
protected static $F2;
protected static $G2;
protected static $G22;
protected static $F3;
protected static $G3;
protected static $F4;
protected static $G4;
protected static $G42;
protected static $G43;
protected static $G44;
protected static $grad4 = [[0, 1, 1, 1], [0, 1, 1, -1], [0, 1, -1, 1], [0, 1, -1, -1],
[0, -1, 1, 1], [0, -1, 1, -1], [0, -1, -1, 1], [0, -1, -1, -1],
[1, 0, 1, 1], [1, 0, 1, -1], [1, 0, -1, 1], [1, 0, -1, -1],
[-1, 0, 1, 1], [-1, 0, 1, -1], [-1, 0, -1, 1], [-1, 0, -1, -1],
[1, 1, 0, 1], [1, 1, 0, -1], [1, -1, 0, 1], [1, -1, 0, -1],
[-1, 1, 0, 1], [-1, 1, 0, -1], [-1, -1, 0, 1], [-1, -1, 0, -1],
[1, 1, 1, 0], [1, 1, -1, 0], [1, -1, 1, 0], [1, -1, -1, 0],
[-1, 1, 1, 0], [-1, 1, -1, 0], [-1, -1, 1, 0], [-1, -1, -1, 0]];
protected static $simplex = [
[0, 1, 2, 3], [0, 1, 3, 2], [0, 0, 0, 0], [0, 2, 3, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 2, 3, 0],
[0, 2, 1, 3], [0, 0, 0, 0], [0, 3, 1, 2], [0, 3, 2, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [1, 3, 2, 0],
[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
[1, 2, 0, 3], [0, 0, 0, 0], [1, 3, 0, 2], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [2, 3, 0, 1], [2, 3, 1, 0],
[1, 0, 2, 3], [1, 0, 3, 2], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [2, 0, 3, 1], [0, 0, 0, 0], [2, 1, 3, 0],
[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0],
[2, 0, 1, 3], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3, 0, 1, 2], [3, 0, 2, 1], [0, 0, 0, 0], [3, 1, 2, 0],
[2, 1, 0, 3], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [3, 1, 0, 2], [0, 0, 0, 0], [3, 2, 0, 1], [3, 2, 1, 0]];
protected $offsetW;
public function __construct(Random $random, $octaves, $frequency, $amplitude){
parent::__construct($random, $octaves, $frequency, $amplitude);
$this->offsetW = $random->nextFloat() * 256;
self::$SQRT_3 = sqrt(3);
self::$SQRT_5 = sqrt(5);
self::$F2 = 0.5 * (self::$SQRT_3 - 1);
self::$G2 = (3 - self::$SQRT_3) / 6;
self::$G22 = self::$G2 * 2.0 - 1;
self::$F3 = 1.0 / 3.0;
self::$G3 = 1.0 / 6.0;
self::$F4 = (self::$SQRT_5 - 1.0) / 4.0;
self::$G4 = (5.0 - self::$SQRT_5) / 20.0;
self::$G42 = self::$G4 * 2.0;
self::$G43 = self::$G4 * 3.0;
self::$G44 = self::$G4 * 4.0 - 1.0;
}
protected static function dot2D($g, $x, $y){
return $g[0] * $x + $g[1] * $y;
}
protected static function dot3D($g, $x, $y, $z){
return $g[0] * $x + $g[1] * $y + $g[2] * $z;
}
protected static function dot4D($g, $x, $y, $z, $w){
return $g[0] * $x + $g[1] * $y + $g[2] * $z + $g[3] * $w;
}
public function getNoise3D($x, $y, $z){
$x += $this->offsetX;
$y += $this->offsetY;
$z += $this->offsetZ;
// Skew the input space to determine which simplex cell we're in
$s = ($x + $y + $z) * self::$F3; // Very nice and simple skew factor for 3D
$i = (int) floor($x + $s);
$j = (int) floor($y + $s);
$k = (int) floor($z + $s);
$t = ($i + $j + $k) * self::$G3;
$X0 = $i - $t; // Unskew the cell origin back to (x,y,z) space
$Y0 = $j - $t;
$Z0 = $k - $t;
$x0 = $x - $X0; // The x,y,z distances from the cell origin
$y0 = $y - $Y0;
$z0 = $z - $Z0;
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
// Determine which simplex we are in.
if($x0 >= $y0){
if($y0 >= $z0){
$i1 = 1;
$j1 = 0;
$k1 = 0;
$i2 = 1;
$j2 = 1;
$k2 = 0;
} // X Y Z order
elseif($x0 >= $z0){
$i1 = 1;
$j1 = 0;
$k1 = 0;
$i2 = 1;
$j2 = 0;
$k2 = 1;
} // X Z Y order
else{
$i1 = 0;
$j1 = 0;
$k1 = 1;
$i2 = 1;
$j2 = 0;
$k2 = 1;
}
// Z X Y order
}else{ // x0<y0
if($y0 < $z0){
$i1 = 0;
$j1 = 0;
$k1 = 1;
$i2 = 0;
$j2 = 1;
$k2 = 1;
} // Z Y X order
elseif($x0 < $z0){
$i1 = 0;
$j1 = 1;
$k1 = 0;
$i2 = 0;
$j2 = 1;
$k2 = 1;
} // Y Z X order
else{
$i1 = 0;
$j1 = 1;
$k1 = 0;
$i2 = 1;
$j2 = 1;
$k2 = 0;
}
// Y X Z order
}
// A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
// a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
// a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
// c = 1/6.
$x1 = $x0 - $i1 + self::$G3; // Offsets for second corner in (x,y,z) coords
$y1 = $y0 - $j1 + self::$G3;
$z1 = $z0 - $k1 + self::$G3;
$x2 = $x0 - $i2 + 2.0 * self::$G3; // Offsets for third corner in (x,y,z) coords
$y2 = $y0 - $j2 + 2.0 * self::$G3;
$z2 = $z0 - $k2 + 2.0 * self::$G3;
$x3 = $x0 - 1.0 + 3.0 * self::$G3; // Offsets for last corner in (x,y,z) coords
$y3 = $y0 - 1.0 + 3.0 * self::$G3;
$z3 = $z0 - 1.0 + 3.0 * self::$G3;
// Work out the hashed gradient indices of the four simplex corners
$ii = $i & 255;
$jj = $j & 255;
$kk = $k & 255;
$gi0 = $this->perm[$ii + $this->perm[$jj + $this->perm[$kk]]] % 12;
$gi1 = $this->perm[$ii + $i1 + $this->perm[$jj + $j1 + $this->perm[$kk + $k1]]] % 12;
$gi2 = $this->perm[$ii + $i2 + $this->perm[$jj + $j2 + $this->perm[$kk + $k2]]] % 12;
$gi3 = $this->perm[$ii + 1 + $this->perm[$jj + 1 + $this->perm[$kk + 1]]] % 12;
// Calculate the contribution from the four corners
$t0 = 0.6 - $x0 * $x0 - $y0 * $y0 - $z0 * $z0;
if($t0 < 0){
$n0 = 0.0;
}else{
$t0 *= $t0;
$n0 = $t0 * $t0 * self::dot3D(self::$grad3[$gi0], $x0, $y0, $z0);
}
$t1 = 0.6 - $x1 * $x1 - $y1 * $y1 - $z1 * $z1;
if($t1 < 0){
$n1 = 0.0;
}else{
$t1 *= $t1;
$n1 = $t1 * $t1 * self::dot3D(self::$grad3[$gi1], $x1, $y1, $z1);
}
$t2 = 0.6 - $x2 * $x2 - $y2 * $y2 - $z2 * $z2;
if($t2 < 0){
$n2 = 0.0;
}else{
$t2 *= $t2;
$n2 = $t2 * $t2 * self::dot3D(self::$grad3[$gi2], $x2, $y2, $z2);
}
$t3 = 0.6 - $x3 * $x3 - $y3 * $y3 - $z3 * $z3;
if($t3 < 0){
$n3 = 0.0;
}else{
$t3 *= $t3;
$n3 = $t3 * $t3 * self::dot3D(self::$grad3[$gi3], $x3, $y3, $z3);
}
// Add contributions from each corner to get the noise value.
// The result is scaled to stay just inside [-1,1]
return 32.0 * ($n0 + $n1 + $n2 + $n3);
}
public function getNoise2D($x, $y){
$x += $this->offsetX;
$y += $this->offsetY;
// Skew the input space to determine which simplex cell we're in
$s = ($x + $y) * self::$F2; // Hairy factor for 2D
$i = (int) floor($x + $s);
$j = (int) floor($y + $s);
$t = ($i + $j) * self::$G2;
$X0 = $i - $t; // Unskew the cell origin back to (x,y) space
$Y0 = $j - $t;
$x0 = $x - $X0; // The x,y distances from the cell origin
$y0 = $y - $Y0;
// For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in.
if($x0 > $y0){
$i1 = 1;
$j1 = 0;
} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
else{
$i1 = 0;
$j1 = 1;
}
// upper triangle, YX order: (0,0)->(0,1)->(1,1)
// A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
// a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
// c = (3-sqrt(3))/6
$x1 = $x0 - $i1 + self::$G2; // Offsets for middle corner in (x,y) unskewed coords
$y1 = $y0 - $j1 + self::$G2;
$x2 = $x0 + self::$G22; // Offsets for last corner in (x,y) unskewed coords
$y2 = $y0 + self::$G22;
// Work out the hashed gradient indices of the three simplex corners
$ii = $i & 255;
$jj = $j & 255;
$gi0 = $this->perm[$ii + $this->perm[$jj]] % 12;
$gi1 = $this->perm[$ii + $i1 + $this->perm[$jj + $j1]] % 12;
$gi2 = $this->perm[$ii + 1 + $this->perm[$jj + 1]] % 12;
// Calculate the contribution from the three corners
$t0 = 0.5 - $x0 * $x0 - $y0 * $y0;
if($t0 < 0){
$n0 = 0.0;
}else{
$t0 *= $t0;
$n0 = $t0 * $t0 * self::dot2D(self::$grad3[$gi0], $x0, $y0); // (x,y) of grad3 used for 2D gradient
}
$t1 = 0.5 - $x1 * $x1 - $y1 * $y1;
if($t1 < 0){
$n1 = 0.0;
}else{
$t1 *= $t1;
$n1 = $t1 * $t1 * self::dot2D(self::$grad3[$gi1], $x1, $y1);
}
$t2 = 0.5 - $x2 * $x2 - $y2 * $y2;
if($t2 < 0){
$n2 = 0.0;
}else{
$t2 *= $t2;
$n2 = $t2 * $t2 * self::dot2D(self::$grad3[$gi2], $x2, $y2);
}
// Add contributions from each corner to get the noise value.
// The result is scaled to return values in the interval [-1,1].
return 70.0 * ($n0 + $n1 + $n2);
}
/**
* Computes and returns the 4D simplex noise for the given coordinates in
* 4D space
*
* @param float $x X coordinate
* @param float $y Y coordinate
* @param float $z Z coordinate
* @param float $w W coordinate
*
* @return float Noise at given location, from range -1 to 1
*/
/*public function getNoise4D($x, $y, $z, $w){
x += offsetX;
y += offsetY;
z += offsetZ;
w += offsetW;
n0, n1, n2, n3, n4; // Noise contributions from the five corners
// Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
s = (x + y + z + w) * self::$F4; // Factor for 4D skewing
i = floor(x + s);
j = floor(y + s);
k = floor(z + s);
l = floor(w + s);
t = (i + j + k + l) * self::$G4; // Factor for 4D unskewing
X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
Y0 = j - t;
Z0 = k - t;
W0 = l - t;
x0 = x - X0; // The x,y,z,w distances from the cell origin
y0 = y - Y0;
z0 = z - Z0;
w0 = w - W0;
// For the 4D case, the simplex is a 4D shape I won't even try to describe.
// To find out which of the 24 possible simplices we're in, we need to
// determine the magnitude ordering of x0, y0, z0 and w0.
// The method below is a good way of finding the ordering of x,y,z,w and
// then find the correct traversal order for the simplex were in.
// First, six pair-wise comparisons are performed between each possible pair
// of the four coordinates, and the results are used to add up binary bits
// for an integer index.
c1 = (x0 > y0) ? 32 : 0;
c2 = (x0 > z0) ? 16 : 0;
c3 = (y0 > z0) ? 8 : 0;
c4 = (x0 > w0) ? 4 : 0;
c5 = (y0 > w0) ? 2 : 0;
c6 = (z0 > w0) ? 1 : 0;
c = c1 + c2 + c3 + c4 + c5 + c6;
i1, j1, k1, l1; // The integer offsets for the second simplex corner
i2, j2, k2, l2; // The integer offsets for the third simplex corner
i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
// simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
// Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
// impossible. Only the 24 indices which have non-zero entries make any sense.
// We use a thresholding to set the coordinates in turn from the largest magnitude.
// The number 3 in the "simplex" array is at the position of the largest coordinate.
i1 = simplex[c][0] >= 3 ? 1 : 0;
j1 = simplex[c][1] >= 3 ? 1 : 0;
k1 = simplex[c][2] >= 3 ? 1 : 0;
l1 = simplex[c][3] >= 3 ? 1 : 0;
// The number 2 in the "simplex" array is at the second largest coordinate.
i2 = simplex[c][0] >= 2 ? 1 : 0;
j2 = simplex[c][1] >= 2 ? 1 : 0;
k2 = simplex[c][2] >= 2 ? 1 : 0;
l2 = simplex[c][3] >= 2 ? 1 : 0;
// The number 1 in the "simplex" array is at the second smallest coordinate.
i3 = simplex[c][0] >= 1 ? 1 : 0;
j3 = simplex[c][1] >= 1 ? 1 : 0;
k3 = simplex[c][2] >= 1 ? 1 : 0;
l3 = simplex[c][3] >= 1 ? 1 : 0;
// The fifth corner has all coordinate offsets = 1, so no need to look that up.
x1 = x0 - i1 + self::$G4; // Offsets for second corner in (x,y,z,w) coords
y1 = y0 - j1 + self::$G4;
z1 = z0 - k1 + self::$G4;
w1 = w0 - l1 + self::$G4;
x2 = x0 - i2 + self::$G42; // Offsets for third corner in (x,y,z,w) coords
y2 = y0 - j2 + self::$G42;
z2 = z0 - k2 + self::$G42;
w2 = w0 - l2 + self::$G42;
x3 = x0 - i3 + self::$G43; // Offsets for fourth corner in (x,y,z,w) coords
y3 = y0 - j3 + self::$G43;
z3 = z0 - k3 + self::$G43;
w3 = w0 - l3 + self::$G43;
x4 = x0 + self::$G44; // Offsets for last corner in (x,y,z,w) coords
y4 = y0 + self::$G44;
z4 = z0 + self::$G44;
w4 = w0 + self::$G44;
// Work out the hashed gradient indices of the five simplex corners
ii = i & 255;
jj = j & 255;
kk = k & 255;
ll = l & 255;
gi0 = $this->perm[ii + $this->perm[jj + $this->perm[kk + $this->perm[ll]]]] % 32;
gi1 = $this->perm[ii + i1 + $this->perm[jj + j1 + $this->perm[kk + k1 + $this->perm[ll + l1]]]] % 32;
gi2 = $this->perm[ii + i2 + $this->perm[jj + j2 + $this->perm[kk + k2 + $this->perm[ll + l2]]]] % 32;
gi3 = $this->perm[ii + i3 + $this->perm[jj + j3 + $this->perm[kk + k3 + $this->perm[ll + l3]]]] % 32;
gi4 = $this->perm[ii + 1 + $this->perm[jj + 1 + $this->perm[kk + 1 + $this->perm[ll + 1]]]] % 32;
// Calculate the contribution from the five corners
t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
if(t0 < 0){
n0 = 0.0;
}else{
t0 *= t0;
n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0);
}
t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
if(t1 < 0){
n1 = 0.0;
}else{
t1 *= t1;
n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1);
}
t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
if(t2 < 0){
n2 = 0.0;
}else{
t2 *= t2;
n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2);
}
t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
if(t3 < 0){
n3 = 0.0;
}else{
t3 *= t3;
n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3);
}
t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
if(t4 < 0){
n4 = 0.0;
}else{
t4 *= t4;
n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4);
}
// Sum up and scale the result to cover the range [-1,1]
return 27.0 * (n0 + n1 + n2 + n3 + n4);
}*/
}

View File

@ -0,0 +1,85 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
class BigTree extends Tree{
private $trunkHeightMultiplier = 0.618;
private $trunkHeight;
private $leafAmount = 1;
private $leafDistanceLimit = 5;
private $widthScale = 1;
private $branchSlope = 0.381;
private $totalHeight = 6;
private $leavesHeight = 3;
protected $radiusIncrease = 0;
private $addLeavesVines = false;
private $addLogVines = false;
private $addCocoaPlants = false;
public function canPlaceObject(Level $level, Vector3 $pos){
return false;
}
public function placeObject(Level $level, Vector3 $pos, $type){
$this->trunkHeight = (int) ($this->totalHeight * $this->trunkHeightMultiplier);
$leaves = $this->getLeafGroupPoints($level, $pos);
foreach($leaves as $leafGroup){
$groupX = $leafGroup->getBlockX();
$groupY = $leafGroup->getBlockY();
$groupZ = $leafGroup->getBlockZ();
for($yy = $groupY; $yy < $groupY + $this->leafDistanceLimit; ++$yy){
$this->generateGroupLayer($level, $groupX, $yy, $groupZ, $this->getLeafGroupLayerSize($yy - $groupY));
}
}
/*final BlockIterator trunk = new BlockIterator(new Point(w, x, y - 1, z), new Point(w, x, y + trunkHeight, z));
while (trunk.hasNext()) {
trunk.next().setMaterial(VanillaMaterials.LOG, logMetadata);
}
generateBranches(w, x, y, z, leaves);
$level->setBlock($x, $pos->y - 1, $z, 3, 0);
$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);
$xzRadius = (int) (($this->radiusIncrease + 1) - $yRadius / 2);
for($xx = -$xzRadius; $xx < ($xzRadius + 1); ++$xx){
for($zz = -$xzRadius; $zz < ($xzRadius + 1); ++$zz){
if((abs($xx) != $xzRadius or abs($zz) != $xzRadius) and $yRadius != 0){
$level->setBlock($pos->x + $xx, $pos->y + $yy, $pos->z + $zz, 18, $type);
}
}
}
}
for($yy = 0; $yy < ($this->totalHeight - 1); ++$yy){
$level->setBlock($x, $pos->y + $yy, $z, 17, $type);
}
*/
}
}

View File

@ -0,0 +1,30 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
/**
* All the different object classes used in populators
*/
namespace pocketmine\level\generator\object;
abstract class Object{
}

View File

@ -0,0 +1,94 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\math\VectorMath;
use pocketmine\utils\Random;
class Ore{
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, $x, $y, $z){
return ($level->level->getBlockID($x, $y, $z) !== 0);
}
public function placeObject(Level $level, Vector3 $pos){
$clusterSize = (int) $this->type->clusterSize;
$angle = $this->random->nextFloat() * M_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 * (M_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 = ($x + 0.5 - $seedX) / $size;
$sizeX *= $sizeX;
if($sizeX < 1){
for($y = $startY; $y <= $endY; ++$y){
$sizeY = ($y + 0.5 - $seedY) / $size;
$sizeY *= $sizeY;
if($y > 0 and ($sizeX + $sizeY) < 1){
for($z = $startZ; $z <= $endZ; ++$z){
$sizeZ = ($z + 0.5 - $seedZ) / $size;
$sizeZ *= $sizeZ;
if(($sizeX + $sizeY + $sizeZ) < 1 and $level->level->getBlockID($x, $y, $z) === 1){
$level->setBlockRaw(new Vector3($x, $y, $z), $this->type->material);
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,36 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\block\Block;
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;
}
}

View File

@ -0,0 +1,97 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\block\Dirt;
use pocketmine\block\Leaves;
use pocketmine\block\Wood;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class PineTree extends Tree{
var $type = 1;
private $totalHeight = 8;
private $leavesSizeY = -1;
private $leavesAbsoluteMaxRadius = -1;
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){
$checkRadius = $this->leavesAbsoluteMaxRadius;
}
for($xx = -$checkRadius; $xx < ($checkRadius + 1); ++$xx){
for($zz = -$checkRadius; $zz < ($checkRadius + 1); ++$zz){
if(!isset($this->overridable[$level->level->getBlockID($pos->x + $xx, $pos->y + $yy, $pos->z + $zz)])){
return false;
}
}
}
}
return true;
}
private function findRandomLeavesSize(Random $random){
$this->totalHeight += $random->nextRange(-1, 2);
$this->leavesSizeY = 1 + $random->nextRange(0, 2);
$this->leavesAbsoluteMaxRadius = 2 + $random->nextRange(0, 1);
}
public function placeObject(Level $level, Vector3 $pos, Random $random){
if($this->leavesSizeY === -1 or $this->leavesAbsoluteMaxRadius === -1){
$this->findRandomLeavesSize($random);
}
$level->setBlockRaw(new Vector3($pos->x, $pos->y - 1, $pos->z), new Dirt());
$leavesRadius = 0;
$leavesMaxRadius = 1;
$leavesBottomY = $this->totalHeight - $this->leavesSizeY;
$firstMaxedRadius = false;
for($leavesY = 0; $leavesY <= $leavesBottomY; ++$leavesY){
$yy = $this->totalHeight - $leavesY;
for($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx){
for($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz){
if(abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0){
$level->setBlockRaw(new Vector3($pos->x + $xx, $pos->y + $yy, $pos->z + $zz), new Leaves($this->type));
}
}
}
if($leavesRadius >= $leavesMaxRadius){
$leavesRadius = $firstMaxedRadius ? 1 : 0;
$firstMaxedRadius = true;
if(++$leavesMaxRadius > $this->leavesAbsoluteMaxRadius){
$leavesMaxRadius = $this->leavesAbsoluteMaxRadius;
}
}else{
++$leavesRadius;
}
}
$trunkHeightReducer = $random->nextRange(0, 3);
for($yy = 0; $yy < ($this->totalHeight - $trunkHeightReducer); ++$yy){
$level->setBlockRaw(new Vector3($pos->x, $pos->y + $yy, $pos->z), new Wood($this->type));
}
}
}

View File

@ -0,0 +1,44 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\block\Block;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class Pond{
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){
}
}

View File

@ -0,0 +1,104 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\block\Dirt;
use pocketmine\block\Leaves;
use pocketmine\block\Wood;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class SmallTree extends Tree{
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 $addLeavesVines = false;
private $addLogVines = false;
private $addCocoaPlants = false;
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){
++$radiusToCheck;
}
for($xx = -$radiusToCheck; $xx < ($radiusToCheck + 1); ++$xx){
for($zz = -$radiusToCheck; $zz < ($radiusToCheck + 1); ++$zz){
if(!isset($this->overridable[$level->level->getBlockID($pos->x + $xx, $pos->y + $yy, $pos->z + $zz)])){
return false;
}
}
}
}
return true;
}
public function placeObject(Level $level, Vector3 $pos, Random $random){
// The base dirt block
$dirtpos = new Vector3($pos->x, $pos->y - 1, $pos->z);
$level->setBlockRaw($dirtpos, new Dirt());
// Adjust the tree trunk's height randomly
// plot [-14:11] int( x / 8 ) + 5
// - 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 = $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 = $random->nextRange($this->trunkHeight, 10) / 20; // (TODO: seed may apply)
// Now build the tree (from the top down)
$leaflevel = 0;
for($yy = ($this->trunkHeight + 1); $yy >= 0; --$yy){
if($leaflevel < self::$leavesHeight){
// The size is a slight variation on the trunkheight
$radius = self::$leafRadii[$leaflevel] + $leafPre;
$bRadius = 3;
for($xx = -$bRadius; $xx <= $bRadius; ++$xx){
for($zz = -$bRadius; $zz <= $bRadius; ++$zz){
if(sqrt(($xx * $xx) + ($zz * $zz)) <= $radius){
$leafpos = new Vector3($pos->x + $xx,
$pos->y + $yy,
$pos->z + $zz);
$level->setBlockRaw($leafpos, new Leaves($this->type));
}
}
}
$leaflevel++;
}
// Place the trunk last
if($leaflevel > 1){
$trunkpos = new Vector3($pos->x, $pos->y + $yy, $pos->z);
$level->setBlockRaw($trunkpos, new Wood($this->type));
}
}
}
}

View File

@ -0,0 +1,88 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\block\Dirt;
use pocketmine\block\Leaves;
use pocketmine\block\Wood;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class SpruceTree extends Tree{
var $type = 1;
private $totalHeight = 8;
private $leavesBottomY = -1;
private $leavesMaxRadius = -1;
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){
$checkRadius = $this->leavesMaxRadius;
}
for($xx = -$checkRadius; $xx < ($checkRadius + 1); ++$xx){
for($zz = -$checkRadius; $zz < ($checkRadius + 1); ++$zz){
if(!isset($this->overridable[$level->level->getBlockID($pos->x + $xx, $pos->y + $yy, $pos->z + $zz)])){
return false;
}
}
}
}
return true;
}
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, Random $random){
if($this->leavesBottomY === -1 or $this->leavesMaxRadius === -1){
$this->findRandomLeavesSize($random);
}
$level->setBlockRaw(new Vector3($pos->x, $pos->y - 1, $pos->z), new Dirt());
$leavesRadius = 0;
for($yy = $this->totalHeight; $yy >= $this->leavesBottomY; --$yy){
for($xx = -$leavesRadius; $xx <= $leavesRadius; ++$xx){
for($zz = -$leavesRadius; $zz <= $leavesRadius; ++$zz){
if(abs($xx) != $leavesRadius or abs($zz) != $leavesRadius or $leavesRadius <= 0){
$level->setBlockRaw(new Vector3($pos->x + $xx, $pos->y + $yy, $pos->z + $zz), new Leaves($this->type));
}
}
}
if($leavesRadius > 0 and $yy === ($pos->y + $this->leavesBottomY + 1)){
--$leavesRadius;
}elseif($leavesRadius < $this->leavesMaxRadius){
++$leavesRadius;
}
}
for($yy = 0; $yy < ($this->totalHeight - 1); ++$yy){
$level->setBlockRaw(new Vector3($pos->x, $pos->y + $yy, $pos->z), new Wood($this->type));
}
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\block\Block;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class TallGrass{
public static function growGrass(Level $level, Vector3 $pos, Random $random, $count = 15, $radius = 10){
$arr = array(
Block::get(Block::DANDELION, 0),
Block::get(Block::CYAN_FLOWER, 0),
Block::get(Block::TALL_GRASS, 1),
Block::get(Block::TALL_GRASS, 1),
Block::get(Block::TALL_GRASS, 1),
Block::get(Block::TALL_GRASS, 1)
);
$arrC = count($arr) - 1;
for($c = 0; $c < $count; ++$c){
$x = $random->nextRange($pos->x - $radius, $pos->x + $radius);
$z = $random->nextRange($pos->z - $radius, $pos->z + $radius);
if($level->level->getBlockID($x, $pos->y + 1, $z) === Block::AIR and $level->level->getBlockID($x, $pos->y, $z) === Block::GRASS){
$t = $arr[$random->nextRange(0, $arrC)];
$level->setBlockRaw(new Vector3($x, $pos->y + 1, $z), $t);
}
}
}
}

View File

@ -0,0 +1,69 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\object;
use pocketmine\block\Sapling;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class Tree{
public $overridable = array(
0 => true,
2 => true,
3 => true,
6 => true,
17 => true,
18 => true,
);
public static function growTree(Level $level, Vector3 $pos, Random $random, $type = 0){
switch($type & 0x03){
case Sapling::SPRUCE:
if($random->nextRange(0, 1) === 1){
$tree = new SpruceTree();
}else{
$tree = new PineTree();
}
break;
case Sapling::BIRCH:
$tree = new SmallTree();
$tree->type = Sapling::BIRCH;
break;
case Sapling::JUNGLE:
$tree = new SmallTree();
$tree->type = Sapling::JUNGLE;
break;
case Sapling::OAK:
default:
/*if($random->nextRange(0, 9) === 0){
$tree = new BigTree();
}else{*/
$tree = new SmallTree();
//}
break;
}
if($tree->canPlaceObject($level, $pos, $random)){
$tree->placeObject($level, $pos, $random);
}
}
}

View File

@ -0,0 +1,40 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\populator;
use pocketmine\level\Level;
use pocketmine\utils\Random;
class Mineshaft 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, self::$ODD) === 0){
//$mineshaft = new Mineshaft($random);
}
}
}

View File

@ -0,0 +1,49 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\populator;
use pocketmine\level\generator\object\Ore as ObjectOre;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class Ore extends Populator{
private $oreTypes = array();
public function populate(Level $level, $chunkX, $chunkZ, Random $random){
foreach($this->oreTypes as $type){
$ore = new ObjectOre($random, $type);
for($i = 0; $i < $ore->type->clusterCount; ++$i){
$x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15);
$y = $random->nextRange($ore->type->minHeight, $ore->type->maxHeight);
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
if($ore->canPlaceObject($level, $x, $y, $z)){
$ore->placeObject($level, new Vector3($x, $y, $z));
}
}
}
}
public function setOreTypes(array $types){
$this->oreTypes = $types;
}
}

View File

@ -0,0 +1,59 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\populator;
use pocketmine\block\Water;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class Pond 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 \pocketmine\level\generator\object\Pond($random, new Water());
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;
}
}

View File

@ -0,0 +1,32 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
/**
* All the Object populator classes
*/
namespace pocketmine\level\generator\populator;
use pocketmine\level\Level;
use pocketmine\utils\Random;
abstract class Populator{
public abstract function populate(Level $level, $chunkX, $chunkZ, Random $random);
}

View File

@ -0,0 +1,80 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\populator;
use pocketmine\block\Block;
use pocketmine\block\TallGrass as BlockTallGrass;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class TallGrass extends Populator{
/** @var Level */
private $level;
private $randomAmount;
private $baseAmount;
public function setRandomAmount($amount){
$this->randomAmount = $amount;
}
public function setBaseAmount($amount){
$this->baseAmount = $amount;
}
public function populate(Level $level, $chunkX, $chunkZ, Random $random){
$this->level = $level;
$amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount;
for($i = 0; $i < $amount; ++$i){
$x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15);
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
for($size = 30; $size > 0; --$size){
$xx = $x - 7 + $random->nextRange(0, 15);
$zz = $z - 7 + $random->nextRange(0, 15);
$yy = $this->getHighestWorkableBlock($xx, $zz);
$vector = new Vector3($xx, $yy, $zz);
if($yy !== -1 and $this->canTallGrassStay($this->level->getBlockRaw($vector))){
$this->level->setBlockRaw($vector, new BlockTallGrass(1));
}
}
}
}
private function canTallGrassStay(Block $block){
return $block->getID() === Block::AIR and $block->getSide(0)->getID() === Block::GRASS;
}
private function getHighestWorkableBlock($x, $z){
for($y = 128; $y > 0; --$y){
$b = $this->level->getBlockRaw(new Vector3($x, $y, $z));
if($b->getID() === Block::AIR or $b->getID() === Block::LEAVES){
if(--$y <= 0){
return -1;
}
}else{
break;
}
}
return ++$y;
}
}

View File

@ -0,0 +1,77 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* 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.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\level\generator\populator;
use pocketmine\block\Block;
use pocketmine\block\Sapling;
use pocketmine\level\generator\object\Tree as ObjectTree;
use pocketmine\level\Level;
use pocketmine\math\Vector3 as Vector3;
use pocketmine\utils\Random;
class Tree extends Populator{
private $level;
private $randomAmount;
private $baseAmount;
public function setRandomAmount($amount){
$this->randomAmount = $amount;
}
public function setBaseAmount($amount){
$this->baseAmount = $amount;
}
public function populate(Level $level, $chunkX, $chunkZ, Random $random){
$this->level = $level;
$amount = $random->nextRange(0, $this->randomAmount + 1) + $this->baseAmount;
for($i = 0; $i < $amount; ++$i){
$x = $random->nextRange($chunkX << 4, ($chunkX << 4) + 15);
$z = $random->nextRange($chunkZ << 4, ($chunkZ << 4) + 15);
$y = $this->getHighestWorkableBlock($x, $z);
if($y === -1){
continue;
}
if($random->nextFloat() > 0.75){
$meta = Sapling::BIRCH;
}else{
$meta = Sapling::OAK;
}
ObjectTree::growTree($this->level, new Vector3($x, $y, $z), $random, $meta);
}
}
private function getHighestWorkableBlock($x, $z){
for($y = 128; $y > 0; --$y){
$b = $this->level->getBlockRaw(new Vector3($x, $y, $z));
if($b->getID() !== Block::DIRT and $b->getID() !== Block::GRASS){
if(--$y <= 0){
return -1;
}
}else{
break;
}
}
return ++$y;
}
}