Adds a designation buffer in dig-now's processing algorithm

This may fix the issue seen when channeling consecutive layers, needs to be tested
develop
Josh Cooper 2023-02-13 17:35:17 -08:00 committed by Josh Cooper
parent 838acfdf22
commit c990def894
1 changed files with 80 additions and 43 deletions

@ -15,6 +15,7 @@
#include "modules/Random.h" #include "modules/Random.h"
#include "modules/Units.h" #include "modules/Units.h"
#include "modules/World.h" #include "modules/World.h"
#include "modules/EventManager.h"
#include <df/historical_entity.h> #include <df/historical_entity.h>
#include <df/map_block.h> #include <df/map_block.h>
@ -28,6 +29,7 @@
#include <df/world_site.h> #include <df/world_site.h>
#include <cinttypes> #include <cinttypes>
#include <unordered_set>
DFHACK_PLUGIN("dig-now"); DFHACK_PLUGIN("dig-now");
REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(plotinfo);
@ -46,6 +48,31 @@ namespace DFHack {
using namespace DFHack; using namespace DFHack;
struct designation{
df::coord pos;
df::tile_designation type;
df::tile_occupancy occupancy;
designation(const df::coord &c, const df::tile_designation &td, const df::tile_occupancy &to) : pos(c), type(td), occupancy(to) {}
bool operator==(const designation &rhs) const {
return pos == rhs.pos;
}
bool operator!=(const designation &rhs) const {
return !(rhs == *this);
}
};
namespace std {
template<>
struct hash<designation> {
std::size_t operator()(const designation &c) const {
std::hash<df::coord> hash_coord;
return hash_coord(c.pos);
}
};
}
struct boulder_percent_options { struct boulder_percent_options {
// percent chance ([0..100]) for creating a boulder for the given rock type // percent chance ([0..100]) for creating a boulder for the given rock type
uint32_t layer; uint32_t layer;
@ -367,7 +394,7 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map,
// todo: does can_dig_channel return false? // todo: does can_dig_channel return false?
if (can_dig_channel(tt) && map.ensureBlockAt(pos_below) if (can_dig_channel(tt) && map.ensureBlockAt(pos_below)
&& is_diggable(map, pos_below, map.tiletypeAt(pos_below))) { && is_diggable(map, pos_below, map.tiletypeAt(pos_below))) {
TRACE(channels).print("dig_tile: channeling at (" COORD ")\n",COORDARGS(pos_below)); TRACE(channels).print("dig_tile: channeling at (" COORD ") [can_dig_channel: true]\n",COORDARGS(pos_below));
target_type = df::tiletype::OpenSpace; target_type = df::tiletype::OpenSpace;
DFCoord pos_above(pos.x, pos.y, pos.z+1); DFCoord pos_above(pos.x, pos.y, pos.z+1);
if (map.ensureBlockAt(pos_above)) { if (map.ensureBlockAt(pos_above)) {
@ -375,17 +402,16 @@ static bool dig_tile(color_ostream &out, MapExtras::MapCache &map,
} }
df::tile_dig_designation td_below = map.designationAt(pos_below).bits.dig; df::tile_dig_designation td_below = map.designationAt(pos_below).bits.dig;
// todo: what is this chain of dig_tile(below)? // todo: digging to floor below?
if (dig_tile(out, map, pos_below, df::tile_dig_designation::Ramp, dug_tiles)) { if (dig_tile(out, map, pos_below, df::tile_dig_designation::Ramp, dug_tiles)) {
clean_ramps(map, pos_below); clean_ramps(map, pos_below);
if (td_below == df::tile_dig_designation::Default) { if (td_below == df::tile_dig_designation::Default) {
// todo: removing ramp?
dig_tile(out, map, pos_below, td_below, dug_tiles); dig_tile(out, map, pos_below, td_below, dug_tiles);
} }
return true; return true;
} }
} else { } else {
DEBUG(channels).print("dig_tile: failed to channel at (" COORD ")\n", COORDARGS(pos_below)); DEBUG(channels).print("dig_tile: failed to channel at (" COORD ") [can_dig_channel: false]\n", COORDARGS(pos_below));
} }
break; break;
} }
@ -630,6 +656,7 @@ static void do_dig(color_ostream &out, std::vector<DFCoord> &dug_coords,
rng.init(); rng.init();
std::unordered_set<designation> buffer;
// go down levels instead of up so stacked ramps behave as expected // go down levels instead of up so stacked ramps behave as expected
for (int16_t z = options.end.z; z >= options.start.z; --z) { for (int16_t z = options.end.z; z >= options.start.z; --z) {
for (int16_t y = options.start.y; y <= options.end.y; ++y) { for (int16_t y = options.start.y; y <= options.end.y; ++y) {
@ -646,10 +673,22 @@ static void do_dig(color_ostream &out, std::vector<DFCoord> &dug_coords,
DFCoord pos(x, y, z); DFCoord pos(x, y, z);
df::tile_designation td = map.designationAt(pos); df::tile_designation td = map.designationAt(pos);
df::tile_occupancy to = map.occupancyAt(pos); df::tile_occupancy to = map.occupancyAt(pos);
// we're only buffering designations, so that processing doesn't affect what we're buffering
buffer.emplace(pos, td, to);
}
}
}
// process designations
for(auto &d : buffer) {
auto pos = d.pos;
auto td = d.type;
auto to = d.occupancy;
if (td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) { if (td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) {
std::vector<dug_tile_info> dug_tiles; std::vector<dug_tile_info> dug_tiles;
// todo: check why dig_tile doesn't dig the second layer of channels
if (dig_tile(out, map, pos, td.bits.dig, dug_tiles)) { if (dig_tile(out, map, pos, td.bits.dig, dug_tiles)) {
for (auto info: dug_tiles) { for (auto info: dug_tiles) {
td = map.designationAt(info.pos); td = map.designationAt(info.pos);
@ -688,8 +727,6 @@ static void do_dig(color_ostream &out, std::vector<DFCoord> &dug_coords,
} }
} }
} }
}
}
map.WriteAll(); map.WriteAll();
} }