diff --git a/src/client/renderer/TileRenderer.cpp b/src/client/renderer/TileRenderer.cpp index cdbdc7d..0e53915 100755 --- a/src/client/renderer/TileRenderer.cpp +++ b/src/client/renderer/TileRenderer.cpp @@ -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 ) { + // @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; - //Icon *firstTex = tt->getTextureLayer(0); - //Icon *secondTex = tt->getTextureLayer(1); - //Icon *tex = firstTex; int tex = tt->getTexture(0); -// if (hasFixedTexture()) tex = fixedTexture; if (fixedTexture >= 0) tex = fixedTexture; - -// t.color( 1.0f, 1.0f, 1.0f ); -// t.tex( getLightColor(tt, level, x, y, z ) ); - - - - - - - - - float br = tt->getBrightness( level, x, y, z ); - t.color( br, br, br ); + float br = tt->getBrightness( level, x, y, z ); + t.color( br, br, br ); int xt = ((tex & 0xf) << 4); 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 v0 = (yt) / 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 ) ) { @@ -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 + 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; 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 + h ), ( float )( z + 0 ), ( float )( u1 ), ( float )( v0 ) ); -// tex = firstTex; + u0 = (xt) / 256.0f; u1 = (xt + 15.99f) / 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; if ( ( ( x + y + z ) & 1 ) == 1 ) { - // tex = secondTex; u0 = (xt) / 256.0f; u1 = (xt + 15.99f) / 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 z1_ = z + 0.5f + 0.5f; - // tex = firstTex; u0 = (xt) / 256.0f; u1 = (xt + 15.99f) / 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 + 1 ), ( float )( u0 ), ( float )( v0 ) ); -// tex = secondTex; u0 = (xt) / 256.0f; u1 = (xt + 15.99f) / 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 + h ), ( float )( z1_ ), ( float )( u0 ), ( float )( v0 ) ); -// tex = secondTex; u0 = (xt) / 256.0f; u1 = (xt + 15.99f) / 256.0f; v0 = (yt) / 256.0f; diff --git a/src/world/item/FlintAndSteelItem.h b/src/world/item/FlintAndSteelItem.h index 45458e7..701fc96 100755 --- a/src/world/item/FlintAndSteelItem.h +++ b/src/world/item/FlintAndSteelItem.h @@ -19,7 +19,7 @@ public: setMaxDamage(64); } - /* + 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 == 1) y++; @@ -30,14 +30,14 @@ public: int targetType = level->getTile(x, y, z); if (targetType == 0) { - level->playSound(x + 0.5, y + 0.5, z + 0.5, "fire.ignite", 1, sharedRandom.nextFloat() * 0.4f + 0.8f); - level->setTile(x, y, z, Tile::fire->id); + 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*)Tile::fire)->id); } instance->hurt(1); return true; } - */ + }; #endif /*NET_MINECRAFT_WORLD_ITEM__FlintAndSteelItem_H__*/ diff --git a/src/world/level/biome/Biome.cpp b/src/world/level/biome/Biome.cpp index d0a842a..7ccbdfe 100755 --- a/src/world/level/biome/Biome.cpp +++ b/src/world/level/biome/Biome.cpp @@ -2,6 +2,7 @@ #include "../levelgen/feature/TreeFeature.h" #include "../levelgen/feature/TallgrassFeature.h" +#include "../levelgen/feature/BasicTree.h" #include "../../entity/EntityTypes.h" #include "../../entity/MobCategory.h" @@ -140,7 +141,7 @@ void Biome::teardownBiomes() { Feature* Biome::getTreeFeature( Random* random ) { if (random->nextInt(10) == 0) { - //return /*new*/ BasicTree(); + return new BasicTree(false); } return new TreeFeature(false); } @@ -148,6 +149,15 @@ Feature* Biome::getGrassFeature( Random* random ) { 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 ) { int a = (int) (temperature * 63); diff --git a/src/world/level/biome/Biome.h b/src/world/level/biome/Biome.h index 48a49d5..23fd495 100755 --- a/src/world/level/biome/Biome.h +++ b/src/world/level/biome/Biome.h @@ -71,6 +71,7 @@ public: virtual Feature* getTreeFeature(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); diff --git a/src/world/level/biome/ForestBiome.h b/src/world/level/biome/ForestBiome.h index dbc38e5..fa47dc0 100755 --- a/src/world/level/biome/ForestBiome.h +++ b/src/world/level/biome/ForestBiome.h @@ -6,6 +6,7 @@ #include "Biome.h" #include "../levelgen/feature/TreeFeature.h" #include "../levelgen/feature/BirchFeature.h" +#include "../levelgen/feature/BasicTree.h" class ForestBiome: public Biome { @@ -15,7 +16,7 @@ public: return new BirchFeature(); } if (random->nextInt(3) == 0) { - //return new BasicTree(); + return new BasicTree(false); } return new TreeFeature(false); } diff --git a/src/world/level/biome/RainforestBiome.h b/src/world/level/biome/RainforestBiome.h index 153ed61..cc80e84 100755 --- a/src/world/level/biome/RainforestBiome.h +++ b/src/world/level/biome/RainforestBiome.h @@ -6,13 +6,14 @@ #include "Biome.h" #include "../../../util/Random.h" #include "../levelgen/feature/TreeFeature.h" +#include "../levelgen/feature/BasicTree.h" class RainforestBiome: public Biome { public: Feature* getTreeFeature(Random* random) { if (random->nextInt(3) == 0) { - //return new BasicTree(); + return new BasicTree(false); } return new TreeFeature(false); } diff --git a/src/world/level/levelgen/RandomLevelSource.cpp b/src/world/level/levelgen/RandomLevelSource.cpp index 7ef40e3..56f5b8b 100755 --- a/src/world/level/levelgen/RandomLevelSource.cpp +++ b/src/world/level/levelgen/RandomLevelSource.cpp @@ -370,6 +370,18 @@ void RandomLevelSource::postProcess(ChunkSource* parent, int xt, int zt) { } //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++) { int x = xo + random.nextInt(16) + 8; diff --git a/src/world/level/levelgen/feature/BasicTree.h b/src/world/level/levelgen/feature/BasicTree.h index 7b6db51..48f80e7 100644 --- a/src/world/level/levelgen/feature/BasicTree.h +++ b/src/world/level/levelgen/feature/BasicTree.h @@ -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]; - - // Set up the pseudorandom number generator Random *rnd; - - // Make fields to hold the level data and the random seed Level *thisLevel; - - // Field to hold the tree origin, x y and z. int origin[3]; - // Field to hold the tree height. int height; - // Other important tree information. int trunkHeight; double trunkHeightScale; double branchDensity; @@ -58,19 +33,13 @@ private: int trunkWidth; int heightVariance; int foliageHeight; - // The foliage coordinates are a list of [x,y,z,y of branch base] values for each cluster int **foliageCoords; int foliageCoordsLength; 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); if (trunkHeight >= height) trunkHeight = height - 1; 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++ ) { @@ -99,7 +68,6 @@ private: continue; } - // The originOffset is to put the value in the middle of the block. double originOffset = 0.5; while (num < clustersPerY) { @@ -109,10 +77,7 @@ private: int z = Mth::floor(radius * cos(angle) + origin[2] + originOffset); 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)); double branchHeight = distance * branchSlope; @@ -124,11 +89,8 @@ private: { checkBranchBase[1] = (int) (checkStart[1] - branchHeight); } - // Now check the branch path 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][1] = y; tempFoliageCoords[clusterCount][2] = z; @@ -141,34 +103,22 @@ private: 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); + } 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); byte secidx1 = axisConversionArray[direction]; byte secidx2 = axisConversionArray[direction + 3]; @@ -196,8 +146,6 @@ private: 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; } @@ -211,12 +159,6 @@ private: } 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; float radius = ((float) height) / ((float) 2.0); float adjacent = (((float) height) / ((float) 2.0)) - y; @@ -224,29 +166,19 @@ private: 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; return distance; } 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; else if ((y == 0) || (y == (foliageHeight - 1))) return (float) 2; else return (float) 3; } 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 cury = topy - 1; float radius; - // 4J Stu - Generate foliage from the top down so that we don't keep recalculating heightmaps while (cury >= y) { radius = foliageShape(cury - y); @@ -257,11 +189,6 @@ private: } 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 }; byte idx = 0; byte primidx = 0; @@ -274,22 +201,15 @@ private: } idx++; } - // If the largest distance is zero, don't bother to do anything else. if (delta[primidx] == 0) return; - // set up the other two axis indices. byte secidx1 = axisConversionArray[primidx]; 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; 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]); - // Initialize the coordinates. 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) @@ -319,8 +239,6 @@ private: } } void makeFoliage(){ - // Create the tree foliage. - // Call foliageCluster at the correct locations int idx = 0; int finish = foliageCoordsLength; while (idx < finish) @@ -333,18 +251,10 @@ private: } } 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; else return true; } void makeTrunk(){ - // Create the trunk of the tree. int x = origin[0]; int startY = origin[1]; int topY = origin[1] + trunkHeight; @@ -366,9 +276,6 @@ private: } } 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 finish = foliageCoordsLength; int baseCoord[] = { origin[0], origin[1], origin[2] }; @@ -386,12 +293,6 @@ private: } } 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 }; byte idx = 0; @@ -405,22 +306,15 @@ private: } idx++; } - // If the largest distance is zero, don't bother to do anything else. if (delta[primidx] == 0) return -1; - // set up the other two axis indices. byte secidx1 = axisConversionArray[primidx]; 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; // 4J Stu - Was byte, but we use in a sum below and byte=unsigned char so we were setting endoffset incorrectly + char primsign; 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]); - // Initialize the coordinates. 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; @@ -432,60 +326,46 @@ private: 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; } primoffset += primsign; } - // If you reached the end without finding anything, return -1. + if (primoffset == endoffset) { return -1; } - // Otherwise, return the number of steps you took. + else { return abs(primoffset); } } 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 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]); if (!((baseMaterial == 2) || (baseMaterial == 3))) { return false; } int allowedHeight = checkLine(startPosition, endPosition); - // If the set height is good, go with that if (allowedHeight == -1) { return true; } - // If the space is too short, tell the build to abort + 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 { height = allowedHeight; - //System.out.println("Shortened the tree"); return true; } } @@ -502,9 +382,7 @@ public: origin[0] = 0; origin[1] = 0; origin[2] = 0; - // Field to hold the tree height. height = 0; - // Other important tree information. trunkHeight = 0; trunkHeightScale = 0.618; branchDensity = 1.0; @@ -528,65 +406,40 @@ public: } 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); if (heightInit > 0.5) foliageHeight = 5; widthScale = widthInit; foliageDensity = foliageDensityInit; } 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; __int64 seed = random->nextLong(); rnd->setSeed(seed); - // Initialize the origin of the tree trunk origin[0] = x; origin[1] = y; origin[2] = z; - // Sets the height. Take out this line if height is passed as a parameter if (height == 0) { height = 5 + rnd->nextInt(heightVariance); } if (!(checkLocation())) { - //System.out.println("Tree location failed"); + return false; } - //System.out.println("The height is"); - //System.out.println(height); - //System.out.println("Trunk Height check done"); + prepare(); - //System.out.println("Prepare done"); - makeFoliage(); - //System.out.println("Foliage done"); - makeTrunk(); - //System.out.println("Trunk done"); - makeBranches(); - //System.out.println("Branches done"); - return true; } };