static void on_update(const Level *level, UpdateEvent *ev) { if (level_get_block(level, ev->x, ev->y, ev->z) != ev->new_t) return; switch (ev->new_t) { case BLOCK_SPONGE: { int x1 = max(ev->x - 3 + 1, 0), x2 = min(ev->x + 3, level->size.x); int y1 = max(ev->y - 3 + 1, 0), y2 = min(ev->y + 3, level->size.y); int z1 = max(ev->z - 3 + 1, 0), z2 = min(ev->z + 3, level->size.z); int x, y, z; for (x = x1; x < x2; ++x) { for (y = y1; y < y2; ++y) { for (z = z1; z < z2; ++z) { if (is_fluid(level_get_block(level, x, y, z))) update_block(x, y, z, BLOCK_EMPTY); } } } } break; case BLOCK_SUPERSPONGE: { /* Flood-filling super sponge */ int d; for (d = 0; d < 6; ++d) { int nx = ev->x + DX[d]; int ny = ev->y + DY[d]; int nz = ev->z + DZ[d]; Type t = level_get_block(level, nx, ny,nz); if (is_fluid(t)) { update_block_delayed(nx, ny, nz, BLOCK_SUPERSPONGE, &supersponge_delay); } } update_block(ev->x, ev->y, ev->z, BLOCK_EMPTY); } break; } if (ev->old_t == BLOCK_SPONGE) { activate_blocks_nearby(level, ev->x, ev->y, ev->z, 3); } else { activate_block(level, ev->x, ev->y, ev->z); activate_neighbours(level, ev->x, ev->y, ev->z); } }
static void on_flow(const Level *level, FlowEvent *ev) { int d; Type t = level_get_block(level, ev->x, ev->y, ev->z); if (!is_fluid(t)) return; for (d = 0; d < 6; ++d) { int nx, ny, nz; if (DY[d] > 0) continue; /* don't flow upward */ nx = ev->x + DX[d]; ny = ev->y + DY[d]; nz = ev->z + DZ[d]; if (level_index_valid(level, nx, ny, nz)) { Type u = level_get_block(level, nx, ny, nz); if ( u == BLOCK_EMPTY && !type_nearby(level, nx, ny, nz, BLOCK_SPONGE, 3)) { /* Propagate fluid */ update_block(nx, ny, nz, t); } else if ((is_water(t) && is_lava(u)) || (is_lava(t) && is_water(u))) { /* Water and lava make stone */ update_block(nx, ny, nz, BLOCK_STONE_GREY); } } } }
// Is this a beach that gets shore plopped down next to it? bool is_shore(ter_num_t ter_type) { if(is_fluid(ter_type)) return false; if(univ.scenario.ter_types[ter_type].trim_type == eTrimType::WATERFALL) return false; // if(ter_type == 77) // return false; // if(ter_type == 90) // return false; /* if(ter_type == 240) return false; if((ter_type >= 117) && (ter_type <= 131)) return false; if((ter_type >= 193) && (ter_type <= 207)) return false; */ return true; }
static bool is_supporter(Type t) { return t != BLOCK_EMPTY && !is_plant(t) && !is_fluid(t); }
char get_fluid_trim(location where,ter_num_t ter_type) { bool at_top = false,at_bot = false,at_left = false,at_right = false; ter_num_t store; char to_return = 0; if(where.x == 0) at_left = true; if(where.y == 0) at_top = true; if((overall_mode == MODE_OUTDOORS) || (overall_mode == MODE_LOOK_OUTDOORS)) { if(where.x == 95) at_right = true; if(where.y == 95) at_bot = true; } else { if(where.x == univ.town->max_dim() - 1) at_right = true; if(where.y == univ.town->max_dim() - 1) at_bot = true; } // Set up trim for fluids if(is_fluid(ter_type)) { if(!at_left) { store = coord_to_ter(where.x - 1,where.y); if(is_shore(store)) to_return |= 64; } if(!at_right) { store = coord_to_ter(where.x + 1,where.y); if(is_shore(store)) to_return |= 4; } if(!at_top) { store = coord_to_ter(where.x,where.y - 1); if(is_shore(store)) to_return |= 1; } if(!at_bot) { store = coord_to_ter(where.x,where.y + 1); if(is_shore(store)) to_return |= 16; } if((!at_left) && (!at_top)) { store = coord_to_ter(where.x - 1,where.y - 1); if(is_shore(store)) to_return |= 128; } if((!at_right) && (!at_bot)) { store = coord_to_ter(where.x + 1,where.y + 1); if(is_shore(store)) to_return |= 8; } if((!at_right) && (!at_top)) { store = coord_to_ter(where.x + 1,where.y - 1); if(is_shore(store)) to_return |= 2; } if((!at_left) && (!at_bot)) { store = coord_to_ter(where.x - 1,where.y + 1); if(is_shore(store)) to_return |= 32; } } if(to_return & 1) to_return &= 125; if(to_return & 4) to_return &= 245; if(to_return & 10) to_return &= 215; if(to_return & 64) to_return &= 95; return to_return; }