diff options
Diffstat (limited to 'library/lua/gui/dwarfmode.lua')
| -rw-r--r-- | library/lua/gui/dwarfmode.lua | 132 |
1 files changed, 120 insertions, 12 deletions
diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index c1a8bcb9..661e1559 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -6,6 +6,9 @@ local gui = require('gui') local utils = require('utils') local dscreen = dfhack.screen + +local g_cursor = df.global.cursor +local g_sel_rect = df.global.selection_rect local world_map = df.global.world.map AREA_MAP_WIDTH = 23 @@ -43,8 +46,8 @@ function getPanelLayout() end function getCursorPos() - if df.global.cursor.x ~= -30000 then - return copyall(df.global.cursor) + if g_cursor.x ~= -30000 then + return copyall(g_cursor) end end @@ -56,6 +59,51 @@ function clearCursorPos() df.global.cursor = xyz2pos(nil) end +function getSelection() + local p1, p2 + if g_sel_rect.start_x ~= -30000 then + p1 = xyz2pos(g_sel_rect.start_x, g_sel_rect.start_y, g_sel_rect.start_z) + end + if g_sel_rect.end_x ~= -30000 then + p2 = xyz2pos(g_sel_rect.end_x, g_sel_rect.end_y, g_sel_rect.end_z) + end + return p1, p2 +end + +function setSelectionStart(pos) + g_sel_rect.start_x = pos.x + g_sel_rect.start_y = pos.y + g_sel_rect.start_z = pos.z +end + +function setSelectionEnd(pos) + g_sel_rect.end_x = pos.x + g_sel_rect.end_y = pos.y + g_sel_rect.end_z = pos.z +end + +function clearSelection() + g_sel_rect.start_x = -30000 + g_sel_rect.start_y = -30000 + g_sel_rect.start_z = -30000 + g_sel_rect.end_x = -30000 + g_sel_rect.end_y = -30000 + g_sel_rect.end_z = -30000 +end + +function getSelectionRange(p1, p2) + local r1 = xyz2pos( + math.min(p1.x, p2.x), math.min(p1.y, p2.y), math.min(p1.z, p2.z) + ) + local r2 = xyz2pos( + math.max(p1.x, p2.x), math.max(p1.y, p2.y), math.max(p1.z, p2.z) + ) + local sz = xyz2pos( + r2.x - r1.x + 1, r2.y - r1.y + 1, r2.z - r1.z + 1 + ) + return r1, sz, r2 +end + Viewport = defclass(Viewport) function Viewport.make(map,x,y,z) @@ -88,6 +136,14 @@ function Viewport:set() return vp end +function Viewport:getPos() + return xyz2pos(self.x1, self.y1, self.z) +end + +function Viewport:getSize() + return xy2pos(self.width, self.height) +end + function Viewport:clip(x,y,z) return self:make( math.max(0, math.min(x or self.x1, world_map.x_count-self.width)), @@ -111,6 +167,18 @@ function Viewport:isVisible(target,gap) return self:isVisibleXY(target,gap) and target.z == self.z end +function Viewport:tileToScreen(coord) + return xyz2pos(coord.x - self.x1, coord.y - self.y1, coord.z - self.z) +end + +function Viewport:getCenter() + return xyz2pos( + math.floor((self.x2+self.x1)/2), + math.floor((self.y2+self.y1)/2), + self.z + ) +end + function Viewport:centerOn(target) return self:clip( target.x - math.floor(self.width/2), @@ -159,16 +227,24 @@ MOVEMENT_KEYS = { CURSOR_UP_Z_AUX = { 0, 0, 1 }, CURSOR_DOWN_Z_AUX = { 0, 0, -1 }, } -function Viewport:scrollByKey(key) +local function get_movement_delta(key, delta, big_step) local info = MOVEMENT_KEYS[key] if info then - local delta = 10 - if info[4] then delta = 20 end + if info[4] then + delta = big_step + end + return delta*info[1], delta*info[2], info[3] + end +end + +function Viewport:scrollByKey(key) + local dx, dy, dz = get_movement_delta(key, 10, 20) + if dx then return self:clip( - self.x1 + delta*info[1], - self.y1 + delta*info[2], - self.z + info[3] + self.x1 + dx, + self.y1 + dy, + self.z + dz ) else return self @@ -189,16 +265,23 @@ function DwarfOverlay:getViewport(old_vp) end end -function DwarfOverlay:moveCursorTo(cursor,viewport) +function DwarfOverlay:moveCursorTo(cursor,viewport,gap) setCursorPos(cursor) - self:getViewport(viewport):reveal(cursor, 5, 0, 10):set() + self:zoomViewportTo(cursor,viewport,gap) end -function DwarfOverlay:selectBuilding(building,cursor,viewport) +function DwarfOverlay:zoomViewportTo(target, viewport, gap) + if gap and self:getViewport():isVisible(target, gap) then + return + end + self:getViewport(viewport):reveal(target, 5, 0, 10):set() +end + +function DwarfOverlay:selectBuilding(building,cursor,viewport,gap) cursor = cursor or utils.getBuildingCenter(building) df.global.world.selected_building = building - self:moveCursorTo(cursor, viewport) + self:moveCursorTo(cursor, viewport, gap) end function DwarfOverlay:propagateMoveKeys(keys) @@ -234,6 +317,31 @@ function DwarfOverlay:simulateViewScroll(keys, anchor, no_clip_cursor) end end +function DwarfOverlay:simulateCursorMovement(keys, anchor) + local layout = self.df_layout + local cursor = getCursorPos() + local cx, cy, cz = pos2xyz(cursor) + + if anchor and keys.A_MOVE_SAME_SQUARE then + setCursorPos(anchor) + self:getViewport():centerOn(anchor):set() + return 'A_MOVE_SAME_SQUARE' + end + + for code,_ in pairs(MOVEMENT_KEYS) do + if 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 + end + end +end + function DwarfOverlay:onAboutToShow(below) local screen = dfhack.gui.getCurViewscreen() if below then screen = below.parent end |
