add ASCII-mode highlight for smoothing and carving designations

develop
Myk Taylor 2023-09-10 05:29:55 -07:00
parent f23d96bf25
commit a0919ec316
No known key found for this signature in database
5 changed files with 121 additions and 9 deletions

@ -54,6 +54,7 @@ Template for new versions:
## New Tools
## New Features
- `dig`: new overlay for ASCII mode that visualizes designations for smoothing, engraving, carving tracks, and carving fortifications
## Fixes
- `buildingplan`: make the construction dimensions readout visible again

@ -183,8 +183,19 @@ After you have a pattern set, you can use ``expdig`` to apply it again.
Overlay
-------
This tool also provides an overlay that is managed by the `overlay` framework.
When the ``dig.asciiwarmdamp`` overlay is enabled and you are in non-graphics
(ASCII) mode, warm tiles will be highlighted in red and damp tiles will be
highlighted in blue. Box selection characters and the keyboard cursor will also
This tool also provides two overlays that are managed by the `overlay`
framework. Both have no effect when in graphics mode, but when in ASCII mode,
they display useful highlights that are otherwise missing from the ASCII mode
interface.
The ``dig.asciiwarmdamp`` overlay highlights warm tiles red and damp tiles in
blue. Box selection characters and the keyboard cursor will also
change color as appropriate when over the warm or damp tile.
The ``dig.asciicarve`` overlay highlights tiles that are designated for
smoothing, engraving, track carving, or fortification carving. The designations
blink so you can still see what is underneath them.
Note that due to the limitations of the ASCII mode screen buffer, the
designation highlights may show through other interface elements that overlap
the designated area.

@ -293,13 +293,13 @@ extern DFHACK_EXPORT df::tiletype *getTileType(int32_t x, int32_t y, int32_t z);
extern DFHACK_EXPORT df::tile_designation *getTileDesignation(int32_t x, int32_t y, int32_t z);
extern DFHACK_EXPORT df::tile_occupancy *getTileOccupancy(int32_t x, int32_t y, int32_t z);
inline df::tiletype *getTileType(df::coord pos) {
inline df::tiletype *getTileType(const df::coord &pos) {
return getTileType(pos.x, pos.y, pos.z);
}
inline df::tile_designation *getTileDesignation(df::coord pos) {
inline df::tile_designation *getTileDesignation(const df::coord &pos) {
return getTileDesignation(pos.x, pos.y, pos.z);
}
inline df::tile_occupancy *getTileOccupancy(df::coord pos) {
inline df::tile_occupancy *getTileOccupancy(const df::coord &pos) {
return getTileOccupancy(pos.x, pos.y, pos.z);
}

@ -20,10 +20,30 @@ WarmDampOverlay.ATTRS{
overlay_only=true,
}
function WarmDampOverlay:onRenderFrame(dc)
function WarmDampOverlay:onRenderFrame()
pathable.paintScreenWarmDamp()
end
OVERLAY_WIDGETS = {asciiwarmdamp=WarmDampOverlay}
CarveOverlay = defclass(CarveOverlay, overlay.OverlayWidget)
CarveOverlay.ATTRS{
viewscreens={
'dwarfmode/Designate/SMOOTH',
'dwarfmode/Designate/ENGRAVE',
'dwarfmode/Designate/TRACK',
'dwarfmode/Designate/FORTIFY',
'dwarfmode/Designate/ERASE',
},
default_enabled=true,
overlay_only=true,
}
function CarveOverlay:onRenderFrame()
pathable.paintScreenCarve()
end
OVERLAY_WIDGETS = {
asciiwarmdamp=WarmDampOverlay,
asciicarve=CarveOverlay,
}
return _ENV

@ -1,4 +1,5 @@
#include "Debug.h"
#include "MemAccess.h"
#include "PluginManager.h"
#include "TileTypes.h"
@ -209,8 +210,87 @@ static void paintScreenWarmDamp(bool show_hidden = false) {
}
}
static bool is_designated_for_smoothing(const df::coord &pos) {
auto des = Maps::getTileDesignation(pos);
if (!des)
return false;
return des->bits.smooth == 1;
}
static bool is_designated_for_engraving(const df::coord &pos) {
auto des = Maps::getTileDesignation(pos);
if (!des)
return false;
return des->bits.smooth == 2;
}
static bool is_designated_for_track_carving(const df::coord &pos) {
auto occ = Maps::getTileOccupancy(pos);
if (!occ)
return false;
return occ->bits.carve_track_east || occ->bits.carve_track_north || occ->bits.carve_track_south || occ->bits.carve_track_west;
}
static bool is_smooth_wall(const df::coord &pos) {
df::tiletype *tt = Maps::getTileType(pos);
return tt && tileSpecial(*tt) == df::tiletype_special::SMOOTH
&& tileShape(*tt) == df::tiletype_shape::WALL;
}
static bool blink(int delay) {
return (Core::getInstance().p->getTickCount()/delay) % 2 == 0;
}
static void paintScreenCarve() {
DEBUG(log).print("entering paintScreenCarve\n");
if (Screen::inGraphicsMode() || blink(500))
return;
auto dims = Gui::getDwarfmodeViewDims().map();
for (int y = dims.first.y; y <= dims.second.y; ++y) {
for (int x = dims.first.x; x <= dims.second.x; ++x) {
df::coord map_pos(*window_x + x, *window_y + y, *window_z);
if (!Maps::isValidTilePos(map_pos))
continue;
if (!Maps::isTileVisible(map_pos)) {
TRACE(log).print("skipping hidden tile\n");
continue;
}
TRACE(log).print("scanning map tile at (%d, %d, %d) screen offset (%d, %d)\n",
map_pos.x, map_pos.y, map_pos.z, x, y);
Screen::Pen cur_tile;
cur_tile.fg = COLOR_DARKGREY;
if (is_designated_for_smoothing(map_pos)) {
if (is_smooth_wall(map_pos))
cur_tile.ch = 206; // hash, indicating a fortification designation
else
cur_tile.ch = 219; // solid block, indicating a smoothing designation
}
else if (is_designated_for_engraving(map_pos)) {
cur_tile.ch = 10; // solid block with a circle on it
}
else if (is_designated_for_track_carving(map_pos)) {
cur_tile.ch = 186; // parallel tracks
}
else {
TRACE(log).print("skipping tile with no carving designation\n");
continue;
}
Screen::paintTile(cur_tile, x, y, true);
}
}
}
DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION(paintScreenPathable),
DFHACK_LUA_FUNCTION(paintScreenWarmDamp),
DFHACK_LUA_FUNCTION(paintScreenCarve),
DFHACK_LUA_END
};