|
|
@ -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,48 +673,58 @@ 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);
|
|
|
|
if (td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) {
|
|
|
|
|
|
|
|
std::vector<dug_tile_info> dug_tiles;
|
|
|
|
// we're only buffering designations, so that processing doesn't affect what we're buffering
|
|
|
|
|
|
|
|
buffer.emplace(pos, td, to);
|
|
|
|
// todo: check why dig_tile doesn't dig the second layer of channels
|
|
|
|
}
|
|
|
|
if (dig_tile(out, map, pos, td.bits.dig, dug_tiles)) {
|
|
|
|
}
|
|
|
|
for (auto info: dug_tiles) {
|
|
|
|
}
|
|
|
|
td = map.designationAt(info.pos);
|
|
|
|
|
|
|
|
td.bits.dig = df::tile_dig_designation::No;
|
|
|
|
// process designations
|
|
|
|
map.setDesignationAt(info.pos, td);
|
|
|
|
for(auto &d : buffer) {
|
|
|
|
|
|
|
|
auto pos = d.pos;
|
|
|
|
dug_coords.push_back(info.pos);
|
|
|
|
auto td = d.type;
|
|
|
|
refresh_adjacent_smooth_walls(map, info.pos);
|
|
|
|
auto to = d.occupancy;
|
|
|
|
if (info.imat < 0)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
if (td.bits.dig != df::tile_dig_designation::No && !to.bits.dig_marked) {
|
|
|
|
if (produces_item(options.boulder_percents,
|
|
|
|
std::vector<dug_tile_info> dug_tiles;
|
|
|
|
map, rng, info)) {
|
|
|
|
|
|
|
|
auto k = std::make_pair(info.itype, info.imat);
|
|
|
|
if (dig_tile(out, map, pos, td.bits.dig, dug_tiles)) {
|
|
|
|
item_coords[k].push_back(info.pos);
|
|
|
|
for (auto info: dug_tiles) {
|
|
|
|
}
|
|
|
|
td = map.designationAt(info.pos);
|
|
|
|
}
|
|
|
|
td.bits.dig = df::tile_dig_designation::No;
|
|
|
|
}
|
|
|
|
map.setDesignationAt(info.pos, td);
|
|
|
|
// todo: check mark mode of smooth designations
|
|
|
|
|
|
|
|
} else if (td.bits.smooth == 1) {
|
|
|
|
dug_coords.push_back(info.pos);
|
|
|
|
if (smooth_tile(out, map, pos)) {
|
|
|
|
refresh_adjacent_smooth_walls(map, info.pos);
|
|
|
|
to = map.occupancyAt(pos);
|
|
|
|
if (info.imat < 0)
|
|
|
|
td.bits.smooth = 0;
|
|
|
|
continue;
|
|
|
|
map.setDesignationAt(pos, td);
|
|
|
|
if (produces_item(options.boulder_percents,
|
|
|
|
}
|
|
|
|
map, rng, info)) {
|
|
|
|
} else if (to.bits.carve_track_north == 1
|
|
|
|
auto k = std::make_pair(info.itype, info.imat);
|
|
|
|
|| to.bits.carve_track_east == 1
|
|
|
|
item_coords[k].push_back(info.pos);
|
|
|
|
|| to.bits.carve_track_south == 1
|
|
|
|
|
|
|
|
|| to.bits.carve_track_west == 1) {
|
|
|
|
|
|
|
|
if (carve_tile(map, pos, to)) {
|
|
|
|
|
|
|
|
to = map.occupancyAt(pos);
|
|
|
|
|
|
|
|
to.bits.carve_track_north = 0;
|
|
|
|
|
|
|
|
to.bits.carve_track_east = 0;
|
|
|
|
|
|
|
|
to.bits.carve_track_south = 0;
|
|
|
|
|
|
|
|
to.bits.carve_track_west = 0;
|
|
|
|
|
|
|
|
map.setOccupancyAt(pos, to);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// todo: check mark mode of smooth designations
|
|
|
|
|
|
|
|
} else if (td.bits.smooth == 1) {
|
|
|
|
|
|
|
|
if (smooth_tile(out, map, pos)) {
|
|
|
|
|
|
|
|
to = map.occupancyAt(pos);
|
|
|
|
|
|
|
|
td.bits.smooth = 0;
|
|
|
|
|
|
|
|
map.setDesignationAt(pos, td);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (to.bits.carve_track_north == 1
|
|
|
|
|
|
|
|
|| to.bits.carve_track_east == 1
|
|
|
|
|
|
|
|
|| to.bits.carve_track_south == 1
|
|
|
|
|
|
|
|
|| to.bits.carve_track_west == 1) {
|
|
|
|
|
|
|
|
if (carve_tile(map, pos, to)) {
|
|
|
|
|
|
|
|
to = map.occupancyAt(pos);
|
|
|
|
|
|
|
|
to.bits.carve_track_north = 0;
|
|
|
|
|
|
|
|
to.bits.carve_track_east = 0;
|
|
|
|
|
|
|
|
to.bits.carve_track_south = 0;
|
|
|
|
|
|
|
|
to.bits.carve_track_west = 0;
|
|
|
|
|
|
|
|
map.setOccupancyAt(pos, to);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|