the whole game

This commit is contained in:
Kolyah35
2026-03-02 22:04:18 +03:00
parent 816e9060b4
commit f0617a5d22
2069 changed files with 581500 additions and 0 deletions

View 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__*/

View 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__*/

View 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__*/

View 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);
}
}

View 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__*/

View 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__*/

View 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__*/

View 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__*/

View 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__*/

View 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__*/

View 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__*/

View 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__*/

View 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__*/

View 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__*/

View 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__*/