mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-04-06 15:33:32 +00:00
the whole game
This commit is contained in:
168
src/world/level/levelgen/CanyonFeature.cpp
Executable file
168
src/world/level/levelgen/CanyonFeature.cpp
Executable file
@@ -0,0 +1,168 @@
|
||||
#if 0
|
||||
|
||||
#include "CanyonFeature.h"
|
||||
|
||||
#include "../Level.h"
|
||||
#include "../tile/Tile.h"
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../../util/Mth.h"
|
||||
|
||||
void CanyonFeature::addTunnel( int xOffs, int zOffs, unsigned char* blocks, float xCave, float yCave, float zCave, float thickness, float yRot, float xRot, int step, int dist, float yScale )
|
||||
{
|
||||
float xMid = xOffs * 16 + 8;
|
||||
float zMid = zOffs * 16 + 8;
|
||||
|
||||
float yRota = 0;
|
||||
float xRota = 0;
|
||||
// int dist = CAVE_RADIUS * 16 - 16;
|
||||
// if (step>0) dist = step*2;
|
||||
Random random(this->random.nextLong());
|
||||
|
||||
if (dist <= 0) {
|
||||
int max = radius * 16 - 16;
|
||||
dist = max - random.nextInt(max / 4);
|
||||
}
|
||||
bool singleStep = false;
|
||||
|
||||
if (step == -1) {
|
||||
step = dist / 2;
|
||||
singleStep = true;
|
||||
}
|
||||
|
||||
int splitPoint = random.nextInt(dist / 2) + dist / 4;
|
||||
bool steep = random.nextInt(6) == 0;
|
||||
|
||||
for (; step < dist; step++) {
|
||||
float rad = 1.5 + (sin(step * Mth::PI / dist) * thickness) * 1;
|
||||
float yRad = rad * yScale;
|
||||
|
||||
float xc = cos(xRot);
|
||||
float xs = sin(xRot);
|
||||
xCave += cos(yRot) * xc;
|
||||
yCave += xs;
|
||||
zCave += sin(yRot) * xc;
|
||||
|
||||
if (steep) {
|
||||
xRot *= 0.92f;
|
||||
} else {
|
||||
xRot *= 0.7f;
|
||||
}
|
||||
xRot += xRota * 0.1f;
|
||||
yRot += yRota * 0.1f;
|
||||
|
||||
xRota *= 0.50f;
|
||||
yRota *= 0.50f;
|
||||
xRota += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2;
|
||||
yRota += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4;
|
||||
|
||||
|
||||
if (!singleStep && step == splitPoint && thickness > 1) {
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, random.nextFloat() * 0.5f + 0.5f, yRot - Mth::PI / 2, xRot / 3, step, dist, 1.0);
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, random.nextFloat() * 0.5f + 0.5f, yRot + Mth::PI / 2, xRot / 3, step, dist, 1.0);
|
||||
return;
|
||||
}
|
||||
if (!singleStep && random.nextInt(4) == 0) continue;
|
||||
|
||||
{
|
||||
float xd = xCave - xMid;
|
||||
float zd = zCave - zMid;
|
||||
float remaining = dist - step;
|
||||
float rr = (thickness + 2) + 16;
|
||||
if (xd * xd + zd * zd - (remaining * remaining) > rr * rr) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (xCave < xMid - 16 - rad * 2 || zCave < zMid - 16 - rad * 2 || xCave > xMid + 16 + rad * 2 || zCave > zMid + 16 + rad * 2) continue;
|
||||
|
||||
int x0 = floor(xCave - rad) - xOffs * 16 - 1;
|
||||
int x1 = floor(xCave + rad) - xOffs * 16 + 1;
|
||||
|
||||
int y0 = floor(yCave - yRad) - 1;
|
||||
int y1 = floor(yCave + yRad) + 1;
|
||||
|
||||
int z0 = floor(zCave - rad) - zOffs * 16 - 1;
|
||||
int z1 = floor(zCave + rad) - zOffs * 16 + 1;
|
||||
|
||||
if (x0 < 0) x0 = 0;
|
||||
if (x1 > 16) x1 = 16;
|
||||
|
||||
if (y0 < 1) y0 = 1;
|
||||
if (y1 > 120) y1 = 120;
|
||||
|
||||
if (z0 < 0) z0 = 0;
|
||||
if (z1 > 16) z1 = 16;
|
||||
|
||||
bool detectedWater = false;
|
||||
for (int xx = x0; !detectedWater && xx < x1; xx++) {
|
||||
for (int zz = z0; !detectedWater && zz < z1; zz++) {
|
||||
for (int yy = y1 + 1; !detectedWater && yy >= y0 - 1; yy--) {
|
||||
int p = (xx * 16 + zz) * 128 + yy;
|
||||
if (yy < 0 || yy >= Level::DEPTH) continue;
|
||||
if (blocks[p] == Tile::water->id || blocks[p] == Tile::calmWater->id) {
|
||||
detectedWater = true;
|
||||
}
|
||||
if (yy != y0 - 1 && xx != x0 && xx != x1 - 1 && zz != z0 && zz != z1 - 1) {
|
||||
yy = y0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (detectedWater) continue;
|
||||
|
||||
for (int xx = x0; xx < x1; xx++) {
|
||||
float xd = ((xx + xOffs * 16 + 0.5) - xCave) / rad;
|
||||
for (int zz = z0; zz < z1; zz++) {
|
||||
float zd = ((zz + zOffs * 16 + 0.5) - zCave) / rad;
|
||||
int p = (xx * 16 + zz) * 128 + y1;
|
||||
bool hasGrass = false;
|
||||
for (int yy = y1 - 1; yy >= y0; yy--) {
|
||||
float yd = (yy + 0.5 - yCave) / yRad;
|
||||
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
|
||||
int block = blocks[p];
|
||||
if (block == Tile::grass->id) hasGrass = true;
|
||||
if (block == Tile::rock->id || block == Tile::dirt->id || block == Tile::grass->id) {
|
||||
if (yy < 10) {
|
||||
blocks[p] = (unsigned char) Tile::lava->id;
|
||||
} else {
|
||||
blocks[p] = (unsigned char) 0;
|
||||
if (hasGrass && blocks[p - 1] == Tile::dirt->id) blocks[p - 1] = (unsigned char) Tile::grass->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
p--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (singleStep) break;
|
||||
}
|
||||
}
|
||||
|
||||
void CanyonFeature::addFeature( Level level, int x, int z, int xOffs, int zOffs, char* blocks )
|
||||
{
|
||||
if (random.nextInt(15) != 0) return;
|
||||
|
||||
float xCave = x * 16 + random.nextInt(16);
|
||||
float yCave = random.nextInt(random.nextInt(120) + 8);
|
||||
float zCave = z * 16 + random.nextInt(16);
|
||||
|
||||
float yRot = random.nextFloat() * Mth::PI * 2;
|
||||
float xRot = ((random.nextFloat() - 0.5f) * 2) / 8;
|
||||
float thickness = (random.nextFloat() * 2 + random.nextFloat()) + 1;
|
||||
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, thickness, yRot, xRot, 0, 0, 5.0);
|
||||
}
|
||||
|
||||
/* //private
|
||||
void addCaves(Level level, int xOffs, int zOffs, byte[] blocks) {
|
||||
int r = radius;
|
||||
|
||||
random.setSeed(level.seed);
|
||||
long xScale = random.nextLong() / 2 * 2 + 1;
|
||||
long zScale = random.nextLong() / 2 * 2 + 1;
|
||||
|
||||
for (int x = xOffs - r; x <= xOffs + r; x++) {
|
||||
for (int z = zOffs - r; z <= zOffs + r; z++) {
|
||||
random.setSeed((x * xScale + z * zScale) ^ level.seed);*/
|
||||
|
||||
#endif
|
||||
19
src/world/level/levelgen/CanyonFeature.h
Executable file
19
src/world/level/levelgen/CanyonFeature.h
Executable file
@@ -0,0 +1,19 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__CanyonFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__CanyonFeature_H__
|
||||
|
||||
#if 0
|
||||
|
||||
//package net.minecraft.world.level.levelgen;
|
||||
|
||||
#include "LargeFeature.h"
|
||||
|
||||
class CanyonFeature: public LargeFeature {
|
||||
|
||||
/*protected*/
|
||||
void addTunnel(int xOffs, int zOffs, unsigned char* blocks, float xCave, float yCave, float zCave, float thickness, float yRot, float xRot, int step, int dist, float yScale);
|
||||
/*protected*/
|
||||
void addFeature(Level level, int x, int z, int xOffs, int zOffs, char* blocks);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__CanyonFeature_H__*/
|
||||
176
src/world/level/levelgen/DungeonFeature.cpp
Executable file
176
src/world/level/levelgen/DungeonFeature.cpp
Executable file
@@ -0,0 +1,176 @@
|
||||
#if 0
|
||||
|
||||
#include "DungeonFeature.h"
|
||||
|
||||
#include "../Level.h"
|
||||
#include "../tile/Tile.h"
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../../util/Mth.h"
|
||||
|
||||
void DungeonFeature::addRoom( int xOffs, int zOffs, unsigned char* blocks, float xRoom, float yRoom, float zRoom )
|
||||
{
|
||||
addTunnel(xOffs, zOffs, blocks, xRoom, yRoom, zRoom, 1 + random.nextFloat() * 6, 0, 0, -1, -1, 0.5);
|
||||
}
|
||||
|
||||
void DungeonFeature::addTunnel( int xOffs, int zOffs, unsigned char* blocks, float xCave, float yCave, float zCave, float thickness, float yRot, float xRot, int step, int dist, float yScale )
|
||||
{
|
||||
float xMid = xOffs * 16 + 8;
|
||||
float zMid = zOffs * 16 + 8;
|
||||
|
||||
float yRota = 0;
|
||||
float xRota = 0;
|
||||
// int dist = CAVE_RADIUS * 16 - 16;
|
||||
// if (step>0) dist = step*2;
|
||||
Random random(this->random.nextLong());
|
||||
|
||||
if (dist <= 0) {
|
||||
int max = radius * 16 - 16;
|
||||
dist = max - random.nextInt(max / 4);
|
||||
}
|
||||
bool singleStep = false;
|
||||
|
||||
if (step == -1) {
|
||||
step = dist / 2;
|
||||
singleStep = true;
|
||||
}
|
||||
|
||||
|
||||
int splitPoint = random.nextInt(dist / 2) + dist / 4;
|
||||
bool steep = random.nextInt(6) == 0;
|
||||
|
||||
for (; step < dist; step++) {
|
||||
float rad = 1.5 + (sin(step * Mth::PI / dist) * thickness) * 1;
|
||||
float yRad = rad * yScale;
|
||||
|
||||
float xc = cos(xRot);
|
||||
float xs = sin(xRot);
|
||||
xCave += cos(yRot) * xc;
|
||||
yCave += xs;
|
||||
zCave += sin(yRot) * xc;
|
||||
|
||||
if (steep) {
|
||||
xRot *= 0.92f;
|
||||
} else {
|
||||
xRot *= 0.7f;
|
||||
}
|
||||
xRot += xRota * 0.1f;
|
||||
yRot += yRota * 0.1f;
|
||||
|
||||
xRota *= 0.90f;
|
||||
yRota *= 0.75f;
|
||||
xRota += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2;
|
||||
yRota += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4;
|
||||
|
||||
|
||||
if (!singleStep && step == splitPoint && thickness > 1) {
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, random.nextFloat() * 0.5f + 0.5f, yRot - Mth::PI / 2, xRot / 3, step, dist, 1.0);
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, random.nextFloat() * 0.5f + 0.5f, yRot + Mth::PI / 2, xRot / 3, step, dist, 1.0);
|
||||
return;
|
||||
}
|
||||
if (!singleStep && random.nextInt(4) == 0) continue;
|
||||
|
||||
{
|
||||
float xd = xCave - xMid;
|
||||
float zd = zCave - zMid;
|
||||
float remaining = dist - step;
|
||||
float rr = (thickness + 2) + 16;
|
||||
if (xd * xd + zd * zd - (remaining * remaining) > rr * rr) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (xCave < xMid - 16 - rad * 2 || zCave < zMid - 16 - rad * 2 || xCave > xMid + 16 + rad * 2 || zCave > zMid + 16 + rad * 2) continue;
|
||||
|
||||
int x0 = floor(xCave - rad) - xOffs * 16 - 1;
|
||||
int x1 = floor(xCave + rad) - xOffs * 16 + 1;
|
||||
|
||||
int y0 = floor(yCave - yRad) - 1;
|
||||
int y1 = floor(yCave + yRad) + 1;
|
||||
|
||||
int z0 = floor(zCave - rad) - zOffs * 16 - 1;
|
||||
int z1 = floor(zCave + rad) - zOffs * 16 + 1;
|
||||
|
||||
if (x0 < 0) x0 = 0;
|
||||
if (x1 > 16) x1 = 16;
|
||||
|
||||
if (y0 < 1) y0 = 1;
|
||||
if (y1 > 120) y1 = 120;
|
||||
|
||||
if (z0 < 0) z0 = 0;
|
||||
if (z1 > 16) z1 = 16;
|
||||
|
||||
bool detectedWater = false;
|
||||
for (int xx = x0; !detectedWater && xx < x1; xx++) {
|
||||
for (int zz = z0; !detectedWater && zz < z1; zz++) {
|
||||
for (int yy = y1 + 1; !detectedWater && yy >= y0 - 1; yy--) {
|
||||
int p = (xx * 16 + zz) * 128 + yy;
|
||||
if (yy < 0 || yy >= Level::DEPTH) continue;
|
||||
if (blocks[p] == Tile::water->id || blocks[p] == Tile::calmWater->id) {
|
||||
detectedWater = true;
|
||||
}
|
||||
if (yy != y0 - 1 && xx != x0 && xx != x1 - 1 && zz != z0 && zz != z1 - 1) {
|
||||
yy = y0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (detectedWater) continue;
|
||||
|
||||
for (int xx = x0; xx < x1; xx++) {
|
||||
float xd = ((xx + xOffs * 16 + 0.5) - xCave) / rad;
|
||||
for (int zz = z0; zz < z1; zz++) {
|
||||
float zd = ((zz + zOffs * 16 + 0.5) - zCave) / rad;
|
||||
int p = (xx * 16 + zz) * 128 + y1;
|
||||
bool hasGrass = false;
|
||||
for (int yy = y1 - 1; yy >= y0; yy--) {
|
||||
float yd = (yy + 0.5 - yCave) / yRad;
|
||||
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
|
||||
int block = blocks[p];
|
||||
if (block == Tile::grass->id) hasGrass = true;
|
||||
if (block == Tile::rock->id || block == Tile.dirt.id || block == Tile.grass.id) {
|
||||
if (yy < 10) {
|
||||
blocks[p] = (char) Tile.lava.id;
|
||||
} else {
|
||||
blocks[p] = (char) 0;
|
||||
if (hasGrass && blocks[p - 1] == Tile.dirt.id) blocks[p - 1] = (char) Tile.grass.id;
|
||||
}
|
||||
}
|
||||
}
|
||||
p--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (singleStep) break;
|
||||
}
|
||||
}
|
||||
|
||||
void DungeonFeature::addFeature( Level level, int x, int z, int xOffs, int zOffs, unsigned char* blocks )
|
||||
{
|
||||
int caves = random.nextInt(random.nextInt(random.nextInt(40) + 1) + 1);
|
||||
if (random.nextInt(15) != 0) caves = 0;
|
||||
|
||||
for (int cave = 0; cave < caves; cave++) {
|
||||
float xCave = x * 16 + random.nextInt(16);
|
||||
// float yCave = (random.nextInt(random.nextInt(120) + 8) + random.nextInt(128)) / 2;
|
||||
float yCave = random.nextInt(random.nextInt(120) + 8);
|
||||
//float yCave = random.nextInt(128);
|
||||
float zCave = z * 16 + random.nextInt(16);
|
||||
|
||||
int tunnels = 1;
|
||||
if (random.nextInt(4) == 0) {
|
||||
addRoom(xOffs, zOffs, blocks, xCave, yCave, zCave);
|
||||
tunnels += random.nextInt(4);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tunnels; i++) {
|
||||
|
||||
float yRot = random.nextFloat() * Mth::PI * 2;
|
||||
float xRot = ((random.nextFloat() - 0.5f) * 2) / 8;
|
||||
float thickness = random.nextFloat() * 2 + random.nextFloat();
|
||||
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, thickness, yRot, xRot, 0, 0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
23
src/world/level/levelgen/DungeonFeature.h
Executable file
23
src/world/level/levelgen/DungeonFeature.h
Executable file
@@ -0,0 +1,23 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__DungeonFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__DungeonFeature_H__
|
||||
|
||||
#if 0
|
||||
|
||||
//package net.minecraft.world.level.levelgen;
|
||||
|
||||
#include "LargeFeature.h"
|
||||
|
||||
class DungeonFeature: public LargeFeature {
|
||||
|
||||
/*protected*/
|
||||
void addRoom(int xOffs, int zOffs, unsigned char* blocks, float xRoom, float yRoom, float zRoom);
|
||||
|
||||
/*protected*/
|
||||
void addTunnel(int xOffs, int zOffs, unsigned char* blocks, float xCave, float yCave, float zCave, float thickness, float yRot, float xRot, int step, int dist, float yScale);
|
||||
|
||||
/*protected*/
|
||||
void addFeature(Level level, int x, int z, int xOffs, int zOffs, unsigned char* blocks);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__DungeonFeature_H__*/
|
||||
0
src/world/level/levelgen/LargeCaveFeature.cpp
Executable file
0
src/world/level/levelgen/LargeCaveFeature.cpp
Executable file
180
src/world/level/levelgen/LargeCaveFeature.h
Executable file
180
src/world/level/levelgen/LargeCaveFeature.h
Executable file
@@ -0,0 +1,180 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__LargeCaveFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__LargeCaveFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
#include "../../../util/Mth.h"
|
||||
|
||||
#include "LargeFeature.h"
|
||||
|
||||
#include "../Level.h"
|
||||
#include "../tile/Tile.h"
|
||||
#include "../tile/GrassTile.h"
|
||||
|
||||
class LargeCaveFeature: public LargeFeature
|
||||
{
|
||||
protected:
|
||||
void addRoom(int xOffs, int zOffs, unsigned char* blocks, float xRoom, float yRoom, float zRoom) {
|
||||
addTunnel(xOffs, zOffs, blocks, xRoom, yRoom, zRoom, 1 + random.nextFloat() * 6, 0, 0, -1, -1, 0.5);
|
||||
}
|
||||
|
||||
void addTunnel(int xOffs, int zOffs, unsigned char* blocks, float xCave, float yCave, float zCave, float thickness, float yRot, float xRot, int step, int dist, float yScale) {
|
||||
float xMid = (float)(xOffs * 16 + 8);
|
||||
float zMid = (float)(zOffs * 16 + 8);
|
||||
|
||||
float yRota = 0;
|
||||
float xRota = 0;
|
||||
Random random(this->random.nextLong());
|
||||
|
||||
if (dist <= 0) {
|
||||
int max = radius * 16 - 16;
|
||||
dist = max - random.nextInt(max / 4);
|
||||
}
|
||||
bool singleStep = false;
|
||||
|
||||
if (step == -1) {
|
||||
step = dist / 2;
|
||||
singleStep = true;
|
||||
}
|
||||
|
||||
|
||||
int splitPoint = random.nextInt(dist / 2) + dist / 4;
|
||||
bool steep = random.nextInt(6) == 0;
|
||||
|
||||
for (; step < dist; step++) {
|
||||
float rad = 1.5f + (sin(step * Mth::PI / dist) * thickness) * 1;
|
||||
float yRad = rad * yScale;
|
||||
|
||||
float xc = cos(xRot);
|
||||
float xs = sin(xRot);
|
||||
xCave += cos(yRot) * xc;
|
||||
yCave += xs;
|
||||
zCave += sin(yRot) * xc;
|
||||
|
||||
if (steep) {
|
||||
xRot *= 0.92f;
|
||||
} else {
|
||||
xRot *= 0.7f;
|
||||
}
|
||||
xRot += xRota * 0.1f;
|
||||
yRot += yRota * 0.1f;
|
||||
|
||||
xRota *= 0.90f;
|
||||
yRota *= 0.75f;
|
||||
xRota += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 2;
|
||||
yRota += (random.nextFloat() - random.nextFloat()) * random.nextFloat() * 4;
|
||||
|
||||
|
||||
if (!singleStep && step == splitPoint && thickness > 1) {
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, random.nextFloat() * 0.5f + 0.5f, yRot - Mth::PI / 2, xRot / 3, step, dist, 1.0);
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, random.nextFloat() * 0.5f + 0.5f, yRot + Mth::PI / 2, xRot / 3, step, dist, 1.0);
|
||||
return;
|
||||
}
|
||||
if (!singleStep && random.nextInt(4) == 0) continue;
|
||||
|
||||
{
|
||||
float xd = xCave - xMid;
|
||||
float zd = zCave - zMid;
|
||||
float remaining = (float)(dist - step);
|
||||
float rr = (thickness + 2) + 16;
|
||||
if (xd * xd + zd * zd - (remaining * remaining) > rr * rr) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (xCave < xMid - 16 - rad * 2 || zCave < zMid - 16 - rad * 2 || xCave > xMid + 16 + rad * 2 || zCave > zMid + 16 + rad * 2) continue;
|
||||
|
||||
int x0 = (int)floor(xCave - rad) - xOffs * 16 - 1;
|
||||
int x1 = (int)floor(xCave + rad) - xOffs * 16 + 1;
|
||||
|
||||
int y0 = (int)floor(yCave - yRad) - 1;
|
||||
int y1 = (int)floor(yCave + yRad) + 1;
|
||||
|
||||
int z0 = (int)floor(zCave - rad) - zOffs * 16 - 1;
|
||||
int z1 = (int)floor(zCave + rad) - zOffs * 16 + 1;
|
||||
|
||||
if (x0 < 0) x0 = 0;
|
||||
if (x1 > 16) x1 = 16;
|
||||
|
||||
if (y0 < 1) y0 = 1;
|
||||
if (y1 > 120) y1 = 120;
|
||||
|
||||
if (z0 < 0) z0 = 0;
|
||||
if (z1 > 16) z1 = 16;
|
||||
|
||||
bool detectedWater = false;
|
||||
for (int xx = x0; !detectedWater && xx < x1; xx++) {
|
||||
for (int zz = z0; !detectedWater && zz < z1; zz++) {
|
||||
for (int yy = y1 + 1; !detectedWater && yy >= y0 - 1; yy--) {
|
||||
int p = (xx * 16 + zz) * 128 + yy;
|
||||
if (yy < 0 || yy >= Level::DEPTH) continue;
|
||||
if (blocks[p] == Tile::water->id || blocks[p] == Tile::calmWater->id) {
|
||||
detectedWater = true;
|
||||
}
|
||||
if (yy != y0 - 1 && xx != x0 && xx != x1 - 1 && zz != z0 && zz != z1 - 1) {
|
||||
yy = y0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (detectedWater) continue;
|
||||
|
||||
for (int xx = x0; xx < x1; xx++) {
|
||||
float xd = ((xx + xOffs * 16 + 0.5f) - xCave) / rad;
|
||||
for (int zz = z0; zz < z1; zz++) {
|
||||
float zd = ((zz + zOffs * 16 + 0.5f) - zCave) / rad;
|
||||
int p = (xx * 16 + zz) * 128 + y1;
|
||||
bool hasGrass = false;
|
||||
if (xd * xd + zd * zd < 1) {
|
||||
for (int yy = y1 - 1; yy >= y0; yy--) {
|
||||
float yd = (yy + 0.5f - yCave) / yRad;
|
||||
if (yd > -0.7 && xd * xd + yd * yd + zd * zd < 1) {
|
||||
int block = blocks[p];
|
||||
if (block == Tile::grass->id) hasGrass = true;
|
||||
if (block == Tile::rock->id || block == Tile::dirt->id || block == Tile::grass->id) {
|
||||
if (yy < 10) {
|
||||
blocks[p] = (unsigned char) Tile::lava->id;
|
||||
} else {
|
||||
blocks[p] = (unsigned char) 0;
|
||||
if (hasGrass && blocks[p - 1] == Tile::dirt->id) blocks[p - 1] = (unsigned char) Tile::grass->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
p--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (singleStep) break;
|
||||
}
|
||||
}
|
||||
|
||||
void addFeature(Level* level, int x, int z, int xOffs, int zOffs, unsigned char* blocks, int blocksSize) {
|
||||
int caves = random.nextInt(random.nextInt(random.nextInt(40) + 1) + 1);
|
||||
if (random.nextInt(15) != 0) caves = 0;
|
||||
|
||||
for (int cave = 0; cave < caves; cave++) {
|
||||
float xCave = (float)(x * 16 + random.nextInt(16));
|
||||
float yCave = (float)(random.nextInt(random.nextInt(120) + 8));
|
||||
float zCave = (float)(z * 16 + random.nextInt(16));
|
||||
|
||||
int tunnels = 1;
|
||||
if (random.nextInt(4) == 0) {
|
||||
addRoom(xOffs, zOffs, blocks, xCave, yCave, zCave);
|
||||
tunnels += random.nextInt(4);
|
||||
}
|
||||
|
||||
for (int i = 0; i < tunnels; i++) {
|
||||
|
||||
float yRot = random.nextFloat() * Mth::PI * 2;
|
||||
float xRot = ((random.nextFloat() - 0.5f) * 2) / 8;
|
||||
float thickness = random.nextFloat() * 2 + random.nextFloat();
|
||||
|
||||
addTunnel(xOffs, zOffs, blocks, xCave, yCave, zCave, thickness, yRot, xRot, 0, 0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__LargeCaveFeature_H__*/
|
||||
27
src/world/level/levelgen/LargeFeature.cpp
Executable file
27
src/world/level/levelgen/LargeFeature.cpp
Executable file
@@ -0,0 +1,27 @@
|
||||
#include "LargeFeature.h"
|
||||
#include "../Level.h"
|
||||
|
||||
LargeFeature::LargeFeature() : radius(8)
|
||||
{
|
||||
}
|
||||
|
||||
LargeFeature::~LargeFeature()
|
||||
{
|
||||
}
|
||||
|
||||
void LargeFeature::apply( ChunkSource* chunkSource, Level* level, int xOffs, int zOffs, unsigned char* blocks, int blocksSize )
|
||||
{
|
||||
int r = radius;
|
||||
|
||||
random.setSeed(level->getSeed());
|
||||
long xScale = random.nextLong() / 2 * 2 + 1;
|
||||
long zScale = random.nextLong() / 2 * 2 + 1;
|
||||
|
||||
for (int x = xOffs - r; x <= xOffs + r; x++) {
|
||||
for (int z = zOffs - r; z <= zOffs + r; z++) {
|
||||
random.setSeed((x * xScale + z * zScale) ^ level->getSeed());
|
||||
addFeature(level, x, z, xOffs, zOffs, blocks, blocksSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
src/world/level/levelgen/LargeFeature.h
Executable file
27
src/world/level/levelgen/LargeFeature.h
Executable file
@@ -0,0 +1,27 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__LargeFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__LargeFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen;
|
||||
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
class Random;
|
||||
class Level;
|
||||
class ChunkSource;
|
||||
|
||||
class LargeFeature
|
||||
{
|
||||
public:
|
||||
LargeFeature();
|
||||
virtual ~LargeFeature();
|
||||
|
||||
virtual void apply(ChunkSource* chunkSource, Level* level, int xOffs, int zOffs, unsigned char* blocks, int blocksSize);
|
||||
|
||||
protected:
|
||||
virtual void addFeature(Level* level, int x, int z, int xOffs, int zOffs, unsigned char* blocks, int blocksSize) = 0;
|
||||
|
||||
int radius;
|
||||
Random random;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__LargeFeature_H__*/
|
||||
723
src/world/level/levelgen/RandomLevelSource.cpp
Executable file
723
src/world/level/levelgen/RandomLevelSource.cpp
Executable file
@@ -0,0 +1,723 @@
|
||||
#include "RandomLevelSource.h"
|
||||
|
||||
#include "feature/FeatureInclude.h"
|
||||
#include "../Level.h"
|
||||
#include "../ChunkPos.h"
|
||||
#include "../MobSpawner.h"
|
||||
#include "../biome/Biome.h"
|
||||
#include "../biome/BiomeSource.h"
|
||||
#include "../chunk/LevelChunk.h"
|
||||
#include "../material/Material.h"
|
||||
#include "../tile/Tile.h"
|
||||
#include "../tile/HeavyTile.h"
|
||||
#include "../../../util/Random.h"
|
||||
|
||||
const float RandomLevelSource::SNOW_CUTOFF = 0.5f;
|
||||
const float RandomLevelSource::SNOW_SCALE = 0.3f;
|
||||
static const int MAX_BUFFER_SIZE = 1024;
|
||||
|
||||
RandomLevelSource::RandomLevelSource(Level* level, long seed, int version, bool spawnMobs)
|
||||
: random(seed),
|
||||
level(level),
|
||||
lperlinNoise1(&random, 16),
|
||||
lperlinNoise2(&random, 16),
|
||||
perlinNoise1(&random, 8),
|
||||
perlinNoise2(&random, 4),
|
||||
perlinNoise3(&random, 4),
|
||||
scaleNoise(&random, 10),
|
||||
depthNoise(&random, 16),
|
||||
forestNoise(&random, 8),
|
||||
spawnMobs(spawnMobs),
|
||||
pnr(NULL), ar(NULL), br(NULL), sr(NULL), dr(NULL), fi(NULL), fis(NULL)
|
||||
//biomes(NULL)
|
||||
{
|
||||
for (int i=0; i<32; ++i)
|
||||
for (int j=0; j<32; ++j)
|
||||
waterDepths[i][j] = 0;
|
||||
|
||||
buffer = new float[MAX_BUFFER_SIZE];
|
||||
|
||||
Random randomCopy = random;
|
||||
printf("random.get : %d\n", randomCopy.nextInt());
|
||||
}
|
||||
|
||||
RandomLevelSource::~RandomLevelSource() {
|
||||
|
||||
// chunks are deleted in the chunk cache instead
|
||||
//ChunkMap::iterator it = chunkMap.begin();
|
||||
//while (it != chunkMap.end()) {
|
||||
// it->second->deleteBlockData(); //@attn: we delete the block data here, for now
|
||||
// delete it->second;
|
||||
// ++it;
|
||||
//}
|
||||
|
||||
delete[] buffer;
|
||||
delete[] pnr;
|
||||
delete[] ar;
|
||||
delete[] br;
|
||||
delete[] sr;
|
||||
delete[] dr;
|
||||
delete[] fi;
|
||||
delete[] fis;
|
||||
}
|
||||
|
||||
/*public*/
|
||||
void RandomLevelSource::prepareHeights(int xOffs, int zOffs, unsigned char* blocks, /*Biome*/void* biomes, float* temperatures) {
|
||||
|
||||
int xChunks = 16 / CHUNK_WIDTH;
|
||||
int waterHeight = Level::DEPTH - 64;
|
||||
|
||||
int xSize = xChunks + 1;
|
||||
int ySize = 128 / CHUNK_HEIGHT + 1;
|
||||
int zSize = xChunks + 1;
|
||||
buffer = getHeights(buffer, xOffs * xChunks, 0, zOffs * xChunks, xSize, ySize, zSize);
|
||||
|
||||
for (int xc = 0; xc < xChunks; xc++) {
|
||||
for (int zc = 0; zc < xChunks; zc++) {
|
||||
for (int yc = 0; yc < 128 / CHUNK_HEIGHT; yc++) {
|
||||
float yStep = 1 / (float) CHUNK_HEIGHT;
|
||||
float s0 = buffer[((xc + 0) * zSize + (zc + 0)) * ySize + (yc + 0)];
|
||||
float s1 = buffer[((xc + 0) * zSize + (zc + 1)) * ySize + (yc + 0)];
|
||||
float s2 = buffer[((xc + 1) * zSize + (zc + 0)) * ySize + (yc + 0)];
|
||||
float s3 = buffer[((xc + 1) * zSize + (zc + 1)) * ySize + (yc + 0)];
|
||||
|
||||
float s0a = (buffer[((xc + 0) * zSize + (zc + 0)) * ySize + (yc + 1)] - s0) * yStep;
|
||||
float s1a = (buffer[((xc + 0) * zSize + (zc + 1)) * ySize + (yc + 1)] - s1) * yStep;
|
||||
float s2a = (buffer[((xc + 1) * zSize + (zc + 0)) * ySize + (yc + 1)] - s2) * yStep;
|
||||
float s3a = (buffer[((xc + 1) * zSize + (zc + 1)) * ySize + (yc + 1)] - s3) * yStep;
|
||||
|
||||
for (int y = 0; y < CHUNK_HEIGHT; y++) {
|
||||
float xStep = 1 / (float) CHUNK_WIDTH;
|
||||
|
||||
float _s0 = s0;
|
||||
float _s1 = s1;
|
||||
float _s0a = (s2 - s0) * xStep;
|
||||
float _s1a = (s3 - s1) * xStep;
|
||||
|
||||
for (int x = 0; x < CHUNK_WIDTH; x++) {
|
||||
int offs = (x + xc * CHUNK_WIDTH) << 11 | (0 + zc * CHUNK_WIDTH) << 7 | (yc * CHUNK_HEIGHT + y);
|
||||
int step = 1 << 7;
|
||||
float zStep = 1 / (float) CHUNK_WIDTH;
|
||||
|
||||
float val = _s0;
|
||||
float vala = (_s1 - _s0) * zStep;
|
||||
for (int z = 0; z < CHUNK_WIDTH; z++) {
|
||||
// + (zc * CHUNK_WIDTH + z)];
|
||||
float temp = temperatures[(xc * CHUNK_WIDTH + x) * 16 + (zc * CHUNK_WIDTH + z)];
|
||||
int tileId = 0;
|
||||
if (yc * CHUNK_HEIGHT + y < waterHeight) {
|
||||
if (temp < SNOW_CUTOFF && yc * CHUNK_HEIGHT + y >= waterHeight - 1) {
|
||||
tileId = Tile::ice->id;
|
||||
} else {
|
||||
tileId = Tile::calmWater->id;
|
||||
}
|
||||
}
|
||||
if (val > 0) {
|
||||
tileId = Tile::rock->id;
|
||||
} else {
|
||||
}
|
||||
|
||||
blocks[offs] = (unsigned char) tileId;
|
||||
offs += step;
|
||||
val += vala;
|
||||
}
|
||||
_s0 += _s0a;
|
||||
_s1 += _s1a;
|
||||
}
|
||||
|
||||
s0 += s0a;
|
||||
s1 += s1a;
|
||||
s2 += s2a;
|
||||
s3 += s3a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RandomLevelSource::buildSurfaces(int xOffs, int zOffs, unsigned char* blocks, Biome** biomes) {
|
||||
int waterHeight = Level::DEPTH - 64;
|
||||
|
||||
float s = 1 / 32.0f;
|
||||
perlinNoise2.getRegion(sandBuffer, (float)(xOffs * 16), (float)(zOffs * 16), 0, 16, 16, 1, s, s, 1);
|
||||
perlinNoise2.getRegion(gravelBuffer, (float)(xOffs * 16), 109.01340f, (float)(zOffs * 16), 16, 1, 16, s, 1, s);
|
||||
perlinNoise3.getRegion(depthBuffer, (float)(xOffs * 16), (float)(zOffs * 16), 0, 16, 16, 1, s * 2, s * 2, s * 2);
|
||||
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
float temp = 1; // @todo: read temp from BiomeSource
|
||||
Biome* b = biomes[x + z * 16];
|
||||
bool sand = (sandBuffer[x + z * 16] + random.nextFloat() * 0.2f) > 0;
|
||||
bool gravel = (gravelBuffer[x + z * 16] + random.nextFloat() * 0.2f) > 3;
|
||||
int runDepth = (int) (depthBuffer[x + z * 16] / 3 + 3 + random.nextFloat() * 0.25f);
|
||||
|
||||
int run = -1;
|
||||
|
||||
char top = b->topMaterial;
|
||||
char material = b->material;
|
||||
|
||||
for (int y = 127; y >= 0; y--) {
|
||||
int offs = (z * 16 + x) * 128 + y;
|
||||
|
||||
if (y <= 0 + random.nextInt(5)) {
|
||||
blocks[offs] = (char) Tile::unbreakable->id;
|
||||
} else {
|
||||
int old = blocks[offs];
|
||||
|
||||
if (old == 0) {
|
||||
run = -1;
|
||||
} else if (old == Tile::rock->id) {
|
||||
if (run == -1) {
|
||||
if (runDepth <= 0) {
|
||||
top = 0;
|
||||
material = (char) Tile::rock->id;
|
||||
} else if (y >= waterHeight - 4 && y <= waterHeight + 1) {
|
||||
top = b->topMaterial;
|
||||
material = b->material;
|
||||
|
||||
//@attn: ?
|
||||
if (gravel) {
|
||||
top = 0;
|
||||
material = (char) Tile::gravel->id;
|
||||
}
|
||||
if (sand) {
|
||||
top = (char) Tile::sand->id;
|
||||
material = (char) Tile::sand->id;
|
||||
}
|
||||
}
|
||||
|
||||
if (y < waterHeight && top == 0) {
|
||||
if (temp < 0.15f)
|
||||
top = (char) Tile::ice->id;
|
||||
else
|
||||
top = (char) Tile::calmWater->id;
|
||||
}
|
||||
|
||||
run = runDepth;
|
||||
if (y >= waterHeight - 1) blocks[offs] = top;
|
||||
else blocks[offs] = material;
|
||||
} else if (run > 0) {
|
||||
run--;
|
||||
blocks[offs] = material;
|
||||
|
||||
// place a few sandstone blocks beneath sand
|
||||
// runs
|
||||
if (run == 0 && material == Tile::sand->id) {
|
||||
run = random.nextInt(4);
|
||||
material = (char) Tile::sandStone->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*public*/
|
||||
void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
|
||||
|
||||
level->isGeneratingTerrain = true;
|
||||
|
||||
HeavyTile::instaFall = true;
|
||||
int xo = xt * 16;
|
||||
int zo = zt * 16;
|
||||
|
||||
Biome* biome = level->getBiomeSource()->getBiome(xo + 16, zo + 16);
|
||||
// Biome* biome = Biome::forest;
|
||||
|
||||
random.setSeed(level->getSeed());
|
||||
int xScale = random.nextInt() / 2 * 2 + 1;
|
||||
int zScale = random.nextInt() / 2 * 2 + 1;
|
||||
random.setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed());
|
||||
|
||||
// //@todo: hide those chunks if they are aren't visible
|
||||
// if (random.nextInt(4) == 0) {
|
||||
// int x = xo + random.nextInt(16) + 8;
|
||||
// int y = random.nextInt(128);
|
||||
// int z = zo + random.nextInt(16) + 8;
|
||||
// LakeFeature feature(Tile::calmWater->id);
|
||||
// feature.place(level, &random, x, y, z);
|
||||
// LOGI("Adding underground lake @ (%d,%d,%d)\n", x, y, z);
|
||||
// }
|
||||
|
||||
////@todo: hide those chunks if they are aren't visible
|
||||
// if (random.nextInt(8) == 0) {
|
||||
// int x = xo + random.nextInt(16) + 8;
|
||||
// int y = random.nextInt(random.nextInt(120) + 8);
|
||||
// int z = zo + random.nextInt(16) + 8;
|
||||
// if (y < 64 || random.nextInt(10) == 0) {
|
||||
// LakeFeature feature(Tile::calmLava->id);
|
||||
// feature.place(level, &random, x, y, z);
|
||||
// }
|
||||
// }
|
||||
|
||||
static float totalTime = 0;
|
||||
const float st = getTimeS();
|
||||
|
||||
//for (int i = 0; i < 8; i++) {
|
||||
// int x = xo + random.nextInt(16) + 8;
|
||||
// int y = random.nextInt(128);
|
||||
// int z = zo + random.nextInt(16) + 8;
|
||||
// MonsterRoomFeature().place(level, random, x, y, z);
|
||||
//}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16);
|
||||
ClayFeature feature(32);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::dirt->id, 32);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::gravel->id, 32);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::coalOre->id, 16);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(64);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::ironOre->id, 8);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(32);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::goldOre->id, 8);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(16);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::redStoneOre->id, 7);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(16);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::emeraldOre->id, 7);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
// lapis ore
|
||||
for (int i = 0; i < 1; i++) {
|
||||
int x = xo + random.nextInt(16);
|
||||
int y = random.nextInt(16) + random.nextInt(16);
|
||||
int z = zo + random.nextInt(16);
|
||||
OreFeature feature(Tile::lapisOre->id, 6);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
const float ss = 0.5f;
|
||||
int oFor = (int) ((forestNoise.getValue(xo * ss, zo * ss) / 8 + random.nextFloat() * 4 + 4) / 3);
|
||||
int forests = 0;//1; (java: 0)
|
||||
if (random.nextInt(10) == 0) forests += 1;
|
||||
|
||||
if (biome == Biome::forest) forests += oFor + 2; // + 5
|
||||
if (biome == Biome::rainForest) forests += oFor + 2; //+ 5
|
||||
if (biome == Biome::seasonalForest) forests += oFor + 1; // 2
|
||||
if (biome == Biome::taiga) {
|
||||
forests += oFor + 1; // + 5
|
||||
//LOGI("Biome is taiga!\n");
|
||||
}
|
||||
|
||||
if (biome == Biome::desert) forests -= 20;
|
||||
if (biome == Biome::tundra) forests -= 20;
|
||||
if (biome == Biome::plains) forests -= 20;
|
||||
|
||||
for (int i = 0; i < forests; i++) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
int y = level->getHeightmap(x, z);
|
||||
Feature* tree = biome->getTreeFeature(&random);
|
||||
if (tree) {
|
||||
tree->init(1, 1, 1);
|
||||
tree->place(level, &random, x, y, z);
|
||||
delete tree;
|
||||
}
|
||||
//printf("placing tree at %d, %d, %d\n", x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
FlowerFeature feature(Tile::flower->id);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
if (random.nextInt(2) == 0) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
FlowerFeature feature(Tile::rose->id);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
if (random.nextInt(4) == 0) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
FlowerFeature feature(Tile::mushroom1->id);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
if (random.nextInt(8) == 0) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
FlowerFeature feature(Tile::mushroom2->id);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
/*int grassCount = 1;
|
||||
for (int i = 0; i < grassCount; i++) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(Level::genDepth);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
Feature* grassFeature = biome->getGrassFeature(&random);
|
||||
if (grassFeature) {
|
||||
grassFeature->place(level, &random, x, y, z);
|
||||
delete grassFeature;
|
||||
}
|
||||
}*/
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
ReedsFeature feature;
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
|
||||
//if (random.nextInt(32) == 0) {
|
||||
// int x = xo + random.nextInt(16) + 8;
|
||||
// int y = random.nextInt(128);
|
||||
// int z = zo + random.nextInt(16) + 8;
|
||||
// PumpkinFeature().place(level, random, x, y, z);
|
||||
//}
|
||||
|
||||
int cacti = 0;
|
||||
if (biome == Biome::desert) cacti += 5;
|
||||
|
||||
for (int i = 0; i < cacti; i++) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(128);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
CactusFeature feature;
|
||||
//LOGI("Tried creating a cactus at %d, %d, %d\n", x, y, z);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 50; i++) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(random.nextInt(120) + 8);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
SpringFeature feature(Tile::water->id);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x = xo + random.nextInt(16) + 8;
|
||||
int y = random.nextInt(random.nextInt(random.nextInt(112) + 8) + 8);
|
||||
int z = zo + random.nextInt(16) + 8;
|
||||
SpringFeature feature(Tile::lava->id);
|
||||
feature.place(level, &random, x, y, z);
|
||||
}
|
||||
|
||||
if (spawnMobs && !level->isClientSide)
|
||||
MobSpawner::postProcessSpawnMobs(level, biome, xo + 8, zo + 8, 16, 16, &random);
|
||||
|
||||
//LOGI("Reading temp: 1\n");
|
||||
float* temperatures = level->getBiomeSource()->getTemperatureBlock(/*NULL,*/ xo + 8, zo + 8, 16, 16);
|
||||
for (int x = xo + 8; x < xo + 8 + 16; x++)
|
||||
for (int z = zo + 8; z < zo + 8 + 16; z++) {
|
||||
int xp = x - (xo + 8);
|
||||
int zp = z - (zo + 8);
|
||||
int y = level->getTopSolidBlock(x, z);
|
||||
float temp = temperatures[xp * 16 + zp] - (y - 64) / 64.0f * SNOW_SCALE;
|
||||
if (temp < SNOW_CUTOFF) {
|
||||
if (y > 0 && y < 128 && level->isEmptyTile(x, y, z) && level->getMaterial(x, y - 1, z)->blocksMotion()) {
|
||||
if (level->getMaterial(x, y - 1, z) != Material::ice) level->setTile(x, y, z, Tile::topSnow->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
//LOGI("Reading temp: 0 END\n");
|
||||
|
||||
const float et = getTimeS();
|
||||
totalTime += (et-st);
|
||||
|
||||
//printf("Time to place features: %f. Total %f\n", et - st, totalTime);
|
||||
|
||||
HeavyTile::instaFall = false;
|
||||
|
||||
level->isGeneratingTerrain = false;
|
||||
}
|
||||
|
||||
LevelChunk* RandomLevelSource::create(int x, int z) {
|
||||
return getChunk(x, z);
|
||||
}
|
||||
|
||||
LevelChunk* RandomLevelSource::getChunk(int xOffs, int zOffs) {
|
||||
//static int chunkx = 0;
|
||||
int hashedPos = ChunkPos::hashCode(xOffs, zOffs);
|
||||
|
||||
ChunkMap::iterator it = chunkMap.find(hashedPos);
|
||||
if (it != chunkMap.end())
|
||||
return it->second;
|
||||
|
||||
random.setSeed((long)(xOffs * 341872712l + zOffs * 132899541l)); //@fix
|
||||
|
||||
unsigned char* blocks = new unsigned char[LevelChunk::ChunkBlockCount];
|
||||
LevelChunk* levelChunk = new LevelChunk(level, blocks, xOffs, zOffs);
|
||||
chunkMap.insert(std::make_pair(hashedPos, levelChunk));
|
||||
|
||||
Biome** biomes = level->getBiomeSource()->getBiomeBlock(/*biomes, */xOffs * 16, zOffs * 16, 16, 16);
|
||||
float* temperatures = level->getBiomeSource()->temperatures;
|
||||
prepareHeights(xOffs, zOffs, blocks, 0, temperatures);//biomes, temperatures);
|
||||
buildSurfaces(xOffs, zOffs, blocks, biomes);
|
||||
|
||||
//caveFeature.apply(this, level, xOffs, zOffs, blocks, LevelChunk::ChunkBlockCount);
|
||||
levelChunk->recalcHeightmap();
|
||||
|
||||
return levelChunk;
|
||||
}
|
||||
|
||||
/*private*/
|
||||
float* RandomLevelSource::getHeights(float* buffer, int x, int y, int z, int xSize, int ySize, int zSize) {
|
||||
const int size = xSize * ySize * zSize;
|
||||
if (size > MAX_BUFFER_SIZE) {
|
||||
LOGI("RandomLevelSource::getHeights: TOO LARGE BUFFER REQUESTED: %d (max %d)\n", size, MAX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
float s = 1 * 684.412f;
|
||||
float hs = 1 * 684.412f;
|
||||
|
||||
float* temperatures = level->getBiomeSource()->temperatures;
|
||||
float* downfalls = level->getBiomeSource()->downfalls;
|
||||
sr = scaleNoise.getRegion(sr, x, z, xSize, zSize, 1.121f, 1.121f, 0.5f);
|
||||
dr = depthNoise.getRegion(dr, x, z, xSize, zSize, 200.0f, 200.0f, 0.5f);
|
||||
|
||||
pnr = perlinNoise1.getRegion(pnr, (float)x, (float)y, (float)z, xSize, ySize, zSize, s / 80.0f, hs / 160.0f, s / 80.0f);
|
||||
ar = lperlinNoise1.getRegion(ar, (float)x, (float)y, (float)z, xSize, ySize, zSize, s, hs, s);
|
||||
br = lperlinNoise2.getRegion(br, (float)x, (float)y, (float)z, xSize, ySize, zSize, s, hs, s);
|
||||
|
||||
int p = 0;
|
||||
int pp = 0;
|
||||
|
||||
int wScale = 16 / xSize;
|
||||
for (int xx = 0; xx < xSize; xx++) {
|
||||
int xp = xx * wScale + wScale / 2;
|
||||
|
||||
for (int zz = 0; zz < zSize; zz++) {
|
||||
int zp = zz * wScale + wScale / 2;
|
||||
float temperature = temperatures[xp * 16 + zp];
|
||||
float downfall = downfalls[xp * 16 + zp] * temperature;
|
||||
float dd = 1 - downfall;
|
||||
dd = dd * dd;
|
||||
dd = dd * dd;
|
||||
dd = 1 - dd;
|
||||
|
||||
float scale = ((sr[pp] + 256.0f) / 512);
|
||||
scale *= dd;
|
||||
if (scale > 1) scale = 1;
|
||||
|
||||
|
||||
float depth = (dr[pp] / 8000.0f);
|
||||
if (depth < 0) depth = -depth * 0.3f;
|
||||
depth = depth * 3.0f - 2.0f;
|
||||
|
||||
if (depth < 0) {
|
||||
depth = depth / 2;
|
||||
if (depth < -1) depth = -1;
|
||||
depth = depth / 1.4f;
|
||||
depth /= 2;
|
||||
scale = 0;
|
||||
} else {
|
||||
if (depth > 1) depth = 1;
|
||||
depth = depth / 8;
|
||||
}
|
||||
|
||||
if (scale < 0) scale = 0;
|
||||
scale = (scale) + 0.5f;
|
||||
depth = depth * ySize / 16;
|
||||
|
||||
float yCenter = ySize / 2.0f + depth * 4;
|
||||
|
||||
pp++;
|
||||
|
||||
for (int yy = 0; yy < ySize; yy++) {
|
||||
float val = 0;
|
||||
|
||||
float yOffs = (yy - (yCenter)) * 12 / scale;
|
||||
if (yOffs < 0) yOffs *= 4;
|
||||
|
||||
float bb = ar[p] / 512;
|
||||
float cc = br[p] / 512;
|
||||
|
||||
float v = (pnr[p] / 10 + 1) / 2;
|
||||
if (v < 0) val = bb;
|
||||
else if (v > 1) val = cc;
|
||||
else val = bb + (cc - bb) * v;
|
||||
val -= yOffs;
|
||||
|
||||
if (yy > ySize - 4) {
|
||||
float slide = (yy - (ySize - 4)) / (4 - 1.0f);
|
||||
val = val * (1 - slide) + -10 * slide;
|
||||
}
|
||||
|
||||
buffer[p] = val;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*private*/
|
||||
void RandomLevelSource::calcWaterDepths(ChunkSource* parent, int xt, int zt) {
|
||||
int xo = xt * 16;
|
||||
int zo = zt * 16;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int y = level->getSeaLevel();
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int xp = xo + x + 7;
|
||||
int zp = zo + z + 7;
|
||||
int h = level->getHeightmap(xp, zp);
|
||||
if (h <= 0) {
|
||||
if (level->getHeightmap(xp - 1, zp) > 0 || level->getHeightmap(xp + 1, zp) > 0 || level->getHeightmap(xp, zp - 1) > 0 || level->getHeightmap(xp, zp + 1) > 0) {
|
||||
bool hadWater = false;
|
||||
if (hadWater || (level->getTile(xp - 1, y, zp) == Tile::calmWater->id && level->getData(xp - 1, y, zp) < 7)) hadWater = true;
|
||||
if (hadWater || (level->getTile(xp + 1, y, zp) == Tile::calmWater->id && level->getData(xp + 1, y, zp) < 7)) hadWater = true;
|
||||
if (hadWater || (level->getTile(xp, y, zp - 1) == Tile::calmWater->id && level->getData(xp, y, zp - 1) < 7)) hadWater = true;
|
||||
if (hadWater || (level->getTile(xp, y, zp + 1) == Tile::calmWater->id && level->getData(xp, y, zp + 1) < 7)) hadWater = true;
|
||||
if (hadWater) {
|
||||
for (int x2 = -5; x2 <= 5; x2++) {
|
||||
for (int z2 = -5; z2 <= 5; z2++) {
|
||||
int d = (x2 > 0 ? x2 : -x2) + (z2 > 0 ? z2 : -z2);
|
||||
|
||||
if (d <= 5) {
|
||||
d = 6 - d;
|
||||
if (level->getTile(xp + x2, y, zp + z2) == Tile::calmWater->id) {
|
||||
int od = level->getData(xp + x2, y, zp + z2);
|
||||
if (od < 7 && od < d) {
|
||||
level->setData(xp + x2, y, zp + z2, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hadWater) {
|
||||
level->setTileAndDataNoUpdate(xp, y, zp, Tile::calmWater->id, 7);
|
||||
for (int y2 = 0; y2 < y; y2++) {
|
||||
level->setTileAndDataNoUpdate(xp, y2, zp, Tile::calmWater->id, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RandomLevelSource::hasChunk(int x, int y) {
|
||||
//return x >= 0 && x < 16 && y >= 0 && y < 16;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RandomLevelSource::tick() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RandomLevelSource::shouldSave() {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string RandomLevelSource::gatherStats() {
|
||||
return "RandomLevelSource";
|
||||
}
|
||||
|
||||
//bool RandomLevelSource::save(bool force, ProgressListener progressListener) {
|
||||
// return true;
|
||||
//}
|
||||
|
||||
Biome::MobList RandomLevelSource::getMobsAt(const MobCategory& mobCategory, int x, int y, int z) {
|
||||
BiomeSource* biomeSource = level->getBiomeSource();
|
||||
if (biomeSource == NULL) {
|
||||
return Biome::MobList();
|
||||
}
|
||||
// static Stopwatch sw; sw.start();
|
||||
Biome* biome = biomeSource->getBiome(x, z);
|
||||
// sw.stop();
|
||||
// sw.printEvery(10, "getBiome::");
|
||||
if (biome == NULL) {
|
||||
return Biome::MobList();
|
||||
}
|
||||
return biome->getMobs(mobCategory);
|
||||
}
|
||||
|
||||
|
||||
LevelChunk* PerformanceTestChunkSource::create(int x, int z)
|
||||
{
|
||||
unsigned char* blocks = new unsigned char[LevelChunk::ChunkBlockCount];
|
||||
memset(blocks, 0, LevelChunk::ChunkBlockCount);
|
||||
|
||||
for (int y = 0; y < 65; y++)
|
||||
{
|
||||
if (y < 60)
|
||||
{
|
||||
for (int x = (y + 1) & 1; x < 16; x += 2)
|
||||
{
|
||||
for (int z = y & 1; z < 16; z += 2)
|
||||
{
|
||||
blocks[x << 11 | z << 7 | y] = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < 16; x += 2)
|
||||
{
|
||||
for (int z = 0; z < 16; z += 2)
|
||||
{
|
||||
blocks[x << 11 | z << 7 | y] = 3;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
LevelChunk* levelChunk = new LevelChunk(level, blocks, x, z);
|
||||
|
||||
//caveFeature.apply(this, level, xOffs, zOffs, blocks, LevelChunk::ChunkBlockCount);
|
||||
levelChunk->recalcHeightmap();
|
||||
|
||||
return levelChunk;
|
||||
}
|
||||
125
src/world/level/levelgen/RandomLevelSource.h
Executable file
125
src/world/level/levelgen/RandomLevelSource.h
Executable file
@@ -0,0 +1,125 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__RandomLevelSource_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__RandomLevelSource_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen;
|
||||
|
||||
class Biome;
|
||||
class Level;
|
||||
class LevelChunk;
|
||||
|
||||
#if 1 || USE_MAP
|
||||
#include <map>
|
||||
typedef std::map<int, LevelChunk*> ChunkMap;
|
||||
#else
|
||||
#if defined(__APPLE__)
|
||||
#include <ext/hash_map>
|
||||
namespace std {
|
||||
using namespace __gnu_cxx;
|
||||
}
|
||||
#else
|
||||
#include <hash_map>
|
||||
#endif
|
||||
typedef std::hash_map<int, LevelChunk*> ChunkMap;
|
||||
#endif
|
||||
|
||||
|
||||
#include "../chunk/ChunkSource.h"
|
||||
#include "LargeCaveFeature.h"
|
||||
#include "synth/PerlinNoise.h"
|
||||
#include "../../../SharedConstants.h"
|
||||
|
||||
class RandomLevelSource: public ChunkSource
|
||||
{
|
||||
static const float SNOW_CUTOFF;
|
||||
static const float SNOW_SCALE;
|
||||
|
||||
public:
|
||||
static const int CHUNK_HEIGHT = 8;
|
||||
static const int CHUNK_WIDTH = 4;
|
||||
|
||||
RandomLevelSource(Level* level, long seed, int version, bool spawnMobs);
|
||||
~RandomLevelSource();
|
||||
|
||||
bool hasChunk(int x, int y);
|
||||
LevelChunk* create(int x, int z);
|
||||
LevelChunk* getChunk(int xOffs, int zOffs);
|
||||
|
||||
void prepareHeights(int xOffs, int zOffs, unsigned char* blocks, /*Biome*/void* biomes, float* temperatures);
|
||||
void buildSurfaces(int xOffs, int zOffs, unsigned char* blocks, Biome** biomes);
|
||||
void postProcess(ChunkSource* parent, int xt, int zt);
|
||||
|
||||
bool tick();
|
||||
|
||||
Biome::MobList getMobsAt(const MobCategory& mobCategory, int x, int y, int z);
|
||||
|
||||
bool shouldSave();
|
||||
std::string gatherStats();
|
||||
|
||||
//bool save(bool force, ProgressListener progressListener) {
|
||||
private:
|
||||
float* getHeights(float* buffer, int x, int y, int z, int xSize, int ySize, int zSize);
|
||||
void calcWaterDepths(ChunkSource* parent, int xt, int zt);
|
||||
|
||||
public:
|
||||
//Biome** biomes;
|
||||
LargeCaveFeature caveFeature;
|
||||
int waterDepths[16+16][16+16];
|
||||
private:
|
||||
ChunkMap chunkMap;
|
||||
|
||||
Random random;
|
||||
PerlinNoise lperlinNoise1;
|
||||
PerlinNoise lperlinNoise2;
|
||||
PerlinNoise perlinNoise1;
|
||||
PerlinNoise perlinNoise2;
|
||||
PerlinNoise perlinNoise3;
|
||||
PerlinNoise scaleNoise;
|
||||
PerlinNoise depthNoise;
|
||||
PerlinNoise forestNoise;
|
||||
|
||||
Level* level;
|
||||
bool spawnMobs;
|
||||
|
||||
float* buffer;
|
||||
float sandBuffer[16 * 16];
|
||||
float gravelBuffer[16 * 16];
|
||||
float depthBuffer[16 * 16];
|
||||
float* pnr;
|
||||
float* ar;
|
||||
float* br;
|
||||
float* sr;
|
||||
float* dr;
|
||||
float* fi;
|
||||
float* fis;
|
||||
///*private*/ float[] temperatures;
|
||||
};
|
||||
|
||||
class PerformanceTestChunkSource : public ChunkSource
|
||||
{
|
||||
Level* level;
|
||||
public:
|
||||
PerformanceTestChunkSource(Level* level)
|
||||
: ChunkSource(),
|
||||
level(level)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual bool hasChunk(int x, int y) { return true; };
|
||||
virtual LevelChunk* getChunk(int x, int z) { return create(x, z); };
|
||||
|
||||
virtual LevelChunk* create(int x, int z);
|
||||
virtual void postProcess(ChunkSource* parent, int x, int z) {};
|
||||
|
||||
virtual bool tick() { return false; };
|
||||
|
||||
virtual bool shouldSave() { return false; };
|
||||
|
||||
/**
|
||||
* Returns some stats that are rendered when the user holds F3.
|
||||
*/
|
||||
virtual std::string gatherStats() { return "PerformanceTestChunkSource"; };
|
||||
};
|
||||
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__RandomLevelSource_H__*/
|
||||
13
src/world/level/levelgen/TownFeature.h
Executable file
13
src/world/level/levelgen/TownFeature.h
Executable file
@@ -0,0 +1,13 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__TownFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__TownFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen;
|
||||
|
||||
#include "world/level/Level.h"
|
||||
|
||||
/*public*/ class TownFeature extends LargeFeature {
|
||||
/*protected*/ void addFeature(Level level, int x, int z, int xOffs, int zOffs, byte[] blocks) {
|
||||
}
|
||||
}
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN__TownFeature_H__*/
|
||||
75
src/world/level/levelgen/feature/BirchFeature.h
Executable file
75
src/world/level/levelgen/feature/BirchFeature.h
Executable file
@@ -0,0 +1,75 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__BirchFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__BirchFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../../../util/Random.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/LeafTile.h"
|
||||
#include "../../tile/Tile.h"
|
||||
#include "../../tile/TreeTile.h"
|
||||
|
||||
/**
|
||||
* Same as tree feature, but slightly taller and white in color
|
||||
*
|
||||
*/
|
||||
class BirchFeature: public Feature
|
||||
{
|
||||
typedef Feature super;
|
||||
public:
|
||||
BirchFeature(bool doUpdate = false)
|
||||
: super(doUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
int treeHeight = random->nextInt(3) + 5;
|
||||
|
||||
bool free = true;
|
||||
if (y < 1 || y + treeHeight + 1 > Level::DEPTH) return false;
|
||||
|
||||
for (int yy = y; yy <= y + 1 + treeHeight; yy++) {
|
||||
int r = 1;
|
||||
if (yy == y) r = 0;
|
||||
if (yy >= y + 1 + treeHeight - 2) r = 2;
|
||||
for (int xx = x - r; xx <= x + r && free; xx++) {
|
||||
for (int zz = z - r; zz <= z + r && free; zz++) {
|
||||
if (yy >= 0 && yy < Level::DEPTH) {
|
||||
int tt = level->getTile(xx, yy, zz);
|
||||
if (tt != 0 && tt != ((Tile*)Tile::leaves)->id) free = false;
|
||||
} else {
|
||||
free = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!free) return false;
|
||||
|
||||
int belowTile = level->getTile(x, y - 1, z);
|
||||
if ((belowTile != ((Tile*)Tile::grass)->id && belowTile != Tile::dirt->id) || y >= Level::DEPTH - treeHeight - 1) return false;
|
||||
|
||||
placeBlock(level, x, y - 1, z, Tile::dirt->id);
|
||||
|
||||
for (int yy = y - 3 + treeHeight; yy <= y + treeHeight; yy++) {
|
||||
int yo = yy - (y + treeHeight);
|
||||
int offs = 1 - yo / 2;
|
||||
for (int xx = x - offs; xx <= x + offs; xx++) {
|
||||
int xo = xx - (x);
|
||||
for (int zz = z - offs; zz <= z + offs; zz++) {
|
||||
int zo = zz - (z);
|
||||
if (std::abs(xo) == offs && std::abs(zo) == offs && (random->nextInt(2) == 0 || yo == 0)) continue;
|
||||
if (!Tile::solid[level->getTile(xx, yy, zz)]) placeBlock(level, xx, yy, zz, Tile::leaves->id, LeafTile::BIRCH_LEAF);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int hh = 0; hh < treeHeight; hh++) {
|
||||
int t = level->getTile(x, y + hh, z);
|
||||
if (t == 0 || t == ((Tile*)Tile::leaves)->id) placeBlock(level, x, y + hh, z, Tile::treeTrunk->id, TreeTile::BIRCH_TRUNK);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__BirchFeature_H__*/
|
||||
35
src/world/level/levelgen/feature/CactusFeature.h
Executable file
35
src/world/level/levelgen/feature/CactusFeature.h
Executable file
@@ -0,0 +1,35 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__CactusFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__CactusFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "../../../../util/Mth.h"
|
||||
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/CactusTile.h"
|
||||
/* import net.minecraft.world.level.tile.* */
|
||||
|
||||
class CactusFeature: public Feature
|
||||
{
|
||||
public:
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
int x2 = x + random->nextInt(8) - random->nextInt(8);
|
||||
int y2 = y + random->nextInt(4) - random->nextInt(4);
|
||||
int z2 = z + random->nextInt(8) - random->nextInt(8);
|
||||
if (level->isEmptyTile(x2, y2, z2)) {
|
||||
int h = 1 + random->nextInt(random->nextInt(3) + 1);
|
||||
for (int yy = 0; yy < h; yy++) {
|
||||
if (Tile::cactus->canSurvive(level, x2, y2+yy, z2)) {
|
||||
//LOGI("Creating cactus part at %d, %d, %d\n", x, y, z);
|
||||
level->setTileNoUpdate(x2, y2+yy, z2, Tile::cactus->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__CactusFeature_H__*/
|
||||
63
src/world/level/levelgen/feature/ClayFeature.h
Executable file
63
src/world/level/levelgen/feature/ClayFeature.h
Executable file
@@ -0,0 +1,63 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__ClayFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__ClayFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/Tile.h"
|
||||
#include "../../material/Material.h"
|
||||
#include "../../../../util/Mth.h"
|
||||
#include "../../../../util/Random.h"
|
||||
|
||||
class ClayFeature: public Feature
|
||||
{
|
||||
int tile;
|
||||
int count;
|
||||
|
||||
public:
|
||||
ClayFeature(int count) {
|
||||
this->tile = Tile::clay->id;
|
||||
this->count = count;
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
if (level->getMaterial(x, y, z) != Material::water) return false;
|
||||
|
||||
float dir = random->nextFloat() * Mth::PI;
|
||||
|
||||
float x0 = x + 8 + sin(dir) * count / 8;
|
||||
float x1 = x + 8 - sin(dir) * count / 8;
|
||||
float z0 = z + 8 + cos(dir) * count / 8;
|
||||
float z1 = z + 8 - cos(dir) * count / 8;
|
||||
|
||||
float y0 = (float)(y + random->nextInt(3) + 2);
|
||||
float y1 = (float)(y + random->nextInt(3) + 2);
|
||||
|
||||
for (int d = 0; d <= count; d++) {
|
||||
float xx = x0 + (x1 - x0) * d / count;
|
||||
float yy = y0 + (y1 - y0) * d / count;
|
||||
float zz = z0 + (z1 - z0) * d / count;
|
||||
|
||||
float ss = random->nextFloat() * (float)(count >> 4);
|
||||
float r = (sin(d * Mth::PI / count) + 1) * ss + 1;
|
||||
float hr = (sin(d * Mth::PI / count) + 1) * ss + 1;
|
||||
|
||||
for (int x2 = (int) (xx - r / 2); x2 <= (int) (xx + r * 0.5f); x2++)
|
||||
for (int y2 = (int) (yy - hr / 2); y2 <= (int) (yy + hr * 0.5f); y2++)
|
||||
for (int z2 = (int) (zz - r / 2); z2 <= (int) (zz + r * 0.5f); z2++) {
|
||||
float xd = ((x2 + 0.5f) - xx) / (r * 0.5f);
|
||||
float yd = ((y2 + 0.5f) - yy) / (hr * 0.5f);
|
||||
float zd = ((z2 + 0.5f) - zz) / (r * 0.5f);
|
||||
if (xd * xd + yd * yd + zd * zd < 1) {
|
||||
int t = level->getTile(x2, y2, z2);
|
||||
if (t == Tile::sand->id) level->setTileNoUpdate(x2, y2, z2, tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__ClayFeature_H__*/
|
||||
26
src/world/level/levelgen/feature/Feature.cpp
Executable file
26
src/world/level/levelgen/feature/Feature.cpp
Executable file
@@ -0,0 +1,26 @@
|
||||
#include "Feature.h"
|
||||
|
||||
Feature::Feature( bool doUpdate /*= false*/ )
|
||||
: doUpdate(doUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
void Feature::placeBlock( Level* level, int x, int y, int z, int tile )
|
||||
{
|
||||
placeBlock(level, x, y, z, tile, 0);
|
||||
}
|
||||
|
||||
void Feature::placeBlock( Level* level, int x, int y, int z, int tile, int data )
|
||||
{
|
||||
if (doUpdate) {
|
||||
level->setTileAndData(x, y, z, tile, data);
|
||||
/*
|
||||
} else if (level->hasChunkAt(x, y, z) && level->getChunkAt(x, z).seenByPlayer) {
|
||||
if (level->setTileAndDataNoUpdate(x, y, z, tile, data)) {
|
||||
level->sendTileUpdated(x, y, z);
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
level->setTileAndDataNoUpdate(x, y, z, tile, data);
|
||||
}
|
||||
}
|
||||
23
src/world/level/levelgen/feature/Feature.h
Executable file
23
src/world/level/levelgen/feature/Feature.h
Executable file
@@ -0,0 +1,23 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__Feature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__Feature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "../../Level.h"
|
||||
class Random;
|
||||
|
||||
class Feature
|
||||
{
|
||||
public:
|
||||
Feature(bool doUpdate = false);
|
||||
virtual ~Feature() {}
|
||||
virtual bool place(Level* level, Random* random, int x, int y, int z) = 0;
|
||||
virtual void init(float v1, float v2, float v3) {}
|
||||
protected:
|
||||
void placeBlock(Level* level, int x, int y, int z, int tile);
|
||||
void placeBlock(Level* level, int x, int y, int z, int tile, int data);
|
||||
private:
|
||||
bool doUpdate;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__Feature_H__*/
|
||||
14
src/world/level/levelgen/feature/FeatureInclude.h
Executable file
14
src/world/level/levelgen/feature/FeatureInclude.h
Executable file
@@ -0,0 +1,14 @@
|
||||
#ifndef FEATURE_INCLUDE_H__
|
||||
#define FEATURE_INCLUDE_H__
|
||||
|
||||
#include "Feature.h"
|
||||
#include "CactusFeature.h"
|
||||
#include "ClayFeature.h"
|
||||
#include "FlowerFeature.h"
|
||||
#include "TreeFeature.h"
|
||||
#include "LakeFeature.h"
|
||||
#include "OreFeature.h"
|
||||
#include "ReedsFeature.h"
|
||||
#include "SpringFeature.h"
|
||||
|
||||
#endif /*FEATURE_INCLUDE__H__*/
|
||||
35
src/world/level/levelgen/feature/FlowerFeature.h
Executable file
35
src/world/level/levelgen/feature/FlowerFeature.h
Executable file
@@ -0,0 +1,35 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__FlowerFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__FlowerFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "../../../../util/Random.h"
|
||||
#include "../../Level.h"
|
||||
|
||||
#include "../../tile/Bush.h"
|
||||
#include "Feature.h"
|
||||
|
||||
class FlowerFeature: public Feature {
|
||||
public:
|
||||
int tile;
|
||||
|
||||
FlowerFeature(int tile) {
|
||||
this->tile = tile;
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
for (int i = 0; i < 64; i++) {
|
||||
int x2 = x + random->nextInt(8) - random->nextInt(8);
|
||||
int y2 = y + random->nextInt(4) - random->nextInt(4);
|
||||
int z2 = z + random->nextInt(8) - random->nextInt(8);
|
||||
if (level->isEmptyTile(x2, y2, z2)) {
|
||||
if (((Bush*) Tile::tiles[tile])->canSurvive(level, x2, y2, z2)) {
|
||||
level->setTileNoUpdate(x2, y2, z2, tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__FlowerFeature_H__*/
|
||||
127
src/world/level/levelgen/feature/LakeFeature.h
Executable file
127
src/world/level/levelgen/feature/LakeFeature.h
Executable file
@@ -0,0 +1,127 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__LakeFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__LakeFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/Tile.h"
|
||||
#include "../../material/Material.h"
|
||||
#include "../../../../util/Mth.h"
|
||||
#include "../../../../util/Random.h"
|
||||
|
||||
class LakeFeature: public Feature
|
||||
{
|
||||
int tile;
|
||||
|
||||
public:
|
||||
LakeFeature(int tile_)
|
||||
: tile(tile_)
|
||||
{
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
x -= 8;
|
||||
z -= 8;
|
||||
while (y > 0 && level->isEmptyTile(x, y, z))
|
||||
y--;
|
||||
|
||||
y -= 4;
|
||||
|
||||
const int size = 16 * 16 * 8;
|
||||
bool grid[size];
|
||||
for (int i = 0; i < size; ++i)
|
||||
grid[i] = false;
|
||||
|
||||
int spots = random->nextInt(4) + 4;
|
||||
for (int i = 0; i < spots; i++) {
|
||||
float xr = random->nextFloat() * 6 + 3;
|
||||
float yr = random->nextFloat() * 4 + 2;
|
||||
float zr = random->nextFloat() * 6 + 3;
|
||||
|
||||
float xp = random->nextFloat() * (16 - xr - 2) + 1 + xr / 2;
|
||||
float yp = random->nextFloat() * (8 - yr - 4) + 2 + yr / 2;
|
||||
float zp = random->nextFloat() * (16 - zr - 2) + 1 + zr / 2;
|
||||
|
||||
for (int xx = 1; xx < 15; xx++) {
|
||||
for (int zz = 1; zz < 15; zz++) {
|
||||
for (int yy = 1; yy < 7; yy++) {
|
||||
float xd = ((xx - xp) / (xr / 2));
|
||||
float yd = ((yy - yp) / (yr / 2));
|
||||
float zd = ((zz - zp) / (zr / 2));
|
||||
float d = xd * xd + yd * yd + zd * zd;
|
||||
if (d < 1) grid[((xx) * 16 + (zz)) * 8 + (yy)] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int xx = 0; xx < 16; xx++) {
|
||||
for (int zz = 0; zz < 16; zz++) {
|
||||
for (int yy = 0; yy < 8; yy++) {
|
||||
bool check = !grid[((xx) * 16 + (zz)) * 8 + (yy)] && (false//
|
||||
|| (xx < 15 && grid[((xx + 1) * 16 + (zz)) * 8 + (yy)])//
|
||||
|| (xx > 0 && grid[((xx - 1) * 16 + (zz)) * 8 + (yy)])//
|
||||
|| (zz < 15 && grid[((xx) * 16 + (zz + 1)) * 8 + (yy)])//
|
||||
|| (zz > 0 && grid[((xx) * 16 + (zz - 1)) * 8 + (yy)])//
|
||||
|| (yy < 7 && grid[((xx) * 16 + (zz)) * 8 + (yy + 1)])//
|
||||
|| (yy > 0 && grid[((xx) * 16 + (zz)) * 8 + (yy - 1)]));
|
||||
|
||||
if (check) {
|
||||
const Material* m = level->getMaterial(x + xx, y + yy, z + zz);
|
||||
if (yy >= 4 && m->isLiquid()) return false;
|
||||
if (yy < 4 && (!m->isSolid() && level->getTile(x + xx, y + yy, z + zz) != tile)) return false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int xx = 0; xx < 16; xx++) {
|
||||
for (int zz = 0; zz < 16; zz++) {
|
||||
for (int yy = 0; yy < 8; yy++) {
|
||||
if (grid[((xx) * 16 + (zz)) * 8 + (yy)]) {
|
||||
level->setTileNoUpdate(x + xx, y + yy, z + zz, yy >= 4 ? 0 : tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int xx = 0; xx < 16; xx++) {
|
||||
for (int zz = 0; zz < 16; zz++) {
|
||||
for (int yy = 4; yy < 8; yy++) {
|
||||
if (grid[((xx) * 16 + (zz)) * 8 + (yy)]) {
|
||||
if (level->getTile(x + xx, y + yy - 1, z + zz) == Tile::dirt->id && level->getBrightness(LightLayer::Sky, x + xx, y + yy, z + zz) > 0) {
|
||||
level->setTileNoUpdate(x + xx, y + yy - 1, z + zz, Tile::grass->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Tile::tiles[tile]->material == Material::lava) {
|
||||
for (int xx = 0; xx < 16; xx++) {
|
||||
for (int zz = 0; zz < 16; zz++) {
|
||||
for (int yy = 0; yy < 8; yy++) {
|
||||
bool check = !grid[((xx) * 16 + (zz)) * 8 + (yy)] && (false//
|
||||
|| (xx < 15 && grid[((xx + 1) * 16 + (zz)) * 8 + (yy)])//
|
||||
|| (xx > 0 && grid[((xx - 1) * 16 + (zz)) * 8 + (yy)])//
|
||||
|| (zz < 15 && grid[((xx) * 16 + (zz + 1)) * 8 + (yy)])//
|
||||
|| (zz > 0 && grid[((xx) * 16 + (zz - 1)) * 8 + (yy)])//
|
||||
|| (yy < 7 && grid[((xx) * 16 + (zz)) * 8 + (yy + 1)])//
|
||||
|| (yy > 0 && grid[((xx) * 16 + (zz)) * 8 + (yy - 1)]));
|
||||
|
||||
if (check) {
|
||||
if ((yy<4 || random->nextInt(2)!=0) && level->getMaterial(x + xx, y + yy, z + zz)->isSolid()) {
|
||||
level->setTileNoUpdate(x + xx, y + yy, z + zz, Tile::rock->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__LakeFeature_H__*/
|
||||
77
src/world/level/levelgen/feature/OreFeature.h
Executable file
77
src/world/level/levelgen/feature/OreFeature.h
Executable file
@@ -0,0 +1,77 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__OreFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__OreFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/Tile.h"
|
||||
#include "../../material/Material.h"
|
||||
#include "../../../../util/Mth.h"
|
||||
#include "../../../../util/Random.h"
|
||||
|
||||
class OreFeature: public Feature {
|
||||
int tile;
|
||||
int count;
|
||||
|
||||
public:
|
||||
OreFeature(int tile, int count) {
|
||||
this->tile = tile;
|
||||
this->count = count;
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
|
||||
float dir = random->nextFloat() * Mth::PI;
|
||||
|
||||
float x0 = x + 8 + Mth::sin(dir) * count / 8;
|
||||
float x1 = x + 8 - Mth::sin(dir) * count / 8;
|
||||
float z0 = z + 8 + Mth::cos(dir) * count / 8;
|
||||
float z1 = z + 8 - Mth::cos(dir) * count / 8;
|
||||
|
||||
float y0 = (float)(y + random->nextInt(3) + 2);
|
||||
float y1 = (float)(y + random->nextInt(3) + 2);
|
||||
|
||||
|
||||
for (int D = 0; D <= count; D++) {
|
||||
float d = (float) D;
|
||||
float xx = x0 + (x1 - x0) * d / count;
|
||||
float yy = y0 + (y1 - y0) * d / count;
|
||||
float zz = z0 + (z1 - z0) * d / count;
|
||||
|
||||
float ss = random->nextFloat() * count / 16;
|
||||
float r = (Mth::sin(d * Mth::PI / count) + 1) * ss + 1;
|
||||
float hr = (Mth::sin(d * Mth::PI / count) + 1) * ss + 1;
|
||||
|
||||
int xt0 = (int) (xx - r / 2);
|
||||
int yt0 = (int) (yy - hr / 2);
|
||||
int zt0 = (int) (zz - r / 2);
|
||||
|
||||
int xt1 = (int) (xx + r / 2);
|
||||
int yt1 = (int) (yy + hr / 2);
|
||||
int zt1 = (int) (zz + r / 2);
|
||||
|
||||
for (int x2 = xt0; x2 <= xt1; x2++) {
|
||||
float xd = ((x2 + 0.5f) - xx) / (r / 2);
|
||||
if (xd * xd < 1) {
|
||||
for (int y2 = yt0; y2 <= yt1; y2++) {
|
||||
float yd = ((y2 + 0.5f) - yy) / (hr / 2);
|
||||
if (xd * xd + yd * yd < 1) {
|
||||
for (int z2 = zt0; z2 <= zt1; z2++) {
|
||||
float zd = ((z2 + 0.5f) - zz) / (r / 2);
|
||||
if (xd * xd + yd * yd + zd * zd < 1) {
|
||||
if (level->getTile(x2, y2, z2) == Tile::rock->id) level->setTileNoUpdate(x2, y2, z2, tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__OreFeature_H__*/
|
||||
92
src/world/level/levelgen/feature/PineFeature.h
Executable file
92
src/world/level/levelgen/feature/PineFeature.h
Executable file
@@ -0,0 +1,92 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__PineFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__PineFeature_H__
|
||||
|
||||
//package net.minecraft.world.level->levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../../../util/Random.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/LeafTile.h"
|
||||
#include "../../tile/Tile.h"
|
||||
#include "../../tile/TreeTile.h"
|
||||
|
||||
class PineFeature: public Feature
|
||||
{
|
||||
typedef Feature super;
|
||||
public:
|
||||
PineFeature(bool doUpdate = false)
|
||||
: super(doUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
|
||||
// pines can be quite tall
|
||||
int treeHeight = random->nextInt(5) + 7;
|
||||
int trunkHeight = treeHeight - random->nextInt(2) - 3;
|
||||
int topHeight = treeHeight - trunkHeight;
|
||||
int topRadius = 1 + random->nextInt(topHeight + 1);
|
||||
|
||||
bool free = true;
|
||||
// may not be outside of y boundaries
|
||||
if (y < 1 || y + treeHeight + 1 > Level::DEPTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure there is enough space
|
||||
for (int yy = y; yy <= y + 1 + treeHeight && free; yy++) {
|
||||
|
||||
int r = 1;
|
||||
if ((yy - y) < trunkHeight) {
|
||||
r = 0;
|
||||
} else {
|
||||
r = topRadius;
|
||||
}
|
||||
for (int xx = x - r; xx <= x + r && free; xx++) {
|
||||
for (int zz = z - r; zz <= z + r && free; zz++) {
|
||||
if (yy >= 0 && yy < Level::DEPTH) {
|
||||
int tt = level->getTile(xx, yy, zz);
|
||||
if (tt != 0 && tt != Tile::leaves->id) free = false;
|
||||
} else {
|
||||
free = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!free) return false;
|
||||
|
||||
// must stand on ground
|
||||
int belowTile = level->getTile(x, y - 1, z);
|
||||
if ((belowTile != ((Tile*)Tile::grass)->id && belowTile != Tile::dirt->id) || y >= Level::DEPTH - treeHeight - 1) return false;
|
||||
|
||||
placeBlock(level, x, y - 1, z, Tile::dirt->id);
|
||||
|
||||
// place leaf top
|
||||
int currentRadius = 0;
|
||||
for (int yy = y + treeHeight; yy >= y + trunkHeight; yy--) {
|
||||
|
||||
for (int xx = x - currentRadius; xx <= x + currentRadius; xx++) {
|
||||
int xo = xx - (x);
|
||||
for (int zz = z - currentRadius; zz <= z + currentRadius; zz++) {
|
||||
int zo = zz - (z);
|
||||
if (std::abs(xo) == currentRadius && std::abs(zo) == currentRadius && currentRadius > 0) continue;
|
||||
if (!Tile::solid[level->getTile(xx, yy, zz)]) placeBlock(level, xx, yy, zz, Tile::leaves->id, LeafTile::EVERGREEN_LEAF);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentRadius >= 1 && yy == (y + trunkHeight + 1)) {
|
||||
currentRadius -= 1;
|
||||
} else if (currentRadius < topRadius) {
|
||||
currentRadius += 1;
|
||||
}
|
||||
}
|
||||
for (int hh = 0; hh < treeHeight - 1; hh++) {
|
||||
int t = level->getTile(x, y + hh, z);
|
||||
if (t == 0 || t == Tile::leaves->id) placeBlock(level, x, y + hh, z, Tile::treeTrunk->id, TreeTile::DARK_TRUNK);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__PineFeature_H__*/
|
||||
40
src/world/level/levelgen/feature/ReedsFeature.h
Executable file
40
src/world/level/levelgen/feature/ReedsFeature.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__ReedsFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__ReedsFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/Tile.h"
|
||||
#include "../../material/Material.h"
|
||||
#include "../../../../util/Random.h"
|
||||
|
||||
class ReedsFeature: public Feature
|
||||
{
|
||||
public:
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int x2 = x + random->nextInt(4) - random->nextInt(4);
|
||||
int y2 = y;
|
||||
int z2 = z + random->nextInt(4) - random->nextInt(4);
|
||||
if (level->isEmptyTile(x2, y2, z2)) {
|
||||
if (level->getMaterial(x2-1, y2-1, z2) == Material::water ||
|
||||
level->getMaterial(x2+1, y2-1, z2) == Material::water ||
|
||||
level->getMaterial(x2, y2-1, z2-1) == Material::water ||
|
||||
level->getMaterial(x2, y2-1, z2+1) == Material::water) {
|
||||
|
||||
int h = 2 + random->nextInt(random->nextInt(3) + 1);
|
||||
for (int yy = 0; yy < h; yy++) {
|
||||
if (Tile::reeds->canSurvive(level, x2, y2 + yy, z2)) {
|
||||
level->setTileNoUpdate(x2, y2 + yy, z2, Tile::reeds->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__ReedsFeature_H__*/
|
||||
50
src/world/level/levelgen/feature/SpringFeature.h
Executable file
50
src/world/level/levelgen/feature/SpringFeature.h
Executable file
@@ -0,0 +1,50 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__SpringFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__SpringFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/Tile.h"
|
||||
#include "../../material/Material.h"
|
||||
#include "../../../../util/Random.h"
|
||||
|
||||
class SpringFeature: public Feature
|
||||
{
|
||||
int tile;
|
||||
|
||||
public:
|
||||
SpringFeature(int tile) {
|
||||
this->tile = tile;
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
if (level->getTile(x, y + 1, z) != Tile::rock->id) return false;
|
||||
if (level->getTile(x, y - 1, z) != Tile::rock->id) return false;
|
||||
|
||||
if (level->getTile(x, y, z) != 0 && level->getTile(x, y, z) != Tile::rock->id) return false;
|
||||
|
||||
int rockCount = 0;
|
||||
if (level->getTile(x - 1, y, z) == Tile::rock->id) rockCount++;
|
||||
if (level->getTile(x + 1, y, z) == Tile::rock->id) rockCount++;
|
||||
if (level->getTile(x, y, z - 1) == Tile::rock->id) rockCount++;
|
||||
if (level->getTile(x, y, z + 1) == Tile::rock->id) rockCount++;
|
||||
|
||||
int holeCount = 0;
|
||||
if (level->isEmptyTile(x - 1, y, z)) holeCount++;
|
||||
if (level->isEmptyTile(x + 1, y, z)) holeCount++;
|
||||
if (level->isEmptyTile(x, y, z - 1)) holeCount++;
|
||||
if (level->isEmptyTile(x, y, z + 1)) holeCount++;
|
||||
|
||||
if (rockCount == 3 && holeCount == 1) {
|
||||
level->setTile(x, y, z, tile);
|
||||
level->instaTick = true;
|
||||
Tile::tiles[tile]->tick(level, x, y, z, random);
|
||||
level->instaTick = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__SpringFeature_H__*/
|
||||
101
src/world/level/levelgen/feature/SpruceFeature.h
Executable file
101
src/world/level/levelgen/feature/SpruceFeature.h
Executable file
@@ -0,0 +1,101 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__SpruceFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__SpruceFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
#include "../../../../util/Random.h"
|
||||
#include "../../Level.h"
|
||||
#include "../../tile/LeafTile.h"
|
||||
#include "../../tile/TreeTile.h"
|
||||
|
||||
class SpruceFeature: public Feature
|
||||
{
|
||||
typedef Feature super;
|
||||
public:
|
||||
SpruceFeature(bool doUpdate = false)
|
||||
: super(doUpdate)
|
||||
{
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
|
||||
// pines can be quite tall
|
||||
int treeHeight = random->nextInt(4) + 6;
|
||||
int trunkHeight = 1 + random->nextInt(2);
|
||||
int topHeight = treeHeight - trunkHeight;
|
||||
int leafRadius = 2 + random->nextInt(2);
|
||||
|
||||
bool free = true;
|
||||
// may not be outside of y boundaries
|
||||
if (y < 1 || y + treeHeight + 1 > Level::DEPTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// make sure there is enough space
|
||||
for (int yy = y; yy <= y + 1 + treeHeight && free; yy++) {
|
||||
|
||||
int r = 1;
|
||||
if ((yy - y) < trunkHeight) {
|
||||
r = 0;
|
||||
} else {
|
||||
r = leafRadius;
|
||||
}
|
||||
for (int xx = x - r; xx <= x + r && free; xx++) {
|
||||
for (int zz = z - r; zz <= z + r && free; zz++) {
|
||||
if (yy >= 0 && yy < Level::DEPTH) {
|
||||
int tt = level->getTile(xx, yy, zz);
|
||||
if (tt != 0 && tt != Tile::leaves->id) free = false;
|
||||
} else {
|
||||
free = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!free) return false;
|
||||
|
||||
// must stand on ground
|
||||
int belowTile = level->getTile(x, y - 1, z);
|
||||
if ((belowTile != ((Tile*)Tile::grass)->id && belowTile != Tile::dirt->id) || y >= Level::DEPTH - treeHeight - 1) return false;
|
||||
|
||||
placeBlock(level, x, y - 1, z, Tile::dirt->id);
|
||||
|
||||
// place leaf top
|
||||
int currentRadius = random->nextInt(2);
|
||||
int maxRadius = 1;
|
||||
int minRadius = 0;
|
||||
for (int heightPos = 0; heightPos <= topHeight; heightPos++) {
|
||||
|
||||
const int yy = y + treeHeight - heightPos;
|
||||
|
||||
for (int xx = x - currentRadius; xx <= x + currentRadius; xx++) {
|
||||
int xo = xx - (x);
|
||||
for (int zz = z - currentRadius; zz <= z + currentRadius; zz++) {
|
||||
int zo = zz - (z);
|
||||
if (std::abs(xo) == currentRadius && std::abs(zo) == currentRadius && currentRadius > 0) continue;
|
||||
if (!Tile::solid[level->getTile(xx, yy, zz)]) placeBlock(level, xx, yy, zz, Tile::leaves->id, LeafTile::EVERGREEN_LEAF);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentRadius >= maxRadius) {
|
||||
currentRadius = minRadius;
|
||||
minRadius = 1;
|
||||
maxRadius += 1;
|
||||
if (maxRadius > leafRadius) {
|
||||
maxRadius = leafRadius;
|
||||
}
|
||||
} else {
|
||||
currentRadius = currentRadius + 1;
|
||||
}
|
||||
}
|
||||
int topOffset = random->nextInt(3);
|
||||
for (int hh = 0; hh < treeHeight - topOffset; hh++) {
|
||||
int t = level->getTile(x, y + hh, z);
|
||||
if (t == 0 || t == Tile::leaves->id) placeBlock(level, x, y + hh, z, Tile::treeTrunk->id, TreeTile::DARK_TRUNK);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__SpruceFeature_H__*/
|
||||
40
src/world/level/levelgen/feature/TallgrassFeature.h
Executable file
40
src/world/level/levelgen/feature/TallgrassFeature.h
Executable file
@@ -0,0 +1,40 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__TallgrassFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__TallgrassFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
|
||||
class TallgrassFeature : public Feature
|
||||
{
|
||||
typedef Feature super;
|
||||
public:
|
||||
TallgrassFeature(int tile, int type)
|
||||
: super(false), tile(tile), type(type)
|
||||
{
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
int t = 0;
|
||||
while (((t = level->getTile(x, y, z)) == 0 || t == Tile::leaves->id) && y > 0)
|
||||
y--;
|
||||
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int x2 = x + random->nextInt(8) - random->nextInt(8);
|
||||
int y2 = y + random->nextInt(4) - random->nextInt(4);
|
||||
int z2 = z + random->nextInt(8) - random->nextInt(8);
|
||||
if (level->isEmptyTile(x2, y2, z2)) {
|
||||
if (Tile::tiles[tile]->canSurvive(level, x2, y2, z2)) {
|
||||
level->setTileAndDataNoUpdate(x2, y2, z2, tile, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
int tile;
|
||||
int type;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__TallgrassFeature_H__*/
|
||||
74
src/world/level/levelgen/feature/TreeFeature.h
Executable file
74
src/world/level/levelgen/feature/TreeFeature.h
Executable file
@@ -0,0 +1,74 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__TreeFeature_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__TreeFeature_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.feature;
|
||||
|
||||
#include "Feature.h"
|
||||
|
||||
#include "../../../../util/Random.h"
|
||||
#include "../../Level.h"
|
||||
|
||||
#include "../../tile/TreeTile.h"
|
||||
|
||||
class TreeFeature: public Feature
|
||||
{
|
||||
typedef Feature super;
|
||||
public:
|
||||
TreeFeature(bool doUpdate, int trunkType = TreeTile::NORMAL_TRUNK)
|
||||
: super(doUpdate),
|
||||
trunkType(trunkType)
|
||||
{
|
||||
}
|
||||
|
||||
bool place(Level* level, Random* random, int x, int y, int z) {
|
||||
int treeHeight = random->nextInt(3) + 4;
|
||||
|
||||
bool free = true;
|
||||
if (y < 1 || y + treeHeight + 1 > Level::DEPTH) return false;
|
||||
|
||||
for (int yy = y; yy <= y + 1 + treeHeight; yy++) {
|
||||
int r = 1;
|
||||
if (yy == y) r = 0;
|
||||
if (yy >= y + 1 + treeHeight - 2) r = 2;
|
||||
for (int xx = x - r; xx <= x + r && free; xx++) {
|
||||
for (int zz = z - r; zz <= z + r && free; zz++) {
|
||||
if (yy >= 0 && yy < Level::DEPTH) {
|
||||
int tt = level->getTile(xx, yy, zz);
|
||||
if (tt != 0 && tt != ((Tile*)Tile::leaves)->id) free = false;
|
||||
} else {
|
||||
free = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!free) return false;
|
||||
|
||||
int belowTile = level->getTile(x, y - 1, z);
|
||||
if ((belowTile != ((Tile*)Tile::grass)->id && belowTile != Tile::dirt->id) || y >= Level::DEPTH - treeHeight - 1) return false;
|
||||
|
||||
placeBlock(level, x, y - 1, z, Tile::dirt->id);
|
||||
|
||||
for (int yy = y - 3 + treeHeight; yy <= y + treeHeight; yy++) {
|
||||
int yo = yy - (y + treeHeight);
|
||||
int offs = 1 - yo / 2;
|
||||
for (int xx = x - offs; xx <= x + offs; xx++) {
|
||||
int xo = xx - (x);
|
||||
for (int zz = z - offs; zz <= z + offs; zz++) {
|
||||
int zo = zz - (z);
|
||||
if (std::abs(xo) == offs && std::abs(zo) == offs && (random->nextInt(2) == 0 || yo == 0)) continue;
|
||||
if (!Tile::solid[level->getTile(xx, yy, zz)]) placeBlock(level, xx, yy, zz, ((Tile*)Tile::leaves)->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int hh = 0; hh < treeHeight; hh++) {
|
||||
int t = level->getTile(x, y + hh, z);
|
||||
if (t == 0 || t == ((Tile*)Tile::leaves)->id) placeBlock(level, x, y + hh, z, Tile::treeTrunk->id, trunkType);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
int trunkType;
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_FEATURE__TreeFeature_H__*/
|
||||
205
src/world/level/levelgen/synth/ImprovedNoise.cpp
Executable file
205
src/world/level/levelgen/synth/ImprovedNoise.cpp
Executable file
@@ -0,0 +1,205 @@
|
||||
#include "ImprovedNoise.h"
|
||||
#include "../../../../util/Random.h"
|
||||
|
||||
ImprovedNoise::ImprovedNoise()
|
||||
{
|
||||
Random random(1);
|
||||
init(&random);
|
||||
}
|
||||
|
||||
ImprovedNoise::ImprovedNoise( Random* random )
|
||||
{
|
||||
init(random);
|
||||
}
|
||||
|
||||
void ImprovedNoise::init( Random* random )
|
||||
{
|
||||
xo = random->nextFloat() * 256.f;
|
||||
yo = random->nextFloat() * 256.f;
|
||||
zo = random->nextFloat() * 256.f;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
p[i] = i;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int j = random->nextInt(256 - i) + i;
|
||||
int tmp = p[i];
|
||||
p[i] = p[j];
|
||||
p[j] = tmp;
|
||||
|
||||
p[i + 256] = p[i];
|
||||
}
|
||||
}
|
||||
|
||||
float ImprovedNoise::noise( float _x, float _y, float _z )
|
||||
{
|
||||
float x = _x + xo;
|
||||
float y = _y + yo;
|
||||
float z = _z + zo;
|
||||
|
||||
int xf = (int) x;
|
||||
int yf = (int) y;
|
||||
int zf = (int) z;
|
||||
|
||||
if (x < xf) xf--;
|
||||
if (y < yf) yf--;
|
||||
if (z < zf) zf--;
|
||||
|
||||
int X = xf & 255, // FIND UNIT CUBE THAT
|
||||
Y = yf & 255, // CONTAINS POINT.
|
||||
Z = zf & 255;
|
||||
|
||||
x -= xf; // FIND RELATIVE X,Y,Z
|
||||
y -= yf; // OF POINT IN CUBE.
|
||||
z -= zf;
|
||||
|
||||
float u = x * x * x * (x * (x * 6 - 15) + 10), // COMPUTE FADE CURVES
|
||||
v = y * y * y * (y * (y * 6 - 15) + 10), // FOR EACH OF X,Y,Z.
|
||||
w = z * z * z * (z * (z * 6 - 15) + 10);
|
||||
|
||||
int A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z, // HASH COORDINATES OF
|
||||
B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z; // THE 8 CUBE CORNERS,
|
||||
|
||||
return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), // AND ADD
|
||||
grad(p[BA], x - 1, y, z)), // BLENDED
|
||||
lerp(u, grad(p[AB], x, y - 1, z), // RESULTS
|
||||
grad(p[BB], x - 1, y - 1, z))),// FROM 8
|
||||
lerp(v, lerp(u, grad(p[AA + 1], x, y, z - 1), // CORNERS
|
||||
grad(p[BA + 1], x - 1, y, z - 1)), // OF CUBE
|
||||
lerp(u, grad(p[AB + 1], x, y - 1, z - 1), grad(p[BB + 1], x - 1, y - 1, z - 1))));
|
||||
}
|
||||
|
||||
const float ImprovedNoise::lerp( float t, float a, float b )
|
||||
{
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
const float ImprovedNoise::grad2( int hash, float x, float z )
|
||||
{
|
||||
int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
|
||||
|
||||
float u = (1-((h&8)>>3))*x, // INTO 12 GRADIENT DIRECTIONS.
|
||||
v = h < 4 ? 0 : h == 12 || h == 14 ? x : z;
|
||||
|
||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
||||
}
|
||||
|
||||
const float ImprovedNoise::grad( int hash, float x, float y, float z )
|
||||
{
|
||||
int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
|
||||
|
||||
float u = h < 8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.
|
||||
v = h < 4 ? y : h == 12 || h == 14 ? x : z;
|
||||
|
||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
||||
}
|
||||
|
||||
float ImprovedNoise::getValue( float x, float y )
|
||||
{
|
||||
return noise(x, y, 0);
|
||||
}
|
||||
|
||||
float ImprovedNoise::getValue( float x, float y, float z )
|
||||
{
|
||||
return noise(x, y, z);
|
||||
}
|
||||
|
||||
void ImprovedNoise::add( float* buffer, float _x, float _y, float _z, int xSize, int ySize, int zSize, float xs, float ys, float zs, float pow )
|
||||
{
|
||||
if (ySize==1) {
|
||||
int A = 0, AA = 0, B = 0, BA = 0;
|
||||
float vv0 = 0, vv2 = 0;
|
||||
int pp = 0;
|
||||
float scale = 1.0f / pow;
|
||||
for (int xx = 0; xx < xSize; xx++) {
|
||||
float x = (_x + xx) * xs + xo;
|
||||
int xf = (int) x;
|
||||
if (x < xf) xf--;
|
||||
int X = xf & 255;
|
||||
x -= xf;
|
||||
float u = x * x * x * (x * (x * 6 - 15) + 10);
|
||||
|
||||
for (int zz = 0; zz < zSize; zz++) {
|
||||
float z = (_z + zz) * zs + zo;
|
||||
int zf = (int) z;
|
||||
if (z < zf) zf--;
|
||||
int Z = zf & 255;
|
||||
z -= zf;
|
||||
float w = z * z * z * (z * (z * 6 - 15) + 10);
|
||||
|
||||
A = p[X] + 0;
|
||||
AA = p[A] + Z;
|
||||
B = p[X + 1] + 0;
|
||||
BA = p[B] + Z;
|
||||
vv0 = lerp(u, grad2(p[AA], x, z), grad(p[BA], x - 1, 0, z));
|
||||
vv2 = lerp(u, grad(p[AA + 1], x, 0, z - 1), grad(p[BA + 1], x - 1, 0, z - 1));
|
||||
|
||||
float val = lerp(w, vv0, vv2);
|
||||
|
||||
buffer[pp++] += val * scale;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
int pp = 0;
|
||||
float scale = 1 / pow;
|
||||
int yOld = -1;
|
||||
int A = 0, AA = 0, AB = 0, B = 0, BA = 0, BB = 0;
|
||||
float vv0 = 0, vv1 = 0, vv2 = 0, vv3 = 0;
|
||||
|
||||
for (int xx = 0; xx < xSize; xx++) {
|
||||
float x = (_x + xx) * xs + xo;
|
||||
int xf = (int) x;
|
||||
if (x < xf) xf--;
|
||||
int X = xf & 255;
|
||||
x -= xf;
|
||||
float u = x * x * x * (x * (x * 6 - 15) + 10);
|
||||
|
||||
|
||||
for (int zz = 0; zz < zSize; zz++) {
|
||||
float z = (_z + zz) * zs + zo;
|
||||
int zf = (int) z;
|
||||
if (z < zf) zf--;
|
||||
int Z = zf & 255;
|
||||
z -= zf;
|
||||
float w = z * z * z * (z * (z * 6 - 15) + 10);
|
||||
|
||||
for (int yy = 0; yy < ySize; yy++) {
|
||||
float y = (_y + yy) * ys + yo;
|
||||
int yf = (int) y;
|
||||
if (y < yf) yf--;
|
||||
int Y = yf & 255;
|
||||
y -= yf;
|
||||
float v = y * y * y * (y * (y * 6 - 15) + 10);
|
||||
|
||||
if (yy == 0 || Y != yOld) {
|
||||
yOld = Y;
|
||||
A = p[X] + Y;
|
||||
AA = p[A] + Z;
|
||||
AB = p[A + 1] + Z;
|
||||
B = p[X + 1] + Y;
|
||||
BA = p[B] + Z;
|
||||
BB = p[B + 1] + Z;
|
||||
vv0 = lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1, y, z));
|
||||
vv1 = lerp(u, grad(p[AB], x, y - 1, z), grad(p[BB], x - 1, y - 1, z));
|
||||
vv2 = lerp(u, grad(p[AA + 1], x, y, z - 1), grad(p[BA + 1], x - 1, y, z - 1));
|
||||
vv3 = lerp(u, grad(p[AB + 1], x, y - 1, z - 1), grad(p[BB + 1], x - 1, y - 1, z - 1));
|
||||
}
|
||||
|
||||
float v0 = lerp(v, vv0, vv1);
|
||||
float v1 = lerp(v, vv2, vv3);
|
||||
float val = lerp(w, v0, v1);
|
||||
|
||||
buffer[pp++] += val * scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ImprovedNoise::hashCode() {
|
||||
int x = 4711;
|
||||
for (int i = 0; i < 512; ++i)
|
||||
x = x * 37 + p[i];
|
||||
return x;
|
||||
}
|
||||
|
||||
38
src/world/level/levelgen/synth/ImprovedNoise.h
Executable file
38
src/world/level/levelgen/synth/ImprovedNoise.h
Executable file
@@ -0,0 +1,38 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__ImprovedNoise_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__ImprovedNoise_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.synth;
|
||||
|
||||
#include "Synth.h"
|
||||
class Random;
|
||||
|
||||
class ImprovedNoise: public Synth
|
||||
{
|
||||
public:
|
||||
ImprovedNoise();
|
||||
|
||||
ImprovedNoise(Random* random);
|
||||
|
||||
void init(Random* random);
|
||||
|
||||
float noise(float _x, float _y, float _z);
|
||||
|
||||
const float lerp(float t, float a, float b);
|
||||
|
||||
const float grad2(int hash, float x, float z);
|
||||
const float grad(int hash, float x, float y, float z);
|
||||
|
||||
float getValue(float x, float y);
|
||||
float getValue(float x, float y, float z);
|
||||
|
||||
void add(float* buffer, float _x, float _y, float _z, int xSize, int ySize, int zSize, float xs, float ys, float zs, float pow);
|
||||
|
||||
int hashCode();
|
||||
|
||||
float scale;
|
||||
float xo, yo, zo;
|
||||
private:
|
||||
int p[512];
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__ImprovedNoise_H__*/
|
||||
88
src/world/level/levelgen/synth/PerlinNoise.cpp
Executable file
88
src/world/level/levelgen/synth/PerlinNoise.cpp
Executable file
@@ -0,0 +1,88 @@
|
||||
#include "PerlinNoise.h"
|
||||
#include "ImprovedNoise.h"
|
||||
|
||||
void PerlinNoise::init( int levels )
|
||||
{
|
||||
this->levels = levels;
|
||||
noiseLevels = new ImprovedNoise* [levels];
|
||||
for (int i = 0; i < levels; i++) {
|
||||
noiseLevels[i] = new ImprovedNoise(_rndPtr);
|
||||
}
|
||||
}
|
||||
|
||||
PerlinNoise::~PerlinNoise()
|
||||
{
|
||||
for (int i = 0; i < levels; ++i)
|
||||
delete noiseLevels[i];
|
||||
delete[] noiseLevels;
|
||||
}
|
||||
|
||||
PerlinNoise::PerlinNoise( int levels )
|
||||
{
|
||||
_rndPtr = &_random;
|
||||
init(levels);
|
||||
}
|
||||
|
||||
PerlinNoise::PerlinNoise( Random* random, int levels )
|
||||
{
|
||||
_rndPtr = random;
|
||||
init(levels);
|
||||
}
|
||||
|
||||
float PerlinNoise::getValue( float x, float y )
|
||||
{
|
||||
float value = 0;
|
||||
float pow = 1;
|
||||
|
||||
for (int i = 0; i < levels; i++) {
|
||||
value += noiseLevels[i]->getValue(x * pow, y * pow) / pow;
|
||||
pow /= 2;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
float PerlinNoise::getValue( float x, float y, float z )
|
||||
{
|
||||
float value = 0;
|
||||
float pow = 1;
|
||||
|
||||
for (int i = 0; i < levels; i++) {
|
||||
value += noiseLevels[i]->getValue(x * pow, y * pow, z * pow) / pow;
|
||||
pow /= 2;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
float* PerlinNoise::getRegion( float* buffer, float x, float y, float z, int xSize, int ySize, int zSize, float xScale, float yScale, float zScale )
|
||||
{
|
||||
const int size = xSize * ySize * zSize;
|
||||
if (buffer == 0) {
|
||||
buffer = new float[size];
|
||||
}
|
||||
for (int i = 0; i < size; i++)
|
||||
buffer[i] = 0;
|
||||
|
||||
float pow = 1;
|
||||
|
||||
for (int i = 0; i < levels; i++) {
|
||||
noiseLevels[i]->add(buffer, x, y, z, xSize, ySize, zSize, xScale * pow, yScale * pow, zScale * pow, pow);
|
||||
pow /= 2;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
float* PerlinNoise::getRegion( float* sr, int x, int z, int xSize, int zSize, float xScale, float zScale, float pow )
|
||||
{
|
||||
return getRegion(sr, (float)x, 10.0f, (float)z, xSize, 1, zSize, xScale, 1, zScale);
|
||||
}
|
||||
|
||||
int PerlinNoise::hashCode() {
|
||||
int x = 4711;
|
||||
for (int i = 0; i < levels; ++i)
|
||||
x *= noiseLevels[i]->hashCode();
|
||||
return x;
|
||||
}
|
||||
|
||||
37
src/world/level/levelgen/synth/PerlinNoise.h
Executable file
37
src/world/level/levelgen/synth/PerlinNoise.h
Executable file
@@ -0,0 +1,37 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__PerlinNoise_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__PerlinNoise_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.synth;
|
||||
|
||||
#include "../../../../util/Random.h"
|
||||
#include "Synth.h"
|
||||
|
||||
class ImprovedNoise;
|
||||
|
||||
class PerlinNoise: public Synth
|
||||
{
|
||||
public:
|
||||
PerlinNoise(int levels);
|
||||
PerlinNoise(Random* random, int levels);
|
||||
~PerlinNoise();
|
||||
|
||||
float getValue(float x, float y);
|
||||
float getValue(float x, float y, float z);
|
||||
|
||||
//float[] getRegion(float[] buffer, float x, float y, float z, int xSize, int ySize, int zSize, float xScale, float yScale, float zScale) {
|
||||
float* getRegion(float* buffer, float x, float y, float z, int xSize, int ySize, int zSize, float xScale, float yScale, float zScale);
|
||||
float* getRegion(float* sr, int x, int z, int xSize, int zSize, float xScale, float zScale, float pow);
|
||||
|
||||
int hashCode();
|
||||
|
||||
private:
|
||||
ImprovedNoise** noiseLevels;
|
||||
int levels;
|
||||
|
||||
Random _random;
|
||||
Random* _rndPtr;
|
||||
|
||||
void init(int levels);
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__PerlinNoise_H__*/
|
||||
21
src/world/level/levelgen/synth/Synth.cpp
Executable file
21
src/world/level/levelgen/synth/Synth.cpp
Executable file
@@ -0,0 +1,21 @@
|
||||
#include "Synth.h"
|
||||
|
||||
Synth::~Synth()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int Synth::getDataSize( int width, int height )
|
||||
{
|
||||
return width * height * sizeof(float);
|
||||
}
|
||||
|
||||
void Synth::create( int width, int height, float* result )
|
||||
{
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
result[x + y * width] = getValue((float)x, (float)y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
src/world/level/levelgen/synth/Synth.h
Executable file
18
src/world/level/levelgen/synth/Synth.h
Executable file
@@ -0,0 +1,18 @@
|
||||
#ifndef NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__Synth_H__
|
||||
#define NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__Synth_H__
|
||||
|
||||
//package net.minecraft.world.level.levelgen.synth;
|
||||
|
||||
class Synth
|
||||
{
|
||||
public:
|
||||
virtual ~Synth();
|
||||
|
||||
int getDataSize(int width, int height);
|
||||
|
||||
virtual float getValue(float x, float y) = 0;
|
||||
|
||||
void create(int width, int height, float* result);
|
||||
};
|
||||
|
||||
#endif /*NET_MINECRAFT_WORLD_LEVEL_LEVELGEN_SYNTH__Synth_H__*/
|
||||
Reference in New Issue
Block a user