Merge remote-tracking branch 'eswald/stockflow-43' into develop

develop
lethosor 2016-05-16 20:40:50 -04:00
commit a8f9f912c9
2 changed files with 94 additions and 28 deletions

@ -128,10 +128,6 @@ keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path
# workshop job details # workshop job details
keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job 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
keybinding add Alt-W@overallstatus "gui/workflow status"
# autobutcher front-end # autobutcher front-end
keybinding add Shift-B@pet/List/Unit "gui/autobutcher" keybinding add Shift-B@pet/List/Unit "gui/autobutcher"
@ -220,7 +216,6 @@ enable \
zone \ zone \
stocks \ stocks \
autochop \ autochop \
stockflow \
stockpiles stockpiles
#end a line with a backslash to make it continue to the next line. The \ is deleted for the final command. #end a line with a backslash to make it continue to the next line. The \ is deleted for the final command.
# Multiline commands are ONLY supported for scripts like dfhack.init. You cannot do multiline command manually on the DFHack console. # Multiline commands are ONLY supported for scripts like dfhack.init. You cannot do multiline command manually on the DFHack console.

@ -24,9 +24,9 @@ entry_ints = {
trigger_number = 3, trigger_number = 3,
} }
PageSize = 16 FirstRow = 3
FirstRow = 4
CenterCol = 38 CenterCol = 38
ExtraLines = 9
-- Populate the reaction and stockpile order lists. -- Populate the reaction and stockpile order lists.
-- To be called whenever a world is loaded. -- To be called whenever a world is loaded.
@ -797,10 +797,30 @@ screen = gui.FramedScreen {
function screen:onRenderBody(dc) function screen:onRenderBody(dc)
-- Emulates the built-in manager screen. -- Emulates the built-in manager screen.
if not (self.page_size == self.frame_rect.height - ExtraLines) then
-- The screen size has changed.
self:refilter()
end
-- Top instruction line.
dc:seek(1, 1):string("Type in parts of the name to narrow your search. ", COLOR_WHITE) dc:seek(1, 1):string("Type in parts of the name to narrow your search. ", COLOR_WHITE)
dc:string(gui.getKeyDisplay("LEAVESCREEN"), COLOR_LIGHTGREEN) dc:key("LEAVESCREEN"):string(" to abort.", COLOR_WHITE)
dc:string(" to abort.", COLOR_WHITE)
dc:seek(1, PageSize + 5):string(self.search_string, COLOR_LIGHTCYAN) -- Search term, if any.
dc:seek(1, FirstRow + self.page_size + 1):string(self.search_string, COLOR_LIGHTCYAN)
-- Bottom instruction line.
dc:seek(1, FirstRow + self.page_size + 2)
dc:key("STANDARDSCROLL_UP"):key("STANDARDSCROLL_DOWN")
dc:key("STANDARDSCROLL_PAGEUP"):key("STANDARDSCROLL_PAGEDOWN")
dc:key("STANDARDSCROLL_LEFT"):key("STANDARDSCROLL_RIGHT")
dc:string(": Select", COLOR_WHITE)
dc:seek(CenterCol, FirstRow + self.page_size + 2)
dc:key("SETUPGAME_SAVE_PROFILE_ABORT"):string(": No order", COLOR_WHITE)
-- Reaction lines.
for _, item in ipairs(self.displayed) do for _, item in ipairs(self.displayed) do
dc:seek(item.x, item.y):string(item.name, item.color) dc:seek(item.x, item.y):string(item.name, item.color)
end end
@ -815,28 +835,69 @@ function screen:onInput(keys)
if selected then if selected then
store_order(self.stockpile, selected.index) store_order(self.stockpile, selected.index)
end end
elseif keys.SETUPGAME_SAVE_PROFILE_ABORT then
self:dismiss()
clear_order(self.stockpile)
elseif keys.STANDARDSCROLL_UP then elseif keys.STANDARDSCROLL_UP then
self.position = self.position - 1 self.position = self.position - 1
elseif keys.STANDARDSCROLL_DOWN then elseif keys.STANDARDSCROLL_DOWN then
self.position = self.position + 1 self.position = self.position + 1
elseif keys.STANDARDSCROLL_LEFT then elseif keys.STANDARDSCROLL_LEFT then
self.position = self.position - PageSize if self.position == 1 then
-- Move from the very first item to the very last item.
self.position = #self.reactions
elseif self.position < self.page_size then
-- On the first column, move to the very first item.
self.position = 1
else
-- Move to the same position on the previous column.
self.position = self.position - self.page_size
end
elseif keys.STANDARDSCROLL_RIGHT then elseif keys.STANDARDSCROLL_RIGHT then
self.position = self.position + PageSize if self.position == #self.reactions then
-- Move from the very last item to the very first item.
self.position = 1
else
-- Move to the same position on the next column.
self.position = self.position + self.page_size
if self.position > #self.reactions then
-- If that's past the end, move to the very last item.
self.position = #self.reactions
end
end
elseif keys.STANDARDSCROLL_PAGEUP then elseif keys.STANDARDSCROLL_PAGEUP then
-- Moves to the first item displayed on the new page, for some reason. if self.position == 1 then
self.position = self.position - PageSize*2 - ((self.position-1) % (PageSize*2)) -- Move from the very first item to the very last item.
self.position = #self.reactions
elseif self.position < self.page_size*2 then
-- On the first page, move to the very first item.
self.position = 1
else
-- Move to the same position on the previous page.
self.position = self.position - self.page_size*2
end
elseif keys.STANDARDSCROLL_PAGEDOWN then elseif keys.STANDARDSCROLL_PAGEDOWN then
-- Moves to the first item displayed on the new page, for some reason. if self.position == #self.reactions then
self.position = self.position + PageSize*2 - ((self.position-1) % (PageSize*2)) -- Move from the very last item to the very first item.
self.position = 1
else
-- Move to the same position on the next page.
self.position = self.position + self.page_size*2
if self.position > #self.reactions then
-- If that's past the end, move to the very last item.
self.position = #self.reactions
end
end
elseif keys.STRING_A000 then elseif keys.STRING_A000 then
-- This seems like an odd way to check for Backspace. -- This seems like an odd way to check for Backspace.
self.search_string = string.sub(self.search_string, 1, -2) self.search_string = string.sub(self.search_string, 1, -2)
self.position = 1
elseif keys._STRING and keys._STRING >= 32 then elseif keys._STRING and keys._STRING >= 32 then
-- This interface only accepts letters and spaces. -- This interface only accepts letters and spaces.
local char = string.char(keys._STRING) local char = string.char(keys._STRING)
if char == " " or string.find(char, "^%a") then if char == " " or string.find(char, "^%a") then
self.search_string = self.search_string .. string.upper(char) self.search_string = self.search_string .. string.upper(char)
self.position = 1
end end
end end
@ -886,6 +947,13 @@ function splitstring(full, pattern)
end end
function screen:refilter() function screen:refilter()
-- Determine which rows to show, and in which colors.
-- Todo: The official one now has three categories of search results:
-- * Cyan: Contains at least one exact word from the search terms
-- * Yellow: At least one word starts with at least one search term
-- * Grey: Each search term is found in the middle of a word
self.page_size = self.frame_rect.height - ExtraLines
local filtered = {} local filtered = {}
local needles = splitstring(self.search_string, " ") local needles = splitstring(self.search_string, " ")
for key, value in ipairs(reaction_list) do for key, value in ipairs(reaction_list) do
@ -904,12 +972,12 @@ function screen:refilter()
end end
local start = 1 local start = 1
while self.position >= start + PageSize*2 do while self.position >= start + self.page_size*2 do
start = start + PageSize*2 start = start + self.page_size*2
end end
local displayed = {} local displayed = {}
for n = 0, PageSize*2 - 1 do for n = 0, self.page_size*2 - 1 do
local item = filtered[start + n] local item = filtered[start + n]
if not item then if not item then
break break
@ -918,9 +986,9 @@ function screen:refilter()
local x = 1 local x = 1
local y = FirstRow + n local y = FirstRow + n
if n >= PageSize then if n >= self.page_size then
x = CenterCol x = CenterCol
y = y - PageSize y = y - self.page_size
name = " "..name name = " "..name
end end
@ -941,6 +1009,14 @@ function screen:refilter()
self.displayed = displayed self.displayed = displayed
end end
function clear_order(stockpile)
local saved = saved_orders[stockpile.id]
if saved then
saved.entry:delete()
saved_orders[stockpile.id] = nil
end
end
function store_order(stockpile, order_number) function store_order(stockpile, order_number)
local name = reaction_list[order_number].name local name = reaction_list[order_number].name
-- print("Setting stockpile #"..stockpile.stockpile_number.." to "..name.." (#"..order_number..")") -- print("Setting stockpile #"..stockpile.stockpile_number.." to "..name.." (#"..order_number..")")
@ -1011,12 +1087,6 @@ function order_quantity(order, quantity)
end end
end end
if amount > 30 then
-- Respect the quantity limit.
-- With this many in the queue, we can wait for the next cycle.
return 30
end
return amount return amount
end end
@ -1026,7 +1096,8 @@ function create_orders(order, amount)
new_order.amount_left = amount new_order.amount_left = amount
new_order.amount_total = amount new_order.amount_total = amount
-- Todo: Create in a validated state if the fortress is small enough? -- Todo: Create in a validated state if the fortress is small enough?
new_order.is_validated = 0 new_order.status.validated = false
new_order.status.active = false
df.global.world.manager_orders:insert('#', new_order) df.global.world.manager_orders:insert('#', new_order)
end end