diff --git a/include/globals.h b/include/globals.h index 40a29cc..d9bd84e 100644 --- a/include/globals.h +++ b/include/globals.h @@ -202,10 +202,12 @@ typedef struct { #define UPDATE_BASIC (1 << 0) // the sand at this position will be moved down immediately when this is processed #define UPDATE_FALL_SAND (1 << 1) +#define UPDATE_FLOW_WATER (1 << 2) // 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 { short update_kind; diff --git a/include/procedures.h b/include/procedures.h index 6e6ee01..a51b75e 100644 --- a/include/procedures.h +++ b/include/procedures.h @@ -36,6 +36,7 @@ uint8_t isFallingBlock (uint8_t block); uint8_t isPassableBlock (uint8_t block); uint8_t isPassableSpawnBlock (uint8_t block); uint8_t isReplaceableBlock (uint8_t block); +uint8_t getFluid (uint8_t block); uint32_t isCompostItem (uint16_t item); uint8_t getItemStackSize (uint16_t item); diff --git a/src/procedures.c b/src/procedures.c index 430c1d8..41815ee 100644 --- a/src/procedures.c +++ b/src/procedures.c @@ -765,14 +765,7 @@ uint8_t isInstantlyMined (PlayerData *player, uint8_t block) { // Checks whether the given block can fall down (like sand, anvils, ...) uint8_t isFallingBlock (uint8_t block) { return ( - block == B_snow || - 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 + block == B_sand ); } @@ -805,8 +798,7 @@ uint8_t isPassableBlock (uint8_t block) { } // Checks whether the given block is non-solid and spawnable uint8_t isPassableSpawnBlock (uint8_t block) { - if ((block >= B_water && block < B_water + 8) || - (block >= B_lava && block < B_lava + 4)) + if (getFluid(block)) { return 0; } @@ -1045,7 +1037,6 @@ uint8_t handlePlayerEating (PlayerData *player, uint8_t just_check) { return true; } -/* void handleFluidMovement (short x, uint8_t y, short z, uint8_t fluid, uint8_t block) { // 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 uint8_t level = block - fluid; - uint8_t flow_speed; uint8_t max_level; switch (fluid) { case B_lava: - flow_speed = 30; max_level = 3; break; case B_water: - flow_speed = 5; max_level = 7; 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 (!connected) { makeBlockChange(x, y, z, B_air); - deferBlockUpdate(x + 1, y, z, flow_speed); - deferBlockUpdate(x - 1, y, z, flow_speed); - deferBlockUpdate(x, y, z + 1, flow_speed); - deferBlockUpdate(x, y, z - 1, flow_speed); + updateXYZNeighbors(x, y, z, UPDATE_NOW); 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); if (isReplaceableBlock(block_below)) { makeBlockChange(x, y - 1, z, fluid); - deferBlockUpdate(x, y - 1, z, flow_speed); + updateXYZNeighbors(x, y, z, UPDATE_NOW); 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 if (isReplaceableFluid(adjacent[0], level, fluid)) { 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)) { 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)) { 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)) { 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 0; } -*/ #ifdef ENABLE_PICKUP_ANIMATION // 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) { 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) {