Merge pull request #3587 from myk002/myk_warmdamp

[dig] add warm/damp highlight overlay for ascii mode
develop
Myk 2023-07-21 14:19:20 -07:00 committed by GitHub
commit 41238add15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 147 additions and 11 deletions

@ -36,6 +36,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## New Plugins
- `3dveins`: reinstated for v50, this plugin replaces vanilla DF's blobby vein generation with veins that flow smoothly and naturally between z-levels
- `zone`: new searchable, sortable, filterable screen for assigning units to pastures
- `dig`: new ``dig.asciiwarmdamp`` overlay that highlights warm and damp tiles when in ASCII mode. there is no effect in graphics mode since the tiles are already highlighted there
## Fixes
- Fix extra keys appearing in DFHack text boxes when shift (or any other modifier) is released before the other key you were pressing

@ -179,3 +179,12 @@ Filters:
Take current designation and apply the selected pattern to it.
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
change color as appropriate when over the warm or damp tile.

@ -0,0 +1,29 @@
local _ENV = mkmodule('plugins.dig')
local overlay = require('plugins.overlay')
local pathable = require('plugins.pathable')
WarmDampOverlay = defclass(WarmDampOverlay, overlay.OverlayWidget)
WarmDampOverlay.ATTRS{
viewscreens={
'dwarfmode/Designate/DIG_DIG',
'dwarfmode/Designate/DIG_REMOVE_STAIRS_RAMPS',
'dwarfmode/Designate/DIG_STAIR_UP',
'dwarfmode/Designate/DIG_STAIR_UPDOWN',
'dwarfmode/Designate/DIG_STAIR_DOWN',
'dwarfmode/Designate/DIG_RAMP',
'dwarfmode/Designate/DIG_CHANNEL',
'dwarfmode/Designate/DIG_FROM_MARKER',
'dwarfmode/Designate/DIG_TO_MARKER',
},
default_enabled=true,
overlay_only=true,
}
function WarmDampOverlay:onRenderFrame(dc)
pathable.paintScreenWarmDamp()
end
OVERLAY_WIDGETS = {asciiwarmdamp=WarmDampOverlay}
return _ENV

@ -1,23 +1,26 @@
#include "Debug.h"
#include "PluginManager.h"
#include "TileTypes.h"
#include "modules/Gui.h"
#include "modules/Maps.h"
#include "modules/Screen.h"
#include "modules/Textures.h"
#include "Debug.h"
#include "LuaTools.h"
#include "PluginManager.h"
#include "df/init.h"
#include "df/map_block.h"
#include "df/tile_designation.h"
#include <functional>
using namespace DFHack;
DFHACK_PLUGIN("pathable");
REQUIRE_GLOBAL(gps);
REQUIRE_GLOBAL(init);
REQUIRE_GLOBAL(window_x);
REQUIRE_GLOBAL(window_y);
REQUIRE_GLOBAL(window_z);
REQUIRE_GLOBAL(world);
namespace DFHack {
DBG_DECLARE(pathable, log, DebugCategory::LINFO);
@ -31,7 +34,7 @@ DFhackCExport command_result plugin_shutdown(color_ostream &out) {
return CR_OK;
}
static void paintScreen(df::coord target, bool skip_unrevealed = false) {
static void paintScreenPathable(df::coord target, bool show_hidden = false) {
DEBUG(log).print("entering paintScreen\n");
bool use_graphics = Screen::inGraphicsMode();
@ -39,8 +42,8 @@ static void paintScreen(df::coord target, bool skip_unrevealed = false) {
int selected_tile_texpos = 0;
Screen::findGraphicsTile("CURSORS", 4, 3, &selected_tile_texpos);
long pathable_tile_texpos = df::global::init->load_bar_texpos[1];
long unpathable_tile_texpos = df::global::init->load_bar_texpos[4];
long pathable_tile_texpos = init->load_bar_texpos[1];
long unpathable_tile_texpos = init->load_bar_texpos[4];
long on_off_texpos = Textures::getMapPathableTexposStart();
if (on_off_texpos > 0) {
pathable_tile_texpos = on_off_texpos + 0;
@ -61,7 +64,7 @@ static void paintScreen(df::coord target, bool skip_unrevealed = false) {
continue;
}
if (skip_unrevealed && !Maps::isTileVisible(map_pos)) {
if (!show_hidden && !Maps::isTileVisible(map_pos)) {
TRACE(log).print("skipping hidden tile\n");
continue;
}
@ -110,7 +113,101 @@ static void paintScreen(df::coord target, bool skip_unrevealed = false) {
}
}
static bool is_warm(const df::coord &pos) {
auto block = Maps::getTileBlock(pos);
if (!block)
return false;
return block->temperature_1[pos.x&15][pos.y&15] >= 10075;
}
static bool is_rough_wall(int16_t x, int16_t y, int16_t z) {
df::tiletype *tt = Maps::getTileType(x, y, z);
if (!tt)
return false;
return tileShape(*tt) == df::tiletype_shape::WALL &&
tileSpecial(*tt) != df::tiletype_special::SMOOTH;
}
static bool will_leak(int16_t x, int16_t y, int16_t z) {
auto des = Maps::getTileDesignation(x, y, z);
if (!des)
return false;
if (des->bits.liquid_type == df::tile_liquid::Water && des->bits.flow_size >= 1)
return true;
if (des->bits.water_table && is_rough_wall(x, y, z))
return true;
return false;
}
static bool is_damp(const df::coord &pos) {
return will_leak(pos.x-1, pos.y-1, pos.z) ||
will_leak(pos.x, pos.y-1, pos.z) ||
will_leak(pos.x+1, pos.y-1, pos.z) ||
will_leak(pos.x-1, pos.y, pos.z) ||
will_leak(pos.x+1, pos.y, pos.z) ||
will_leak(pos.x-1, pos.y+1, pos.z) ||
will_leak(pos.x, pos.y+1, pos.z) ||
will_leak(pos.x+1, pos.y+1, pos.z);
will_leak(pos.x, pos.y+1, pos.z+1);
}
static void paintScreenWarmDamp(bool show_hidden = false) {
DEBUG(log).print("entering paintScreenDampWarm\n");
if (Screen::inGraphicsMode())
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 (!show_hidden && !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 = Screen::readTile(x, y, true);
if (!cur_tile.valid()) {
DEBUG(log).print("cannot read tile at offset %d, %d\n", x, y);
continue;
}
int color = is_warm(map_pos) ? COLOR_RED : is_damp(map_pos) ? COLOR_BLUE : COLOR_BLACK;
if (color == COLOR_BLACK) {
TRACE(log).print("skipping non-warm, non-damp tile\n");
continue;
}
// this will also change the color of the cursor or any selection box that overlaps
// the tile. this is intentional since it makes the UI more readable
if (cur_tile.fg && cur_tile.ch != ' ') {
cur_tile.fg = color;
cur_tile.bg = 0;
} else {
cur_tile.fg = 0;
cur_tile.bg = color;
}
cur_tile.bold = false;
if (cur_tile.tile)
cur_tile.tile_mode = Screen::Pen::CharColor;
Screen::paintTile(cur_tile, x, y, true);
}
}
}
DFHACK_PLUGIN_LUA_FUNCTIONS {
DFHACK_LUA_FUNCTION(paintScreen),
DFHACK_LUA_FUNCTION(paintScreenPathable),
DFHACK_LUA_FUNCTION(paintScreenWarmDamp),
DFHACK_LUA_END
};