choose mechanism improvements

sort by heat safety so mechanisms of the least appropriate heat safety
are used first, saving the magma-safe mechanisms for when they are
needed

filter out unreachable mechanisms

item_id -1 => item_id or -1
that is, we wanted to default to -1, not subtract 1 from the item_id
develop
Myk Taylor 2023-11-19 23:38:58 -08:00
parent b078036ac6
commit 72bec1dfdb
No known key found for this signature in database
2 changed files with 48 additions and 6 deletions

@ -56,8 +56,11 @@ Template for new versions:
## New Features ## New Features
## Fixes ## Fixes
- `buildingplan`: fix choosing the wrong mechanism (or something that isn't a mechanism) when linking a lever and manually choosing a mechanism, but then canceling the selection
## Misc Improvements ## Misc Improvements
- `buildingplan`: save magma safe mechanisms for when magma safety is requested when linking levers and pressure plates to targets
- `buildingplan`: when choosing mechanisms for linking levers/pressure plates, filter out unreachable mechanisms
- `tailor`: corrected a corner case that resulted in existing stock being ignored in some circumstances - `tailor`: corrected a corner case that resulted in existing stock being ignored in some circumstances
## Documentation ## Documentation

@ -2,6 +2,7 @@ local _ENV = mkmodule('plugins.buildingplan.mechanisms')
local itemselection = require('plugins.buildingplan.itemselection') local itemselection = require('plugins.buildingplan.itemselection')
local overlay = require('plugins.overlay') local overlay = require('plugins.overlay')
local utils = require('utils')
local widgets = require('gui.widgets') local widgets = require('gui.widgets')
local view_sheets = df.global.game.main_interface.view_sheets local view_sheets = df.global.game.main_interface.view_sheets
@ -102,21 +103,59 @@ local function reset_dlg()
end end
end end
local function is_reachable(bld_pos, item_id)
if not bld_pos then return false end
local item = df.item.find(item_id)
if not item then return false end
return dfhack.maps.canWalkBetween(xyz2pos(dfhack.items.getPosition(item)), bld_pos)
end
local function sort_by_safety(item_ids, safety)
if safety == 2 then return item_ids end
local safety_ids = {[safety]=utils.invert(item_ids)}
for sort_safety=safety+1,2 do
local safety_item_ids = require('plugins.buildingplan').getAvailableItemsByHeat(
df.building_type.Trap, df.trap_type.Lever, -1, 0, sort_safety)
safety_ids[sort_safety] = utils.invert(safety_item_ids)
end
local sorted_ids = {}
for _,item_id in ipairs(item_ids) do
for safety_idx=2,safety,-1 do
if safety_ids[safety_idx][item_id] then
table.insert(ensure_key(sorted_ids, safety_idx), item_id)
break
end
end
end
local ret = {}
for safety_id=safety,2 do
if sorted_ids[safety_id] then
table.move(sorted_ids[safety_id], 1, #sorted_ids[safety_id], #ret+1, ret)
end
end
return ret
end
-- returns mechanisms ordered by heat safety, so the least heat safe mechanisms are used first
-- when heat safety isn't important
local function get_available_items(safety, other_mechanism) local function get_available_items(safety, other_mechanism)
local item_ids = require('plugins.buildingplan').getAvailableItemsByHeat( local item_ids = require('plugins.buildingplan').getAvailableItemsByHeat(
df.building_type.Trap, df.trap_type.Lever, -1, 0, safety) df.building_type.Trap, df.trap_type.Lever, -1, 0, safety)
for idx,item_id in ipairs(item_ids) do local bld = dfhack.gui.getSelectedBuilding(true)
if item_id == other_mechanism then local bld_pos = bld and xyz2pos(bld.centerx, bld.centery, bld.z)
for idx=#item_ids,1,-1 do
local item_id = item_ids[idx]
if item_id == other_mechanism or not is_reachable(bld_pos, item_id) then
table.remove(item_ids, idx) table.remove(item_ids, idx)
break
end end
end end
return item_ids return sort_by_safety(item_ids, safety)
end end
function MechanismOverlay:save_id(which, item_id) function MechanismOverlay:save_id(which, item_id)
local saved_id = ('saved_%s_id'):format(which) local saved_id = ('saved_%s_id'):format(which)
local ui_id = ('linking_lever_mech_%s_id'):format(which) local ui_id = ('linking_lever_mech_%s_id'):format(which)
item_id = item_id or -1
view_sheets[ui_id] = item_id view_sheets[ui_id] = item_id
self[saved_id] = item_id self[saved_id] = item_id
end end
@ -128,7 +167,7 @@ function MechanismOverlay:choose_mechanism(which, autoselect)
local available_item_ids = get_available_items(safety, view_sheets[ui_other_id]) local available_item_ids = get_available_items(safety, view_sheets[ui_other_id])
if autoselect then if autoselect then
self:save_id(which, available_item_ids[1] or -1) self:save_id(which, available_item_ids[1])
return return
end end
@ -148,7 +187,7 @@ function MechanismOverlay:choose_mechanism(which, autoselect)
autoselect=false, autoselect=false,
on_cancel=reset_dlg, on_cancel=reset_dlg,
on_submit=function(chosen_ids) on_submit=function(chosen_ids)
self:save_id(which, chosen_ids[1] or available_item_ids[1] -1) self:save_id(which, chosen_ids[1] or available_item_ids[1])
reset_dlg() reset_dlg()
end, end,
}:show() }:show()