User:Fleeting Frames/zoomToStop

From Dwarf Fortress Wiki
Jump to navigation Jump to search

Save as zoomToStop.lua in /hack/scripts, enable by adding zoomToStop bind to onLoad.init and running zoomToStop patch once to get hotkey reminder display.


--zooms to selected minecart hauling route stop
local args = {...}
local helptext= [[
zoomToStop
==========

Lua script and indicator widget for zooming to selecter hauling route stop or cart.

Possible arguments:

bind - adds z/c hotkeys to zoom to selected route stop/cart in minecart route UI.

unbind - removes aforementioned

patch - patches dwarfmode.lua and dwarfmode.json, then disables-enables dwarfmonitor.

cart - zooms to selected cart

no arguments - zooms to selected stop]]

if args and args[1] and 
    (args[1]:find("help") or args[1]:find("?")) then
    dfhack.println(helptext)
    return
end

if not moduleMode then


function zoom(pos)
    if not pos or pos.x < 0 then return false end
    df.global.cursor:assign(pos)
    dfhack.timeout(3, "frames", function() dfhack.gui.refreshSidebar() end)
    return true
end

function zoomToTarget(ToCart)

  if not (df.global.ui.hauling.in_stop or df.global.ui.hauling.in_advanced_cond or df.global.ui.hauling.in_assign_vehicle or df.global.ui.hauling.in_name) then
    --In stop
  local cur_stop = df.global.ui.hauling.view_stops[df.global.ui.hauling.cursor_top]
    if cur_stop then
      if not ToCart then
        return zoom(xyz2pos(pos2xyz(cur_stop.pos)))
      else
        if cur_stop.cart_id > -1 then
            local cart = df.item.find(cur_stop.cart_id)
            if cart then
                return zoom(xyz2pos(dfhack.items.getPosition(cart)))
            end
        else
            local cur_route = df.global.ui.hauling.view_routes[df.global.ui.hauling.cursor_top]
            if #cur_route.vehicle_ids > 0 then
                for i, tool in pairs(df.global.world.items.other.TOOL) do
                    if tool.vehicle_id == cur_route.vehicle_ids[0] then
                        return zoom(xyz2pos(dfhack.items.getPosition(tool)))
                    end
                end
            end
        end
      end
    end
  end
end

local function patchdwarmonitor(widget_table, widget_str)
    --injects a widget table and widget str into dwarfmonitor.json and dwarfmonitor.lua
    --returns true if injection successful or done before
    if not (widget_table or widget_str or widget_table.type) then qerror ("Inappropriate params to pathdwarfmode") end
    local dmPath = dfhack.getDFPath() .. "/hack/lua/plugins/dwarfmonitor.lua"
    local json = require('json')
    local dmJson = json.decode_file('dfhack-config/dwarfmonitor.json')
    for i, widget in pairs(dmJson.widgets) do if widget.type == widget_table.type then return true end end
    table.insert(dmJson.widgets,widget_table)
    json.encode_file(dmJson,'dfhack-config/dwarfmonitor.json')
    local dmFile, err = io.open(dmPath, "r")
    if err then return false end
    local lines = dmFile:read("*a")
    local insertpoint = "\nreturn _ENV"
    if lines:find(widget_str) then return true end
    lines = lines:gsub(insertpoint, widget_str .. insertpoint)
    dmFile:close()
    dmFile, err = io.open(dmPath, "w")
    if err then return false end
    dmFile:write(lines)
    dmFile:flush()
    dmFile:close()
    return true
end

local zoomWidgetTable = {--need to have a way to add/update with individual indis
    ['type'] = "zoomtostop",
    ['x'] = -3,
    ['y'] = -3,
    ['anchor'] = "right"
}

local widget_str = "pcall(function() Widget_zoomtostop = dfhack.script_environment('zoomToStop').Widget_zoomtostop end)"

if args and args[1] then 
    if args[1] == "cart" then zoomToTarget(true) print("zoomed to cart")
    elseif args[1] == "unbind" then
        dfhack.run_command("keybinding clear Z@dwarfmode/Hauling/Select/Stop")
        dfhack.run_command("keybinding clear C@dwarfmode/Hauling/Select/Stop")
    elseif args[1] == "bind" then
        dfhack.run_command("keybinding add Z@dwarfmode/Hauling/Select/Stop zoomToStop")
        dfhack.run_command("keybinding add C@dwarfmode/Hauling/Select/Stop zoomToStop cart")
    elseif args[1] == "patch" then
        if patchdwarmonitor(zoomWidgetTable, widget_str) then
            dfhack.timeout(10, "frames", function()
                dfhack.run_command("disable dwarfmonitor")
                dfhack.timeout(10, "frames", function()
                    dfhack.run_command("enable dwarfmonitor")
                    dfhack.println("Patched dwarfmonitor for zoomToStop")
                end)
            end)
        else
            dfhack.println("Failed to patch dwarfmonitor")
        end
    end
else
    zoomToTarget()
end

end

--widget section

if moduleMode then
local gps = df.global.gps
local gui = require 'gui'
local dwarfmonitor = require('plugins.dwarfmonitor')

local pstringt = {}
local spos

Widget_zoomtostop = defclass(Widget_zoomtostop, dwarfmonitor.Widget)

function Widget_zoomtostop:update()
  if not (df.global.ui.hauling.in_stop or df.global.ui.hauling.in_advanced_cond or df.global.ui.hauling.in_assign_vehicle or df.global.ui.hauling.in_name) and
     df.global.ui.main.mode == 52 --hauling
     then
      self.output = "zc to zoom"
  else
      self.output = ""
  end
end

function Widget_zoomtostop:get_width()    return #self.output end

function Widget_zoomtostop:render_body(p)
    p:string(self.output, COLOR_GREY)
end

end