oops forgot to include the other files.

This commit is contained in:
Shredder
2026-04-01 23:37:37 +05:00
parent 27f0287986
commit 84e8744387
8 changed files with 51 additions and 194 deletions

View File

@@ -225,29 +225,16 @@ bool TileRenderer::tesselateTorchInWorld( Tile* tt, int x, int y, int z )
bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z ) bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
{ {
// @todo: fire alpha transparency seems to be scuffed, also it seems i might have messed up the second layer while porting from lce/java , need to look into it - shredder
Tesselator& t = Tesselator::instance; Tesselator& t = Tesselator::instance;
//Icon *firstTex = tt->getTextureLayer(0);
//Icon *secondTex = tt->getTextureLayer(1);
//Icon *tex = firstTex;
int tex = tt->getTexture(0); int tex = tt->getTexture(0);
// if (hasFixedTexture()) tex = fixedTexture;
if (fixedTexture >= 0) tex = fixedTexture; if (fixedTexture >= 0) tex = fixedTexture;
float br = tt->getBrightness( level, x, y, z );
// t.color( 1.0f, 1.0f, 1.0f ); t.color( br, br, br );
// t.tex( getLightColor(tt, level, x, y, z ) );
float br = tt->getBrightness( level, x, y, z );
t.color( br, br, br );
int xt = ((tex & 0xf) << 4); int xt = ((tex & 0xf) << 4);
int yt = tex & 0xf0; int yt = tex & 0xf0;
@@ -256,7 +243,7 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
float u1 = (xt + 15.99f) / 256.0f; float u1 = (xt + 15.99f) / 256.0f;
float v0 = (yt) / 256.0f; float v0 = (yt) / 256.0f;
float v1 = (yt + 15.99f) / 256.0f; float v1 = (yt + 15.99f) / 256.0f;
float h = 1.4f; float h = 1.4f;
if ( level->isSolidBlockingTile( x, y - 1, z ) || Tile::fire->canBurn( level, x, y - 1, z ) ) if ( level->isSolidBlockingTile( x, y - 1, z ) || Tile::fire->canBurn( level, x, y - 1, z ) )
{ {
@@ -280,11 +267,7 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
t.vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v1 ) ); t.vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v1 ) );
t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v0 ) ); t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 1 ), ( float )( u0 ), ( float )( v0 ) );
// tex = secondTex;
// u0 = tex->getU0(true);
// v0 = tex->getV0(true);
// u1 = tex->getU1(true);
// v1 = tex->getV1(true);
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
@@ -321,7 +304,7 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
t.vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v1 ) ); t.vertexUV( ( float )( x1 ), ( float )( y + 0 ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v1 ) );
t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v0 ) ); t.vertexUV( ( float )( x1_ ), ( float )( y + h ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v0 ) );
// tex = firstTex;
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
v0 = (yt) / 256.0f; v0 = (yt) / 256.0f;
@@ -343,7 +326,6 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
float yo = 1 / 16.0f; float yo = 1 / 16.0f;
if ( ( ( x + y + z ) & 1 ) == 1 ) if ( ( ( x + y + z ) & 1 ) == 1 )
{ {
// tex = secondTex;
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
v0 = (yt) / 256.0f; v0 = (yt) / 256.0f;
@@ -447,7 +429,6 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
double z0_ = z + 0.5f - 0.5f; double z0_ = z + 0.5f - 0.5f;
double z1_ = z + 0.5f + 0.5f; double z1_ = z + 0.5f + 0.5f;
// tex = firstTex;
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
v0 = (yt) / 256.0f; v0 = (yt) / 256.0f;
@@ -467,7 +448,6 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z + t.vertexUV( ( float )( x0_ ), ( float )( y + h ), ( float )( z +
1 ), ( float )( u0 ), ( float )( v0 ) ); 1 ), ( float )( u0 ), ( float )( v0 ) );
// tex = secondTex;
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
v0 = (yt) / 256.0f; v0 = (yt) / 256.0f;
@@ -493,7 +473,6 @@ bool TileRenderer::tesselateFireInWorld( Tile* tt, int x, int y, int z )
t.vertexUV( ( float )( x + 1.0f ), ( float )( y + t.vertexUV( ( float )( x + 1.0f ), ( float )( y +
h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) );
// tex = secondTex;
u0 = (xt) / 256.0f; u0 = (xt) / 256.0f;
u1 = (xt + 15.99f) / 256.0f; u1 = (xt + 15.99f) / 256.0f;
v0 = (yt) / 256.0f; v0 = (yt) / 256.0f;

View File

@@ -19,7 +19,7 @@ public:
setMaxDamage(64); setMaxDamage(64);
} }
/*
bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) { bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if (face == 0) y--; if (face == 0) y--;
if (face == 1) y++; if (face == 1) y++;
@@ -30,14 +30,14 @@ public:
int targetType = level->getTile(x, y, z); int targetType = level->getTile(x, y, z);
if (targetType == 0) { if (targetType == 0) {
level->playSound(x + 0.5, y + 0.5, z + 0.5, "fire.ignite", 1, sharedRandom.nextFloat() * 0.4f + 0.8f); level->playSound(x + 0.5, y + 0.5, z + 0.5, "fire.ignite", 1, random.nextFloat() * 0.4f + 0.8f);
level->setTile(x, y, z, Tile::fire->id); level->setTile(x, y, z, ((Tile*)Tile::fire)->id);
} }
instance->hurt(1); instance->hurt(1);
return true; return true;
} }
*/
}; };
#endif /*NET_MINECRAFT_WORLD_ITEM__FlintAndSteelItem_H__*/ #endif /*NET_MINECRAFT_WORLD_ITEM__FlintAndSteelItem_H__*/

