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.phys.h"
3#include "net.minecraft.world.level.h"
4#include "net.minecraft.world.h"
5#include "BaseRailTile.h"
6
7BaseRailTile::Rail::Rail(Level *level, int x, int y, int z)
8{
9 this->level = level;
10 this->x = x;
11 this->y = y;
12 this->z = z;
13
14 int id = level->getTile(x, y, z);
15
16 // 4J Stu - We saw a random crash near the end of development on XboxOne orignal version where the id here isn't a tile any more
17 // Adding this check in to avoid that crash
18 m_bValidRail = isRail(id);
19 if(m_bValidRail)
20 {
21 int direction = level->getData(x, y, z);
22 if (((BaseRailTile *) Tile::tiles[id])->usesDataBit)
23 {
24 usesDataBit = true;
25 direction = direction & ~RAIL_DATA_BIT;
26 }
27 else
28 {
29 usesDataBit = false;
30 }
31 updateConnections(direction);
32 }
33}
34
35BaseRailTile::Rail::~Rail()
36{
37 for( int i = 0; i < connections.size(); i++ )
38 {
39 delete connections[i];
40 }
41}
42
43void BaseRailTile::Rail::updateConnections(int direction)
44{
45 if(m_bValidRail)
46 {
47 for( int i = 0; i < connections.size(); i++ )
48 {
49 delete connections[i];
50 }
51 connections.clear();
52 MemSect(50);
53 if (direction == DIR_FLAT_Z)
54 {
55 connections.push_back(new TilePos(x, y, z - 1));
56 connections.push_back(new TilePos(x, y, z + 1));
57 } else if (direction == DIR_FLAT_X)
58 {
59 connections.push_back(new TilePos(x - 1, y, z));
60 connections.push_back(new TilePos(x + 1, y, z));
61 } else if (direction == 2)
62 {
63 connections.push_back(new TilePos(x - 1, y, z));
64 connections.push_back(new TilePos(x + 1, y + 1, z));
65 } else if (direction == 3)
66 {
67 connections.push_back(new TilePos(x - 1, y + 1, z));
68 connections.push_back(new TilePos(x + 1, y, z));
69 } else if (direction == 4)
70 {
71 connections.push_back(new TilePos(x, y + 1, z - 1));
72 connections.push_back(new TilePos(x, y, z + 1));
73 } else if (direction == 5)
74 {
75 connections.push_back(new TilePos(x, y, z - 1));
76 connections.push_back(new TilePos(x, y + 1, z + 1));
77 } else if (direction == 6)
78 {
79 connections.push_back(new TilePos(x + 1, y, z));
80 connections.push_back(new TilePos(x, y, z + 1));
81 } else if (direction == 7)
82 {
83 connections.push_back(new TilePos(x - 1, y, z));
84 connections.push_back(new TilePos(x, y, z + 1));
85 } else if (direction == 8)
86 {
87 connections.push_back(new TilePos(x - 1, y, z));
88 connections.push_back(new TilePos(x, y, z - 1));
89 } else if (direction == 9)
90 {
91 connections.push_back(new TilePos(x + 1, y, z));
92 connections.push_back(new TilePos(x, y, z - 1));
93 }
94 MemSect(0);
95 }
96}
97
98void BaseRailTile::Rail::removeSoftConnections()
99{
100 if(m_bValidRail)
101 {
102 for (unsigned int i = 0; i < connections.size(); i++)
103 {
104 Rail *rail = getRail(connections[i]);
105 if (rail == NULL || !rail->connectsTo(this))
106 {
107 delete connections[i];
108 connections.erase(connections.begin()+i);
109 i--;
110 } else
111 {
112 delete connections[i];
113 MemSect(50);
114 connections[i] =new TilePos(rail->x, rail->y, rail->z);
115 MemSect(0);
116 }
117 delete rail;
118 }
119 }
120}
121
122bool BaseRailTile::Rail::hasRail(int x, int y, int z)
123{
124 if(!m_bValidRail) return false;
125 if (isRail(level, x, y, z)) return true;
126 if (isRail(level, x, y + 1, z)) return true;
127 if (isRail(level, x, y - 1, z)) return true;
128 return false;
129}
130
131BaseRailTile::Rail *BaseRailTile::Rail::getRail(TilePos *p)
132{
133 if(!m_bValidRail) return NULL;
134 if (isRail(level, p->x, p->y, p->z)) return new Rail(level, p->x, p->y, p->z);
135 if (isRail(level, p->x, p->y + 1, p->z)) return new Rail(level, p->x, p->y + 1, p->z);
136 if (isRail(level, p->x, p->y - 1, p->z)) return new Rail(level, p->x, p->y - 1, p->z);
137 return NULL;
138}
139
140
141bool BaseRailTile::Rail::connectsTo(Rail *rail)
142{
143 if(m_bValidRail)
144 {
145 AUTO_VAR(itEnd, connections.end());
146 for (AUTO_VAR(it, connections.begin()); it != itEnd; it++)
147 {
148 TilePos *p = *it; //connections[i];
149 if (p->x == rail->x && p->z == rail->z)
150 {
151 return true;
152 }
153 }
154 }
155 return false;
156}
157
158bool BaseRailTile::Rail::hasConnection(int x, int y, int z)
159{
160 if(m_bValidRail)
161 {
162 AUTO_VAR(itEnd, connections.end());
163 for (AUTO_VAR(it, connections.begin()); it != itEnd; it++)
164 {
165 TilePos *p = *it; //connections[i];
166 if (p->x == x && p->z == z)
167 {
168 return true;
169 }
170 }
171 }
172 return false;
173}
174
175
176int BaseRailTile::Rail::countPotentialConnections()
177{
178 int count = 0;
179
180 if(m_bValidRail)
181 {
182 if (hasRail(x, y, z - 1)) count++;
183 if (hasRail(x, y, z + 1)) count++;
184 if (hasRail(x - 1, y, z)) count++;
185 if (hasRail(x + 1, y, z)) count++;
186 }
187
188 return count;
189}
190
191bool BaseRailTile::Rail::canConnectTo(Rail *rail)
192{
193 if(!m_bValidRail) return false;
194 if (connectsTo(rail)) return true;
195 if (connections.size() == 2)
196 {
197 return false;
198 }
199 if (connections.empty())
200 {
201 return true;
202 }
203
204 return true;
205}
206
207void BaseRailTile::Rail::connectTo(Rail *rail)
208{
209 if(m_bValidRail)
210 {
211 MemSect(50);
212 connections.push_back(new TilePos(rail->x, rail->y, rail->z));
213 MemSect(0);
214
215 bool n = hasConnection(x, y, z - 1);
216 bool s = hasConnection(x, y, z + 1);
217 bool w = hasConnection(x - 1, y, z);
218 bool e = hasConnection(x + 1, y, z);
219
220 int dir = -1;
221
222 if (n || s) dir = DIR_FLAT_Z;
223 if (w || e) dir = DIR_FLAT_X;
224
225 if (!usesDataBit)
226 {
227 if (s && e && !n && !w) dir = 6;
228 if (s && w && !n && !e) dir = 7;
229 if (n && w && !s && !e) dir = 8;
230 if (n && e && !s && !w) dir = 9;
231 }
232 if (dir == DIR_FLAT_Z)
233 {
234 if (isRail(level, x, y + 1, z - 1)) dir = 4;
235 if (isRail(level, x, y + 1, z + 1)) dir = 5;
236 }
237 if (dir == DIR_FLAT_X)
238 {
239 if (isRail(level, x + 1, y + 1, z)) dir = 2;
240 if (isRail(level, x - 1, y + 1, z)) dir = 3;
241 }
242
243 if (dir < 0) dir = DIR_FLAT_Z;
244
245 int data = dir;
246 if (usesDataBit)
247 {
248 data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir;
249 }
250
251 level->setData(x, y, z, data, Tile::UPDATE_ALL);
252 }
253}
254
255bool BaseRailTile::Rail::hasNeighborRail(int x, int y, int z)
256{
257 if(!m_bValidRail) return false;
258 TilePos tp(x,y,z);
259 Rail *neighbor = getRail( &tp );
260 if (neighbor == NULL) return false;
261 neighbor->removeSoftConnections();
262 bool retval = neighbor->canConnectTo(this);
263 delete neighbor;
264 return retval;
265}
266
267void BaseRailTile::Rail::place(bool hasSignal, bool first)
268{
269 if(m_bValidRail)
270 {
271 bool n = hasNeighborRail(x, y, z - 1);
272 bool s = hasNeighborRail(x, y, z + 1);
273 bool w = hasNeighborRail(x - 1, y, z);
274 bool e = hasNeighborRail(x + 1, y, z);
275
276 int dir = -1;
277
278 if ((n || s) && !w && !e) dir = DIR_FLAT_Z;
279 if ((w || e) && !n && !s) dir = DIR_FLAT_X;
280
281 if (!usesDataBit)
282 {
283 if (s && e && !n && !w) dir = 6;
284 if (s && w && !n && !e) dir = 7;
285 if (n && w && !s && !e) dir = 8;
286 if (n && e && !s && !w) dir = 9;
287 }
288 if (dir == -1)
289 {
290 if (n || s) dir = DIR_FLAT_Z;
291 if (w || e) dir = DIR_FLAT_X;
292
293 if (!usesDataBit)
294 {
295 if (hasSignal)
296 {
297 if (s && e) dir = 6;
298 if (w && s) dir = 7;
299 if (e && n) dir = 9;
300 if (n && w) dir = 8;
301 } else {
302 if (n && w) dir = 8;
303 if (e && n) dir = 9;
304 if (w && s) dir = 7;
305 if (s && e) dir = 6;
306 }
307 }
308 }
309
310 if (dir == DIR_FLAT_Z)
311 {
312 if (isRail(level, x, y + 1, z - 1)) dir = 4;
313 if (isRail(level, x, y + 1, z + 1)) dir = 5;
314 }
315 if (dir == DIR_FLAT_X)
316 {
317 if (isRail(level, x + 1, y + 1, z)) dir = 2;
318 if (isRail(level, x - 1, y + 1, z)) dir = 3;
319 }
320
321 if (dir < 0) dir = DIR_FLAT_Z;
322
323 updateConnections(dir);
324
325 int data = dir;
326 if (usesDataBit)
327 {
328 data = (level->getData(x, y, z) & RAIL_DATA_BIT) | dir;
329 }
330
331 if (first || level->getData(x, y, z) != data)
332 {
333 level->setData(x, y, z, data, Tile::UPDATE_ALL);
334
335 AUTO_VAR(itEnd, connections.end());
336 for (AUTO_VAR(it, connections.begin()); it != itEnd; it++)
337 {
338 Rail *neighbor = getRail(*it);
339 if (neighbor == NULL) continue;
340 neighbor->removeSoftConnections();
341
342 if (neighbor->canConnectTo(this))
343 {
344 neighbor->connectTo(this);
345 }
346 delete neighbor;
347 }
348 }
349 }
350}
351
352bool BaseRailTile::isRail(Level *level, int x, int y, int z)
353{
354 return isRail(level->getTile(x, y, z));
355}
356
357bool BaseRailTile::isRail(int id)
358{
359 return id == Tile::rail_Id || id == Tile::goldenRail_Id || id == Tile::detectorRail_Id || id == Tile::activatorRail_Id;
360}
361
362BaseRailTile::BaseRailTile(int id, bool usesDataBit) : Tile(id, Material::decoration, isSolidRender())
363{
364 this->usesDataBit = usesDataBit;
365 setShape(0, 0, 0, 1, 2 / 16.0f, 1);
366
367 iconTurn = NULL;
368}
369
370bool BaseRailTile::isUsesDataBit()
371{
372 return usesDataBit;
373}
374
375AABB *BaseRailTile::getAABB(Level *level, int x, int y, int z)
376{
377 return NULL;
378}
379
380bool BaseRailTile::blocksLight()
381{
382 return false;
383}
384
385bool BaseRailTile::isSolidRender(bool isServerLevel)
386{
387 return false;
388}
389
390HitResult *BaseRailTile::clip(Level *level, int xt, int yt, int zt, Vec3 *a, Vec3 *b)
391{
392 updateShape(level, xt, yt, zt);
393 return Tile::clip(level, xt, yt, zt, a, b);
394}
395
396void BaseRailTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr<TileEntity> forceEntity) // 4J added forceData, forceEntity param
397{
398 int data = level->getData(x, y, z);
399 if (data >= 2 && data <= 5)
400 {
401 setShape(0, 0, 0, 1, 2 / 16.0f + 0.5f, 1);
402 } else
403 {
404 setShape(0, 0, 0, 1, 2 / 16.0f, 1);
405 }
406}
407
408bool BaseRailTile::isCubeShaped()
409{
410 return false;
411}
412
413int BaseRailTile::getRenderShape()
414{
415 return Tile::SHAPE_RAIL;
416}
417
418int BaseRailTile::getResourceCount(Random random)
419{
420 return 1;
421}
422
423bool BaseRailTile::mayPlace(Level *level, int x, int y, int z)
424{
425 if (level->isTopSolidBlocking(x, y - 1, z))
426 {
427 return true;
428 }
429 return false;
430}
431
432void BaseRailTile::onPlace(Level *level, int x, int y, int z)
433{
434 if (!level->isClientSide)
435 {
436 updateDir(level, x, y, z, true);
437
438 if (usesDataBit)
439 {
440 neighborChanged(level, x, y, z, id);
441 }
442 }
443}
444
445void BaseRailTile::neighborChanged(Level *level, int x, int y, int z, int type)
446{
447 if (level->isClientSide) return;
448
449 int data = level->getData(x, y, z);
450 int dir = data;
451 if (usesDataBit) {
452 dir = dir & RAIL_DIRECTION_MASK;
453 }
454 bool remove = false;
455
456 if (!level->isTopSolidBlocking(x, y - 1, z)) remove = true;
457 if (dir == 2 && !level->isTopSolidBlocking(x + 1, y, z)) remove = true;
458 if (dir == 3 && !level->isTopSolidBlocking(x - 1, y, z)) remove = true;
459 if (dir == 4 && !level->isTopSolidBlocking(x, y, z - 1)) remove = true;
460 if (dir == 5 && !level->isTopSolidBlocking(x, y, z + 1)) remove = true;
461
462 if (remove)
463 {
464 spawnResources(level, x, y, z, level->getData(x, y, z), 0);
465 level->removeTile(x, y, z);
466 }
467 else
468 {
469 updateState(level, x, y, z, data, dir, type);
470 }
471
472}
473
474void BaseRailTile::updateState(Level *level, int x, int y, int z, int data, int dir, int type)
475{
476}
477
478void BaseRailTile::updateDir(Level *level, int x, int y, int z, bool first)
479{
480 if (level->isClientSide) return;
481 Rail *rail = new Rail(level, x, y, z);
482 rail->place(level->hasNeighborSignal(x, y, z), first);
483 delete rail;
484}
485
486int BaseRailTile::getPistonPushReaction()
487{
488 // override the decoration material's reaction
489 return Material::PUSH_NORMAL;
490}
491
492void BaseRailTile::onRemove(Level *level, int x, int y, int z, int id, int data)
493{
494 int dir = data;
495 if (usesDataBit)
496 {
497 dir &= RAIL_DIRECTION_MASK;
498 }
499
500 Tile::onRemove(level, x, y, z, id, data);
501
502 if (dir == 2 || dir == 3 || dir == 4 || dir == 5)
503 {
504 level->updateNeighborsAt(x, y + 1, z, id);
505 }
506 if (usesDataBit)
507 {
508 level->updateNeighborsAt(x, y, z, id);
509 level->updateNeighborsAt(x, y - 1, z, id);
510 }
511}