#include #include #include #include //hash function for df::coord #include // sets mark flags as necessary, for all designations void ChannelManager::manage_groups() { INFO(manager).print("manage_groups()\n"); // make sure we've got a fort map to analyze if (World::isFortressMode() && Maps::IsValid()) { // iterate the groups we built/updated for (const auto &group: groups) { manage_group(group, true, has_any_groups_above(groups, group)); } } } void ChannelManager::manage_group(const df::coord &map_pos, bool set_marker_mode, bool marker_mode) { INFO(manager).print("manage_group(" COORD ")\n ", COORDARGS(map_pos)); if (!groups.count(map_pos)) { groups.scan_one(map_pos); } auto iter = groups.find(map_pos); if (iter != groups.end()) { manage_group(*iter, set_marker_mode, marker_mode); } INFO(manager).print("manage_group() is done\n"); } void ChannelManager::manage_group(const Group &group, bool set_marker_mode, bool marker_mode) { INFO(manager).print("manage_group()\n"); if (!set_marker_mode) { if (has_any_groups_above(groups, group)) { marker_mode = true; } else { marker_mode = false; } } for (auto &designation: group) { manage_one(group, designation, true, marker_mode); } INFO(manager).print("manage_group() is done\n"); } bool ChannelManager::manage_one(const Group &group, const df::coord &map_pos, bool set_marker_mode, bool marker_mode) { if (Maps::isValidTilePos(map_pos)) { INFO(manager).print("manage_one(" COORD ")\n", COORDARGS(map_pos)); df::map_block* block = Maps::getTileBlock(map_pos); // we calculate the position inside the block* df::coord local(map_pos); local.x = local.x % 16; local.y = local.y % 16; df::tile_occupancy &tile_occupancy = block->occupancy[Coord(local)]; // ensure that we aren't on the top-most layers if (map_pos.z < mapz - 3) { // do we already know whether to set marker mode? if (set_marker_mode) { DEBUG(manager).print(" -> marker_mode\n"); // if enabling marker mode, just do it if (marker_mode) { tile_occupancy.bits.dig_marked = marker_mode; return true; } // if activating designation, check if it is safe to dig or not a channel designation if (!is_channel_designation(block->designation[Coord(local)]) || is_safe_to_dig_down(map_pos)) { if (!block->flags.bits.designated) { block->flags.bits.designated = true; } tile_occupancy.bits.dig_marked = false; TileCache::Get().cache(map_pos, block->tiletype[Coord(local)]); } return false; } else { // next search for the designation priority DEBUG(manager).print(" if(has_groups_above())\n"); // check that the group has no incomplete groups directly above it if (has_group_above(groups, map_pos) || !is_safe_to_dig_down(map_pos)) { DEBUG(manager).print(" has_groups_above: setting marker mode\n"); tile_occupancy.bits.dig_marked = true; if (jobs.count(map_pos)) { jobs.erase(map_pos); } WARN(manager).print(" <- manage_one() exits normally\n"); return true; } } } else { // if we are though, it should be totally safe to dig tile_occupancy.bits.dig_marked = false; } WARN(manager).print(" <- manage_one() exits normally\n"); } return false; } void ChannelManager::mark_done(const df::coord &map_pos) { groups.remove(map_pos); jobs.erase(map_pos); CSP::dignow_queue.erase(map_pos); TileCache::Get().uncache(map_pos); }