Skip to content

Commit

Permalink
Merge pull request DFHack#3764 from myk002/myk_pathable_with_jobs
Browse files Browse the repository at this point in the history
[pathable] continue to highlight designations once they have become jobs
  • Loading branch information
myk002 authored Sep 11, 2023
2 parents 4ac0be0 + 73b5f0c commit 33c6cda
Showing 1 changed file with 112 additions and 37 deletions.
149 changes: 112 additions & 37 deletions plugins/pathable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
#include "PluginManager.h"
#include "TileTypes.h"

#include "modules/EventManager.h"
#include "modules/Gui.h"
#include "modules/Maps.h"
#include "modules/Screen.h"
#include "modules/Textures.h"

#include "df/block_square_event_designation_priorityst.h"
#include "df/init.h"
#include "df/job_list_link.h"
#include "df/map_block.h"
#include "df/tile_designation.h"
#include "df/block_square_event_designation_priorityst.h"
#include "df/world.h"

#include <functional>

Expand All @@ -23,6 +26,7 @@ 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);
Expand Down Expand Up @@ -211,58 +215,126 @@ 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;
struct designation{
df::coord pos;
df::tile_designation td;
df::tile_occupancy to;
designation() = default;
designation(const df::coord &c, const df::tile_designation &td, const df::tile_occupancy &to) : pos(c), td(td), to(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);
}
};
}

