the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 511 lines 11 kB view raw
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}