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