re-add fluid flow

This commit is contained in:
2025-09-27 20:42:52 +02:00
parent ede77674d3
commit fbc1b3cae4
3 changed files with 39 additions and 27 deletions

View File

@@ -202,10 +202,12 @@ typedef struct {
#define UPDATE_BASIC (1 << 0) #define UPDATE_BASIC (1 << 0)
// the sand at this position will be moved down immediately when this is processed // the sand at this position will be moved down immediately when this is processed
#define UPDATE_FALL_SAND (1 << 1) #define UPDATE_FALL_SAND (1 << 1)
#define UPDATE_FLOW_WATER (1 << 2)
// the sand below this block will fall soon // the sand below this block will fall soon
#define UPDATE_CHECK_SAND_FALL (1 << 2) #define UPDATE_CHECK_SAND_FALL (1 << 3)
#define UPDATE_CHECK_WATER (1 << 4)
#define UPDATE_NOW (UPDATE_BASIC | UPDATE_CHECK_SAND_FALL) #define UPDATE_NOW (UPDATE_BASIC | UPDATE_CHECK_SAND_FALL | UPDATE_CHECK_WATER)
typedef struct { typedef struct {
short update_kind; short update_kind;

View File

@@ -36,6 +36,7 @@ uint8_t isFallingBlock (uint8_t block);
uint8_t isPassableBlock (uint8_t block); uint8_t isPassableBlock (uint8_t block);
uint8_t isPassableSpawnBlock (uint8_t block); uint8_t isPassableSpawnBlock (uint8_t block);
uint8_t isReplaceableBlock (uint8_t block); uint8_t isReplaceableBlock (uint8_t block);
uint8_t getFluid (uint8_t block);
uint32_t isCompostItem (uint16_t item); uint32_t isCompostItem (uint16_t item);
uint8_t getItemStackSize (uint16_t item); uint8_t getItemStackSize (uint16_t item);

View File

@@ -765,14 +765,7 @@ uint8_t isInstantlyMined (PlayerData *player, uint8_t block) {
// Checks whether the given block can fall down (like sand, anvils, ...) // Checks whether the given block can fall down (like sand, anvils, ...)
uint8_t isFallingBlock (uint8_t block) { uint8_t isFallingBlock (uint8_t block) {
return ( return (
block == B_snow || block == B_sand
block == B_moss_carpet ||
block == B_cactus ||
block == B_short_grass ||
block == B_dead_bush ||
block == B_sand ||
block == B_torch ||
block == B_oak_sapling
); );
} }
@@ -805,8 +798,7 @@ uint8_t isPassableBlock (uint8_t block) {
} }
// Checks whether the given block is non-solid and spawnable // Checks whether the given block is non-solid and spawnable
uint8_t isPassableSpawnBlock (uint8_t block) { uint8_t isPassableSpawnBlock (uint8_t block) {
if ((block >= B_water && block < B_water + 8) || if (getFluid(block))
(block >= B_lava && block < B_lava + 4))
{ {
return 0; return 0;
} }
@@ -1045,7 +1037,6 @@ uint8_t handlePlayerEating (PlayerData *player, uint8_t just_check) {
return true; return true;
} }
/*
void handleFluidMovement (short x, uint8_t y, short z, uint8_t fluid, uint8_t block) { void handleFluidMovement (short x, uint8_t y, short z, uint8_t fluid, uint8_t block) {
// Get fluid level (0-7) // Get fluid level (0-7)
@@ -1053,16 +1044,13 @@ void handleFluidMovement (short x, uint8_t y, short z, uint8_t fluid, uint8_t bl
// a higher fluid "level" means the fluid has traveled farther // a higher fluid "level" means the fluid has traveled farther
uint8_t level = block - fluid; uint8_t level = block - fluid;
uint8_t flow_speed;
uint8_t max_level; uint8_t max_level;
switch (fluid) { switch (fluid) {
case B_lava: case B_lava:
flow_speed = 30;
max_level = 3; max_level = 3;
break; break;
case B_water: case B_water:
flow_speed = 5;
max_level = 7; max_level = 7;
break; break;
} }
@@ -1088,10 +1076,7 @@ void handleFluidMovement (short x, uint8_t y, short z, uint8_t fluid, uint8_t bl
// If not connected, clear this block and recalculate surrounding flow // If not connected, clear this block and recalculate surrounding flow
if (!connected) { if (!connected) {
makeBlockChange(x, y, z, B_air); makeBlockChange(x, y, z, B_air);
deferBlockUpdate(x + 1, y, z, flow_speed); updateXYZNeighbors(x, y, z, UPDATE_NOW);
deferBlockUpdate(x - 1, y, z, flow_speed);
deferBlockUpdate(x, y, z + 1, flow_speed);
deferBlockUpdate(x, y, z - 1, flow_speed);
return; return;
} }
} }
@@ -1100,7 +1085,7 @@ void handleFluidMovement (short x, uint8_t y, short z, uint8_t fluid, uint8_t bl
uint8_t block_below = getBlockAt(x, y - 1, z); uint8_t block_below = getBlockAt(x, y - 1, z);
if (isReplaceableBlock(block_below)) { if (isReplaceableBlock(block_below)) {
makeBlockChange(x, y - 1, z, fluid); makeBlockChange(x, y - 1, z, fluid);
deferBlockUpdate(x, y - 1, z, flow_speed); updateXYZNeighbors(x, y, z, UPDATE_NOW);
return; return;
} }
@@ -1110,19 +1095,19 @@ void handleFluidMovement (short x, uint8_t y, short z, uint8_t fluid, uint8_t bl
// Handle lateral water flow, increasing level by 1 // Handle lateral water flow, increasing level by 1
if (isReplaceableFluid(adjacent[0], level, fluid)) { if (isReplaceableFluid(adjacent[0], level, fluid)) {
makeBlockChange(x + 1, y, z, block + 1); makeBlockChange(x + 1, y, z, block + 1);
deferBlockUpdate(x + 1, y, z, flow_speed); updateXYZNeighbors(x, y, z, UPDATE_NOW);
} }
if (isReplaceableFluid(adjacent[1], level, fluid)) { if (isReplaceableFluid(adjacent[1], level, fluid)) {
makeBlockChange(x - 1, y, z, block + 1); makeBlockChange(x - 1, y, z, block + 1);
deferBlockUpdate(x - 1, y, z, flow_speed); updateXYZNeighbors(x, y, z, UPDATE_NOW);
} }
if (isReplaceableFluid(adjacent[2], level, fluid)) { if (isReplaceableFluid(adjacent[2], level, fluid)) {
makeBlockChange(x, y, z + 1, block + 1); makeBlockChange(x, y, z + 1, block + 1);
deferBlockUpdate(x, y, z + 1, flow_speed); updateXYZNeighbors(x, y, z, UPDATE_NOW);
} }
if (isReplaceableFluid(adjacent[3], level, fluid)) { if (isReplaceableFluid(adjacent[3], level, fluid)) {
makeBlockChange(x, y, z - 1, block + 1); makeBlockChange(x, y, z - 1, block + 1);
deferBlockUpdate(x, y, z - 1, flow_speed); updateXYZNeighbors(x, y, z, UPDATE_NOW);
} }
} }
@@ -1133,7 +1118,6 @@ uint8_t getFluid(uint8_t block) {
return B_lava; return B_lava;
return 0; return 0;
} }
*/
#ifdef ENABLE_PICKUP_ANIMATION #ifdef ENABLE_PICKUP_ANIMATION
// Plays the item pickup animation with the given item at the given coordinates // Plays the item pickup animation with the given item at the given coordinates
@@ -1176,7 +1160,32 @@ void playPickupAnimation (PlayerData *player, uint16_t item, double x, double y,
void processBlockUpdate (short x, uint8_t y, short z, uint8_t block, short update_kind) { void processBlockUpdate (short x, uint8_t y, short z, uint8_t block, short update_kind) {
if (update_kind & UPDATE_BASIC) { if (update_kind & UPDATE_BASIC) {
// TODO: water // "normal" block update
}
if (update_kind & UPDATE_CHECK_WATER) {
uint8_t fluid = getFluid(block);
if (fluid) {
uint8_t flow_speed;
switch (fluid) {
case B_lava:
flow_speed = 30;
break;
case B_water:
flow_speed = 5;
break;
}
deferBlockUpdate(x, y, z, flow_speed, UPDATE_FLOW_WATER);
}
}
if (update_kind & UPDATE_FLOW_WATER) {
uint8_t fluid = getFluid(block);
if (fluid) {
handleFluidMovement(x, y, z, fluid, block);
}
} }
if (update_kind & UPDATE_CHECK_SAND_FALL) { if (update_kind & UPDATE_CHECK_SAND_FALL) {