From ff84515c1d9d4fded3e1ab6cff389b4a5e0010c6 Mon Sep 17 00:00:00 2001 From: unboundlopez <47876628+unboundlopez@users.noreply.github.com> Date: Sun, 25 Jan 2026 00:36:16 -0600 Subject: [PATCH] Rename smooth-zlevel to smooth-walls --- docs/smooth-walls.rst | 22 ++++++++ smooth-walls.lua | 120 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 docs/smooth-walls.rst create mode 100644 smooth-walls.lua diff --git a/docs/smooth-walls.rst b/docs/smooth-walls.rst new file mode 100644 index 000000000..2ab3ca278 --- /dev/null +++ b/docs/smooth-walls.rst @@ -0,0 +1,22 @@ +smooth-walls +============ + +.. dfhack-tool:: + :summary: Designate all natural wall tiles on the current z-level for smoothing. + :tags: fort design map + +This script scans the currently viewed z-level and designates only wall tiles +for smoothing. It skips floors, ramps, stairs, already smoothed tiles, and any +tiles with existing dig/smoothing/track designations. Use ``undo`` to clear +existing smoothing designations on wall tiles. + +Usage +----- + +``smooth-walls`` + Designate eligible wall tiles for smoothing on the current z-level. +``smooth-walls smooth`` + Same as the default behavior. +``smooth-walls undo`` + Clear smoothing designations on wall tiles for the current z-level and + remove any existing smooth wall jobs on those tiles. diff --git a/smooth-walls.lua b/smooth-walls.lua new file mode 100644 index 000000000..0bd14ce51 --- /dev/null +++ b/smooth-walls.lua @@ -0,0 +1,120 @@ +-- Designate wall tiles on the current z-level for smoothing. + +local argparse = require('argparse') +local utils = require('utils') + +local options = { help = false } + +local positionals = argparse.processArgsGetopt({...}, { + { 'h', 'help', handler = function() options.help = true end }, +}) + +if positionals[1] == 'help' or options.help then + print(dfhack.script_help()) + return +end + +if not dfhack.isMapLoaded() or not dfhack.world.isFortressMode() then + qerror('This script can only be used in Fortress mode with a loaded map.') +end + +local tile_attrs = df.tiletype.attrs +local hard_natural_materials = utils.invert({ + df.tiletype_material.STONE, + df.tiletype_material.FEATURE, + df.tiletype_material.LAVA_STONE, + df.tiletype_material.MINERAL, + df.tiletype_material.FROZEN_LIQUID, +}) + +local function is_hard(tileattrs) + return hard_natural_materials[tileattrs.material] +end + +local function is_wall(tileattrs) + return tileattrs.shape == df.tiletype_shape.WALL +end + +local function is_smooth(tileattrs) + return tileattrs.special == df.tiletype_special.SMOOTH +end + +local function has_designation(flags, occupancy) + return flags.dig ~= df.tile_dig_designation.No or + flags.smooth > 0 or + occupancy.carve_track_north or + occupancy.carve_track_east or + occupancy.carve_track_south or + occupancy.carve_track_west +end + +local function get_smooth_job_map(z) + local job_map = {} + for _, job in utils.listpairs(df.global.world.jobs.list) do + if job.job_type == df.job_type.SmoothWall and job.pos.z == z then + if not job_map[job.pos.y] then + job_map[job.pos.y] = {} + end + job_map[job.pos.y][job.pos.x] = job + end + end + return job_map +end + +local function designate_smoothing_on_zlevel(z, mode) + local count = 0 + local job_map = mode == 'undo' and get_smooth_job_map(z) or nil + for _, block in ipairs(df.global.world.map.map_blocks) do + if block.map_pos.z == z then + for y = 0, 15 do + for x = 0, 15 do + local tiletype = block.tiletype[x][y] + if tiletype then + local tileattrs = tile_attrs[tiletype] + local flags = block.designation[x][y] + local occupancy = block.occupancy[x][y] + if not flags.hidden and is_wall(tileattrs) then + if mode == 'undo' then + local world_x = block.map_pos.x + x + local world_y = block.map_pos.y + y + local job = job_map and job_map[world_y] and job_map[world_y][world_x] + if flags.smooth > 0 then + flags.smooth = 0 + block.flags.designated = true + count = count + 1 + end + if job then + dfhack.job.removeJob(job) + end + elseif is_hard(tileattrs) and + not is_smooth(tileattrs) and + not has_designation(flags, occupancy) then + flags.smooth = 1 + block.flags.designated = true + count = count + 1 + end + end + end + end + end + end + end + return count +end + +local mode = positionals[1] +if mode == nil or mode == '' then + mode = 'smooth' +end + +if mode ~= 'smooth' and mode ~= 'undo' then + qerror('Usage: smooth-walls [smooth|undo]') +end + +local z = df.global.window_z +local count = designate_smoothing_on_zlevel(z, mode) +if mode == 'undo' then + print(('Cleared smoothing designation on %d wall tile(s) for z-level %d.'):format(count, z)) +else + print(('Designated %d wall tile(s) for smoothing on z-level %d.'):format(count, z)) +end