v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

User:Fleeting Frames/selectSquads

From Dwarf Fortress Wiki
Jump to navigation Jump to search

Save as selectSquads.lua into /hack/scripts folder. Call by typing selectSquads or selectSquads R in dfhack console while having base squad menu open.

--Utility script for quickly selecting metal weapon or bolts combatants.
--ver 1.00

if df.global.ui.main.mode ~= 1 or
    df.global.ui.squads.in_move_order or
    df.global.ui.squads.in_kill_order or
    df.global.ui.squads.in_kill_rect or
    df.global.ui.squads.sel_indiv_squad ~= -1
then qerror("Need to be in base squad select menu") end

local args = {...}

local prevSelectIndiv = df.global.ui.squads.in_select_indiv

df.global.ui.squads.in_select_indiv = true

local function repeatfunction(rfunc)
    --repeats a function every frame, until the function returns false or nil
    local myrfunc
    
    myrfunc = function ()
      timeoutid = dfhack.timeout(1, "frames", function(options)
        if rfunc() then myrfunc() end
       end)
    end
    
    myrfunc()
end

--AutomagicTables from lua wiki by ThomasWrensch and RiciLake, copied wholesale
do 
  local auto, assign

  function auto(tab, key)
    return setmetatable({}, {
            __index = auto,
            __newindex = assign,
            parent = tab,
            key = key
    })
  end

  local meta = {__index = auto}

  -- The if statement below prevents the table from being
  -- created if the value assigned is nil. This is, I think,
  -- technically correct but it might be desirable to use
  -- assignment to nil to force a table into existence.

  function assign(tab, key, val)
  if val ~= nil then
    local oldmt = getmetatable(tab)
    oldmt.parent[oldmt.key] = tab
    setmetatable(tab, meta)
    tab[key] = val
  end
  end

  function AutomagicTable()
    return setmetatable({}, meta)
  end
end

local metalt=AutomagicTable()

for i,squad in ipairs(df.global.ui.squads.list) do 
    for j, squaddie in ipairs(squad.positions) do 
        local notset = true 
        for k,item_id in pairs(squaddie.assigned_items) do 
            if notset and df.item.find(item_id)._type == df.item_weaponst then 
                if df.item.find(item_id).mat_type == 0 then 
                    --print(dfhack.TranslateName(df.historical_figure.find(squaddie.occupant).name))
                    metalt[i+1][j+1]=true
                    notset=false
                end
            end
        end
    end
end

local rangedt = AutomagicTable()

for i,squad in ipairs(df.global.ui.squads.list) do 
    for j, squaddie in ipairs(squad.positions) do 
        local notset = true
        local crossbow = false
        local metalbolts = false
        for k,item_id in pairs(squaddie.assigned_items) do 
            if notset and df.item.find(item_id)._type == df.item_weaponst and df.item.find(item_id).subtype.skill_ranged ~= -1 then
                crossbow = true
            end
            if notset and df.item.find(item_id)._type == df.item_quiverst then
                for m, ammunition in pairs(df.item.find(item_id).general_refs) do
                    if ammunition._type == df.general_ref_contains_itemst and df.item.find(ammunition.item_id).mat_type == 0 then 
                        metalbolts = true
                    end
                end
            end
            if notset and crossbow and metalbolts then 
                rangedt[i+1][j+1]=true
                --print(dfhack.TranslateName(df.historical_figure.find(squaddie.occupant).name))
                notset = false
                crossbow = false
                metalbolts = false
            end
        end
    end
end

local indexkey = {
'OPTION1',
'OPTION2',
'OPTION3',
'OPTION4',
'OPTION5',
'OPTION6',
'OPTION7',
'OPTION8',
'OPTION9',
'OPTION10'
}

local unitindexkey = {
'SEC_OPTION1',
'SEC_OPTION2',
'SEC_OPTION3',
'SEC_OPTION4',
'SEC_OPTION5',
'SEC_OPTION6',
'SEC_OPTION7',
'SEC_OPTION8',
'SEC_OPTION9',
'SEC_OPTION10'
}

local inputlist, tin = {}, table.insert

local targett=metalt
if args and #args>0 and args[1]=="R" then targett=rangedt end

for index,squad in pairs(targett) do
    tin(inputlist,{[indexkey[index]]=true})
    for unitindex,_ in pairs(squad) do
        tin(inputlist, {[unitindexkey[unitindex]]=true})
    end
    tin(inputlist,{['LEAVESCREEN']=true})
end

local guiSim = curry((require 'gui').simulateInput, df.global.gview.view.child)

dfhack.timeout((1+#inputlist), "frames", function() df.global.ui.squads.in_select_indiv = prevSelectIndiv end)

repeatfunction(function() local tr=table.remove(inputlist,1) if tr then guiSim(tr) return true end end)