aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/LiquidTileDynamic.cpp
diff options
context:
space:
mode:
authordaoge <3523206925@qq.com>2026-03-03 03:04:10 +0800
committerGitHub <noreply@github.com>2026-03-03 03:04:10 +0800
commitb3feddfef372618c8a9d7a0abcaf18cfad866c18 (patch)
tree267761c3bb39241ba5c347bfbe2254d06686e287 /Minecraft.World/LiquidTileDynamic.cpp
parent84c31a2331f7a0ec85b9d438992e244f60e5020f (diff)
feat: TU19 (Dec 2014) Features & Content (#155)
* try to resolve merge conflict * feat: TU19 (Dec 2014) Features & Content (#32) * December 2014 files * Working release build * Fix compilation issues * Add sound to Windows64Media * Add DLC content and force Tutorial DLC * Revert "Add DLC content and force Tutorial DLC" This reverts commit 97a43994725008e35fceb984d5549df9c8cea470. * Disable broken light packing * Disable breakpoint during DLC texture map load Allows DLC loading but the DLC textures are still broken * Fix post build not working * ... * fix vs2022 build * fix cmake build --------- Co-authored-by: Loki <lokirautio@gmail.com>
Diffstat (limited to 'Minecraft.World/LiquidTileDynamic.cpp')
-rw-r--r--Minecraft.World/LiquidTileDynamic.cpp343
1 files changed, 176 insertions, 167 deletions
diff --git a/Minecraft.World/LiquidTileDynamic.cpp b/Minecraft.World/LiquidTileDynamic.cpp
index 14a93b93..2c7c74f4 100644
--- a/Minecraft.World/LiquidTileDynamic.cpp
+++ b/Minecraft.World/LiquidTileDynamic.cpp
@@ -6,8 +6,8 @@
LiquidTileDynamic::LiquidTileDynamic(int id, Material *material) : LiquidTile(id, material)
{
maxCount = 0;
- result = new bool[4];
- dist = new int[4];
+ result = new bool[4];
+ dist = new int[4];
m_iterativeInstatick = false;
}
@@ -19,9 +19,8 @@ LiquidTileDynamic::~LiquidTileDynamic()
void LiquidTileDynamic::setStatic(Level *level, int x, int y, int z)
{
- int d = level->getData(x, y, z);
- level->setTileAndDataNoUpdate(x, y, z, id + 1, d);
- level->setTilesDirty(x, y, z, x, y, z);
+ int d = level->getData(x, y, z);
+ level->setTileAndData(x, y, z, id + 1, d, Tile::UPDATE_CLIENTS);
}
bool LiquidTileDynamic::isPathfindable(LevelSource *level, int x, int y, int z)
@@ -32,13 +31,16 @@ bool LiquidTileDynamic::isPathfindable(LevelSource *level, int x, int y, int z)
void LiquidTileDynamic::iterativeTick(Level *level, int x, int y, int z, Random *random)
{
m_tilesToTick.push_back(LiquidTickData(level, x,y,z,random));
-
- while(m_tilesToTick.size() > 0)
+
+ int failsafe = 100;
+ while((m_tilesToTick.size() > 0) && ( failsafe > 0 ) )
{
LiquidTickData tickData = m_tilesToTick.front();
m_tilesToTick.pop_front();
mainTick(tickData.level, tickData.x, tickData.y, tickData.z, tickData.random);
+ failsafe--;
}
+ m_tilesToTick.clear();
}
void LiquidTileDynamic::tick(Level *level, int x, int y, int z, Random *random)
@@ -63,117 +65,119 @@ void LiquidTileDynamic::tick(Level *level, int x, int y, int z, Random *random)
// This is to fix the stack overflow that occurs sometimes when instaticking on level gen.
void LiquidTileDynamic::mainTick(Level *level, int x, int y, int z, Random *random)
{
- int depth = getDepth(level, x, y, z);
+ int depth = getDepth(level, x, y, z);
- int dropOff = 1;
- if (material == Material::lava && !level->dimension->ultraWarm) dropOff = 2;
+ int dropOff = 1;
+ if (material == Material::lava && !level->dimension->ultraWarm) dropOff = 2;
- bool becomeStatic = true;
- if (depth > 0)
+ bool becomeStatic = true;
+ int tickDelay = getTickDelay(level);
+ if (depth > 0)
{
- int highest = -100;
- maxCount = 0;
- highest = getHighest(level, x - 1, y, z, highest);
- highest = getHighest(level, x + 1, y, z, highest);
- highest = getHighest(level, x, y, z - 1, highest);
- highest = getHighest(level, x, y, z + 1, highest);
+ int highest = -100;
+ maxCount = 0;
+ highest = getHighest(level, x - 1, y, z, highest);
+ highest = getHighest(level, x + 1, y, z, highest);
+ highest = getHighest(level, x, y, z - 1, highest);
+ highest = getHighest(level, x, y, z + 1, highest);
- int newDepth = highest + dropOff;
- if (newDepth >= 8 || highest < 0)
+ int newDepth = highest + dropOff;
+ if (newDepth >= 8 || highest < 0)
{
- newDepth = -1;
- }
- if (getDepth(level, x, y + 1, z) >= 0)
+ newDepth = -1;
+ }
+ if (getDepth(level, x, y + 1, z) >= 0)
{
- int above = getDepth(level, x, y + 1, z);
- if (above >= 8) newDepth = above;
- else newDepth = above + 8;
- }
- if (maxCount >= 2 && material == Material::water)
+ int above = getDepth(level, x, y + 1, z);
+ if (above >= 8) newDepth = above;
+ else newDepth = above + 8;
+ }
+ if (maxCount >= 2 && material == Material::water)
{
- // Only spread spring if it's on top of an existing spring, or
+ // Only spread spring if it's on top of an existing spring, or
// on top of solid ground.
- if (level->getMaterial(x, y - 1, z)->isSolid())
+ if (level->getMaterial(x, y - 1, z)->isSolid())
{
- newDepth = 0;
- }
+ newDepth = 0;
+ }
else if (level->getMaterial(x, y - 1, z) == material && level->getData(x, y - 1, z) == 0)
{
- newDepth = 0;
- }
- }
- if (material == Material::lava)
+ newDepth = 0;
+ }
+ }
+ if (material == Material::lava)
{
- if (depth < 8 && newDepth < 8)
+ if (depth < 8 && newDepth < 8)
{
- if (newDepth > depth)
+ if (newDepth > depth)
{
- if (random->nextInt(4) != 0)
+ if (random->nextInt(4) != 0)
{
- newDepth = depth;
- becomeStatic = false;
- }
- }
- }
- }
- if (newDepth == depth)
+ tickDelay = tickDelay * 4;
+ }
+ }
+ }
+ }
+ if (newDepth == depth)
{
- if (becomeStatic)
+ if (becomeStatic)
{
setStatic(level, x, y, z);
}
- }
+ }
else
{
- depth = newDepth;
- if (depth < 0)
+ depth = newDepth;
+ if (depth < 0)
{
- level->setTile(x, y, z, 0);
- } else
+ level->removeTile(x, y, z);
+ }
+ else
{
- level->setData(x, y, z, depth);
- level->addToTickNextTick(x, y, z, id, getTickDelay());
- level->updateNeighborsAt(x, y, z, id);
- }
- }
- } else
+ level->setData(x, y, z, depth, Tile::UPDATE_CLIENTS);
+ level->addToTickNextTick(x, y, z, id, tickDelay);
+ level->updateNeighborsAt(x, y, z, id);
+ }
+ }
+ }
+ else
{
- setStatic(level, x, y, z);
- }
- if (canSpreadTo(level, x, y - 1, z))
+ setStatic(level, x, y, z);
+ }
+ if (canSpreadTo(level, x, y - 1, z))
{
- if (material == Material::lava)
+ if (material == Material::lava)
{
- if (level->getMaterial(x, y - 1, z) == Material::water)
+ if (level->getMaterial(x, y - 1, z) == Material::water)
{
- level->setTile(x, y - 1, z, Tile::rock_Id);
- fizz(level, x, y - 1, z);
- return;
- }
- }
+ level->setTileAndUpdate(x, y - 1, z, Tile::stone_Id);
+ fizz(level, x, y - 1, z);
+ return;
+ }
+ }
- if (depth >= 8) trySpreadTo(level, x, y - 1, z, depth);
- else trySpreadTo(level, x, y - 1, z, depth + 8);
- }
+ if (depth >= 8) trySpreadTo(level, x, y - 1, z, depth);
+ else trySpreadTo(level, x, y - 1, z, depth + 8);
+ }
else if (depth >= 0 && (depth == 0 || isWaterBlocking(level, x, y - 1, z)))
{
- bool *spreads = getSpread(level, x, y, z);
- int neighbor = depth + dropOff;
- if (depth >= 8)
+ bool *spreads = getSpread(level, x, y, z);
+ int neighbor = depth + dropOff;
+ if (depth >= 8)
{
- neighbor = 1;
- }
- if (neighbor >= 8) return;
- if (spreads[0]) trySpreadTo(level, x - 1, y, z, neighbor);
- if (spreads[1]) trySpreadTo(level, x + 1, y, z, neighbor);
- if (spreads[2]) trySpreadTo(level, x, y, z - 1, neighbor);
- if (spreads[3]) trySpreadTo(level, x, y, z + 1, neighbor);
- }
+ neighbor = 1;
+ }
+ if (neighbor >= 8) return;
+ if (spreads[0]) trySpreadTo(level, x - 1, y, z, neighbor);
+ if (spreads[1]) trySpreadTo(level, x + 1, y, z, neighbor);
+ if (spreads[2]) trySpreadTo(level, x, y, z - 1, neighbor);
+ if (spreads[3]) trySpreadTo(level, x, y, z + 1, neighbor);
+ }
}
void LiquidTileDynamic::trySpreadTo(Level *level, int x, int y, int z, int neighbor)
{
- if (canSpreadTo(level, x, y, z))
+ if (canSpreadTo(level, x, y, z))
{
{
int old = level->getTile(x, y, z);
@@ -189,129 +193,129 @@ void LiquidTileDynamic::trySpreadTo(Level *level, int x, int y, int z, int neigh
}
}
}
- level->setTileAndData(x, y, z, id, neighbor);
- }
+ level->setTileAndData(x, y, z, id, neighbor, Tile::UPDATE_ALL);
+ }
}
int LiquidTileDynamic::getSlopeDistance(Level *level, int x, int y, int z, int pass, int from)
{
- int lowest = 1000;
- for (int d = 0; d < 4; d++)
+ int lowest = 1000;
+ for (int d = 0; d < 4; d++)
{
- if (d == 0 && from == 1) continue;
- if (d == 1 && from == 0) continue;
- if (d == 2 && from == 3) continue;
- if (d == 3 && from == 2) continue;
+ if (d == 0 && from == 1) continue;
+ if (d == 1 && from == 0) continue;
+ if (d == 2 && from == 3) continue;
+ if (d == 3 && from == 2) continue;
- int xx = x;
- int yy = y;
- int zz = z;
+ int xx = x;
+ int yy = y;
+ int zz = z;
- if (d == 0) xx--;
- if (d == 1) xx++;
- if (d == 2) zz--;
- if (d == 3) zz++;
+ if (d == 0) xx--;
+ if (d == 1) xx++;
+ if (d == 2) zz--;
+ if (d == 3) zz++;
- if (isWaterBlocking(level, xx, yy, zz))
+ if (isWaterBlocking(level, xx, yy, zz))
{
- continue;
- } else if (level->getMaterial(xx, yy, zz) == material && level->getData(xx, yy, zz) == 0)
+ continue;
+ } else if (level->getMaterial(xx, yy, zz) == material && level->getData(xx, yy, zz) == 0)
{
- continue;
- }
+ continue;
+ }
else
{
- if (isWaterBlocking(level, xx, yy - 1, zz))
+ if (isWaterBlocking(level, xx, yy - 1, zz))
{
- if (pass < 4)
+ if (pass < 4)
{
- int v = getSlopeDistance(level, xx, yy, zz, pass + 1, d);
- if (v < lowest) lowest = v;
- }
- }
+ int v = getSlopeDistance(level, xx, yy, zz, pass + 1, d);
+ if (v < lowest) lowest = v;
+ }
+ }
else
{
- return pass;
- }
- }
- }
- return lowest;
+ return pass;
+ }
+ }
+ }
+ return lowest;
}
bool *LiquidTileDynamic::getSpread(Level *level, int x, int y, int z)
{
- for (int d = 0; d < 4; d++)
+ for (int d = 0; d < 4; d++)
{
- dist[d] = 1000;
- int xx = x;
- int yy = y;
- int zz = z;
+ dist[d] = 1000;
+ int xx = x;
+ int yy = y;
+ int zz = z;
- if (d == 0) xx--;
- if (d == 1) xx++;
- if (d == 2) zz--;
- if (d == 3) zz++;
- if (isWaterBlocking(level, xx, yy, zz))
+ if (d == 0) xx--;
+ if (d == 1) xx++;
+ if (d == 2) zz--;
+ if (d == 3) zz++;
+ if (isWaterBlocking(level, xx, yy, zz))
{
- continue;
- }
+ continue;
+ }
else if (level->getMaterial(xx, yy, zz) == material && level->getData(xx, yy, zz) == 0)
{
- continue;
- }
+ continue;
+ }
{
- if (isWaterBlocking(level, xx, yy - 1, zz))
+ if (isWaterBlocking(level, xx, yy - 1, zz))
{
- dist[d] = getSlopeDistance(level, xx, yy, zz, 1, d);
- }
+ dist[d] = getSlopeDistance(level, xx, yy, zz, 1, d);
+ }
else
{
- dist[d] = 0;
- }
- }
- }
+ dist[d] = 0;
+ }
+ }
+ }
- int lowest = dist[0];
- for (int d = 1; d < 4; d++)
+ int lowest = dist[0];
+ for (int d = 1; d < 4; d++)
{
- if (dist[d] < lowest) lowest = dist[d];
- }
+ if (dist[d] < lowest) lowest = dist[d];
+ }
- for (int d = 0; d < 4; d++)
+ for (int d = 0; d < 4; d++)
{
- result[d] = (dist[d] == lowest);
- }
- return result;
+ result[d] = (dist[d] == lowest);
+ }
+ return result;
}
bool LiquidTileDynamic::isWaterBlocking(Level *level, int x, int y, int z)
{
- int t = level->getTile(x, y, z);
- if (t == Tile::door_wood_Id || t == Tile::door_iron_Id || t == Tile::sign_Id || t == Tile::ladder_Id || t == Tile::reeds_Id)
+ int t = level->getTile(x, y, z);
+ if (t == Tile::door_wood_Id || t == Tile::door_iron_Id || t == Tile::sign_Id || t == Tile::ladder_Id || t == Tile::reeds_Id)
{
- return true;
- }
- if (t == 0) return false;
- Material *m = Tile::tiles[t]->material;
- if (m == Material::portal) return true;
- if (m->blocksMotion()) return true;
- return false;
+ return true;
+ }
+ if (t == 0) return false;
+ Material *m = Tile::tiles[t]->material;
+ if (m == Material::portal) return true;
+ if (m->blocksMotion()) return true;
+ return false;
}
int LiquidTileDynamic::getHighest(Level *level, int x, int y, int z, int current)
{
- int d = getDepth(level, x, y, z);
- if (d < 0) return current;
- if (d == 0) maxCount++;
- if (d >= 8)
+ int d = getDepth(level, x, y, z);
+ if (d < 0) return current;
+ if (d == 0) maxCount++;
+ if (d >= 8)
{
- d = 0;
- }
- return current < 0 || d < current ? d : current;
+ d = 0;
+ }
+ return current < 0 || d < current ? d : current;
}
bool LiquidTileDynamic::canSpreadTo(Level *level, int x, int y, int z)
@@ -326,17 +330,22 @@ bool LiquidTileDynamic::canSpreadTo(Level *level, int x, int y, int z)
if( ( ix < 0 ) || ( ix >= level->chunkSourceXZSize ) ) return false;
if( ( iz < 0 ) || ( iz >= level->chunkSourceXZSize ) ) return false;
- Material *target = level->getMaterial(x, y, z);
- if (target == material) return false;
- if (target == Material::lava) return false;
- return !isWaterBlocking(level, x, y, z);
+ Material *target = level->getMaterial(x, y, z);
+ if (target == material) return false;
+ if (target == Material::lava) return false;
+ return !isWaterBlocking(level, x, y, z);
}
void LiquidTileDynamic::onPlace(Level *level, int x, int y, int z)
{
- LiquidTile::onPlace(level, x, y, z);
- if (level->getTile(x, y, z) == id)
+ LiquidTile::onPlace(level, x, y, z);
+ if (level->getTile(x, y, z) == id)
{
- level->addToTickNextTick(x, y, z, id, getTickDelay());
- }
+ level->addToTickNextTick(x, y, z, id, getTickDelay(level));
+ }
}
+
+bool LiquidTileDynamic::canInstantlyTick()
+{
+ return true;
+} \ No newline at end of file