summaryrefslogtreecommitdiff
path: root/library/lua/gui/dwarfmode.lua
diff options
context:
space:
mode:
Diffstat (limited to 'library/lua/gui/dwarfmode.lua')
-rw-r--r--library/lua/gui/dwarfmode.lua132
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