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 "VineTile.h"
3#include "Material.h"
4#include "JavaMath.h"
5#include "Facing.h"
6#include "net.minecraft.world.level.h"
7#include "net.minecraft.world.item.h"
8#include "net.minecraft.stats.h"
9#include "net.minecraft.world.level.biome.h"
10
11VineTile::VineTile(int id) : Tile(id, Material::replaceable_plant, isSolidRender() )
12{
13 setTicking(true);
14}
15
16void VineTile::updateDefaultShape()
17{
18 setShape(0, 0, 0, 1, 1, 1);
19}
20
21int VineTile::getRenderShape()
22{
23 return SHAPE_VINE;
24}
25
26bool VineTile::isSolidRender(bool isServerLevel)
27{
28 return false;
29}
30
31bool VineTile::isCubeShaped()
32{
33 return false;
34}
35
36void VineTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr<TileEntity> forceEntity) // 4J added forceData, forceEntity param
37{
38 const float thickness = 1.0f / 16.0f;
39
40 int facings = level->getData(x, y, z);
41
42 float minX = 1;
43 float minY = 1;
44 float minZ = 1;
45 float maxX = 0;
46 float maxY = 0;
47 float maxZ = 0;
48 bool hasWall = facings > 0;
49
50 if ((facings & VINE_WEST) != 0)
51 {
52 maxX = Math::_max(maxX, thickness);
53 minX = 0;
54 minY = 0;
55 maxY = 1;
56 minZ = 0;
57 maxZ = 1;
58 hasWall = true;
59 }
60 if ((facings & VINE_EAST) != 0)
61 {
62 minX = Math::_min(minX, 1 - thickness);
63 maxX = 1;
64 minY = 0;
65 maxY = 1;
66 minZ = 0;
67 maxZ = 1;
68 hasWall = true;
69 }
70 if ((facings & VINE_NORTH) != 0)
71 {
72 maxZ = Math::_max(maxZ, thickness);
73 minZ = 0;
74 minX = 0;
75 maxX = 1;
76 minY = 0;
77 maxY = 1;
78 hasWall = true;
79 }
80 if ((facings & VINE_SOUTH) != 0)
81 {
82 minZ = Math::_min(minZ, 1 - thickness);
83 maxZ = 1;
84 minX = 0;
85 maxX = 1;
86 minY = 0;
87 maxY = 1;
88 hasWall = true;
89 }
90 if (!hasWall && isAcceptableNeighbor(level->getTile(x, y + 1, z)))
91 {
92 minY = Math::_min(minY, 1 - thickness);
93 maxY = 1;
94 minX = 0;
95 maxX = 1;
96 minZ = 0;
97 maxZ = 1;
98 }
99 setShape(minX, minY, minZ, maxX, maxY, maxZ);
100
101}
102
103AABB *VineTile::getAABB(Level *level, int x, int y, int z)
104{
105 return NULL;
106}
107
108bool VineTile::mayPlace(Level *level, int x, int y, int z, int face)
109{
110 switch (face)
111 {
112 default:
113 return false;
114 case Facing::UP:
115 return isAcceptableNeighbor(level->getTile(x, y + 1, z));
116 case Facing::NORTH:
117 return isAcceptableNeighbor(level->getTile(x, y, z + 1));
118 case Facing::SOUTH:
119 return isAcceptableNeighbor(level->getTile(x, y, z - 1));
120 case Facing::EAST:
121 return isAcceptableNeighbor(level->getTile(x - 1, y, z));
122 case Facing::WEST:
123 return isAcceptableNeighbor(level->getTile(x + 1, y, z));
124 }
125}
126
127bool VineTile::isAcceptableNeighbor(int id)
128{
129 if (id == 0) return false;
130 Tile *tile = Tile::tiles[id];
131 if (tile->isCubeShaped() && tile->material->blocksMotion()) return true;
132 return false;
133}
134
135bool VineTile::updateSurvival(Level *level, int x, int y, int z)
136{
137 int facings = level->getData(x, y, z);
138 int newFacings = facings;
139
140 if (newFacings > 0)
141 {
142 for (int d = 0; d <= 3; d++)
143 {
144 int facing = 1 << d;
145 if ((facings & facing) != 0)
146 {
147 if (!isAcceptableNeighbor(level->getTile(x + Direction::STEP_X[d], y, z + Direction::STEP_Z[d])))
148 {
149 // no attachment in this direction,
150 // verify that there is vines hanging above
151 if (level->getTile(x, y + 1, z) != id || (level->getData(x, y + 1, z) & facing) == 0)
152 {
153 newFacings &= ~facing;
154 }
155 }
156 }
157 }
158 }
159
160 if (newFacings == 0)
161 {
162 // the block will die unless it has a roof
163 if (!isAcceptableNeighbor(level->getTile(x, y + 1, z)))
164 {
165 return false;
166 }
167 }
168 if (newFacings != facings)
169 {
170 level->setData(x, y, z, newFacings, Tile::UPDATE_CLIENTS);
171 }
172 return true;
173
174}
175
176int VineTile::getColor() const
177{
178 return FoliageColor::getDefaultColor();
179}
180
181int VineTile::getColor(int auxData)
182{
183 return FoliageColor::getDefaultColor();
184}
185
186int VineTile::getColor(LevelSource *level, int x, int y, int z, int data)
187{
188 return getColor(level, x, y, z);
189}
190
191int VineTile::getColor(LevelSource *level, int x, int y, int z)
192{
193 return level->getBiome(x, z)->getFolageColor();
194}
195
196void VineTile::neighborChanged(Level *level, int x, int y, int z, int type)
197{
198 if (!level->isClientSide && !updateSurvival(level, x, y, z))
199 {
200 spawnResources(level, x, y, z, level->getData(x, y, z), 0);
201 level->removeTile(x, y, z);
202 }
203}
204
205void VineTile::tick(Level *level, int x, int y, int z, Random *random)
206{
207 if (!level->isClientSide)
208 {
209 if (level->random->nextInt(4) == 0)
210 {
211 // 4J - Brought side spread check forward from 1.2.3
212 int r = 4;
213 int max = 5;
214 bool noSideSpread = false;
215 for (int xx = x - r; xx <= x + r; xx++)
216 {
217 for (int zz = z - r; zz <= z + r; zz++)
218 for (int yy = y - 1; yy <= y + 1; yy++)
219 {
220 if (level->getTile(xx, yy, zz) == id && --max <= 0)
221 {
222 noSideSpread = true;
223 goto testLoop;
224 }
225 }
226testLoop: if(noSideSpread) break;
227 }
228
229 int currentFacings = level->getData(x, y, z);
230 int testFacing = level->random->nextInt(6);
231 int testDirection = Direction::FACING_DIRECTION[testFacing];
232
233 if (testFacing == Facing::UP && y < (Level::maxBuildHeight - 1) && level->isEmptyTile(x, y + 1, z))
234 {
235 // 4J - Brought side spread check forward from 1.2.3
236 if (noSideSpread) return;
237
238 // grow upwards, but only if there is something to cling to
239 int spawnFacings = level->random->nextInt(16) & currentFacings;
240 if (spawnFacings > 0)
241 {
242 for (int d = 0; d <= 3; d++)
243 {
244 if (!isAcceptableNeighbor(level->getTile(x + Direction::STEP_X[d], y + 1, z + Direction::STEP_Z[d])))
245 {
246 spawnFacings &= ~(1 << d);
247 }
248 }
249 if (spawnFacings > 0)
250 {
251 level->setTileAndData(x, y + 1, z, id, spawnFacings, Tile::UPDATE_CLIENTS);
252 }
253 }
254 }
255 else if (testFacing >= Facing::NORTH && testFacing <= Facing::EAST && (currentFacings & (1 << testDirection)) == 0)
256 {
257 // 4J - Brought side spread check forward from 1.2.3
258 if (noSideSpread) return;
259
260 int edgeTile = level->getTile(x + Direction::STEP_X[testDirection], y, z + Direction::STEP_Z[testDirection]);
261
262 if (edgeTile == 0 || Tile::tiles[edgeTile] == NULL)
263 {
264 // if the edge tile is air, we could possibly cling
265 // to something
266 int left = (testDirection + 1) & 3;
267 int right = (testDirection + 3) & 3;
268
269 // attempt to grow straight onto solid tiles
270 if ((currentFacings & (1 << left)) != 0
271 && isAcceptableNeighbor(level->getTile(x + Direction::STEP_X[testDirection] + Direction::STEP_X[left], y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[left])))
272 {
273 level->setTileAndData(x + Direction::STEP_X[testDirection], y, z + Direction::STEP_Z[testDirection], id, 1 << left, Tile::UPDATE_CLIENTS);
274 }
275 else if ((currentFacings & (1 << right)) != 0
276 && isAcceptableNeighbor(level->getTile(x + Direction::STEP_X[testDirection] + Direction::STEP_X[right], y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[right])))
277 {
278 level->setTileAndData(x + Direction::STEP_X[testDirection], y, z + Direction::STEP_Z[testDirection], id, 1 << right, Tile::UPDATE_CLIENTS);
279 }
280 // attempt to grow around corners, but only if the
281 // base tile is solid
282 else if ((currentFacings & (1 << left)) != 0
283 && level->isEmptyTile(x + Direction::STEP_X[testDirection] + Direction::STEP_X[left], y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[left])
284 && isAcceptableNeighbor(level->getTile(x + Direction::STEP_X[left], y, z + Direction::STEP_Z[left])))
285 {
286 level->setTileAndData(x + Direction::STEP_X[testDirection] + Direction::STEP_X[left], y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[left], id,
287 1 << ((testDirection + 2) & 3), Tile::UPDATE_CLIENTS);
288 }
289 else if ((currentFacings & (1 << right)) != 0
290 && level->isEmptyTile(x + Direction::STEP_X[testDirection] + Direction::STEP_X[right], y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[right])
291 && isAcceptableNeighbor(level->getTile(x + Direction::STEP_X[right], y, z + Direction::STEP_Z[right])))
292 {
293 level->setTileAndData(x + Direction::STEP_X[testDirection] + Direction::STEP_X[right], y, z + Direction::STEP_Z[testDirection] + Direction::STEP_Z[right], id,
294 1 << ((testDirection + 2) & 3), Tile::UPDATE_CLIENTS);
295 }
296 // attempt to grow onto the ceiling
297 else if (isAcceptableNeighbor(level->getTile(x + Direction::STEP_X[testDirection], y + 1, z + Direction::STEP_Z[testDirection])))
298 {
299 level->setTileAndData(x + Direction::STEP_X[testDirection], y, z + Direction::STEP_Z[testDirection], id, 0, Tile::UPDATE_CLIENTS);
300 }
301
302 }
303 else if (Tile::tiles[edgeTile]->material->isSolidBlocking() && Tile::tiles[edgeTile]->isCubeShaped())
304 {
305 // we have a wall that we can cling to
306 level->setData(x, y, z, currentFacings | (1 << testDirection), Tile::UPDATE_CLIENTS);
307 }
308 }
309 // growing downwards happens more often than the other
310 // directions
311 else if (y > 1)
312 {
313 int belowTile = level->getTile(x, y - 1, z);
314 // grow downwards into air
315 if (belowTile == 0)
316 {
317 int spawnFacings = level->random->nextInt(16) & currentFacings;
318 if (spawnFacings > 0)
319 {
320 level->setTileAndData(x, y - 1, z, id, spawnFacings, Tile::UPDATE_CLIENTS);
321 }
322 }
323 else if (belowTile == id)
324 {
325 int spawnFacings = level->random->nextInt(16) & currentFacings;
326 int belowData = level->getData(x, y - 1, z);
327 if (belowData != (belowData | spawnFacings))
328 {
329 level->setData(x, y - 1, z, belowData | spawnFacings, Tile::UPDATE_CLIENTS);
330 }
331 }
332 }
333 }
334 }
335}
336
337int VineTile::getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue)
338{
339 int facings = 0;
340 switch (face)
341 {
342 case Facing::NORTH:
343 facings = VINE_SOUTH;
344 break;
345 case Facing::SOUTH:
346 facings = VINE_NORTH;
347 break;
348 case Facing::WEST:
349 facings = VINE_EAST;
350 break;
351 case Facing::EAST:
352 facings = VINE_WEST;
353 break;
354 }
355 if (facings != 0)
356 {
357 return facings;
358 }
359 return itemValue;
360}
361
362int VineTile::getResource(int data, Random *random, int playerBonusLevel)
363{
364 return 0;
365}
366
367int VineTile::getResourceCount(Random *random)
368{
369 return 0;
370}
371
372void VineTile::playerDestroy(Level *level, shared_ptr<Player>player, int x, int y, int z, int data)
373{
374 if (!level->isClientSide && player->getSelectedItem() != NULL && player->getSelectedItem()->id == Item::shears->id)
375 {
376 player->awardStat(
377 GenericStats::blocksMined(id),
378 GenericStats::param_blocksMined(id,data,1)
379 );
380
381 // drop leaf block instead of sapling
382 popResource(level, x, y, z, shared_ptr<ItemInstance>(new ItemInstance(Tile::vine, 1, 0)));
383 }
384 else
385 {
386 Tile::playerDestroy(level, player, x, y, z, data);
387 }
388}