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.redstone.h"
4#include "net.minecraft.world.level.h"
5#include "net.minecraft.world.level.tile.h"
6#include "net.minecraft.world.item.h"
7#include "net.minecraft.world.entity.h"
8#include "net.minecraft.world.h"
9#include "DiodeTile.h"
10
11DiodeTile::DiodeTile(int id, bool on) : DirectionalTile(id, Material::decoration,isSolidRender())
12{
13 this->on = on;
14 updateDefaultShape();
15}
16
17// 4J Added override
18void DiodeTile::updateDefaultShape()
19{
20 setShape(0, 0, 0, 1, 2.0f / 16.0f, 1);
21}
22
23bool DiodeTile::isCubeShaped()
24{
25 return false;
26}
27
28bool DiodeTile::mayPlace(Level *level, int x, int y, int z)
29{
30 if (!level->isTopSolidBlocking(x, y - 1, z))
31 {
32 return false;
33 }
34 return Tile::mayPlace(level, x, y, z);
35}
36
37bool DiodeTile::canSurvive(Level *level, int x, int y, int z)
38{
39 if (!level->isTopSolidBlocking(x, y - 1, z))
40 {
41 return false;
42 }
43 return Tile::canSurvive(level, x, y, z);
44}
45
46void DiodeTile::tick(Level *level, int x, int y, int z, Random *random)
47{
48 int data = level->getData(x, y, z);
49 if (!isLocked(level, x, y, z, data))
50 {
51 bool sourceOn = shouldTurnOn(level, x, y, z, data);
52 if (on && !sourceOn)
53 {
54 level->setTileAndData(x, y, z, getOffTile()->id, data, Tile::UPDATE_CLIENTS);
55 }
56 else if (!on)
57 {
58 // when off-diodes are ticked, they always turn on for one tick and
59 // then off again if necessary
60 level->setTileAndData(x, y, z, getOnTile()->id, data, Tile::UPDATE_CLIENTS);
61 if (!sourceOn)
62 {
63 level->addToTickNextTick(x, y, z, getOnTile()->id, getTurnOffDelay(data), -1);
64 }
65 }
66 }
67}
68
69Icon *DiodeTile::getTexture(int face, int data)
70{
71 // down is used by the torch tesselator
72 if (face == Facing::DOWN)
73 {
74 if (on)
75 {
76 return Tile::redstoneTorch_on->getTexture(face);
77 }
78 return Tile::redstoneTorch_off->getTexture(face);
79 }
80 if (face == Facing::UP)
81 {
82 return icon;
83 }
84 // edge of stone half-step
85 return Tile::stoneSlab->getTexture(Facing::UP);
86}
87
88bool DiodeTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face)
89{
90 if (face == Facing::DOWN || face == Facing::UP)
91 {
92 // up and down is a special case handled by the shape renderer
93 return false;
94 }
95 return true;
96}
97
98int DiodeTile::getRenderShape()
99{
100 return SHAPE_DIODE;
101}
102
103bool DiodeTile::isOn(int data)
104{
105 return on;
106}
107
108int DiodeTile::getDirectSignal(LevelSource *level, int x, int y, int z, int dir)
109{
110 return getSignal(level, x, y, z, dir);
111}
112
113int DiodeTile::getSignal(LevelSource *level, int x, int y, int z, int facing)
114{
115 int data = level->getData(x, y, z);
116 if (!isOn(data))
117 {
118 return Redstone::SIGNAL_NONE;
119 }
120
121 int dir = getDirection(data);
122
123 if (dir == Direction::SOUTH && facing == Facing::SOUTH) return getOutputSignal(level, x, y, z, data);
124 if (dir == Direction::WEST && facing == Facing::WEST) return getOutputSignal(level, x, y, z, data);
125 if (dir == Direction::NORTH && facing == Facing::NORTH) return getOutputSignal(level, x, y, z, data);
126 if (dir == Direction::EAST && facing == Facing::EAST) return getOutputSignal(level, x, y, z, data);
127
128 return Redstone::SIGNAL_NONE;
129}
130
131void DiodeTile::neighborChanged(Level *level, int x, int y, int z, int type)
132{
133 if (!canSurvive(level, x, y, z))
134 {
135 this->spawnResources(level, x, y, z, level->getData(x, y, z), 0);
136 level->removeTile(x, y, z);
137 level->updateNeighborsAt(x + 1, y, z, id);
138 level->updateNeighborsAt(x - 1, y, z, id);
139 level->updateNeighborsAt(x, y, z + 1, id);
140 level->updateNeighborsAt(x, y, z - 1, id);
141 level->updateNeighborsAt(x, y - 1, z, id);
142 level->updateNeighborsAt(x, y + 1, z, id);
143 return;
144 }
145
146 checkTickOnNeighbor(level, x, y, z, type);
147}
148
149void DiodeTile::checkTickOnNeighbor(Level *level, int x, int y, int z, int type)
150{
151 int data = level->getData(x, y, z);
152
153 if (!isLocked(level, x, y, z, data))
154 {
155 bool sourceOn = shouldTurnOn(level, x, y, z, data);
156 if ((on && !sourceOn || !on && sourceOn) && !level->isTileToBeTickedAt(x, y, z, id))
157 {
158 int prio = -1;
159
160 // if the tile in front is a repeater, we prioritize this update
161 if (shouldPrioritize(level, x, y, z, data))
162 {
163 prio = -3;
164 }
165 else if (on)
166 {
167 prio = -2;
168 }
169
170 level->addToTickNextTick(x, y, z, id, getTurnOnDelay(data), prio);
171 }
172 }
173}
174
175bool DiodeTile::isLocked(LevelSource *level, int x, int y, int z, int data)
176{
177 return false;
178}
179
180bool DiodeTile::shouldTurnOn(Level *level, int x, int y, int z, int data)
181{
182 return getInputSignal(level, x, y, z, data) > Redstone::SIGNAL_NONE;
183}
184
185int DiodeTile::getInputSignal(Level *level, int x, int y, int z, int data)
186{
187 int dir = getDirection(data);
188
189 int xx = x + Direction::STEP_X[dir];
190 int zz = z + Direction::STEP_Z[dir];
191 int input = level->getSignal(xx, y, zz, Direction::DIRECTION_FACING[dir]);
192
193 if (input >= Redstone::SIGNAL_MAX) return input;
194 return max(input, level->getTile(xx, y, zz) == Tile::redStoneDust_Id ? level->getData(xx, y, zz) : Redstone::SIGNAL_NONE);
195}
196
197int DiodeTile::getAlternateSignal(LevelSource *level, int x, int y, int z, int data)
198{
199 int dir = getDirection(data);
200
201 switch (dir)
202 {
203 case Direction::SOUTH:
204 case Direction::NORTH:
205 return max(getAlternateSignalAt(level, x - 1, y, z, Facing::WEST), getAlternateSignalAt(level, x + 1, y, z, Facing::EAST));
206 case Direction::EAST:
207 case Direction::WEST:
208 return max(getAlternateSignalAt(level, x, y, z + 1, Facing::SOUTH), getAlternateSignalAt(level, x, y, z - 1, Facing::NORTH));
209 }
210
211 return Redstone::SIGNAL_NONE;
212}
213
214int DiodeTile::getAlternateSignalAt(LevelSource *level, int x, int y, int z, int facing)
215{
216 int tile = level->getTile(x, y, z);
217
218 if (isAlternateInput(tile))
219 {
220 if (tile == Tile::redStoneDust_Id)
221 {
222 return level->getData(x, y, z);
223 }
224 else
225 {
226 return level->getDirectSignal(x, y, z, facing);
227 }
228 }
229
230 return Redstone::SIGNAL_NONE;
231}
232
233bool DiodeTile::isSignalSource()
234{
235 return true;
236}
237
238void DiodeTile::setPlacedBy(Level *level, int x, int y, int z, shared_ptr<LivingEntity> by, shared_ptr<ItemInstance> itemInstance)
239{
240 int dir = (((Mth::floor(by->yRot * 4 / (360) + 0.5)) & 3) + 2) % 4;
241 level->setData(x, y, z, dir, Tile::UPDATE_ALL);
242
243 bool sourceOn = shouldTurnOn(level, x, y, z, dir);
244 if (sourceOn)
245 {
246 level->addToTickNextTick(x, y, z, id, 1);
247 }
248}
249
250void DiodeTile::onPlace(Level *level, int x, int y, int z)
251{
252 updateNeighborsInFront(level, x, y, z);
253}
254
255void DiodeTile::updateNeighborsInFront(Level *level, int x, int y, int z)
256{
257 int dir = getDirection(level->getData(x, y, z));
258 if (dir == Direction::WEST)
259 {
260 level->neighborChanged(x + 1, y, z, id);
261 level->updateNeighborsAtExceptFromFacing(x + 1, y, z, id, Facing::WEST);
262 }
263 if (dir == Direction::EAST)
264 {
265 level->neighborChanged(x - 1, y, z, id);
266 level->updateNeighborsAtExceptFromFacing(x - 1, y, z, id, Facing::EAST);
267 }
268 if (dir == Direction::NORTH)
269 {
270 level->neighborChanged(x, y, z + 1, id);
271 level->updateNeighborsAtExceptFromFacing(x, y, z + 1, id, Facing::NORTH);
272 }
273 if (dir == Direction::SOUTH)
274 {
275 level->neighborChanged(x, y, z - 1, id);
276 level->updateNeighborsAtExceptFromFacing(x, y, z - 1, id, Facing::SOUTH);
277 }
278}
279
280void DiodeTile::destroy(Level *level, int x, int y, int z, int data)
281{
282 if (on)
283 {
284 level->updateNeighborsAt(x + 1, y, z, id);
285 level->updateNeighborsAt(x - 1, y, z, id);
286 level->updateNeighborsAt(x, y, z + 1, id);
287 level->updateNeighborsAt(x, y, z - 1, id);
288 level->updateNeighborsAt(x, y - 1, z, id);
289 level->updateNeighborsAt(x, y + 1, z, id);
290 }
291 Tile::destroy(level, x, y, z, data);
292}
293
294bool DiodeTile::isSolidRender(bool isServerLevel)
295{
296 return false;
297}
298
299bool DiodeTile::isAlternateInput(int tile)
300{
301 Tile *tt = Tile::tiles[tile];
302 return tt != NULL && tt->isSignalSource();
303}
304
305int DiodeTile::getOutputSignal(LevelSource *level, int x, int y, int z, int data)
306{
307 return Redstone::SIGNAL_MAX;
308}
309
310bool DiodeTile::isDiode(int id)
311{
312 return Tile::diode_off->isSameDiode(id) || Tile::comparator_off->isSameDiode(id);
313}
314
315bool DiodeTile::isSameDiode(int id)
316{
317 return id == getOnTile()->id || id == getOffTile()->id;
318}
319
320bool DiodeTile::shouldPrioritize(Level *level, int x, int y, int z, int data)
321{
322 int dir = getDirection(data);
323 if (isDiode(level->getTile(x - Direction::STEP_X[dir], y, z - Direction::STEP_Z[dir])))
324 {
325 int odata = level->getData(x - Direction::STEP_X[dir], y, z - Direction::STEP_Z[dir]);
326 int odir = getDirection(odata);
327 return odir != dir;
328 }
329 return false;
330}
331
332int DiodeTile::getTurnOffDelay(int data)
333{
334 return getTurnOnDelay(data);
335}
336
337bool DiodeTile::isMatching(int id)
338{
339 return isSameDiode(id);
340}