many improvements to advfort:

fixed being able to engrave soft materials, started using ui_buttons for better workshop functionality, started working on manual item assignment
develop
Warmist 2013-01-03 23:21:57 +02:00
parent c22c4d009c
commit e3ca612ed5
1 changed files with 216 additions and 7 deletions

@ -17,6 +17,7 @@ local dialog=require 'gui.dialogs'
local buildings=require 'dfhack.buildings' local buildings=require 'dfhack.buildings'
local bdialog=require 'gui.buildings' local bdialog=require 'gui.buildings'
local workshopJobs=require 'dfhack.workshops' local workshopJobs=require 'dfhack.workshops'
local utils=require 'utils'
local tile_attrs = df.tiletype.attrs local tile_attrs = df.tiletype.attrs
@ -211,10 +212,19 @@ function IsConstruct(args)
return false, "Can only do it on constructions" return false, "Can only do it on constructions"
end end
end end
function SameSquare(args)
local pos1=args.pos
local pos2=args.from_pos
if pos1.x==pos2.x and pos1.y==pos2.y and pos1.z==pos2.z then
return true
else
return false, "Can only do it on same square"
end
end
function IsHardMaterial(args) function IsHardMaterial(args)
local tt=dfhack.maps.getTileType(args.pos) local tt=dfhack.maps.getTileType(args.pos)
local mat=tile_attrs[tt].material local mat=tile_attrs[tt].material
local hard_materials={df.tiletype_material.STONE,df.tiletype_material.FEATURE, local hard_materials=makeset{df.tiletype_material.STONE,df.tiletype_material.FEATURE,
df.tiletype_material.LAVA_STONE,df.tiletype_material.MINERAL,df.tiletype_material.FROZEN_LIQUID,} df.tiletype_material.LAVA_STONE,df.tiletype_material.MINERAL,df.tiletype_material.FROZEN_LIQUID,}
if hard_materials[mat] then if hard_materials[mat] then
return true return true
@ -440,6 +450,155 @@ function EnumItems(args)
end end
return ret return ret
end end
jobitemEditor=defclass(jobitemEditor,gui.FramedScreen)
jobitemEditor.ATTRS{
frame_style = gui.GREY_LINE_FRAME,
frame_inset = 1,
allow_add=false,
allow_remove=false,
allow_any_item=false,
job=DEFAULT_NIL,
items=DEFAULT_NIL,
}
function jobitemEditor:init(args)
--self.job=args.job
if self.job==nil then qerror("This screen must have job target") end
if self.items==nil then qerror("This screen must have item list") end
local itemChoices={}
table.insert(itemChoices,{text="<nothing>"})
for k,v in pairs(self.items) do
table.insert(itemChoices,{item=v,text=dfhack.items.getDescription(v, 0)})
end
self.itemChoices=itemChoices
self:addviews{
wid.Label{
view_id = 'label',
text = args.prompt,
text_pen = args.text_pen,
frame = { l = 0, t = 0 },
},
wid.List{
view_id = 'itemList',
frame = { l = 0, t = 2 ,b=2},
on_submit = self:callback("selectJobItem")
},
wid.Label{
frame = { b=1,l=1},
text ={{text= ": cancel",
key = "LEAVESCREEN",
on_activate= self:callback("dismiss")
},
{
gap=3,
text= ": accept",
key = "SEC_SELECT",
on_activate= self:callback("commit"),
enabled=self:callback("jobValid")
},
{
gap=3,
text= ": add",
key = "CUSTOM_A",
enabled=false,
--on_activate= self:callback("commit")
},
{
gap=3,
text= ": remove",
key = "CUSTOM_R",
enabled=false,
--on_activate= self:callback("commit")
},}
},
}
self.assigned={}
self:fill(self.job)
end
function jobitemEditor:fill(job)
local choices={}
for item_id, trg_job_item in ipairs(job.job_items) do
local str="<nothing>"
if self.assigned[item_id] ~=nil then
str=dfhack.items.getDescription(self.assigned[item_id],0)
end
local text={string.format("%3d:",item_id)}
if self.assigned[item_id]~=nil then
for subid,assigned_item in ipairs(self.assigned[item_id]) do
table.insert(text," "..dfhack.items.getDescription(assigned_item,0))
table.insert(text,"\n")
end
else
table.insert(text,"<nothing>")
end
table.insert(choices,{text=text,
job_item=trg_job_item,job_item_idx=item_id})
end
self.choices=choices
self.subviews.itemList:setChoices(choices)
end
function jobitemEditor:countMatched(job_item_idx,job_item)
local sum=0
if self.assigned[job_item_idx]==nil then return false end
for k,v in pairs(self.assigned[job_item_idx]) do
sum=sum+v:getTotalDimension()
end
return job_item.quantity<=sum
end
function jobitemEditor:jobValid()
for k,v in pairs(self.job.job_items) do
if not self:countMatched(k,v) then
return false
end
end
return true
end
function jobitemEditor:itemChosen(job_choice,index,choice)
if choice.item==nil then
self.assigned[job_choice.job_item_idx]=nil
else
self.assigned[job_choice.job_item_idx]=self.assigned[job_choice.job_item_idx] or {}
table.insert(self.assigned[job_choice.job_item_idx],choice.item)
if not self:countMatched(job_choice.job_item_idx,job_choice.job_item) then
self:selectJobItem(nil,job_choice)
end
end
self:fill(self.job)
end
function jobitemEditor:selectJobItem(index,choice)
local filtered_items={}
for k,v in pairs(self.itemChoices) do
if (v.text=="<nothing>" or isSuitableItem(choice.job_item,v.item)) and (v.item==nil or not self:isAssigned(v.item)) then
table.insert(filtered_items,v)
end
end
dialog.showListPrompt("Item choice", "Choose item:", nil, filtered_items, self:callback("itemChosen",choice), nil,nil,true) --custom item choice dialog req
end
function jobitemEditor:isAssigned(item)
for k,v in pairs(self.assigned) do
for subid, aitem in pairs(v) do
if aitem.id==item.id then
return true
end
end
end
end
function jobitemEditor:commit()
for job_item_id,v in pairs(self.assigned) do
for sub_id,cur_item in pairs(v) do
self.job.items:insert("#",{new=true,item=cur_item,role=df.job_item_ref.T_role.Reagent,job_item_idx=job_item_id})
end
end
local uncollected = getItemsUncollected(job)
if #uncollected == 0 then
self.job.flags.working=true
else
uncollected[1].is_fetching=1
self.job.flags.fetching=true
end
self:dismiss()
end
function AssignJobItems(args) function AssignJobItems(args)
if settings.df_assign then --use df default logic and hope that it would work if settings.df_assign then --use df default logic and hope that it would work
@ -450,6 +609,16 @@ function AssignJobItems(args)
local its=EnumItems{pos=args.from_pos,unit=args.unit, local its=EnumItems{pos=args.from_pos,unit=args.unit,
inv={[df.unit_inventory_item.T_mode.Hauled]=settings.check_inv,[df.unit_inventory_item.T_mode.Worn]=settings.check_inv, inv={[df.unit_inventory_item.T_mode.Hauled]=settings.check_inv,[df.unit_inventory_item.T_mode.Worn]=settings.check_inv,
[df.unit_inventory_item.T_mode.Weapon]=settings.check_inv,},deep=true} [df.unit_inventory_item.T_mode.Weapon]=settings.check_inv,},deep=true}
--[[ job item editor...
jobitemEditor{job=args.job,items=its}:show()
local ok=job.flags.working or job.flags.fetching
if not ok then
return ok, "Stuff"
else
return ok
end
--]]
-- [=[
--[[while(#job.items>0) do --clear old job items --[[while(#job.items>0) do --clear old job items
job.items[#job.items-1]:delete() job.items[#job.items-1]:delete()
job.items:erase(#job.items-1) job.items:erase(#job.items-1)
@ -496,6 +665,7 @@ function AssignJobItems(args)
--todo set working for workshops if items are present, else set fetching (and at least one item to is_fetching=1) --todo set working for workshops if items are present, else set fetching (and at least one item to is_fetching=1)
--job.flags.working=true --job.flags.working=true
return true return true
--]=]
end end
function AssignJobToBuild(args) function AssignJobToBuild(args)
local bld=dfhack.buildings.findAtTile(args.pos) local bld=dfhack.buildings.findAtTile(args.pos)
@ -554,9 +724,9 @@ function ContinueJob(unit)
end end
actions={ actions={
{"CarveFortification" ,df.job_type.CarveFortification,{IsWall,IsHardMat}}, {"CarveFortification" ,df.job_type.CarveFortification,{IsWall,IsHardMaterial}},
{"DetailWall" ,df.job_type.DetailWall,{IsWall,IsHardMat}}, {"DetailWall" ,df.job_type.DetailWall,{IsWall,IsHardMaterial}},
{"DetailFloor" ,df.job_type.DetailFloor,{IsFloor,IsHardMat}}, {"DetailFloor" ,df.job_type.DetailFloor,{IsFloor,IsHardMaterial,SameSquare}},
--{"CarveTrack" ,df.job_type.CarveTrack}, -- does not work?? --{"CarveTrack" ,df.job_type.CarveTrack}, -- does not work??
{"Dig" ,df.job_type.Dig,{MakePredicateWieldsItem(df.job_skill.MINING),IsWall}}, {"Dig" ,df.job_type.Dig,{MakePredicateWieldsItem(df.job_skill.MINING),IsWall}},
{"CarveUpwardStaircase" ,df.job_type.CarveUpwardStaircase,{MakePredicateWieldsItem(df.job_skill.MINING),IsWall}}, {"CarveUpwardStaircase" ,df.job_type.CarveUpwardStaircase,{MakePredicateWieldsItem(df.job_skill.MINING),IsWall}},
@ -745,8 +915,47 @@ function usetool:openSiegeWindow(building)
require("gui.dialogs").showListPrompt("Engine job choice", "Choose what to do:",COLOR_WHITE,{"Turn","Load","Fire"}, require("gui.dialogs").showListPrompt("Engine job choice", "Choose what to do:",COLOR_WHITE,{"Turn","Load","Fire"},
dfhack.curry(siegeWeaponActionChosen,building)) dfhack.curry(siegeWeaponActionChosen,building))
end end
function usetool:onWorkShopButtonClicked(building,index,choice)
local adv=df.global.world.units.active[0]
if df.interface_button_building_new_jobst:is_instance(choice.button) then
choice.button:click()
if #building.jobs>0 then
local job=building.jobs[#building.jobs-1]
AssignUnitToJob(job,adv,adv.pos)
AssignJobItems{job=job,from_pos=adv.pos,pos=adv.pos,unit=adv}
end
elseif df.interface_button_building_category_selectorst:is_instance(choice.button) or
df.interface_button_building_material_selectorst:is_instance(choice.button) then
choice.button:click()
self:openShopWindowButtoned(building,true)
end
printall(choice)
end
function usetool:openShopWindowButtoned(building,no_reset)
local wui=df.global.ui_sidebar_menus.workshop_job
if not no_reset then
wui:assign{category_id=-1,mat_type=-1,mat_index=-1}
for k,v in pairs(wui.material_category) do
wui.material_category[k]=false
end
end
building:fillSidebarMenu()
local list={}
for id,choice in pairs(wui.choices_visible) do
table.insert(list,{text=utils.call_with_string(choice,"getLabel"),button=choice})
end
if #list ==0 then
self:openShopWindow(building)
return
--qerror("No jobs for this workshop")
end
require("gui.dialogs").showListPrompt("Workshop job choice", "Choose what to make",COLOR_WHITE,list,self:callback("onWorkShopButtonClicked",building)
,nil, nil,true)
end
function usetool:openShopWindow(building) function usetool:openShopWindow(building)
local adv=df.global.world.units.active[0] local adv=df.global.world.units.active[0]
local filter_pile=workshopJobs.getJobs(building:getType(),building:getSubtype(),building:getCustomType()) local filter_pile=workshopJobs.getJobs(building:getType(),building:getSubtype(),building:getCustomType())
if filter_pile then if filter_pile then
local state={unit=adv,from_pos={x=adv.pos.x,y=adv.pos.y, z=adv.pos.z} local state={unit=adv,from_pos={x=adv.pos.x,y=adv.pos.y, z=adv.pos.z}
@ -788,11 +997,11 @@ MODES={
}, },
[df.building_type.Workshop]={ [df.building_type.Workshop]={
name="Workshop menu", name="Workshop menu",
input=usetool.openShopWindow, input=usetool.openShopWindowButtoned,
}, },
[df.building_type.Furnace]={ [df.building_type.Furnace]={
name="Workshop menu", name="Workshop menu",
input=usetool.openShopWindow, input=usetool.openShopWindowButtoned,
}, },
[df.building_type.SiegeEngine]={ [df.building_type.SiegeEngine]={
name="Siege menu", name="Siege menu",
@ -809,7 +1018,7 @@ function usetool:shopMode(enable,mode,building)
end end
function usetool:shopInput(keys) function usetool:shopInput(keys)
if keys[keybinds.workshop.key] then if keys[keybinds.workshop.key] then
self:openShopWindow(self.in_shop) self:openShopWindowButtoned(self.in_shop)
end end
end end
function usetool:fieldInput(keys) function usetool:fieldInput(keys)