diff --git a/dfhack.init-example b/dfhack.init-example index 239d68a0f..27801b73d 100644 --- a/dfhack.init-example +++ b/dfhack.init-example @@ -76,7 +76,7 @@ keybinding add Ctrl-W@layer_military/Equip/Customize/View gui/choose-weapons keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path # 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 ############################ # UI and game logic tweaks # diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index 0c1b0599c..cef52ae24 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -238,6 +238,19 @@ local function get_movement_delta(key, delta, big_step) end end +HOTKEY_KEYS = {} + +for i,v in ipairs(df.global.ui.main.hotkeys) do + HOTKEY_KEYS['D_HOTKEY'..(i+1)] = v +end + +local function get_hotkey_target(key) + local hk = HOTKEY_KEYS[key] + if hk and hk.cmd == df.ui_hotkey.T_cmd.Zoom then + return xyz2pos(hk.x, hk.y, hk.z) + end +end + function Viewport:scrollByKey(key) local dx, dy, dz = get_movement_delta(key, 10, 20) if dx then @@ -247,7 +260,12 @@ function Viewport:scrollByKey(key) self.z + dz ) else - return self + local hk_pos = get_hotkey_target(key) + if hk_pos then + return self:centerOn(hk_pos) + else + return self + end end end @@ -286,9 +304,11 @@ function DwarfOverlay:selectBuilding(building,cursor,viewport,gap) end function DwarfOverlay:propagateMoveKeys(keys) - for code,_ in pairs(MOVEMENT_KEYS) do - if keys[code] then - self:sendInputToParent(code) + for code,_ in pairs(keys) do + if MOVEMENT_KEYS[code] or HOTKEY_KEYS[code] then + if not HOTKEY_KEYS[code] or get_hotkey_target(code) then + self:sendInputToParent(code) + end return code end end @@ -305,8 +325,8 @@ function DwarfOverlay:simulateViewScroll(keys, anchor, no_clip_cursor) return 'A_MOVE_SAME_SQUARE' end - for code,_ in pairs(MOVEMENT_KEYS) do - if keys[code] then + for code,_ in pairs(keys) do + if MOVEMENT_KEYS[code] or HOTKEY_KEYS[code] then local vp = self:getViewport():scrollByKey(code) if (cursor and not no_clip_cursor) or no_clip_cursor == false then vp = vp:reveal(anchor,4,20,4,true) @@ -329,16 +349,26 @@ function DwarfOverlay:simulateCursorMovement(keys, anchor) return 'A_MOVE_SAME_SQUARE' end - for code,_ in pairs(MOVEMENT_KEYS) do - if keys[code] then + for code,_ in pairs(keys) do + if MOVEMENT_KEYS[code] then local dx, dy, dz = get_movement_delta(code, 1, 10) local ncur = xyz2pos(cx+dx, cy+dy, cz+dz) if dfhack.maps.isValidTilePos(ncur) then setCursorPos(ncur) self:getViewport():reveal(ncur,4,10,6,true):set() - return code end + + return code + elseif HOTKEY_KEYS[code] then + local pos = get_hotkey_target(code) + + if pos and dfhack.maps.isValidTilePos(pos) then + setCursorPos(pos) + self:getViewport():centerOn(pos):set() + end + + return code end end end diff --git a/scripts/gui/workshop-job.lua b/scripts/gui/workshop-job.lua index 973d5cc17..74e33595f 100644 --- a/scripts/gui/workshop-job.lua +++ b/scripts/gui/workshop-job.lua @@ -18,12 +18,14 @@ JobDetails.ATTRS { } function JobDetails:init(args) + self.building = dfhack.job.getHolder(self.job) + local status = { text = 'No worker', pen = COLOR_DARKGREY } local worker = dfhack.job.getWorker(self.job) if self.job.flags.suspend then status = { text = 'Suspended', pen = COLOR_RED } elseif worker then - status = { text = dfhack.TranslateName(dfhack.unit.getVisibleName(worker)), pen = COLOR_GREEN } + status = { text = dfhack.TranslateName(dfhack.units.getVisibleName(worker)), pen = COLOR_GREEN } end self:addviews{ @@ -63,6 +65,14 @@ function JobDetails:init(args) self:initListChoices() end +function JobDetails:onGetSelectedBuilding() + return self.building +end + +function JobDetails:onGetSelectedJob() + return self.job +end + function describe_item_type(iobj) local itemline = 'any item' if iobj.item_type >= 0 then @@ -79,10 +89,7 @@ function describe_item_type(iobj) end function is_caste_mat(iobj) - if iobj.item_type >= 0 then - return df.item_type.attrs[iobj.item_type].is_caste_mat - end - return false + return dfhack.items.isCasteMaterial(iobj.item_type) end function describe_material(iobj) @@ -119,7 +126,7 @@ function JobDetails:initListChoices() local choices = {} for i,iobj in ipairs(self.job.job_items) do - local head = 'Item '..(i+1)..': '..(items[idx] or 0)..' of '..iobj.quantity + local head = 'Item '..(i+1)..': '..(items[i] or 0)..' of '..iobj.quantity if iobj.min_dimension > 0 then head = head .. '(size '..iobj.min_dimension..')' end @@ -175,16 +182,22 @@ function JobDetails:canChangeIType() return obj ~= nil end +function JobDetails:setItemType(obj, item_type, item_subtype) + obj.iobj.item_type = item_type + obj.iobj.item_subtype = item_subtype + + if is_caste_mat(obj.iobj) then + self:setMaterial(obj, -1, -1) + end +end + function JobDetails:onChangeIType() local idx, obj = self.subviews.list:getSelected() guimat.ItemTypeDialog{ prompt = 'Please select a new item type for input '..idx, none_caption = 'any item', item_filter = curry(dfhack.job.isSuitableItem, obj.iobj), - on_select = function(item_type, item_subtype) - obj.iobj.item_type = item_type - obj.iobj.item_subtype = item_subtype - end + on_select = self:callback('setItemType', obj) }:show() end @@ -193,6 +206,20 @@ function JobDetails:canChangeMat() return obj ~= nil and not is_caste_mat(obj.iobj) end +function JobDetails:setMaterial(obj, mat_type, mat_index) + if obj.index == 0 + and self.job.mat_type == obj.iobj.mat_type + and self.job.mat_index == obj.iobj.mat_index + and self.job.job_type ~= df.job_type.PrepareMeal + then + self.job.mat_type = mat_type + self.job.mat_index = mat_index + end + + obj.iobj.mat_type = mat_type + obj.iobj.mat_index = mat_index +end + function JobDetails:onChangeMat() local idx, obj = self.subviews.list:getSelected() @@ -213,20 +240,18 @@ function JobDetails:onChangeMat() mat_filter = function(mat,parent,mat_type,mat_index) return dfhack.job.isSuitableMaterial(obj.iobj, mat_type, mat_index) end, - on_select = function(mat_type, mat_index) - if idx == 1 - and self.job.mat_type == obj.iobj.mat_type - and self.job.mat_index == obj.iobj.mat_index - and self.job.job_type ~= df.job_type.PrepareMeal - then - self.job.mat_type = mat_type - self.job.mat_index = mat_index - end + on_select = self:callback('setMaterial', obj) + }:show() +end - obj.iobj.mat_type = mat_type - obj.iobj.mat_index = mat_index +function JobDetails:onInput(keys) + if self:propagateMoveKeys(keys) then + if df.global.world.selected_building ~= self.building then + self:dismiss() end - }:show() + else + JobDetails.super.onInput(self, keys) + end end if not string.match(dfhack.gui.getCurFocus(), '^dwarfmode/QueryBuilding/Some/Workshop/Job') then