mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/4jcraft.git
synced 2026-05-23 11:55:29 +00:00
chore: format Minecraft.World
This commit is contained in:
@@ -3,25 +3,22 @@
|
||||
#include "../../Headers/net.minecraft.world.level.tile.h"
|
||||
#include "BasicTreeFeature.h"
|
||||
|
||||
uint8_t BasicTree::axisConversionArray[] = { 2, 0, 0, 1, 2, 1 };
|
||||
uint8_t BasicTree::axisConversionArray[] = {2, 0, 0, 1, 2, 1};
|
||||
|
||||
BasicTree::~BasicTree()
|
||||
{
|
||||
delete rnd;
|
||||
BasicTree::~BasicTree() {
|
||||
delete rnd;
|
||||
|
||||
for( int i = 0; i < foliageCoordsLength; i++ )
|
||||
{
|
||||
delete [] foliageCoords[i];
|
||||
}
|
||||
delete [] foliageCoords;
|
||||
for (int i = 0; i < foliageCoordsLength; i++) {
|
||||
delete[] foliageCoords[i];
|
||||
}
|
||||
delete[] foliageCoords;
|
||||
}
|
||||
|
||||
BasicTree::BasicTree(bool doUpdate) : Feature(doUpdate)
|
||||
{
|
||||
rnd = new Random();
|
||||
BasicTree::BasicTree(bool doUpdate) : Feature(doUpdate) {
|
||||
rnd = new Random();
|
||||
origin[0] = 0;
|
||||
origin[1] = 0;
|
||||
origin[2] = 0;
|
||||
origin[1] = 0;
|
||||
origin[2] = 0;
|
||||
// Field to hold the tree height.
|
||||
height = 0;
|
||||
// Other important tree information.
|
||||
@@ -34,26 +31,25 @@ BasicTree::BasicTree(bool doUpdate) : Feature(doUpdate)
|
||||
trunkWidth = 1;
|
||||
heightVariance = 12;
|
||||
foliageHeight = 4;
|
||||
foliageCoords = NULL;
|
||||
foliageCoordsLength = 0;
|
||||
foliageCoords = NULL;
|
||||
foliageCoordsLength = 0;
|
||||
}
|
||||
|
||||
void BasicTree::prepare()
|
||||
{
|
||||
void BasicTree::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;
|
||||
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;
|
||||
// The foliage coordinates are a list of [x,y,z,y of branch base] values for each cluster
|
||||
int **tempFoliageCoords = new int *[clustersPerY * height];
|
||||
for( int i = 0; i < clustersPerY * height; i++ )
|
||||
{
|
||||
tempFoliageCoords[i] = new int[4];
|
||||
}
|
||||
// The foliage coordinates are a list of [x,y,z,y of branch base] values for
|
||||
// each cluster
|
||||
int** tempFoliageCoords = new int*[clustersPerY * height];
|
||||
for (int i = 0; i < clustersPerY * height; i++) {
|
||||
tempFoliageCoords[i] = new int[4];
|
||||
}
|
||||
int y = origin[1] + height - foliageHeight;
|
||||
int clusterCount = 1;
|
||||
int trunkTop = origin[1] + trunkHeight;
|
||||
@@ -65,13 +61,11 @@ void BasicTree::prepare()
|
||||
tempFoliageCoords[0][3] = trunkTop;
|
||||
y--;
|
||||
|
||||
while (relativeY >= 0)
|
||||
{
|
||||
while (relativeY >= 0) {
|
||||
int num = 0;
|
||||
|
||||
float shapefac = treeShape(relativeY);
|
||||
if (shapefac < 0)
|
||||
{
|
||||
if (shapefac < 0) {
|
||||
y--;
|
||||
relativeY--;
|
||||
continue;
|
||||
@@ -79,32 +73,30 @@ void BasicTree::prepare()
|
||||
|
||||
// The originOffset is to put the value in the middle of the block.
|
||||
double originOffset = 0.5;
|
||||
while (num < clustersPerY)
|
||||
{
|
||||
double radius = widthScale * (shapefac * (rnd->nextFloat() + 0.328));
|
||||
while (num < clustersPerY) {
|
||||
double radius =
|
||||
widthScale * (shapefac * (rnd->nextFloat() + 0.328));
|
||||
double angle = rnd->nextFloat() * 2.0 * 3.14159;
|
||||
int x = Mth::floor(radius * sin(angle) + origin[0] + originOffset);
|
||||
int z = Mth::floor(radius * cos(angle) + origin[2] + originOffset);
|
||||
int checkStart[] = { x, y, z };
|
||||
int checkEnd[] = { x, y + foliageHeight, z };
|
||||
int checkStart[] = {x, y, z};
|
||||
int checkEnd[] = {x, y + foliageHeight, z};
|
||||
// check the center column of the cluster for obstructions.
|
||||
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] };
|
||||
double distance = sqrt(pow(abs(origin[0] - checkStart[0]), 2.0) + pow(abs(origin[2] - checkStart[2]), 2.0));
|
||||
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 branchHeight = distance * branchSlope;
|
||||
if ((checkStart[1] - branchHeight) > trunkTop)
|
||||
{
|
||||
if ((checkStart[1] - branchHeight) > trunkTop) {
|
||||
checkBranchBase[1] = trunkTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkBranchBase[1] = (int) (checkStart[1] - branchHeight);
|
||||
} else {
|
||||
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;
|
||||
@@ -119,24 +111,25 @@ void BasicTree::prepare()
|
||||
y--;
|
||||
relativeY--;
|
||||
}
|
||||
// 4J Stu - Rather than copying the array, we are storing the number of valid elements in the array
|
||||
foliageCoordsLength = clusterCount;
|
||||
foliageCoords = tempFoliageCoords;
|
||||
// Delete the rest of the array whilst we still know how big it was
|
||||
for( int i = clusterCount; i < clustersPerY * height; i++ )
|
||||
{
|
||||
delete [] tempFoliageCoords[i];
|
||||
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);
|
||||
|
||||
// 4J Stu - Rather than copying the array, we are storing the number of
|
||||
// valid elements in the array
|
||||
foliageCoordsLength = clusterCount;
|
||||
foliageCoords = tempFoliageCoords;
|
||||
// Delete the rest of the array whilst we still know how big it was
|
||||
for (int i = clusterCount; i < clustersPerY * height; i++) {
|
||||
delete[] tempFoliageCoords[i];
|
||||
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 BasicTree::crossection(int x, int y, int z, float radius, uint8_t direction, int material)
|
||||
{
|
||||
PIXBeginNamedEvent(0, "BasicTree crossection");
|
||||
void BasicTree::crossection(int x, int y, int z, float radius,
|
||||
uint8_t direction, int material) {
|
||||
PIXBeginNamedEvent(0, "BasicTree crossection");
|
||||
// Create a circular cross section.
|
||||
//
|
||||
// Used to nearly everything in the foliage, branches, and trunk.
|
||||
@@ -145,116 +138,115 @@ void BasicTree::crossection(int x, int y, int z, float radius, uint8_t direction
|
||||
// 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);
|
||||
// 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);
|
||||
uint8_t secidx1 = axisConversionArray[direction];
|
||||
uint8_t secidx2 = axisConversionArray[direction + 3];
|
||||
int center[] = { x, y, z };
|
||||
int position[] = { 0, 0, 0 };
|
||||
int center[] = {x, y, z};
|
||||
int position[] = {0, 0, 0};
|
||||
int offset1 = -rad;
|
||||
int offset2 = -rad;
|
||||
int thismat;
|
||||
position[direction] = center[direction];
|
||||
while (offset1 <= rad)
|
||||
{
|
||||
while (offset1 <= rad) {
|
||||
position[secidx1] = center[secidx1] + offset1;
|
||||
offset2 = -rad;
|
||||
while (offset2 <= rad)
|
||||
{
|
||||
double thisdistance = pow(abs(offset1) + 0.5, 2) + pow(abs(offset2) + 0.5, 2);
|
||||
if (thisdistance > radius * radius)
|
||||
{
|
||||
while (offset2 <= rad) {
|
||||
double thisdistance =
|
||||
pow(abs(offset1) + 0.5, 2) + pow(abs(offset2) + 0.5, 2);
|
||||
if (thisdistance > radius * radius) {
|
||||
offset2++;
|
||||
continue;
|
||||
}
|
||||
position[secidx2] = center[secidx2] + offset2;
|
||||
PIXBeginNamedEvent(0,"BasicTree getting tile");
|
||||
PIXBeginNamedEvent(0, "BasicTree getting tile");
|
||||
thismat = thisLevel->getTile(position[0], position[1], position[2]);
|
||||
PIXEndNamedEvent();
|
||||
if (!((thismat == 0) || (thismat == Tile::leaves_Id)))
|
||||
{
|
||||
PIXEndNamedEvent();
|
||||
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++;
|
||||
continue;
|
||||
}
|
||||
PIXBeginNamedEvent(0,"BasicTree placing block");
|
||||
placeBlock(thisLevel, position[0], position[1], position[2], material, 0);
|
||||
PIXEndNamedEvent();
|
||||
PIXBeginNamedEvent(0, "BasicTree placing block");
|
||||
placeBlock(thisLevel, position[0], position[1], position[2],
|
||||
material, 0);
|
||||
PIXEndNamedEvent();
|
||||
offset2++;
|
||||
}
|
||||
offset1++;
|
||||
}
|
||||
PIXEndNamedEvent();
|
||||
PIXEndNamedEvent();
|
||||
}
|
||||
|
||||
float BasicTree::treeShape(int y)
|
||||
{
|
||||
float BasicTree::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;
|
||||
float radius = ((float) height) / ((float) 2.0);
|
||||
float adjacent = (((float) height) / ((float) 2.0)) - y;
|
||||
// This method should return a consistent value for each y (don't
|
||||
// randomize).
|
||||
if (y < (((float)height) * 0.3)) return (float)-1.618;
|
||||
float radius = ((float)height) / ((float)2.0);
|
||||
float adjacent = (((float)height) / ((float)2.0)) - y;
|
||||
float distance;
|
||||
if (adjacent == 0) distance = radius;
|
||||
else if (abs(adjacent) >= radius) distance = (float) 0.0;
|
||||
else distance = (float) sqrt(pow(abs(radius), 2) - pow(abs(adjacent), 2));
|
||||
if (adjacent == 0)
|
||||
distance = radius;
|
||||
else if (abs(adjacent) >= radius)
|
||||
distance = (float)0.0;
|
||||
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;
|
||||
}
|
||||
|
||||
float BasicTree::foliageShape(int y)
|
||||
{
|
||||
float BasicTree::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;
|
||||
else if ((y == 0) || (y == (foliageHeight - 1))) return (float) 2;
|
||||
else return (float) 3;
|
||||
if ((y < 0) || (y >= foliageHeight))
|
||||
return (float)-1;
|
||||
else if ((y == 0) || (y == (foliageHeight - 1)))
|
||||
return (float)2;
|
||||
else
|
||||
return (float)3;
|
||||
}
|
||||
|
||||
void BasicTree::foliageCluster(int x, int y, int z)
|
||||
{
|
||||
PIXBeginNamedEvent(0,"BasicTree foliageCluster");
|
||||
void BasicTree::foliageCluster(int x, int y, int z) {
|
||||
PIXBeginNamedEvent(0, "BasicTree foliageCluster");
|
||||
// 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 cury = topy - 1;
|
||||
float radius;
|
||||
// 4J Stu - Generate foliage from the top down so that we don't keep recalculating heightmaps
|
||||
while (cury >= y)
|
||||
{
|
||||
// 4J Stu - Generate foliage from the top down so that we don't keep
|
||||
// recalculating heightmaps
|
||||
while (cury >= y) {
|
||||
radius = foliageShape(cury - y);
|
||||
crossection(x, cury, z, radius, (uint8_t) 1, Tile::leaves_Id);
|
||||
crossection(x, cury, z, radius, (uint8_t)1, Tile::leaves_Id);
|
||||
cury--;
|
||||
}
|
||||
PIXEndNamedEvent();
|
||||
PIXEndNamedEvent();
|
||||
}
|
||||
|
||||
void BasicTree::limb(int *start, int *end, int material)
|
||||
{
|
||||
void BasicTree::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};
|
||||
uint8_t idx = 0;
|
||||
uint8_t primidx = 0;
|
||||
while (idx < 3)
|
||||
{
|
||||
while (idx < 3) {
|
||||
delta[idx] = end[idx] - start[idx];
|
||||
if (abs(delta[idx]) > abs(delta[primidx]))
|
||||
{
|
||||
if (abs(delta[idx]) > abs(delta[primidx])) {
|
||||
primidx = idx;
|
||||
}
|
||||
idx++;
|
||||
@@ -267,51 +259,49 @@ void BasicTree::limb(int *start, int *end, int material)
|
||||
// primsign is digit 1 or -1 depending on whether the limb is headed
|
||||
// along the positive or negative primidx axis.
|
||||
char primsign;
|
||||
if (delta[primidx] > 0) primsign = 1;
|
||||
else primsign = -1;
|
||||
if (delta[primidx] > 0)
|
||||
primsign = 1;
|
||||
else
|
||||
primsign = -1;
|
||||
// Initilize the per-step movement for the non-primary axies.
|
||||
double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]);
|
||||
double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]);
|
||||
double secfac1 = ((double)delta[secidx1]) / ((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 endoffset = delta[primidx] + primsign;
|
||||
while (primoffset != endoffset)
|
||||
{
|
||||
while (primoffset != endoffset) {
|
||||
coordinate[primidx] = Mth::floor(start[primidx] + primoffset + 0.5);
|
||||
coordinate[secidx1] = Mth::floor(start[secidx1] + (primoffset * secfac1) + 0.5);
|
||||
coordinate[secidx2] = Mth::floor(start[secidx2] + (primoffset * secfac2) + 0.5);
|
||||
coordinate[secidx1] =
|
||||
Mth::floor(start[secidx1] + (primoffset * secfac1) + 0.5);
|
||||
coordinate[secidx2] =
|
||||
Mth::floor(start[secidx2] + (primoffset * secfac2) + 0.5);
|
||||
|
||||
int dir = TreeTile::FACING_Y;
|
||||
int xdiff = abs(coordinate[0] - start[0]);
|
||||
int zdiff = abs(coordinate[2] - start[2]);
|
||||
int maxdiff = std::max(xdiff, zdiff);
|
||||
int dir = TreeTile::FACING_Y;
|
||||
int xdiff = abs(coordinate[0] - start[0]);
|
||||
int zdiff = abs(coordinate[2] - start[2]);
|
||||
int maxdiff = std::max(xdiff, zdiff);
|
||||
|
||||
if (maxdiff > 0)
|
||||
{
|
||||
if (xdiff == maxdiff)
|
||||
{
|
||||
dir = TreeTile::FACING_X;
|
||||
}
|
||||
else if (zdiff == maxdiff)
|
||||
{
|
||||
dir = TreeTile::FACING_Z;
|
||||
}
|
||||
}
|
||||
placeBlock(thisLevel, coordinate[0], coordinate[1], coordinate[2], material, dir);
|
||||
if (maxdiff > 0) {
|
||||
if (xdiff == maxdiff) {
|
||||
dir = TreeTile::FACING_X;
|
||||
} else if (zdiff == maxdiff) {
|
||||
dir = TreeTile::FACING_Z;
|
||||
}
|
||||
}
|
||||
placeBlock(thisLevel, coordinate[0], coordinate[1], coordinate[2],
|
||||
material, dir);
|
||||
primoffset += primsign;
|
||||
}
|
||||
}
|
||||
|
||||
void BasicTree::makeFoliage()
|
||||
{
|
||||
void BasicTree::makeFoliage() {
|
||||
// Create the tree foliage.
|
||||
// Call foliageCluster at the correct locations
|
||||
int idx = 0;
|
||||
int finish = foliageCoordsLength;
|
||||
while (idx < finish)
|
||||
{
|
||||
while (idx < finish) {
|
||||
int x = foliageCoords[idx][0];
|
||||
int y = foliageCoords[idx][1];
|
||||
int z = foliageCoords[idx][2];
|
||||
@@ -320,8 +310,7 @@ void BasicTree::makeFoliage()
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicTree::trimBranches(int localY)
|
||||
{
|
||||
bool BasicTree::trimBranches(int localY) {
|
||||
// For larger trees, randomly "prune" the branches so there
|
||||
// aren't too many.
|
||||
// Return true if the branch should be created.
|
||||
@@ -329,22 +318,22 @@ bool BasicTree::trimBranches(int localY)
|
||||
// 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;
|
||||
else return true;
|
||||
if (localY < (height * 0.2))
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void BasicTree::makeTrunk()
|
||||
{
|
||||
void BasicTree::makeTrunk() {
|
||||
// Create the trunk of the tree.
|
||||
int x = origin[0];
|
||||
int startY = origin[1];
|
||||
int topY = origin[1] + trunkHeight;
|
||||
int z = origin[2];
|
||||
int startCoord[] = { x, startY, z };
|
||||
int endCoord[] = { x, topY, z };
|
||||
int startCoord[] = {x, startY, z};
|
||||
int endCoord[] = {x, topY, z};
|
||||
limb(startCoord, endCoord, Tile::treeTrunk_Id);
|
||||
if (trunkWidth == 2)
|
||||
{
|
||||
if (trunkWidth == 2) {
|
||||
startCoord[0] += 1;
|
||||
endCoord[0] += 1;
|
||||
limb(startCoord, endCoord, Tile::treeTrunk_Id);
|
||||
@@ -357,45 +346,38 @@ void BasicTree::makeTrunk()
|
||||
}
|
||||
}
|
||||
|
||||
void BasicTree::makeBranches()
|
||||
{
|
||||
void BasicTree::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 finish = foliageCoordsLength;
|
||||
int baseCoord[] = { origin[0], origin[1], origin[2] };
|
||||
while (idx < finish)
|
||||
{
|
||||
int *coordValues = foliageCoords[idx];
|
||||
int endCoord[] = { coordValues[0], coordValues[1], coordValues[2] };
|
||||
int baseCoord[] = {origin[0], origin[1], origin[2]};
|
||||
while (idx < finish) {
|
||||
int* coordValues = foliageCoords[idx];
|
||||
int endCoord[] = {coordValues[0], coordValues[1], coordValues[2]};
|
||||
baseCoord[1] = coordValues[3];
|
||||
int localY = baseCoord[1] - origin[1];
|
||||
if (trimBranches(localY))
|
||||
{
|
||||
if (trimBranches(localY)) {
|
||||
limb(baseCoord, endCoord, Tile::treeTrunk_Id);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
int BasicTree::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 BasicTree::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};
|
||||
uint8_t idx = 0;
|
||||
uint8_t primidx = 0;
|
||||
while (idx < 3)
|
||||
{
|
||||
while (idx < 3) {
|
||||
delta[idx] = end[idx] - start[idx];
|
||||
if (abs(delta[idx]) > abs(delta[primidx]))
|
||||
{
|
||||
if (abs(delta[idx]) > abs(delta[primidx])) {
|
||||
primidx = idx;
|
||||
}
|
||||
idx++;
|
||||
@@ -407,26 +389,31 @@ int BasicTree::checkLine(int *start, int *end)
|
||||
uint8_t 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; // 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;
|
||||
else primsign = -1;
|
||||
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;
|
||||
else
|
||||
primsign = -1;
|
||||
// Initilize the per-step movement for the non-primary axies.
|
||||
double secfac1 = ((double) delta[secidx1]) / ((double) delta[primidx]);
|
||||
double secfac2 = ((double) delta[secidx2]) / ((double) delta[primidx]);
|
||||
double secfac1 = ((double)delta[secidx1]) / ((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 endoffset = delta[primidx] + primsign;
|
||||
int thismat;
|
||||
while (primoffset != endoffset)
|
||||
{
|
||||
while (primoffset != endoffset) {
|
||||
coordinate[primidx] = start[primidx] + primoffset;
|
||||
coordinate[secidx1] = Mth::floor(start[secidx1] + (primoffset * secfac1));
|
||||
coordinate[secidx2] = Mth::floor(start[secidx2] + (primoffset * secfac2));
|
||||
thismat = thisLevel->getTile(coordinate[0], coordinate[1], coordinate[2]);
|
||||
if (!((thismat == 0) || (thismat == Tile::leaves_Id)))
|
||||
{
|
||||
coordinate[secidx1] =
|
||||
Mth::floor(start[secidx1] + (primoffset * secfac1));
|
||||
coordinate[secidx2] =
|
||||
Mth::floor(start[secidx2] + (primoffset * secfac2));
|
||||
thismat =
|
||||
thisLevel->getTile(coordinate[0], coordinate[1], coordinate[2]);
|
||||
if (!((thismat == 0) || (thismat == Tile::leaves_Id))) {
|
||||
// If the material of the checked block is anything other than
|
||||
// air or foliage, stop looking.
|
||||
break;
|
||||
@@ -434,19 +421,16 @@ int BasicTree::checkLine(int *start, int *end)
|
||||
primoffset += primsign;
|
||||
}
|
||||
// If you reached the end without finding anything, return -1.
|
||||
if (primoffset == endoffset)
|
||||
{
|
||||
if (primoffset == endoffset) {
|
||||
return -1;
|
||||
}
|
||||
// Otherwise, return the number of steps you took.
|
||||
else
|
||||
{
|
||||
else {
|
||||
return abs(primoffset);
|
||||
}
|
||||
}
|
||||
|
||||
bool BasicTree::checkLocation()
|
||||
{
|
||||
bool BasicTree::checkLocation() {
|
||||
// Return true if the tree can be placed here.
|
||||
// Return false if the tree can not be placed here.
|
||||
|
||||
@@ -456,71 +440,71 @@ bool BasicTree::checkLocation()
|
||||
// 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 endPosition[] = { origin[0], origin[1] + height - 1, origin[2] };
|
||||
int startPosition[] = {origin[0], origin[1], origin[2]};
|
||||
int endPosition[] = {origin[0], origin[1] + height - 1, origin[2]};
|
||||
|
||||
// 4J Stu Added to stop tree features generating areas previously place by game rule generation
|
||||
if(app.getLevelGenerationOptions() != NULL)
|
||||
{
|
||||
LevelGenerationOptions *levelGenOptions = app.getLevelGenerationOptions();
|
||||
bool intersects = levelGenOptions->checkIntersects(startPosition[0], startPosition[1], startPosition[2], endPosition[0], endPosition[1], endPosition[2]);
|
||||
if(intersects)
|
||||
{
|
||||
//app.DebugPrintf("Skipping reeds feature generation as it overlaps a game rule structure\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 4J Stu Added to stop tree features generating areas previously place by
|
||||
// game rule generation
|
||||
if (app.getLevelGenerationOptions() != NULL) {
|
||||
LevelGenerationOptions* levelGenOptions =
|
||||
app.getLevelGenerationOptions();
|
||||
bool intersects = levelGenOptions->checkIntersects(
|
||||
startPosition[0], startPosition[1], startPosition[2],
|
||||
endPosition[0], endPosition[1], endPosition[2]);
|
||||
if (intersects) {
|
||||
// app.DebugPrintf("Skipping reeds feature generation as it overlaps
|
||||
// a game rule structure\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check the location it is resting on
|
||||
int baseMaterial = thisLevel->getTile(origin[0], origin[1] - 1, origin[2]);
|
||||
if (!((baseMaterial == 2) || (baseMaterial == 3)))
|
||||
{
|
||||
if (!((baseMaterial == 2) || (baseMaterial == 3))) {
|
||||
return false;
|
||||
}
|
||||
int allowedHeight = checkLine(startPosition, endPosition);
|
||||
// If the set height is good, go with that
|
||||
if (allowedHeight == -1)
|
||||
{
|
||||
if (allowedHeight == -1) {
|
||||
return true;
|
||||
}
|
||||
// If the space is too short, tell the build to abort
|
||||
else if (allowedHeight < 6)
|
||||
{
|
||||
else if (allowedHeight < 6) {
|
||||
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;
|
||||
//System.out.println("Shortened the tree");
|
||||
// System.out.println("Shortened the tree");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void BasicTree::init(double heightInit, double widthInit, double foliageDensityInit)
|
||||
{
|
||||
void BasicTree::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.
|
||||
// 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;
|
||||
widthScale = widthInit;
|
||||
foliageDensity = foliageDensityInit;
|
||||
}
|
||||
|
||||
bool BasicTree::place(Level *level, Random *random, int x, int y, int z)
|
||||
{
|
||||
bool BasicTree::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.
|
||||
// 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;
|
||||
@@ -531,35 +515,33 @@ bool BasicTree::place(Level *level, Random *random, int x, int y, int z)
|
||||
origin[1] = y;
|
||||
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);
|
||||
}
|
||||
if (!(checkLocation()))
|
||||
{
|
||||
//System.out.println("Tree location failed");
|
||||
if (!(checkLocation())) {
|
||||
// System.out.println("Tree location failed");
|
||||
return false;
|
||||
}
|
||||
PIXBeginNamedEvent(0, "Placing BasicTree");
|
||||
//System.out.println("The height is");
|
||||
//System.out.println(height);
|
||||
//System.out.println("Trunk Height check done");
|
||||
PIXBeginNamedEvent(0, "Preparing tree");
|
||||
PIXBeginNamedEvent(0, "Placing BasicTree");
|
||||
// System.out.println("The height is");
|
||||
// System.out.println(height);
|
||||
// System.out.println("Trunk Height check done");
|
||||
PIXBeginNamedEvent(0, "Preparing tree");
|
||||
prepare();
|
||||
PIXEndNamedEvent();
|
||||
//System.out.println("Prepare done");
|
||||
PIXBeginNamedEvent(0, "Making foliage");
|
||||
PIXEndNamedEvent();
|
||||
// System.out.println("Prepare done");
|
||||
PIXBeginNamedEvent(0, "Making foliage");
|
||||
makeFoliage();
|
||||
PIXEndNamedEvent();
|
||||
//System.out.println("Foliage done");
|
||||
PIXBeginNamedEvent(0, "Making trunk");
|
||||
PIXEndNamedEvent();
|
||||
// System.out.println("Foliage done");
|
||||
PIXBeginNamedEvent(0, "Making trunk");
|
||||
makeTrunk();
|
||||
PIXEndNamedEvent();
|
||||
//System.out.println("Trunk done");
|
||||
PIXBeginNamedEvent(0, "Making branches");
|
||||
PIXEndNamedEvent();
|
||||
// System.out.println("Trunk done");
|
||||
PIXBeginNamedEvent(0, "Making branches");
|
||||
makeBranches();
|
||||
PIXEndNamedEvent();
|
||||
//System.out.println("Branches done");
|
||||
PIXEndNamedEvent();
|
||||
PIXEndNamedEvent();
|
||||
// System.out.println("Branches done");
|
||||
PIXEndNamedEvent();
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user