Add a script to complement the weapon rack binary patch.

develop
Alexander Gavrilov 2012-10-27 20:16:27 +04:00
parent 34f33a8c91
commit e353f5f03e
5 changed files with 226 additions and 10 deletions

@ -16,6 +16,7 @@ DFHack future
- gui/guide-path: displays the cached path for minecart Guide orders.
- gui/workshop-job: displays inputs of a workshop job and allows tweaking them.
- gui/workflow: a front-end for the workflow plugin.
- gui/assign-rack: works together with a binary patch to fix weapon racks.
Workflow plugin:
- properly considers minecarts assigned to routes busy.
- code for deducing job outputs rewritten in lua for flexibility.

@ -81,6 +81,9 @@ keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job
# workflow front-end
keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow
# assign weapon racks to squads so that they can be used
keybinding add P@dwarfmode/QueryBuilding/Some/Weaponrack gui/assign-rack
############################
# UI and game logic tweaks #
############################
@ -118,3 +121,6 @@ tweak fast-trade
tweak military-stable-assign
# in same list, color units already assigned to squads in brown & green
tweak military-color-assigned
# stop squad equpment stored on weapon racks and armor stands from being stockpiled
tweak armory

@ -65,10 +65,14 @@ end
local function apply_attrs(obj, attrs, init_table)
for k,v in pairs(attrs) do
if v == DEFAULT_NIL then
v = nil
local init_v = init_table[k]
if init_v ~= nil then
obj[k] = init_v
elseif v == DEFAULT_NIL then
obj[k] = nil
else
obj[k] = v
end
obj[k] = init_table[k] or v
end
end

@ -501,14 +501,17 @@ function List:onRenderBody(dc)
local y = (i - top)*self.row_height
if iw and obj.icon then
dc:seek(0, y)
if type(obj.icon) == 'table' then
dc:char(nil,obj.icon)
else
if current then
dc:string(obj.icon, obj.icon_pen or cur_pen)
local icon = getval(obj.icon)
if icon then
dc:seek(0, y)
if type(icon) == 'table' then
dc:char(nil,icon)
else
dc:string(obj.icon, obj.icon_pen or cur_dpen)
if current then
dc:string(icon, obj.icon_pen or self.icon_pen or cur_pen)
else
dc:string(icon, obj.icon_pen or self.icon_pen or cur_dpen)
end
end
end
end

@ -0,0 +1,202 @@
-- Assign weapon racks to squads. Requires patch from bug 1445.
--[[
Required patches:
v0.34.11 linux: http://pastebin.com/mt5EUgFZ
v0.34.11 windows: http://pastebin.com/09nRCybe
]]
local utils = require 'utils'
local gui = require 'gui'
local guidm = require 'gui.dwarfmode'
local widgets = require 'gui.widgets'
local dlg = require 'gui.dialogs'
AssignRack = defclass(AssignRack, guidm.MenuOverlay)
AssignRack.focus_path = 'assign-rack'
AssignRack.ATTRS {
building = DEFAULT_NIL,
frame_inset = 1,
frame_background = COLOR_BLACK,
}
function list_squads(building,squad_table,squad_list)
local sqlist = building:getSquads()
if not sqlist then
return
end
for i,v in ipairs(sqlist) do
local obj = df.squad.find(v.squad_id)
if obj then
if not squad_table[v.squad_id] then
squad_table[v.squad_id] = { id = v.squad_id, obj = obj }
table.insert(squad_list, squad_table[v.squad_id])
end
-- Set specific use flags
for n,ok in pairs(v.mode) do
if ok then
squad_table[v.squad_id][n] = true
end
end
-- Check if any use is possible
local btype = building:getType()
if btype == df.building_type.Bed then
if v.mode.sleep then
squad_table[v.squad_id].any = true
end
elseif btype == df.building.Weaponrack then
if v.mode.train or v.mode.indiv_eq then
squad_table[v.squad_id].any = true
end
else
if v.mode.indiv_eq then
squad_table[v.squad_id].any = true
end
end
end
end
for i,v in ipairs(building.parents) do
list_squads(v, squad_table, squad_list)
end
end
function filter_invalid(list, id)
for i=#list-1,0,-1 do
local bld = df.building.find(list[i])
if not bld or bld:getSpecificSquad() ~= id then
list:erase(i)
end
end
end
function AssignRack:init(args)
self.squad_table = {}
self.squad_list = {}
list_squads(self.building, self.squad_table, self.squad_list)
table.sort(self.squad_list, function(a,b) return a.id < b.id end)
self.choices = {}
for i,v in ipairs(self.squad_list) do
if v.any and (v.train or v.indiv_eq) then
local name = v.obj.alias
if name == '' then
name = dfhack.TranslateName(v.obj.name, true)
end
filter_invalid(v.obj.rack_combat, v.id)
filter_invalid(v.obj.rack_training, v.id)
table.insert(self.choices, {
icon = self:callback('isSelected', v),
icon_pen = COLOR_LIGHTGREEN,
obj = v,
text = {
name, NEWLINE, ' ',
{ text = function()
return string.format('%d combat, %d training', #v.obj.rack_combat, #v.obj.rack_training)
end }
}
})
end
end
self:addviews{
widgets.Label{
frame = { l = 0, t = 0 },
text = {
'Assign Weapon Rack'
}
},
widgets.List{
view_id = 'list',
frame = { t = 2, b = 2 },
icon_width = 2, row_height = 2,
scroll_keys = widgets.SECONDSCROLL,
choices = self.choices,
on_submit = self:callback('onSubmit'),
},
widgets.Label{
frame = { l = 0, t = 2 },
text_pen = COLOR_LIGHTRED,
text = 'No appropriate barracks\n\nNote: weapon racks use the\nIndividual equipment flag',
visible = (#self.choices == 0),
},
widgets.Label{
frame = { l = 0, b = 0 },
text = {
{ key = 'LEAVESCREEN', text = ': Back',
on_activate = self:callback('dismiss') }
}
},
}
end
function AssignRack:isSelected(info)
if self.building.specific_squad == info.id then
return '\xfb'
else
return nil
end
end
function AssignRack:onSubmit(idx, choice)
local rid = self.building.id
local curid = self.building.specific_squad
local cur = df.squad.find(curid)
if cur then
utils.erase_sorted(cur.rack_combat, rid)
utils.erase_sorted(cur.rack_training, rid)
end
self.building.specific_squad = -1
df.global.ui.equipment.update.buildings = true
local new = df.squad.find(choice.obj.id)
if new and choice.obj.id ~= curid then
self.building.specific_squad = choice.obj.id
if choice.obj.indiv_eq then
utils.insert_sorted(new.rack_combat, rid)
end
if choice.obj.train then
utils.insert_sorted(new.rack_training, rid)
end
end
end
function AssignRack:onInput(keys)
if self:propagateMoveKeys(keys) then
if df.global.world.selected_building ~= self.building then
self:dismiss()
end
else
AssignRack.super.onInput(self, keys)
end
end
if dfhack.gui.getCurFocus() ~= 'dwarfmode/QueryBuilding/Some/Weaponrack' then
qerror("This script requires a weapon rack selected in the 'q' mode")
end
AssignRack{ building = dfhack.gui.getSelectedBuilding() }:show()
if not already_warned then
already_warned = true
dlg.showMessage(
'BUG ALERT',
{ 'This script requires a binary patch from', NEWLINE,
'bug 1445 on the tracker. Otherwise the game', NEWLINE,
'will lose your settings due to a bug.' },
COLOR_YELLOW
)
end