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 "JavaMath.h"
3#include "net.minecraft.world.level.h"
4#include "net.minecraft.world.level.dimension.h"
5#include "net.minecraft.world.level.biome.h"
6#include "net.minecraft.world.h"
7#include "LiquidTile.h"
8#include "Facing.h"
9#include "SoundTypes.h"
10
11const wstring LiquidTile::TEXTURE_LAVA_STILL = L"lava";
12const wstring LiquidTile::TEXTURE_WATER_STILL = L"water";
13const wstring LiquidTile::TEXTURE_WATER_FLOW = L"water_flow";
14const wstring LiquidTile::TEXTURE_LAVA_FLOW = L"lava_flow";
15
16LiquidTile::LiquidTile(int id, Material *material) : Tile(id, material,isSolidRender())
17{
18 float yo = 0;
19 float e = 0;
20
21 setShape(0 + e, 0 + yo, 0 + e, 1 + e, 1 + yo, 1 + e);
22 setTicking(true);
23}
24
25bool LiquidTile::isPathfindable(LevelSource *level, int x, int y, int z)
26{
27 return material != Material::lava;
28}
29
30int LiquidTile::getColor() const
31{
32 return 0xffffff;
33}
34
35int LiquidTile::getColor(LevelSource *level, int x, int y, int z)
36{
37
38 return getColor(level, x, y, z, 0);
39}
40
41int LiquidTile::getColor(LevelSource *level, int x, int y, int z, int d)
42{
43 if (material == Material::water)
44 {
45 int totalRed = 0;
46 int totalGreen = 0;
47 int totalBlue = 0;
48
49 for (int oz = -1; oz <= 1; oz++)
50 {
51 for (int ox = -1; ox <= 1; ox++)
52 {
53 int waterColor = level->getBiome(x + ox, z + oz)->getWaterColor();
54
55 totalRed += (waterColor & 0xff0000) >> 16;
56 totalGreen += (waterColor & 0xff00) >> 8;
57 totalBlue += (waterColor & 0xff);
58 }
59 }
60
61 return (((totalRed / 9) & 0xFF) << 16) | (((totalGreen / 9) & 0xFF) << 8) | (((totalBlue / 9) & 0xFF));
62 }
63 return 0xffffff;
64}
65
66float LiquidTile::getHeight(int d)
67{
68 if (d >= 8) d = 0;
69 return (d + 1) / 9.0f;
70}
71
72Icon *LiquidTile::getTexture(int face, int data)
73{
74 if (face == Facing::DOWN || face == Facing::UP)
75 {
76 return icons[0];
77 }
78 else
79 {
80 return icons[1];
81 }
82}
83
84int LiquidTile::getDepth(Level *level, int x, int y, int z)
85{
86 if (level->getMaterial(x, y, z) == material) return level->getData(x, y, z);
87 else return -1;
88}
89
90int LiquidTile::getRenderedDepth(LevelSource *level, int x, int y, int z)
91{
92 if (level->getMaterial(x, y, z) != material) return -1;
93 int d = level->getData(x, y, z);
94 if (d >= 8) d = 0;
95 return d;
96}
97
98bool LiquidTile::isCubeShaped()
99{
100 return false;
101}
102
103bool LiquidTile::isSolidRender(bool isServerLevel)
104{
105 return false;
106}
107
108bool LiquidTile::mayPick(int data, bool liquid)
109{
110 return liquid && data == 0;
111}
112
113bool LiquidTile::isSolidFace(LevelSource *level, int x, int y, int z, int face)
114{
115 Material *m = level->getMaterial(x, y, z);
116 if (m == material) return false;
117 if (face == Facing::UP) return true;
118 if (m == Material::ice) return false;
119
120 return Tile::isSolidFace(level, x, y, z, face);
121}
122
123bool LiquidTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face)
124{
125 Material *m = level->getMaterial(x, y, z);
126 if (m == material) return false;
127 if (face == Facing::UP) return true;
128 if (m == Material::ice) return false;
129 return Tile::shouldRenderFace(level, x, y, z, face);
130}
131
132AABB *LiquidTile::getAABB(Level *level, int x, int y, int z)
133{
134 return NULL;
135}
136
137int LiquidTile::getRenderShape()
138{
139 return Tile::SHAPE_WATER;
140}
141
142int LiquidTile::getResource(int data, Random *random, int playerBonusLevel)
143{
144 return 0;
145}
146
147int LiquidTile::getResourceCount(Random *random)
148{
149 return 0;
150}
151
152Vec3 *LiquidTile::getFlow(LevelSource *level, int x, int y, int z)
153{
154 Vec3 *flow = Vec3::newTemp(0,0,0);
155 int mid = getRenderedDepth(level, x, y, z);
156 for (int d = 0; d < 4; d++)
157 {
158
159 int xt = x;
160 int yt = y;
161 int zt = z;
162
163 if (d == 0) xt--;
164 if (d == 1) zt--;
165 if (d == 2) xt++;
166 if (d == 3) zt++;
167
168 int t = getRenderedDepth(level, xt, yt, zt);
169 if (t < 0)
170 {
171 if (!level->getMaterial(xt, yt, zt)->blocksMotion())
172 {
173 t = getRenderedDepth(level, xt, yt - 1, zt);
174 if (t >= 0)
175 {
176 int dir = t - (mid - 8);
177 flow = flow->add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir);
178 }
179 }
180 } else
181 {
182 if (t >= 0)
183 {
184 int dir = t - mid;
185 flow = flow->add((xt - x) * dir, (yt - y) * dir, (zt - z) * dir);
186 }
187 }
188
189 }
190 if (level->getData(x, y, z) >= 8)
191 {
192 bool ok = false;
193 if (ok || isSolidFace(level, x, y, z - 1, 2)) ok = true;
194 if (ok || isSolidFace(level, x, y, z + 1, 3)) ok = true;
195 if (ok || isSolidFace(level, x - 1, y, z, 4)) ok = true;
196 if (ok || isSolidFace(level, x + 1, y, z, 5)) ok = true;
197 if (ok || isSolidFace(level, x, y + 1, z - 1, 2)) ok = true;
198 if (ok || isSolidFace(level, x, y + 1, z + 1, 3)) ok = true;
199 if (ok || isSolidFace(level, x - 1, y + 1, z, 4)) ok = true;
200 if (ok || isSolidFace(level, x + 1, y + 1, z, 5)) ok = true;
201 if (ok) flow = flow->normalize()->add(0, -6, 0);
202 }
203 flow = flow->normalize();
204 return flow;
205}
206
207void LiquidTile::handleEntityInside(Level *level, int x, int y, int z, shared_ptr<Entity> e, Vec3 *current)
208{
209 Vec3 *flow = getFlow(level, x, y, z);
210 current->x += flow->x;
211 current->y += flow->y;
212 current->z += flow->z;
213}
214
215int LiquidTile::getTickDelay(Level *level)
216{
217 if (material == Material::water) return 5;
218 if (material == Material::lava)
219 {
220 if (level->dimension->hasCeiling)
221 {
222 return 10;
223 }
224 else
225 {
226 return 30;
227 }
228 }
229 return 0;
230}
231
232// 4J - change brought forward from 1.8.2
233int LiquidTile::getLightColor(LevelSource *level, int x, int y, int z, int tileId/*=-1*/)
234{
235 // 4J - note that this code seems to basically be a hack to fix a problem where post-processed things like lakes aren't getting lit properly
236 int a = level->getLightColor(x, y, z, 0, tileId);
237 int b = level->getLightColor(x, y + 1, z, 0, tileId);
238
239 int aa = a & 0xff;
240 int ba = b & 0xff;
241 int ab = (a >> 16) & 0xff;
242 int bb = (b >> 16) & 0xff;
243
244 return (aa > ba ? aa : ba) | ((ab > bb ? ab : bb) << 16);
245}
246
247float LiquidTile::getBrightness(LevelSource *level, int x, int y, int z)
248{
249 float a = level->getBrightness(x, y, z);
250 float b = level->getBrightness(x, y + 1, z);
251 return a > b ? a : b;
252}
253
254int LiquidTile::getRenderLayer()
255{
256 return material == Material::water ? 1 : 0;
257}
258
259void LiquidTile::animateTick(Level *level, int x, int y, int z, Random *random)
260{
261 if (material == Material::water)
262 {
263 if (random->nextInt(10) == 0)
264 {
265 int d = level->getData(x, y, z);
266 if (d <= 0 || d >= 8)
267 {
268 level->addParticle(eParticleType_suspended, x + random->nextFloat(), y + random->nextFloat(), z + random->nextFloat(), 0, 0, 0);
269 }
270 }
271 // 4J-PB - this loop won't run!
272 for (int i = 0; i < 0; i++)
273 { // This was an attempt to add foam to
274 // the bottoms of waterfalls. It
275 // didn't went ok.
276 int dir = random->nextInt(4);
277 int xt = x;
278 int zt = z;
279 if (dir == 0) xt--;
280 if (dir == 1) xt++;
281 if (dir == 2) zt--;
282 if (dir == 3) zt++;
283 if (level->getMaterial(xt, y, zt) == Material::air && (level->getMaterial(xt, y - 1, zt)->blocksMotion() || level->getMaterial(xt, y - 1, zt)->isLiquid()))
284 {
285 float r = 1 / 16.0f;
286 double xx = x + random->nextFloat();
287 double yy = y + random->nextFloat();
288 double zz = z + random->nextFloat();
289 if (dir == 0) xx = x - r;
290 if (dir == 1) xx = x + 1 + r;
291 if (dir == 2) zz = z - r;
292 if (dir == 3) zz = z + 1 + r;
293
294 double xd = 0;
295 double zd = 0;
296
297 if (dir == 0) xd = -r;
298 if (dir == 1) xd = +r;
299 if (dir == 2) zd = -r;
300 if (dir == 3) zd = +r;
301
302 level->addParticle(eParticleType_splash, xx, yy, zz, xd, 0, zd);
303 }
304 }
305 }
306 if (material == Material::water && random->nextInt(64) == 0)
307 {
308 int d = level->getData(x, y, z);
309 if (d > 0 && d < 8)
310 {
311 level->playLocalSound(x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_LIQUID_WATER, random->nextFloat() * 0.25f + 0.75f, random->nextFloat() * 1.0f + 0.5f, false);
312 }
313 }
314 if (material == Material::lava)
315 {
316 if (level->getMaterial(x, y + 1, z) == Material::air && !level->isSolidRenderTile(x, y + 1, z))
317 {
318 if (random->nextInt(100) == 0)
319 {
320 ThreadStorage *tls = (ThreadStorage *)TlsGetValue(Tile::tlsIdxShape);
321 double xx = x + random->nextFloat();
322 double yy = y + tls->yy1;
323 double zz = z + random->nextFloat();
324 level->addParticle(eParticleType_lava, xx, yy, zz, 0, 0, 0);
325 // 4J - new sound brought forward from 1.2.3
326 level->playLocalSound(xx, yy, zz, eSoundType_LIQUID_LAVA_POP, 0.2f + random->nextFloat() * 0.2f, 0.9f + random->nextFloat() * 0.15f, false);
327 }
328 // 4J - new sound brought forward from 1.2.3
329 if (random->nextInt(200) == 0)
330 {
331 level->playLocalSound(x, y, z, eSoundType_LIQUID_LAVA, 0.2f + random->nextFloat() * 0.2f, 0.9f + random->nextFloat() * 0.15f, false);
332 }
333 }
334 }
335
336 if (random->nextInt(10) == 0)
337 {
338 if (level->isTopSolidBlocking(x, y - 1, z) && !level->getMaterial(x, y - 2, z)->blocksMotion())
339 {
340 double xx = x + random->nextFloat();
341 double yy = y - 1.05;
342 double zz = z + random->nextFloat();
343
344 if (material == Material::water) level->addParticle(eParticleType_dripWater, xx, yy, zz, 0, 0, 0);
345 else level->addParticle(eParticleType_dripLava, xx, yy, zz, 0, 0, 0);
346 }
347 }
348}
349
350double LiquidTile::getSlopeAngle(LevelSource *level, int x, int y, int z, Material *m)
351{
352 Vec3 *flow = NULL;
353 if (m == Material::water) flow = ((LiquidTile *) Tile::water)->getFlow(level, x, y, z);
354 if (m == Material::lava) flow = ((LiquidTile *) Tile::lava)->getFlow(level, x, y, z);
355 if (flow->x == 0 && flow->z == 0) return -1000;
356 return atan2(flow->z, flow->x) - PI / 2;
357}
358
359void LiquidTile::onPlace(Level *level, int x, int y, int z)
360{
361 updateLiquid(level, x, y, z);
362}
363
364void LiquidTile::neighborChanged(Level *level, int x, int y, int z, int type)
365{
366 updateLiquid(level, x, y, z);
367}
368
369void LiquidTile::updateLiquid(Level *level, int x, int y, int z)
370{
371 if (level->getTile(x, y, z) != id) return;
372 if (material == Material::lava)
373 {
374 bool water = false;
375 if (water || level->getMaterial(x, y, z - 1) == Material::water) water = true;
376 if (water || level->getMaterial(x, y, z + 1) == Material::water) water = true;
377 if (water || level->getMaterial(x - 1, y, z) == Material::water) water = true;
378 if (water || level->getMaterial(x + 1, y, z) == Material::water) water = true;
379 if (water || level->getMaterial(x, y + 1, z) == Material::water) water = true;
380 if (water)
381 {
382 int data = level->getData(x, y, z);
383 if (data == 0)
384 {
385 level->setTileAndUpdate(x, y, z, Tile::obsidian_Id);
386 }
387 else if (data <= 4)
388 {
389 level->setTileAndUpdate(x, y, z, Tile::cobblestone_Id);
390 }
391 fizz(level, x, y, z);
392 }
393 }
394
395}
396
397void LiquidTile::fizz(Level *level, int x, int y, int z)
398{
399 MemSect(31);
400 level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_RANDOM_FIZZ, 0.5f, 2.6f + (level->random->nextFloat() - level->random->nextFloat()) * 0.8f);
401 MemSect(0);
402 for (int i = 0; i < 8; i++)
403 {
404 level->addParticle(eParticleType_largesmoke, x +Math::random(), y + 1.2, z + Math::random(), 0, 0, 0);
405 }
406}
407
408void LiquidTile::registerIcons(IconRegister *iconRegister)
409{
410 if (material == Material::lava)
411 {
412 icons[0] = iconRegister->registerIcon(TEXTURE_LAVA_STILL);
413 icons[1] = iconRegister->registerIcon(TEXTURE_LAVA_FLOW);
414 }
415 else
416 {
417 icons[0] = iconRegister->registerIcon(TEXTURE_WATER_STILL);
418 icons[1] = iconRegister->registerIcon(TEXTURE_WATER_FLOW);
419 }
420}
421
422Icon *LiquidTile::getTexture(const wstring &name)
423{
424 if (name.compare(TEXTURE_WATER_STILL)==0) return Tile::water->icons[0];
425 if (name.compare(TEXTURE_WATER_FLOW)==0) return Tile::water->icons[1];
426 if (name.compare(TEXTURE_LAVA_STILL)==0) return Tile::lava->icons[0];
427 if (name.compare(TEXTURE_LAVA_FLOW)==0) return Tile::lava->icons[1];
428 return NULL;
429}