Gui for item selection in advfort

develop
Warmist 2014-12-10 00:09:28 +02:00
parent f47565465e
commit 550cddc604
2 changed files with 207 additions and 23 deletions

@ -51,7 +51,7 @@ local utils=require 'utils'
local tile_attrs = df.tiletype.attrs
settings={build_by_items=false,use_worn=false,check_inv=true,teleport_items=true,df_assign=false}
settings={build_by_items=false,use_worn=false,check_inv=false,teleport_items=true,df_assign=false,gui_item_select=false}
function hasValue(tbl,val)
for k,v in pairs(tbl) do
@ -707,48 +707,65 @@ function AssignJobItems(args)
for job_id, trg_job_item in ipairs(job.job_items) do
item_counts[job_id]=trg_job_item.quantity
end
local item_suitability={}
local used_item_id={}
for job_id, trg_job_item in ipairs(job.job_items) do
item_suitability[job_id]={}
for _,cur_item in pairs(its) do
if not used_item_id[cur_item.id] then
local item_suitable,msg=isSuitableItem(trg_job_item,cur_item)
if item_suitable or settings.build_by_items then
table.insert(item_suitability[job_id],cur_item)
end
--[[
if msg then
print(cur_item,msg)
end
]]--
if (item_counts[job_id]>0 and item_suitable) or settings.build_by_items then
--cur_item.flags.in_job=true
job.items:insert("#",{new=true,item=cur_item,role=df.job_item_ref.T_role.Reagent,job_item_idx=job_id})
item_counts[job_id]=item_counts[job_id]-cur_item:getTotalDimension()
--print(string.format("item added, job_item_id=%d, item %s, quantity left=%d",job_id,tostring(cur_item),item_counts[job_id]))
used_item_id[cur_item.id]=true
if not settings.gui_item_select then
if (item_counts[job_id]>0 and item_suitable) or settings.build_by_items then
--cur_item.flags.in_job=true
job.items:insert("#",{new=true,item=cur_item,role=df.job_item_ref.T_role.Reagent,job_item_idx=job_id})
item_counts[job_id]=item_counts[job_id]-cur_item:getTotalDimension()
--print(string.format("item added, job_item_id=%d, item %s, quantity left=%d",job_id,tostring(cur_item),item_counts[job_id]))
used_item_id[cur_item.id]=true
end
end
end
end
end
if settings.gui_item_select then
require('gui.script').start(function()
require('hack.scripts.gui.advfort_items').showItemEditor(job,item_suitability)
end)
if not settings.build_by_items then
for job_id, trg_job_item in ipairs(job.job_items) do
if item_counts[job_id]>0 then
print("Not enough items for this job")
return false, "Not enough items for this job"
else
if not settings.build_by_items then
for job_id, trg_job_item in ipairs(job.job_items) do
if item_counts[job_id]>0 then
print("Not enough items for this job")
return false, "Not enough items for this job"
end
end
end
end
local haul_fix=false
if job.job_type==df.job_type.PlantSeeds then
haul_fix=true
end
if settings.teleport_items and not haul_fix then
local item_mode="teleport"
local item_modes={
[df.job_type.PlantSeeds]="haul",
[df.job_type.ConstructBuilding]="default",
}
item_mode=item_modes[job.job_type]
if settings.teleport_items and item_mode=="teleport" then
putItemsInBuilding(args.building,job.items)
end
local uncollected = getItemsUncollected(job)
if #uncollected == 0 then
job.flags.working=true
if haul_fix then
if item_mode=="haul" then
putItemsInHauling(args.unit,job.items)
end
else
@ -773,7 +790,6 @@ function CheckAndFinishBuilding(args,bld)
if args.job~=nil then
local ok,msg=AssignJobItems(args)
if not ok then
print(msg)
return false,msg
else
AssignUnitToJob(args.job,args.unit,args.from_pos)
@ -1017,6 +1033,7 @@ function siegeWeaponActionChosen(building,actionid)
local ok,msg=makeJob(args)
if not ok then
dfhack.gui.showAnnouncement(msg,5,1)
CancelJob(args.unit)
end
end
end
@ -1051,7 +1068,11 @@ function usetool:onWorkShopButtonClicked(building,index,choice)
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,building=building}
local ok,msg=AssignJobItems{job=job,from_pos=adv.pos,pos=adv.pos,unit=adv,building=building}
if not ok then
dfhack.gui.showAnnouncement(msg,5,1)
CancelJob(adv)
end
end
elseif df.interface_button_building_category_selectorst:is_instance(choice.button) or
df.interface_button_building_material_selectorst:is_instance(choice.button) then
@ -1198,7 +1219,11 @@ function usetool:farmPlot(building)
if not job then
print(msg)
else
print(AssignJobItems(args)) --WHY U NO WORK?
local ok, msg=AssignJobItems(args)
if not ok then
dfhack.gui.showAnnouncement(msg,5,1)
CancelJob(args.unit)
end
end
end
MODES={

@ -0,0 +1,159 @@
local _ENV = mkmodule('hack.scripts.gui.advfort_items')
local gui=require('gui')
local wid=require('gui.widgets')
local gscript=require('gui.script')
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 update_slot_text(slot)
local items=""
for i,v in ipairs(slot.items) do
items=items.." "..dfhack.items.getDescription(v,0)
if i~=#slot.items then
items=items..","
end
end
slot.text=string.format("%02d. Filled(%d/%d):%s",slot.id+1,slot.filled_amount,slot.job_item.quantity,items)
end
--items-> table => key-> id of job.job_items, value-> table => key (num), value => item(ref)
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
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},
},
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=self:callback("can_add"),
on_activate= self:callback("add_item")
},
{
gap=3,
text= ": remove",
key = "CUSTOM_R",
enabled=self:callback("can_remove"),
on_activate= self:callback("remove_item")
},}
},
}
self.assigned={}
self:fill()
end
function jobitemEditor:get_slot()
local idx,choice=self.subviews.itemList:getSelected()
return choice
end
function jobitemEditor:can_add()
local slot=self:get_slot()
return slot.filled_amount<slot.job_item.quantity
end
function jobitemEditor:can_remove()
local slot=self:get_slot()
return #slot.items>0
end
function jobitemEditor:add_item()
local cur_slot=self:get_slot()
local choices={}
table.insert(choices,{text="<no item>"})
for k,v in pairs(cur_slot.choices) do
if not self.assigned[v.id] then
table.insert(choices,{text=dfhack.items.getDescription(v,0),item=v})
end
end
gscript.start(function ()
local _,_2,choice=gscript.showListPrompt("which item?", "Select item", COLOR_WHITE, choices)
if choice ~= nil and choice.item~=nil then
self:add_item_to_slot(cur_slot,choice.item)
end
end
)
end
function jobitemEditor:add_item_to_slot(slot,item)
table.insert(slot.items,item)
slot.filled_amount=slot.filled_amount+item:getTotalDimension()
self.assigned[item.id]=true
update_slot_text(slot)
self.subviews.itemList:setChoices(self.slots)
end
function jobitemEditor:remove_item()
local slot=self:get_slot()
for k,v in pairs(slot.items) do
self.assigned[v.id]=nil
end
slot.items={}
slot.filled_amount=0
update_slot_text(slot)
self.subviews.itemList:setChoices(self.slots)
end
function jobitemEditor:fill()
self.slots={}
for k,v in pairs(self.items) do
table.insert(self.slots,{job_item=self.job.job_items[k], id=k, items={},choices=v,filled_amount=0,slot_id=#self.slots})
update_slot_text(self.slots[#self.slots])
end
self.subviews.itemList:setChoices(self.slots)
end
function jobitemEditor:jobValid()
for k,v in pairs(self.slots) do
if v.filled_amount<v.job_item.quantity then
return false
end
end
return true
end
function jobitemEditor:commit()
for _,slot in pairs(self.slots) do
for _1,cur_item in pairs(slot.items) do
self.job.items:insert("#",{new=true,item=cur_item,role=df.job_item_ref.T_role.Reagent,job_item_idx=slot.id})
end
end
self:dismiss()
end
function showItemEditor(job,item_selections)
jobitemEditor{
job = job,
items = item_selections,
on_close = gscript.qresume(nil)
}:show()
return gscript.wait()
end
return _ENV