View File

@@ -2,6 +2,7 @@
#include "../levelgen/feature/TreeFeature.h" #include "../levelgen/feature/TreeFeature.h"
#include "../levelgen/feature/TallgrassFeature.h" #include "../levelgen/feature/TallgrassFeature.h"
#include "../levelgen/feature/BasicTree.h"
#include "../../entity/EntityTypes.h" #include "../../entity/EntityTypes.h"
#include "../../entity/MobCategory.h" #include "../../entity/MobCategory.h"
@@ -140,7 +141,7 @@ void Biome::teardownBiomes() {
Feature* Biome::getTreeFeature( Random* random ) Feature* Biome::getTreeFeature( Random* random )
{ {
if (random->nextInt(10) == 0) { if (random->nextInt(10) == 0) {
//return /*new*/ BasicTree(); return new BasicTree(false);
} }
return new TreeFeature(false); return new TreeFeature(false);
} }
@@ -148,6 +149,15 @@ Feature* Biome::getGrassFeature( Random* random ) {
return new TallgrassFeature(Tile::tallgrass->id, TallGrass::TALL_GRASS); return new TallgrassFeature(Tile::tallgrass->id, TallGrass::TALL_GRASS);
} }
Feature* Biome::getBasicTreeFeature( Random* random )
{
if (random->nextInt(10) == 0) {
return new BasicTree(false);
}
}
Biome* Biome::getBiome( float temperature, float downfall ) Biome* Biome::getBiome( float temperature, float downfall )
{ {
int a = (int) (temperature * 63); int a = (int) (temperature * 63);

View File

@@ -71,6 +71,7 @@ public:
virtual Feature* getTreeFeature(Random* random); virtual Feature* getTreeFeature(Random* random);
virtual Feature* getGrassFeature(Random* random); virtual Feature* getGrassFeature(Random* random);
virtual Feature* getBasicTreeFeature(Random* random);
static Biome* getBiome(float temperature, float downfall); static Biome* getBiome(float temperature, float downfall);
static Biome* _getBiome(float temperature, float downfall); static Biome* _getBiome(float temperature, float downfall);

View File

@@ -6,6 +6,7 @@
#include "Biome.h" #include "Biome.h"
#include "../levelgen/feature/TreeFeature.h" #include "../levelgen/feature/TreeFeature.h"
#include "../levelgen/feature/BirchFeature.h" #include "../levelgen/feature/BirchFeature.h"
#include "../levelgen/feature/BasicTree.h"
class ForestBiome: public Biome class ForestBiome: public Biome
{ {
@@ -15,7 +16,7 @@ public:
return new BirchFeature(); return new BirchFeature();
} }
if (random->nextInt(3) == 0) { if (random->nextInt(3) == 0) {
//return new BasicTree(); return new BasicTree(false);
} }
return new TreeFeature(false); return new TreeFeature(false);
} }