static bool is_designated_for_engraving(const df::coord &pos) {
auto des = Maps::getTileDesignation(pos);
if (!des)
return false;
return des->bits.smooth == 2;
class Designations {
private:
std::unordered_map<df::coord, designation> designations;
public:
Designations() {
df::job_list_link *link = world->jobs.list.next;
for (; link; link = link->next) {
df::job *job = link->item;

if(!job || !Maps::isValidTilePos(job->pos))
continue;

df::tile_designation td;
df::tile_occupancy to;
switch (job->job_type) {
case df::job_type::SmoothWall:
case df::job_type::SmoothFloor:
case df::job_type::CarveFortification:
td.bits.smooth = 1;
break;
case df::job_type::DetailWall:
case df::job_type::DetailFloor:
td.bits.smooth = 2;
break;
case job_type::CarveTrack:
to.bits.carve_track_north = (job->item_category.whole >> 18) & 1;
to.bits.carve_track_south = (job->item_category.whole >> 19) & 1;
to.bits.carve_track_west = (job->item_category.whole >> 20) & 1;
to.bits.carve_track_east = (job->item_category.whole >> 21) & 1;
break;
default:
break;
}
designations.emplace(job->pos, designation(job->pos, td, to));
}
}

// get from job; if no job, then fall back to querying map
designation get(const df::coord &pos) const {
if (designations.count(pos)) {
return designations.at(pos);
}
auto pdes = Maps::getTileDesignation(pos);
auto pocc = Maps::getTileOccupancy(pos);
if (!pdes || !pocc)
return {};
return designation(pos, *pdes, *pocc);
}
};

static bool is_designated_for_smoothing(const designation &designation) {
return designation.td.bits.smooth == 1;
}

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_designated_for_engraving(const designation &designation) {
return designation.td.bits.smooth == 2;
}

static char get_track_char(const df::coord &pos) {
auto occ = Maps::getTileOccupancy(pos);
if (occ->bits.carve_track_east && occ->bits.carve_track_north && occ->bits.carve_track_south && occ->bits.carve_track_west)
static bool is_designated_for_track_carving(const designation &designation) {
const df::tile_occupancy &occ = designation.to;
return occ.bits.carve_track_east || occ.bits.carve_track_north || occ.bits.carve_track_south || occ.bits.carve_track_west;
}

static char get_track_char(const designation &designation) {
const df::tile_occupancy &occ = designation.to;
if (occ.bits.carve_track_east && occ.bits.carve_track_north && occ.bits.carve_track_south && occ.bits.carve_track_west)
return (char)0xCE; // NSEW
if (occ->bits.carve_track_east && occ->bits.carve_track_north && occ->bits.carve_track_south)
if (occ.bits.carve_track_east && occ.bits.carve_track_north && occ.bits.carve_track_south)
return (char)0xCC; // NSE
if (occ->bits.carve_track_east && occ->bits.carve_track_north && occ->bits.carve_track_west)
if (occ.bits.carve_track_east && occ.bits.carve_track_north && occ.bits.carve_track_west)
return (char)0xCA; // NEW
if (occ->bits.carve_track_east && occ->bits.carve_track_south && occ->bits.carve_track_west)
if (occ.bits.carve_track_east && occ.bits.carve_track_south && occ.bits.carve_track_west)
return (char)0xCB; // SEW
if (occ->bits.carve_track_north && occ->bits.carve_track_south && occ->bits.carve_track_west)
if (occ.bits.carve_track_north && occ.bits.carve_track_south && occ.bits.carve_track_west)
return (char)0xB9; // NSW
if (occ->bits.carve_track_north && occ->bits.carve_track_south)
if (occ.bits.carve_track_north && occ.bits.carve_track_south)
return (char)0xBA; // NS
if (occ->bits.carve_track_east && occ->bits.carve_track_west)
if (occ.bits.carve_track_east && occ.bits.carve_track_west)
return (char)0xCD; // EW
if (occ->bits.carve_track_east && occ->bits.carve_track_north)
if (occ.bits.carve_track_east && occ.bits.carve_track_north)
return (char)0xC8; // NE
if (occ->bits.carve_track_north && occ->bits.carve_track_west)
if (occ.bits.carve_track_north && occ.bits.carve_track_west)
return (char)0xBC; // NW
if (occ->bits.carve_track_east && occ->bits.carve_track_south)
if (occ.bits.carve_track_east && occ.bits.carve_track_south)
return (char)0xC9; // SE
if (occ->bits.carve_track_south && occ->bits.carve_track_west)
if (occ.bits.carve_track_south && occ.bits.carve_track_west)
return (char)0xBB; // SW
if (occ->bits.carve_track_north)
if (occ.bits.carve_track_north)
return (char)0xD0; // N
if (occ->bits.carve_track_south)
if (occ.bits.carve_track_south)
return (char)0xD2; // S
if (occ->bits.carve_track_east)
if (occ.bits.carve_track_east)
return (char)0xC6; // E
if (occ->bits.carve_track_west)
if (occ.bits.carve_track_west)
return (char)0xB5; // W
return (char)0xC5; // single line cross; should never happen
}
Expand Down Expand Up @@ -304,6 +376,7 @@ static void paintScreenCarve() {
if (Screen::inGraphicsMode() || blink(500))
return;

Designations designations;
bool draw_priority = blink(1000);

auto dims = Gui::getDwarfmodeViewDims().map();
Expand All @@ -325,17 +398,19 @@ static void paintScreenCarve() {
Screen::Pen cur_tile;
cur_tile.fg = COLOR_DARKGREY;

if (is_designated_for_smoothing(map_pos)) {
auto des = designations.get(map_pos);

if (is_designated_for_smoothing(des)) {
if (is_smooth_wall(map_pos))
cur_tile.ch = get_tile_char(map_pos, (char)206, draw_priority); // hash, indicating a fortification designation
else
cur_tile.ch = get_tile_char(map_pos, (char)219, draw_priority); // solid block, indicating a smoothing designation
}
else if (is_designated_for_engraving(map_pos)) {
else if (is_designated_for_engraving(des)) {
cur_tile.ch = get_tile_char(map_pos, (char)10, draw_priority); // solid block with a circle on it
}
else if (is_designated_for_track_carving(map_pos)) {
cur_tile.ch = get_tile_char(map_pos, get_track_char(map_pos), draw_priority); // directional track
else if (is_designated_for_track_carving(des)) {
cur_tile.ch = get_tile_char(map_pos, get_track_char(des), draw_priority); // directional track
}
else {
TRACE(log).print("skipping tile with no carving designation\n");
Expand Down

0 comments on commit 33c6cda

Please sign in to comment.