|
| 1 | +-- View whether tiles on the map can be pathed to |
| 2 | + |
| 3 | +--[====[ |
| 4 | +
|
| 5 | +gui/pathable |
| 6 | +============ |
| 7 | +
|
| 8 | +Highlights each visible map tile to indicate whether it is possible to path to |
| 9 | +from the tile at the cursor - green if possible, red if not, similar to |
| 10 | +`gui/siege-engine`. A few options are available: |
| 11 | +
|
| 12 | +* :kbd:`l`: Lock cursor: when enabled, the movement keys move around the map |
| 13 | + instead of moving the cursor. This is useful to check whether parts of the map |
| 14 | + far away from the cursor can be pathed to from the cursor. |
| 15 | +* :kbd:`d`: Draw: allows temporarily disabling the highlighting entirely. |
| 16 | +* :kbd:`u`: Skip unrevealed: when enabled, unrevealed tiles will not be |
| 17 | + highlighed at all. (These would otherwise be highlighted in red.) |
| 18 | +
|
| 19 | +.. note:: |
| 20 | + This tool uses a cache used by DF, which currently does *not* account for |
| 21 | + climbing. If an area of the map is only accessible by climbing, this tool |
| 22 | + may report it as inaccessible. Care should be taken when digging into the |
| 23 | + upper levels of caverns, for example. |
| 24 | +
|
| 25 | +]====] |
| 26 | + |
| 27 | +local guidm = require 'gui.dwarfmode' |
| 28 | +local plugin = require 'plugins.pathable' |
| 29 | + |
| 30 | +opts = opts or { |
| 31 | + lock_cursor = false, |
| 32 | + draw = true, |
| 33 | + skip_unrevealed = false, |
| 34 | +} |
| 35 | + |
| 36 | +function render_toggle(p, key, text, state) |
| 37 | + p:key_string(key, text .. ': ') |
| 38 | + p:string(state and 'Yes' or 'No', state and COLOR_GREEN or COLOR_RED) |
| 39 | +end |
| 40 | + |
| 41 | +Pathable = defclass(Pathable, guidm.MenuOverlay) |
| 42 | + |
| 43 | +function Pathable:onAboutToShow(parent) |
| 44 | + Pathable.super.onAboutToShow(self, parent) |
| 45 | + if df.global.cursor.x == -30000 then |
| 46 | + if df.global.ui.main.mode == df.ui_sidebar_mode.Default then |
| 47 | + parent:feed_key(df.interface_key.D_LOOK) |
| 48 | + else |
| 49 | + qerror("Unsupported UI mode - needs a cursor") |
| 50 | + end |
| 51 | + end |
| 52 | +end |
| 53 | + |
| 54 | +function Pathable:onRenderBody(p) |
| 55 | + p:seek(1, 1) |
| 56 | + p:string("DFHack pathable tile viewer"):newline():newline(1) |
| 57 | + render_toggle(p, 'CUSTOM_L', 'Lock cursor', opts.lock_cursor) |
| 58 | + p:newline(1) |
| 59 | + render_toggle(p, 'CUSTOM_D', 'Draw', opts.draw) |
| 60 | + p:newline(1) |
| 61 | + render_toggle(p, 'CUSTOM_U', 'Skip unrevealed', opts.skip_unrevealed) |
| 62 | + |
| 63 | + p:newline():newline(1) |
| 64 | + p:key_string('LEAVESCREEN', "Exit to cursor"):newline(1) |
| 65 | + p:key_string('LEAVESCREEN_ALL', "Exit to here"):newline(1) |
| 66 | + |
| 67 | + if opts.draw then |
| 68 | + plugin.paintScreen(xyz2pos(pos2xyz(df.global.cursor)), opts.skip_unrevealed) |
| 69 | + end |
| 70 | +end |
| 71 | + |
| 72 | +function Pathable:onInput(keys) |
| 73 | + if keys.LEAVESCREEN then |
| 74 | + self:dismiss() |
| 75 | + dfhack.gui.refreshSidebar() |
| 76 | + elseif keys.LEAVESCREEN_ALL then |
| 77 | + self:dismiss() |
| 78 | + df.global.ui.main.mode = df.ui_sidebar_mode.Default |
| 79 | + elseif keys.CUSTOM_L then |
| 80 | + opts.lock_cursor = not opts.lock_cursor |
| 81 | + elseif keys.CUSTOM_D then |
| 82 | + opts.draw = not opts.draw |
| 83 | + elseif keys.CUSTOM_U then |
| 84 | + opts.skip_unrevealed = not opts.skip_unrevealed |
| 85 | + else |
| 86 | + if opts.lock_cursor then |
| 87 | + -- no_clip_cursor=true: allow scrolling so the cursor isn't in view |
| 88 | + self:simulateViewScroll(keys, nil, true) |
| 89 | + else |
| 90 | + self:propagateMoveKeys(keys) |
| 91 | + end |
| 92 | + end |
| 93 | +end |
| 94 | + |
| 95 | +Pathable():show() |
0 commit comments