the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "net.minecraft.world.level.h"
3#include "net.minecraft.world.level.tile.h"
4#include "MegaTreeFeature.h"
5
6MegaTreeFeature::MegaTreeFeature(bool doUpdate, int baseHeight, int trunkType, int leafType) : Feature(doUpdate), baseHeight(baseHeight), trunkType(trunkType), leafType(leafType)
7{
8}
9
10bool MegaTreeFeature::place(Level *level, Random *random, int x, int y, int z)
11{
12 int treeHeight = random->nextInt(3) + baseHeight;
13
14 bool free = true;
15 if (y < 1 || y + treeHeight + 1 > Level::maxBuildHeight) return false;
16
17 // 4J Stu Added to stop tree features generating areas previously place by game rule generation
18 if(app.getLevelGenerationOptions() != NULL)
19 {
20 PIXBeginNamedEvent(0, "MegaTreeFeature Checking intersects");
21 LevelGenerationOptions *levelGenOptions = app.getLevelGenerationOptions();
22 bool intersects = levelGenOptions->checkIntersects(x - 2, y - 1, z - 2, x + 2, y + treeHeight, z + 2);
23 PIXEndNamedEvent();
24 if(intersects)
25 {
26 //app.DebugPrintf("Skipping reeds feature generation as it overlaps a game rule structure\n");
27 return false;
28 }
29 }
30
31 for (int yy = y; yy <= y + 1 + treeHeight; yy++)
32 {
33 int r = 2;
34 if (yy == y) r = 1;
35 if (yy >= y + 1 + treeHeight - 2) r = 2;
36 for (int xx = x - r; xx <= x + r && free; xx++)
37 {
38 for (int zz = z - r; zz <= z + r && free; zz++)
39 {
40 if (yy >= 0 && yy < Level::maxBuildHeight)
41 {
42 int tt = level->getTile(xx, yy, zz);
43 if (tt != 0 && tt != Tile::leaves_Id && tt != Tile::grass_Id && tt != Tile::dirt_Id && tt != Tile::treeTrunk_Id && tt != Tile::sapling_Id) free = false;
44 }
45 else
46 {
47 free = false;
48 }
49 }
50 }
51 }
52
53 if (!free) return false;
54
55 int belowTile = level->getTile(x, y - 1, z);
56 if ((belowTile != Tile::grass_Id && belowTile != Tile::dirt_Id) || y >= Level::maxBuildHeight - treeHeight - 1) return false;
57
58 level->setTileAndData(x, y - 1, z, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
59 level->setTileAndData(x + 1, y - 1, z, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
60 level->setTileAndData(x, y - 1, z + 1, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
61 level->setTileAndData(x + 1, y - 1, z + 1, Tile::dirt_Id, 0, Tile::UPDATE_CLIENTS);
62
63 PIXBeginNamedEvent(0,"MegaTree placing leaves, %d, %d, %d", x, z, y+treeHeight);
64 placeLeaves(level, x, z, y + treeHeight, 2, random);
65 PIXEndNamedEvent();
66
67 PIXBeginNamedEvent(0,"MegaTree placing branches");
68 int branchHeight = y + treeHeight - 2 - random->nextInt(4);
69 while (branchHeight > y + treeHeight / 2)
70 {
71 float angle = random->nextFloat() * PI * 2.0f;
72 int bx = x + (int) (0.5f + Mth::cos(angle) * 4.0f);
73 int bz = z + (int) (0.5f + Mth::sin(angle) * 4.0f);
74 placeLeaves(level, bx, bz, branchHeight, 0, random);
75
76 for (int b = 0; b < 5; b++)
77 {
78 bx = x + (int) (1.5f + Mth::cos(angle) * b);
79 bz = z + (int) (1.5f + Mth::sin(angle) * b);
80 placeBlock(level, bx, branchHeight - 3 + b / 2, bz, Tile::treeTrunk_Id, trunkType);
81 }
82
83 branchHeight -= 2 + random->nextInt(4);
84 }
85 PIXEndNamedEvent();
86
87 PIXBeginNamedEvent(0, "MegaTree placing vines");
88 for (int hh = 0; hh < treeHeight; hh++)
89 {
90 int t = level->getTile(x, y + hh, z);
91 if (t == 0 || t == Tile::leaves_Id)
92 {
93 placeBlock(level, x, y + hh, z, Tile::treeTrunk_Id, trunkType);
94 if (hh > 0)
95 {
96 if (random->nextInt(3) > 0 && level->isEmptyTile(x - 1, y + hh, z))
97 {
98 placeBlock(level, x - 1, y + hh, z, Tile::vine_Id, VineTile::VINE_EAST);
99 }
100 if (random->nextInt(3) > 0 && level->isEmptyTile(x, y + hh, z - 1))
101 {
102 placeBlock(level, x, y + hh, z - 1, Tile::vine_Id, VineTile::VINE_SOUTH);
103 }
104 }
105 }
106 if (hh < (treeHeight - 1))
107 {
108 t = level->getTile(x + 1, y + hh, z);
109 if (t == 0 || t == Tile::leaves_Id)
110 {
111 placeBlock(level, x + 1, y + hh, z, Tile::treeTrunk_Id, trunkType);
112 if (hh > 0)
113 {
114 if (random->nextInt(3) > 0 && level->isEmptyTile(x + 2, y + hh, z))
115 {
116 placeBlock(level, x + 2, y + hh, z, Tile::vine_Id, VineTile::VINE_WEST);
117 }
118 if (random->nextInt(3) > 0 && level->isEmptyTile(x + 1, y + hh, z - 1))
119 {
120 placeBlock(level, x + 1, y + hh, z - 1, Tile::vine_Id, VineTile::VINE_SOUTH);
121 }
122 }
123 }
124 t = level->getTile(x + 1, y + hh, z + 1);
125 if (t == 0 || t == Tile::leaves_Id)
126 {
127 placeBlock(level, x + 1, y + hh, z + 1, Tile::treeTrunk_Id, trunkType);
128 if (hh > 0)
129 {
130 if (random->nextInt(3) > 0 && level->isEmptyTile(x + 2, y + hh, z + 1))
131 {
132 placeBlock(level, x + 2, y + hh, z + 1, Tile::vine_Id, VineTile::VINE_WEST);
133 }
134 if (random->nextInt(3) > 0 && level->isEmptyTile(x + 1, y + hh, z + 2))
135 {
136 placeBlock(level, x + 1, y + hh, z + 2, Tile::vine_Id, VineTile::VINE_NORTH);
137 }
138 }
139 }
140 t = level->getTile(x, y + hh, z + 1);
141 if (t == 0 || t == Tile::leaves_Id)
142 {
143 placeBlock(level, x, y + hh, z + 1, Tile::treeTrunk_Id, trunkType);
144 if (hh > 0)
145 {
146 if (random->nextInt(3) > 0 && level->isEmptyTile(x - 1, y + hh, z + 1))
147 {
148 placeBlock(level, x - 1, y + hh, z + 1, Tile::vine_Id, VineTile::VINE_EAST);
149 }
150 if (random->nextInt(3) > 0 && level->isEmptyTile(x, y + hh, z + 2))
151 {
152 placeBlock(level, x, y + hh, z + 2, Tile::vine_Id, VineTile::VINE_NORTH);
153 }
154 }
155 }
156 }
157 }
158 PIXEndNamedEvent();
159
160 return true;
161}
162
163void MegaTreeFeature::placeLeaves(Level *level, int x, int z, int topPosition, int baseRadius, Random *random)
164{
165 int grassHeight = 2;
166 // 4J Stu - Generate from top down so that we don't have to keep adjusting the heightmaps
167 for (int yy = topPosition; yy >= topPosition - grassHeight; yy--)
168 {
169 int yo = yy - (topPosition);
170 int radius = baseRadius + 1 - yo;
171 for (int xx = x - radius; xx <= x + radius + 1; xx++)
172 {
173 int xo = xx - (x);
174 for (int zz = z - radius; zz <= z + radius + 1; zz++)
175 {
176 int zo = zz - (z);
177 if ((xo < 0 && zo < 0) && (xo * xo + zo * zo) > (radius * radius))
178 {
179 continue;
180 }
181 if ((xo > 0 || zo > 0) && (xo * xo + zo * zo) > ((radius + 1) * (radius + 1)))
182 {
183 continue;
184 }
185 if (random->nextInt(4) == 0 && (xo * xo + zo * zo) > ((radius - 1) * (radius - 1)))
186 {
187 continue;
188 }
189 PIXBeginNamedEvent(0,"Getting tile");
190 int t = level->getTile(xx, yy, zz);
191 PIXEndNamedEvent();
192 if (t == 0 || t == Tile::leaves_Id)
193 {
194 PIXBeginNamedEvent(0,"Placing block");
195 placeBlock(level, xx, yy, zz, Tile::leaves_Id, leafType);
196 PIXEndNamedEvent();
197 }
198 }
199 }
200 }
201}