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.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}