View File

@@ -6,13 +6,14 @@
#include "Biome.h" #include "Biome.h"
#include "../../../util/Random.h" #include "../../../util/Random.h"
#include "../levelgen/feature/TreeFeature.h" #include "../levelgen/feature/TreeFeature.h"
#include "../levelgen/feature/BasicTree.h"
class RainforestBiome: public Biome class RainforestBiome: public Biome
{ {
public: public:
Feature* getTreeFeature(Random* random) { Feature* getTreeFeature(Random* random) {
if (random->nextInt(3) == 0) { if (random->nextInt(3) == 0) {
//return new BasicTree(); return new BasicTree(false);
} }
return new TreeFeature(false); return new TreeFeature(false);
} }

View File

@@ -370,6 +370,18 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) {
} }
//printf("placing tree at %d, %d, %d\n", x, y, z); //printf("placing tree at %d, %d, %d\n", x, y, z);
} }
// 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->getBasicTreeFeature(&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++) { for (int i = 0; i < 2; i++) {
int x = xo + random.nextInt(16) + 8; int x = xo + random.nextInt(16) + 8;

View File

@@ -19,36 +19,11 @@ private:
// The axisConversionArray, when given a primary index, allows easy
// access to the indices of the other two axies. Access the data at the
// primary index location to get the horizontal secondary axis.
// Access the data at the primary location plus three to get the
// remaining, tertiary, axis.
// All directions are specified by an index, 0, 1, or 2 which
// correspond to x, y, and z.
// The axisConversionArray is used in several places
// notably the crossection and taperedLimb methods.
// Example:
// If the primary axis is z, then the primary index is 2.
// The secondary index is axisConversionArray[2] which is 0,
// the index for the x axis.
// The remaining axis is axisConversionArray[2 + 3] which is 1,
// the index for the y axis.
// Using this method, the secondary axis will always be horizontal (x or z),
// and the tertiary always vertical (y), if possible.
unsigned char axisConversionArray[6]; unsigned char axisConversionArray[6];
// Set up the pseudorandom number generator
Random *rnd; Random *rnd;
// Make fields to hold the level data and the random seed
Level *thisLevel; Level *thisLevel;
// Field to hold the tree origin, x y and z.
int origin[3]; int origin[3];
// Field to hold the tree height.
int height; int height;
// Other important tree information.
int trunkHeight; int trunkHeight;
double trunkHeightScale; double trunkHeightScale;
double branchDensity; double branchDensity;
@@ -58,19 +33,13 @@ private:
int trunkWidth; int trunkWidth;
int heightVariance; int heightVariance;
int foliageHeight; int foliageHeight;
// The foliage coordinates are a list of [x,y,z,y of branch base] values for each cluster
int **foliageCoords; int **foliageCoords;
int foliageCoordsLength; int foliageCoordsLength;
void prepare(){ void prepare(){
// Initialize the instance variables.
// Populate the list of foliage cluster locations.
// Designed to be overridden in child classes to change basic
// tree properties (trunk width, branch angle, foliage density, etc..).
trunkHeight = (int) (height * trunkHeightScale); trunkHeight = (int) (height * trunkHeightScale);
if (trunkHeight >= height) trunkHeight = height - 1; if (trunkHeight >= height) trunkHeight = height - 1;
int clustersPerY = (int) (1.382 + pow(foliageDensity * height / 13.0, 2)); int clustersPerY = (int) (1.382 + pow(foliageDensity * height / 13.0, 2));
if (clustersPerY < 1) clustersPerY = 1; if (clustersPerY < 1) clustersPerY = 1;
// The foliage coordinates are a list of [x,y,z,y of branch base] values for each cluster
int **tempFoliageCoords = new int *[clustersPerY * height]; int **tempFoliageCoords = new int *[clustersPerY * height];
for( int i = 0; i < clustersPerY * height; i++ ) for( int i = 0; i < clustersPerY * height; i++ )
{ {
@@ -99,7 +68,6 @@ private:
continue; continue;
} }
// The originOffset is to put the value in the middle of the block.
double originOffset = 0.5; double originOffset = 0.5;
while (num < clustersPerY) while (num < clustersPerY)
{ {
@@ -109,10 +77,7 @@ private:
int z = Mth::floor(radius * cos(angle) + origin[2] + originOffset); int z = Mth::floor(radius * cos(angle) + origin[2] + originOffset);
int checkStart[] = { x, y, z }; int checkStart[] = { x, y, z };
int checkEnd[] = { x, y + foliageHeight, z }; int checkEnd[] = { x, y + foliageHeight, z };
// check the center column of the cluster for obstructions.
if (checkLine(checkStart, checkEnd) == -1) { if (checkLine(checkStart, checkEnd) == -1) {
// If the cluster can be created, check the branch path
// for obstructions.
int checkBranchBase[] = { origin[0], origin[1], origin[2] }; int checkBranchBase[] = { origin[0], origin[1], origin[2] };
double distance = sqrt(pow(abs(origin[0] - checkStart[0]), 2.0) + pow(abs(origin[2] - checkStart[2]), 2.0)); double distance = sqrt(pow(abs(origin[0] - checkStart[0]), 2.0) + pow(abs(origin[2] - checkStart[2]), 2.0));
double branchHeight = distance * branchSlope; double branchHeight = distance * branchSlope;
@@ -124,11 +89,8 @@ private:
{ {
checkBranchBase[1] = (int) (checkStart[1] - branchHeight); checkBranchBase[1] = (int) (checkStart[1] - branchHeight);
} }
// Now check the branch path
if (checkLine(checkBranchBase, checkStart) == -1) if (checkLine(checkBranchBase, checkStart) == -1)
{ {
// If the branch path is clear, add the position to the list
// of foliage positions
tempFoliageCoords[clusterCount][0] = x; tempFoliageCoords[clusterCount][0] = x;
tempFoliageCoords[clusterCount][1] = y; tempFoliageCoords[clusterCount][1] = y;
tempFoliageCoords[clusterCount][2] = z; tempFoliageCoords[clusterCount][2] = z;
@@ -141,34 +103,22 @@ private:
y--; y--;
relativeY--; relativeY--;
} }
// 4J Stu - Rather than copying the array, we are storing the number of valid elements in the array
foliageCoordsLength = clusterCount; foliageCoordsLength = clusterCount;
foliageCoords = tempFoliageCoords; foliageCoords = tempFoliageCoords;
// Delete the rest of the array whilst we still know how big it was
for( int i = clusterCount; i < clustersPerY * height; i++ ) for( int i = clusterCount; i < clustersPerY * height; i++ )
{ {
delete [] tempFoliageCoords[i]; delete [] tempFoliageCoords[i];
tempFoliageCoords[i] = NULL; tempFoliageCoords[i] = NULL;
} }
// 4J - original code for above is the following, it isn't obvious to me why it is doing a copy of the array, so let's not for now
// foliageCoords = new int[clusterCount][4];
// System.arraycopy(tempFoliageCoords, 0, foliageCoords, 0, clusterCount);
} }
void crossection(int x, int y, int z, float radius, byte direction, int material) void crossection(int x, int y, int z, float radius, byte direction, int material)
{ {
// Create a circular cross section.
//
// Used to nearly everything in the foliage, branches, and trunk.
// This is a good target for performance optimization.
// Passed values:
// x,y,z is the center location of the cross section
// radius is the radius of the section from the center
// direction is the direction the cross section is pointed, 0 for x, 1 for y, 2 for z
// material is the index number for the material to use
int rad = (int) (radius + 0.618); int rad = (int) (radius + 0.618);
byte secidx1 = axisConversionArray[direction]; byte secidx1 = axisConversionArray[direction];
byte secidx2 = axisConversionArray[direction + 3]; byte secidx2 = axisConversionArray[direction + 3];
@@ -196,8 +146,6 @@ private:
if (!((thismat == 0) || (thismat == Tile::leaves->id))) if (!((thismat == 0) || (thismat == Tile::leaves->id)))
{ {
// If the material of the checked block is anything other than
// air or foliage, skip this tile.
offset2++; offset2++;
continue; continue;
} }
@@ -211,12 +159,6 @@ private:
} }
float treeShape(int y){ float treeShape(int y){
// Take the y position relative to the base of the tree.
// Return the distance the foliage should be from the trunk axis.
// Return a negative number if foliage should not be created at this height.
// This method is intended for overriding in child classes, allowing
// different shaped trees.
// This method should return a consistent value for each y (don't randomize).
if (y < (((float) height) * 0.3)) return (float) -1.618; if (y < (((float) height) * 0.3)) return (float) -1.618;
float radius = ((float) height) / ((float) 2.0); float radius = ((float) height) / ((float) 2.0);
float adjacent = (((float) height) / ((float) 2.0)) - y; float adjacent = (((float) height) / ((float) 2.0)) - y;
@@ -224,29 +166,19 @@ private:
if (adjacent == 0) distance = radius; if (adjacent == 0) distance = radius;
else if (abs(adjacent) >= radius) distance = (float) 0.0; else if (abs(adjacent) >= radius) distance = (float) 0.0;
else distance = (float) sqrt(pow(abs(radius), 2) - pow(abs(adjacent), 2)); else distance = (float) sqrt(pow(abs(radius), 2) - pow(abs(adjacent), 2));
// Alter this factor to change the overall width of the tree.
distance *= (float) 0.5; distance *= (float) 0.5;
return distance; return distance;
} }
float foliageShape(int y){ float foliageShape(int y){
// Take the y position relative to the base of the foliage cluster.
// Return the radius of the cluster at this y
// Return a negative number if no foliage should be created at this level
// this method is intended for overriding in child classes, allowing
// foliage of different sizes and shapes.
if ((y < 0) || (y >= foliageHeight)) return (float) -1; if ((y < 0) || (y >= foliageHeight)) return (float) -1;
else if ((y == 0) || (y == (foliageHeight - 1))) return (float) 2; else if ((y == 0) || (y == (foliageHeight - 1))) return (float) 2;
else return (float) 3; else return (float) 3;
} }
void foliageCluster(int x, int y, int z){ void foliageCluster(int x, int y, int z){
// Generate a cluster of foliage, with the base at x, y, z.
// The shape of the cluster is derived from foliageShape
// crossection is called to make each level.
int topy = y + foliageHeight; int topy = y + foliageHeight;
int cury = topy - 1; int cury = topy - 1;
float radius; float radius;
// 4J Stu - Generate foliage from the top down so that we don't keep recalculating heightmaps
while (cury >= y) while (cury >= y)
{ {
radius = foliageShape(cury - y); radius = foliageShape(cury - y);
@@ -257,11 +189,6 @@ private:
} }
void limb(int *start, int *end, int material) void limb(int *start, int *end, int material)
{ {
// Create a limb from the start position to the end position.
// Used for creating the branches and trunk.
// Populate delta, the difference between start and end for all three axies.
// Set primidx to the index with the largest overall distance traveled.
int delta[] = { 0, 0, 0 }; int delta[] = { 0, 0, 0 };
byte idx = 0; byte idx = 0;
byte primidx = 0; byte primidx = 0;
@@ -274,22 +201,15 @@ private:
} }
idx++; idx++;
} }
// If the largest distance is zero, don't bother to do anything else.
if (delta[primidx] == 0) return; if (delta[primidx] == 0) return;
// set up the other two axis indices.
byte secidx1 = axisConversionArray[primidx]; byte secidx1 = axisConversionArray[primidx];
byte secidx2 = axisConversionArray[primidx + 3]; byte secidx2 = axisConversionArray[primidx + 3];
// primsign is digit 1 or -1 depending on whether the limb is headed
// along the positive or negative primidx axis.
char primsign; char primsign;
if (delta[primidx] > 0) primsign = 1; if (delta[primidx] > 0) primsign = 1;
else primsign = -1; else primsign = -1;
// Initilize the per-step movement for the non-primary axies.
double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]); double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]);
double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]); double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]);
// Initialize the coordinates.
int coordinate[] = { 0, 0, 0 }; int coordinate[] = { 0, 0, 0 };
// Loop through each crossection along the primary axis, from start to end
int primoffset = 0; int primoffset = 0;
int endoffset = delta[primidx] + primsign; int endoffset = delta[primidx] + primsign;
while (primoffset != endoffset) while (primoffset != endoffset)
@@ -319,8 +239,6 @@ private:
} }
} }
void makeFoliage(){ void makeFoliage(){
// Create the tree foliage.
// Call foliageCluster at the correct locations
int idx = 0; int idx = 0;
int finish = foliageCoordsLength; int finish = foliageCoordsLength;
while (idx < finish) while (idx < finish)
@@ -333,18 +251,10 @@ private:
} }
} }
bool trimBranches(int localY){ bool trimBranches(int localY){
// For larger trees, randomly "prune" the branches so there
// aren't too many.
// Return true if the branch should be created.
// This method is intended for overriding in child classes, allowing
// decent amounts of branches on very large trees.
// Can also be used to disable branches on some tree types, or
// make branches more sparse.
if (localY < (height * 0.2)) return false; if (localY < (height * 0.2)) return false;
else return true; else return true;
} }
void makeTrunk(){ void makeTrunk(){
// Create the trunk of the tree.
int x = origin[0]; int x = origin[0];
int startY = origin[1]; int startY = origin[1];
int topY = origin[1] + trunkHeight; int topY = origin[1] + trunkHeight;
@@ -366,9 +276,6 @@ private:
} }
} }
void makeBranches(){ void makeBranches(){
// Create the tree branches.
// Call trimBranches for each branch to see if you should create it.
// Call taperedLimb to the correct locations
int idx = 0; int idx = 0;
int finish = foliageCoordsLength; int finish = foliageCoordsLength;
int baseCoord[] = { origin[0], origin[1], origin[2] }; int baseCoord[] = { origin[0], origin[1], origin[2] };
@@ -386,12 +293,6 @@ private:
} }
} }
int checkLine(int *start, int *end){ int checkLine(int *start, int *end){
// Check from coordinates start to end (both inclusive) for blocks other than air and foliage
// If a block other than air and foliage is found, return the number of steps taken.
// If no block other than air and foliage is found, return -1.
// Examples:
// If the third block searched is stone, return 2
// If the first block searched is lava, return 0
int delta[] = { 0, 0, 0 }; int delta[] = { 0, 0, 0 };
byte idx = 0; byte idx = 0;
@@ -405,22 +306,15 @@ private:
} }
idx++; idx++;
} }
// If the largest distance is zero, don't bother to do anything else.
if (delta[primidx] == 0) return -1; if (delta[primidx] == 0) return -1;
// set up the other two axis indices.
byte secidx1 = axisConversionArray[primidx]; byte secidx1 = axisConversionArray[primidx];
byte secidx2 = axisConversionArray[primidx + 3]; byte secidx2 = axisConversionArray[primidx + 3];
// primsign is digit 1 or -1 depending on whether the limb is headed char primsign;
// along the positive or negative primidx axis.
char primsign; // 4J Stu - Was byte, but we use in a sum below and byte=unsigned char so we were setting endoffset incorrectly
if (delta[primidx] > 0) primsign = 1; if (delta[primidx] > 0) primsign = 1;
else primsign = -1; else primsign = -1;
// Initilize the per-step movement for the non-primary axies.
double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]); double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]);
double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]); double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]);
// Initialize the coordinates.
int coordinate[] = { 0, 0, 0 }; int coordinate[] = { 0, 0, 0 };
// Loop through each crossection along the primary axis, from start to end
int primoffset = 0; int primoffset = 0;
int endoffset = delta[primidx] + primsign; int endoffset = delta[primidx] + primsign;
int thismat; int thismat;
@@ -432,60 +326,46 @@ private:
thismat = thisLevel->getTile(coordinate[0], coordinate[1], coordinate[2]); thismat = thisLevel->getTile(coordinate[0], coordinate[1], coordinate[2]);
if (!((thismat == 0) || (thismat == Tile::leaves->id))) if (!((thismat == 0) || (thismat == Tile::leaves->id)))
{ {
// If the material of the checked block is anything other than
// air or foliage, stop looking.
break; break;
} }
primoffset += primsign; primoffset += primsign;
} }
// If you reached the end without finding anything, return -1.
if (primoffset == endoffset) if (primoffset == endoffset)
{ {
return -1; return -1;
} }
// Otherwise, return the number of steps you took.
else else
{ {
return abs(primoffset); return abs(primoffset);
} }
} }
bool checkLocation(){ bool checkLocation(){
// Return true if the tree can be placed here.
// Return false if the tree can not be placed here.
// Examine the square under the trunk. Is it grass or dirt?
// If not, return false
// Examine center column for how tall the tree can be.
// If the checked height is shorter than height, but taller
// than 4, set the tree to the maximum height allowed.
// If the space is too short, return false.
int startPosition[] = { origin[0], origin[1], origin[2] }; int startPosition[] = { origin[0], origin[1], origin[2] };
int endPosition[] = { origin[0], origin[1] + height - 1, origin[2] }; int endPosition[] = { origin[0], origin[1] + height - 1, origin[2] };
// Check the location it is resting on
int baseMaterial = thisLevel->getTile(origin[0], origin[1] - 1, origin[2]); int baseMaterial = thisLevel->getTile(origin[0], origin[1] - 1, origin[2]);
if (!((baseMaterial == 2) || (baseMaterial == 3))) if (!((baseMaterial == 2) || (baseMaterial == 3)))
{ {
return false; return false;
} }
int allowedHeight = checkLine(startPosition, endPosition); int allowedHeight = checkLine(startPosition, endPosition);
// If the set height is good, go with that
if (allowedHeight == -1) if (allowedHeight == -1)
{ {
return true; return true;
} }
// If the space is too short, tell the build to abort
else if (allowedHeight < 6) else if (allowedHeight < 6)
{ {
return false; return false;
} }
// If the space is shorter than the set height, but not too short
// shorten the height, and tell the build to continue
else else
{ {
height = allowedHeight; height = allowedHeight;
//System.out.println("Shortened the tree");
return true; return true;
} }
} }
@@ -502,9 +382,7 @@ public:
origin[0] = 0; origin[0] = 0;
origin[1] = 0; origin[1] = 0;
origin[2] = 0; origin[2] = 0;
// Field to hold the tree height.
height = 0; height = 0;
// Other important tree information.
trunkHeight = 0; trunkHeight = 0;
trunkHeightScale = 0.618; trunkHeightScale = 0.618;
branchDensity = 1.0; branchDensity = 1.0;
@@ -528,65 +406,40 @@ public:
} }
virtual void init(double heightInit, double widthInit, double foliageDensityInit){ virtual void init(double heightInit, double widthInit, double foliageDensityInit){
// all of the parameters should be from 0.0 to 1.0
// heightInit scales the maximum overall height of the tree (still randomizes height within the possible range)
// widthInit scales the maximum overall width of the tree (keep this above 0.3 or so)
// foliageDensityInit scales how many foliage clusters are created.
//
// Note, you can call "place" without calling "init".
// This is the same as calling init(1.0,1.0,1.0) and then calling place.
heightVariance = (int) (heightInit * 12); heightVariance = (int) (heightInit * 12);
if (heightInit > 0.5) foliageHeight = 5; if (heightInit > 0.5) foliageHeight = 5;
widthScale = widthInit; widthScale = widthInit;
foliageDensity = foliageDensityInit; foliageDensity = foliageDensityInit;
} }
virtual bool place(Level *level, Random *random, int x, int y, int z){ virtual bool place(Level *level, Random *random, int x, int y, int z){
// Note to Markus.
// currently the following fields are set randomly. If you like, make them
// parameters passed into "place".
//
// height: so the map generator can intelligently set the height of the tree,
// and make forests with large trees in the middle and smaller ones on the edges.
// Initialize the instance fields for the level and the seed.
thisLevel = level; thisLevel = level;
__int64 seed = random->nextLong(); __int64 seed = random->nextLong();
rnd->setSeed(seed); rnd->setSeed(seed);
// Initialize the origin of the tree trunk
origin[0] = x; origin[0] = x;
origin[1] = y; origin[1] = y;
origin[2] = z; origin[2] = z;
// Sets the height. Take out this line if height is passed as a parameter
if (height == 0) if (height == 0)
{ {
height = 5 + rnd->nextInt(heightVariance); height = 5 + rnd->nextInt(heightVariance);
} }
if (!(checkLocation())) if (!(checkLocation()))
{ {
//System.out.println("Tree location failed");
return false; return false;
} }
//System.out.println("The height is");
//System.out.println(height);
//System.out.println("Trunk Height check done");
prepare(); prepare();
//System.out.println("Prepare done");
makeFoliage(); makeFoliage();
//System.out.println("Foliage done");
makeTrunk(); makeTrunk();
//System.out.println("Trunk done");
makeBranches(); makeBranches();
//System.out.println("Branches done");
return true; return true;
} }
}; };