the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 358 lines 10 kB view raw
1#include "stdafx.h" 2#include "net.minecraft.h" 3#include "net.minecraft.world.level.h" 4#include "net.minecraft.world.level.tile.h" 5#include "net.minecraft.world.level.redstone.h" 6#include "TripWireSourceTile.h" 7 8TripWireSourceTile::TripWireSourceTile(int id) : Tile(id, Material::decoration, isSolidRender()) 9{ 10 this->setTicking(true); 11} 12 13AABB *TripWireSourceTile::getAABB(Level *level, int x, int y, int z) 14{ 15 return NULL; 16} 17 18bool TripWireSourceTile::blocksLight() 19{ 20 return false; 21} 22 23bool TripWireSourceTile::isSolidRender(bool isServerLevel) 24{ 25 return false; 26} 27 28bool TripWireSourceTile::isCubeShaped() 29{ 30 return false; 31} 32 33int TripWireSourceTile::getRenderShape() 34{ 35 return Tile::SHAPE_TRIPWIRE_SOURCE; 36} 37 38int TripWireSourceTile::getTickDelay(Level *level) 39{ 40 return 10; 41} 42 43bool TripWireSourceTile::mayPlace(Level *level, int x, int y, int z, int face) 44{ 45 if (face == Facing::NORTH && level->isSolidBlockingTile(x, y, z + 1)) return true; 46 if (face == Facing::SOUTH && level->isSolidBlockingTile(x, y, z - 1)) return true; 47 if (face == Facing::WEST && level->isSolidBlockingTile(x + 1, y, z)) return true; 48 if (face == Facing::EAST && level->isSolidBlockingTile(x - 1, y, z)) return true; 49 return false; 50} 51 52bool TripWireSourceTile::mayPlace(Level *level, int x, int y, int z) 53{ 54 if (level->isSolidBlockingTile(x - 1, y, z)) 55 { 56 return true; 57 } 58 else if (level->isSolidBlockingTile(x + 1, y, z)) 59 { 60 return true; 61 } 62 else if (level->isSolidBlockingTile(x, y, z - 1)) 63 { 64 return true; 65 } 66 else if (level->isSolidBlockingTile(x, y, z + 1)) 67 { 68 return true; 69 } 70 return false; 71} 72 73int TripWireSourceTile::getPlacedOnFaceDataValue(Level *level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, int itemValue) 74{ 75 int dir = 0; 76 77 if (face == Facing::NORTH && level->isSolidBlockingTileInLoadedChunk(x, y, z + 1, true)) dir = Direction::NORTH; 78 if (face == Facing::SOUTH && level->isSolidBlockingTileInLoadedChunk(x, y, z - 1, true)) dir = Direction::SOUTH; 79 if (face == Facing::WEST && level->isSolidBlockingTileInLoadedChunk(x + 1, y, z, true)) dir = Direction::WEST; 80 if (face == Facing::EAST && level->isSolidBlockingTileInLoadedChunk(x - 1, y, z, true)) dir = Direction::EAST; 81 82 return dir; 83} 84 85void TripWireSourceTile::finalizePlacement(Level *level, int x, int y, int z, int data) 86{ 87 calculateState(level, x, y, z, id, data, false, -1, 0); 88} 89 90void TripWireSourceTile::neighborChanged(Level *level, int x, int y, int z, int type) 91{ 92 if (type == this->id) return; 93 if (checkCanSurvive(level, x, y, z)) 94 { 95 int data = level->getData(x, y, z); 96 int dir = data & MASK_DIR; 97 bool replace = false; 98 99 if (!level->isSolidBlockingTile(x - 1, y, z) && dir == Direction::EAST) replace = true; 100 if (!level->isSolidBlockingTile(x + 1, y, z) && dir == Direction::WEST) replace = true; 101 if (!level->isSolidBlockingTile(x, y, z - 1) && dir == Direction::SOUTH) replace = true; 102 if (!level->isSolidBlockingTile(x, y, z + 1) && dir == Direction::NORTH) replace = true; 103 104 if (replace) 105 { 106 spawnResources(level, x, y, z, data, 0); 107 level->removeTile(x, y, z); 108 } 109 } 110} 111 112void TripWireSourceTile::calculateState(Level *level, int x, int y, int z, int id, int data, bool canUpdate, 113 /*4J-Jev, these parameters only used with 'updateSource' -->*/ int wireSource, int wireSourceData) 114{ 115 int dir = data & MASK_DIR; 116 bool wasAttached = (data & MASK_ATTACHED) == MASK_ATTACHED; 117 bool wasPowered = (data & MASK_POWERED) == MASK_POWERED; 118 bool attached = id == Tile::tripWireSource_Id; // id is only != TripwireSource_id when 'onRemove' 119 bool powered = false; 120 bool suspended = !level->isTopSolidBlocking(x, y - 1, z); 121 int stepX = Direction::STEP_X[dir]; 122 int stepZ = Direction::STEP_Z[dir]; 123 int receiverPos = 0; 124 int wiresData[WIRE_DIST_MAX]; 125 126 // Loop over each tile down the wire, from this tile, to the expected opposing src tile. 127 for (int i = 1; i < WIRE_DIST_MAX; i++) 128 { 129 int xx = x + stepX * i; 130 int zz = z + stepZ * i; 131 int tile = level->getTile(xx, y, zz); 132 133 if (tile == Tile::tripWireSource_Id) 134 { 135 int otherData = level->getData(xx, y, zz); 136 137 if ((otherData & MASK_DIR) == Direction::DIRECTION_OPPOSITE[dir]) 138 { 139 receiverPos = i; 140 } 141 142 break; 143 } 144 else if (tile == Tile::tripWire_Id || i == wireSource) // wireSource is the wiretile that caused an 'updateSource' 145 { 146 int wireData = i == wireSource ? wireSourceData : level->getData(xx, y, zz); 147 bool wireArmed = (wireData & TripWireTile::MASK_DISARMED) != TripWireTile::MASK_DISARMED; 148 bool wirePowered = (wireData & TripWireTile::MASK_POWERED) == TripWireTile::MASK_POWERED; 149 bool wireSuspended = (wireData & TripWireTile::MASK_SUSPENDED) == TripWireTile::MASK_SUSPENDED; 150 attached &= wireSuspended == suspended; 151 powered |= wireArmed && wirePowered; 152 153 wiresData[i] = wireData; 154 155 if (i == wireSource) 156 { 157 level->addToTickNextTick(x, y, z, id, getTickDelay(level)); 158 attached &= wireArmed; 159 } 160 } 161 else // Non-wire or src tile encountered. 162 { 163 wiresData[i] = -1; 164 attached = false; 165 } 166 } 167 168 attached &= receiverPos > WIRE_DIST_MIN; 169 powered &= attached; 170 int state = (attached ? MASK_ATTACHED : 0) | (powered ? MASK_POWERED : 0); 171 data = dir | state; 172 173 if (receiverPos > 0) // If a receiver is detected update it's state and notify it's neighbours. 174 { 175 int xx = x + stepX * receiverPos; 176 int zz = z + stepZ * receiverPos; 177 int opposite = Direction::DIRECTION_OPPOSITE[dir]; 178 level->setData(xx, y, zz, opposite | state, Tile::UPDATE_ALL); 179 notifyNeighbors(level, xx, y, zz, opposite); 180 181 playSound(level, xx, y, zz, attached, powered, wasAttached, wasPowered); 182 } 183 184 playSound(level, x, y, z, attached, powered, wasAttached, wasPowered); 185 186 if (id > 0) // ie. it isn't being removed. 187 { 188 level->setData(x, y, z, data, Tile::UPDATE_ALL); 189 if (canUpdate) notifyNeighbors(level, x, y, z, dir); 190 } 191 192 if (wasAttached != attached) 193 { 194 for (int i = 1; i < receiverPos; i++) 195 { 196 int xx = x + stepX * i; 197 int zz = z + stepZ * i; 198 int wireData = wiresData[i]; 199 if (wireData < 0) continue; 200 201 if (attached) 202 { 203 wireData |= TripWireTile::MASK_ATTACHED; 204 } 205 else 206 { 207 wireData &= ~TripWireTile::MASK_ATTACHED; 208 } 209 210 211 level->setData(xx, y, zz, wireData, Tile::UPDATE_ALL); 212 } 213 } 214} 215 216void TripWireSourceTile::tick(Level *level, int x, int y, int z, Random *random) 217{ 218 calculateState(level, x, y, z, id, level->getData(x, y, z), true, -1, 0); 219} 220 221void TripWireSourceTile::playSound(Level *level, int x, int y, int z, bool attached, bool powered, bool wasAttached, bool wasPowered) 222{ 223 if (powered && !wasPowered) 224 { 225 level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK, 0.4f, 0.6f); 226 } 227 else if (!powered && wasPowered) 228 { 229 level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK, 0.4f, 0.5f); 230 } 231 else if (attached && !wasAttached) 232 { 233 level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_CLICK, 0.4f, 0.7f); 234 } 235 else if (!attached && wasAttached) 236 { 237 level->playSound(x + 0.5, y + 0.1, z + 0.5, eSoundType_RANDOM_BOW_HIT, 0.4f, 1.2f / (level->random->nextFloat() * 0.2f + 0.9f)); 238 } 239} 240 241void TripWireSourceTile::notifyNeighbors(Level *level, int x, int y, int z, int dir) 242{ 243 level->updateNeighborsAt(x, y, z, id); 244 245 if (dir == Direction::EAST) 246 { 247 level->updateNeighborsAt(x - 1, y, z, id); 248 } 249 else if (dir == Direction::WEST) 250 { 251 level->updateNeighborsAt(x + 1, y, z, id); 252 } 253 else if (dir == Direction::SOUTH) 254 { 255 level->updateNeighborsAt(x, y, z - 1, id); 256 } 257 else if (dir == Direction::NORTH) 258 { 259 level->updateNeighborsAt(x, y, z + 1, id); 260 } 261} 262 263bool TripWireSourceTile::checkCanSurvive(Level *level, int x, int y, int z) 264{ 265 if (!mayPlace(level, x, y, z)) 266 { 267 this->spawnResources(level, x, y, z, level->getData(x, y, z), 0); 268 level->removeTile(x, y, z); 269 return false; 270 } 271 272 return true; 273} 274 275void TripWireSourceTile::updateShape(LevelSource *level, int x, int y, int z, int forceData, shared_ptr<TileEntity> forceEntity) 276{ 277 int dir = level->getData(x, y, z) & MASK_DIR; 278 float r = 3 / 16.0f; 279 280 if (dir == Direction::EAST) 281 { 282 setShape(0, 0.2f, 0.5f - r, r * 2, 0.8f, 0.5f + r); 283 } 284 else if (dir == Direction::WEST) 285 { 286 setShape(1 - r * 2, 0.2f, 0.5f - r, 1, 0.8f, 0.5f + r); 287 } 288 else if (dir == Direction::SOUTH) 289 { 290 setShape(0.5f - r, 0.2f, 0, 0.5f + r, 0.8f, r * 2); 291 } 292 else if (dir == Direction::NORTH) 293 { 294 setShape(0.5f - r, 0.2f, 1 - r * 2, 0.5f + r, 0.8f, 1); 295 } 296} 297 298void TripWireSourceTile::onRemove(Level *level, int x, int y, int z, int id, int data) 299{ 300 bool attached = (data & MASK_ATTACHED) == MASK_ATTACHED; 301 bool powered = (data & MASK_POWERED) == MASK_POWERED; 302 303 if (attached || powered) 304 { 305 calculateState(level, x, y, z, 0, data, false, -1, 0); // Disconnect 306 // the other end. 307 } 308 309 if (powered) 310 { 311 level->updateNeighborsAt(x, y, z, this->id); 312 int dir = data & MASK_DIR; 313 314 if (dir == Direction::EAST) 315 { 316 level->updateNeighborsAt(x - 1, y, z, this->id); 317 } 318 else if (dir == Direction::WEST) 319 { 320 level->updateNeighborsAt(x + 1, y, z, this->id); 321 } 322 else if (dir == Direction::SOUTH) 323 { 324 level->updateNeighborsAt(x, y, z - 1, this->id); 325 } 326 else if (dir == Direction::NORTH) 327 { 328 level->updateNeighborsAt(x, y, z + 1, this->id); 329 } 330 } 331 332 Tile::onRemove(level, x, y, z, id, data); 333} 334 335int TripWireSourceTile::getSignal(LevelSource *level, int x, int y, int z, int dir) 336{ 337 return (level->getData(x, y, z) & MASK_POWERED) == MASK_POWERED ? Redstone::SIGNAL_MAX : Redstone::SIGNAL_NONE; 338} 339 340int TripWireSourceTile::getDirectSignal(LevelSource *level, int x, int y, int z, int dir) 341{ 342 int data = level->getData(x, y, z); 343 if ((data & MASK_POWERED) != MASK_POWERED) return Redstone::SIGNAL_NONE; 344 int myDir = data & MASK_DIR; 345 346 if (myDir == Direction::NORTH && dir == Facing::NORTH) return Redstone::SIGNAL_MAX; 347 if (myDir == Direction::SOUTH && dir == Facing::SOUTH) return Redstone::SIGNAL_MAX; 348 if (myDir == Direction::WEST && dir == Facing::WEST) return Redstone::SIGNAL_MAX; 349 if (myDir == Direction::EAST && dir == Facing::EAST) return Redstone::SIGNAL_MAX; 350 351 352 return Redstone::SIGNAL_NONE; 353} 354 355bool TripWireSourceTile::isSignalSource() 356{ 357 return true; 358}