2012-11-28 17:26:10 -07:00
-- allows to do jobs in adv. mode.
local gui = require ' gui '
local wid = require ' gui.widgets '
local dialog = require ' gui.dialogs '
local buildings = require ' dfhack.buildings '
--[[**********************
tools and their uses :
1. axe -> chop trees
2. pickaxe -> dig , carve floors / ramps / stairs / etc ( engrave too for now )
--]]
mode = mode or 0
keybinds = {
key_next = { key = " CUSTOM_SHIFT_T " , desc = " Next job in the list " } ,
key_prev = { key = " CUSTOM_SHIFT_R " , desc = " Previous job in the list " } ,
key_continue = { key = " A_WAIT " , desc = " Continue job if available " } ,
--key_down_alt1={key="A_CUSTOM_CTRL_D",desc="Use job down"},--does not work?
key_down_alt2 = { key = " CURSOR_DOWN_Z_AUX " , desc = " Use job down " } ,
--key_up_alt1={key="A_CUSTOM_CTRL_E",desc="Use job up"}, --does not work?
key_up_alt2 = { key = " CURSOR_UP_Z_AUX " , desc = " Use job up " } ,
key_use_same = { key = " A_MOVE_SAME_SQUARE " , desc = " Use job at the tile you are standing " } ,
}
function Disclaimer ( tlb )
local dsc = { " The Gathering Against " , { text = " Goblin " , pen = dfhack.pen . parse { fg = COLOR_GREEN , bg = 0 } } , " Oppresion " ,
" (TGAGO) is not responsible for all " , NEWLINE , " the damage that this tool can (and will) cause to you and your loved worlds " , NEWLINE , " and/or sanity.Please use with caution. " , NEWLINE , { text = " Magma not included. " , pen = dfhack.pen . parse { fg = COLOR_LIGHTRED , bg = 0 } } }
if tlb then
for _ , v in ipairs ( dsc ) do
table.insert ( tlb , v )
end
end
return dsc
end
function showHelp ( )
local helptext = {
" This tool allow you to perform jobs as a dwarf would in dwarf mode. When " , NEWLINE ,
" cursor is available you can press " , { key = " SELECT " , text = " select " , key_sep = " () " } ,
" to enqueue a job from " , NEWLINE , " pointer location. If job is 'Build' and there is no planed construction " , NEWLINE ,
" at cursor this tool show possible building choices. " , NEWLINE , NEWLINE , { text = " Keybindings: " , pen = dfhack.pen . parse { fg = COLOR_CYAN , bg = 0 } } , NEWLINE
}
for k , v in pairs ( keybinds ) do
table.insert ( helptext , { key = v.key , text = v.desc , key_sep = " : " } )
table.insert ( helptext , NEWLINE )
end
table.insert ( helptext , { text = " CAREFULL MOVE " , pen = dfhack.pen . parse { fg = COLOR_LIGHTGREEN , bg = 0 } } )
table.insert ( helptext , " : use job in that direction " )
table.insert ( helptext , NEWLINE )
table.insert ( helptext , NEWLINE )
Disclaimer ( helptext )
require ( " gui.dialogs " ) . showMessage ( " Help!?! " , helptext )
end
function getLastJobLink ( )
local st = df.global . world.job_list
while st.next ~= nil do
st = st.next
end
return st
end
function AddNewJob ( job )
local nn = getLastJobLink ( )
local nl = df.job_list_link : new ( )
nl.prev = nn
nn.next = nl
nl.item = job
job.list_link = nl
end
function MakeJob ( unit , pos , job_type , unit_pos , post_actions )
local nj = df.job : new ( )
nj.id = df.global . job_next_id
df.global . job_next_id = df.global . job_next_id + 1
--nj.flags.special=true
nj.job_type = job_type
nj.completion_timer =- 1
--nj.unk4a=12
--nj.unk4b=0
nj.pos : assign ( pos )
AssignUnitToJob ( nj , unit , unit_pos )
for k , v in ipairs ( post_actions or { } ) do
v { job = nj , pos = pos , old_pos = unit_pos , unit = unit }
end
AddNewJob ( nj )
return nj
end
function AssignUnitToJob ( job , unit , unit_pos )
job.general_refs : insert ( " # " , { new = df.general_ref_unit_workerst , unit_id = unit.id } )
unit.job . current_job = job
unit_pos = unit_pos or { x = job.pos . x , y = job.pos . y , z = job.pos . z }
unit.path . dest : assign ( unit_pos )
end
function SetCreatureRef ( args )
local job = args.job
local pos = args.pos
for k , v in pairs ( df.global . world.units . active ) do
if v.pos . x == pos.x and v.pos . y == pos.y and v.pos . z == pos.z then
job.general_refs : insert ( " # " , { new = df.general_ref_unit_cageest , unit_id = v.id } )
return
end
end
end
function SetPatientRef ( args )
local job = args.job
local pos = args.pos
for k , v in pairs ( df.global . world.units . active ) do
if v.pos . x == pos.x and v.pos . y == pos.y and v.pos . z == pos.z then
job.general_refs : insert ( " # " , { new = df.general_ref_unit_patientst , unit_id = v.id } )
return
end
end
end
function MakePredicateWieldsItem ( item_skill )
local pred = function ( args )
local inv = args.unit . inventory
for k , v in pairs ( inv ) do
if v.mode == 1 and df.item_weaponst : is_instance ( v.item ) then
if v.item . subtype.skill_melee == item_skill then --and unit.body.weapon_bp==v.body_part_id
return true
end
end
end
return false , " Correct tool not equiped "
end
return pred
end
function makeset ( args )
local tbl = { }
for k , v in pairs ( args ) do
tbl [ v ] = true
end
return tbl
end
function IsConstruct ( args )
local tt = dfhack.maps . getTileType ( args.pos )
local cwalls = makeset { df.tiletype . ConstructedWallRD2 , df.tiletype . ConstructedWallR2D , df.tiletype . ConstructedWallR2U , df.tiletype . ConstructedWallRU2 ,
df.tiletype . ConstructedWallL2U , df.tiletype . ConstructedWallLU2 , df.tiletype . ConstructedWallL2D , df.tiletype . ConstructedWallLD2 ,
df.tiletype . ConstructedWallLRUD , df.tiletype . ConstructedWallRUD , df.tiletype . ConstructedWallLRD , df.tiletype . ConstructedWallLRU ,
df.tiletype . ConstructedWallLUD , df.tiletype . ConstructedWallRD , df.tiletype . ConstructedWallRU , df.tiletype . ConstructedWallLU ,
df.tiletype . ConstructedWallLD , df.tiletype . ConstructedWallUD , df.tiletype . ConstructedWallLR , }
if cwalls [ tt ] or dfhack.buildings . findAtTile ( args.pos ) then
return true
else
return false , " Can only do it on constructions "
end
end
function IsWall ( args )
local tt = dfhack.maps . getTileType ( args.pos )
local walls = makeset { df.tiletype . StoneWallWorn1 , df.tiletype . StoneWallWorn2 , df.tiletype . StoneWallWorn3 , df.tiletype . StoneWall ,
df.tiletype . SoilWall , df.tiletype . LavaWallSmoothRD2 , df.tiletype . LavaWallSmoothR2D , df.tiletype . LavaWallSmoothR2U , df.tiletype . LavaWallSmoothRU2 ,
df.tiletype . LavaWallSmoothL2U , df.tiletype . LavaWallSmoothLU2 , df.tiletype . LavaWallSmoothL2D , df.tiletype . LavaWallSmoothLD2 , df.tiletype . LavaWallSmoothLRUD ,
df.tiletype . LavaWallSmoothRUD , df.tiletype . LavaWallSmoothLRD , df.tiletype . LavaWallSmoothLRU , df.tiletype . LavaWallSmoothLUD , df.tiletype . LavaWallSmoothRD ,
df.tiletype . LavaWallSmoothRU , df.tiletype . LavaWallSmoothLU , df.tiletype . LavaWallSmoothLD , df.tiletype . LavaWallSmoothUD , df.tiletype . LavaWallSmoothLR ,
df.tiletype . FeatureWallSmoothRD2 , df.tiletype . FeatureWallSmoothR2D , df.tiletype . FeatureWallSmoothR2U , df.tiletype . FeatureWallSmoothRU2 ,
df.tiletype . FeatureWallSmoothL2U , df.tiletype . FeatureWallSmoothLU2 , df.tiletype . FeatureWallSmoothL2D , df.tiletype . FeatureWallSmoothLD2 ,
df.tiletype . FeatureWallSmoothLRUD , df.tiletype . FeatureWallSmoothRUD , df.tiletype . FeatureWallSmoothLRD , df.tiletype . FeatureWallSmoothLRU ,
df.tiletype . FeatureWallSmoothLUD , df.tiletype . FeatureWallSmoothRD , df.tiletype . FeatureWallSmoothRU , df.tiletype . FeatureWallSmoothLU ,
df.tiletype . FeatureWallSmoothLD , df.tiletype . FeatureWallSmoothUD , df.tiletype . FeatureWallSmoothLR , df.tiletype . StoneWallSmoothRD2 ,
df.tiletype . StoneWallSmoothR2D , df.tiletype . StoneWallSmoothR2U , df.tiletype . StoneWallSmoothRU2 , df.tiletype . StoneWallSmoothL2U ,
df.tiletype . StoneWallSmoothLU2 , df.tiletype . StoneWallSmoothL2D , df.tiletype . StoneWallSmoothLD2 , df.tiletype . StoneWallSmoothLRUD ,
df.tiletype . StoneWallSmoothRUD , df.tiletype . StoneWallSmoothLRD , df.tiletype . StoneWallSmoothLRU , df.tiletype . StoneWallSmoothLUD ,
df.tiletype . StoneWallSmoothRD , df.tiletype . StoneWallSmoothRU , df.tiletype . StoneWallSmoothLU , df.tiletype . StoneWallSmoothLD ,
df.tiletype . StoneWallSmoothUD , df.tiletype . StoneWallSmoothLR , df.tiletype . LavaWallWorn1 , df.tiletype . LavaWallWorn2 , df.tiletype . LavaWallWorn3 ,
df.tiletype . LavaWall , df.tiletype . FeatureWallWorn1 , df.tiletype . FeatureWallWorn2 , df.tiletype . FeatureWallWorn3 , df.tiletype . FeatureWall ,
df.tiletype . FrozenWallWorn1 , df.tiletype . FrozenWallWorn2 , df.tiletype . FrozenWallWorn3 , df.tiletype . FrozenWall , df.tiletype . MineralWallSmoothRD2 ,
df.tiletype . MineralWallSmoothR2D , df.tiletype . MineralWallSmoothR2U , df.tiletype . MineralWallSmoothRU2 , df.tiletype . MineralWallSmoothL2U ,
df.tiletype . MineralWallSmoothLU2 , df.tiletype . MineralWallSmoothL2D , df.tiletype . MineralWallSmoothLD2 , df.tiletype . MineralWallSmoothLRUD ,
df.tiletype . MineralWallSmoothRUD , df.tiletype . MineralWallSmoothLRD , df.tiletype . MineralWallSmoothLRU , df.tiletype . MineralWallSmoothLUD ,
df.tiletype . MineralWallSmoothRD , df.tiletype . MineralWallSmoothRU , df.tiletype . MineralWallSmoothLU , df.tiletype . MineralWallSmoothLD ,
df.tiletype . MineralWallSmoothUD , df.tiletype . MineralWallSmoothLR , df.tiletype . MineralWallWorn1 , df.tiletype . MineralWallWorn2 ,
df.tiletype . MineralWallWorn3 , df.tiletype . MineralWall , df.tiletype . FrozenWallSmoothRD2 , df.tiletype . FrozenWallSmoothR2D ,
df.tiletype . FrozenWallSmoothR2U , df.tiletype . FrozenWallSmoothRU2 , df.tiletype . FrozenWallSmoothL2U , df.tiletype . FrozenWallSmoothLU2 ,
df.tiletype . FrozenWallSmoothL2D , df.tiletype . FrozenWallSmoothLD2 , df.tiletype . FrozenWallSmoothLRUD , df.tiletype . FrozenWallSmoothRUD ,
df.tiletype . FrozenWallSmoothLRD , df.tiletype . FrozenWallSmoothLRU , df.tiletype . FrozenWallSmoothLUD , df.tiletype . FrozenWallSmoothRD ,
df.tiletype . FrozenWallSmoothRU , df.tiletype . FrozenWallSmoothLU , df.tiletype . FrozenWallSmoothLD , df.tiletype . FrozenWallSmoothUD ,
df.tiletype . FrozenWallSmoothLR ,
}
if walls [ tt ] then
return true
else
return false , " Can only do it on walls "
end
end
function IsTree ( args )
local tt = dfhack.maps . getTileType ( args.pos )
if tt == 24 then
return true
else
return false , " Can only do it on trees "
end
end
function IsWater ( args )
return true
end
function IsPlant ( args )
return true
end
function IsUnit ( args )
local pos = args.pos
for k , v in pairs ( df.global . world.units . active ) do
if v.pos . x == pos.x and v.pos . y == pos.y and v.pos . z == pos.z then
return true
end
end
return false , " Unit must be present "
end
function itemsAtPos ( pos )
local ret = { }
for k , v in pairs ( df.global . world.items . all ) do
if v.pos . x == pos.x and v.pos . y == pos.y and v.pos . z == pos.z and v.flags . on_ground then
table.insert ( ret , v )
end
end
return ret
end
function AssignBuildingRef ( args )
local bld = dfhack.buildings . findAtTile ( args.pos )
args.job . general_refs : insert ( " # " , { new = df.general_ref_building_holderst , building_id = bld.id } )
bld.jobs : insert ( " # " , args.job )
end
--[[ building submodule... ]] --
function DialogBuildingChoose ( on_select , on_cancel )
blist = { }
for i = df.building_type . _first_item , df.building_type . _last_item do
table.insert ( blist , df.building_type [ i ] )
end
dialog.showListPrompt ( " Building list " , " Choose building: " , COLOR_WHITE , blist , on_select , on_cancel , nil , true )
end
function DialogSubtypeChoose ( subtype , on_select , on_cancel )
blist = { }
for i = subtype._first_item , subtype._last_item do
table.insert ( blist , subtype [ i ] )
end
dialog.showListPrompt ( " Subtype " , " Choose subtype: " , COLOR_WHITE , blist , on_select , on_cancel , nil , true )
end
--workshop, furnaces, traps
invalid_buildings = { }
function SubtypeChosen ( args , index )
args.subtype = index - 1
buildings.constructBuilding ( args )
end
function BuildingChosen ( st_pos , pos , index )
local b_type = index - 2
local args = { }
args.type = b_type
args.pos = pos
args.items = itemsAtPos ( st_pos )
if invalid_buildings [ b_type ] then
return
elseif b_type == df.building_type . Construction then
DialogSubtypeChoose ( df.construction_type , dfhack.curry ( SubtypeChosen , args ) )
return
elseif b_type == df.building_type . Furnace then
DialogSubtypeChoose ( df.furnace_type , dfhack.curry ( SubtypeChosen , args ) )
return
elseif b_type == df.building_type . Trap then
DialogSubtypeChoose ( df.trap_type , dfhack.curry ( SubtypeChosen , args ) )
return
elseif b_type == df.building_type . Workshop then
DialogSubtypeChoose ( df.workshop_type , dfhack.curry ( SubtypeChosen , args ) )
return
else
buildings.constructBuilding ( args )
end
end
--[[ end of buildings ]] --
function AssignJobToBuild ( args )
local bld = dfhack.buildings . findAtTile ( args.pos )
if bld ~= nil then
if # bld.jobs > 0 then
AssignUnitToJob ( bld.jobs [ 0 ] , args.unit , args.old_pos )
else
local jb = MakeJob ( args.unit , args.pos , df.job_type . ConstructBuilding , args.old_pos , { AssignBuildingRef } )
local its = itemsAtPos ( args.old_pos )
for k , v in pairs ( its ) do
jb.items : insert ( " # " , { new = true , item = v , role = 2 } )
end
end
else
DialogBuildingChoose ( dfhack.curry ( BuildingChosen , args.old_pos , args.pos ) )
end
end
function ContinueJob ( unit )
local c_job = unit.job . current_job
if c_job then
for k , v in pairs ( c_job.items ) do
if v.is_fetching == 1 then
unit.path . dest : assign ( v.item . pos )
return
end
end
unit.path . dest : assign ( c_job.pos )
end
end
dig_modes = {
{ " CarveFortification " , df.job_type . CarveFortification , { IsWall } } ,
{ " DetailWall " , df.job_type . DetailWall , { IsWall } } ,
{ " DetailFloor " , df.job_type . DetailFloor } ,
--{"CarveTrack" ,df.job_type.CarveTrack}, -- does not work??
{ " Dig " , df.job_type . Dig , { MakePredicateWieldsItem ( df.job_skill . MINING ) , IsWall } } ,
{ " CarveUpwardStaircase " , df.job_type . CarveUpwardStaircase , { MakePredicateWieldsItem ( df.job_skill . MINING ) , IsWall } } ,
{ " CarveDownwardStaircase " , df.job_type . CarveDownwardStaircase , { MakePredicateWieldsItem ( df.job_skill . MINING ) } } ,
{ " CarveUpDownStaircase " , df.job_type . CarveUpDownStaircase , { MakePredicateWieldsItem ( df.job_skill . MINING ) } } ,
{ " CarveRamp " , df.job_type . CarveRamp , { MakePredicateWieldsItem ( df.job_skill . MINING ) , IsWall } } ,
{ " DigChannel " , df.job_type . DigChannel , { MakePredicateWieldsItem ( df.job_skill . MINING ) } } ,
{ " FellTree " , df.job_type . FellTree , { MakePredicateWieldsItem ( df.job_skill . AXE ) , IsTree } } ,
{ " Fish " , df.job_type . Fish , { IsWater } } ,
--{"Diagnose Patient" ,df.job_type.DiagnosePatient,{IsUnit},{SetPatientRef}},
--{"Surgery" ,df.job_type.Surgery,{IsUnit},{SetPatientRef}},
--{"TameAnimal" ,df.job_type.TameAnimal,{IsUnit},{SetCreatureRef}},
{ " GatherPlants " , df.job_type . GatherPlants , { IsPlant } } ,
{ " RemoveConstruction " , df.job_type . RemoveConstruction , { IsConstruct } } ,
--{"HandleLargeCreature" ,df.job_type.HandleLargeCreature,{isUnit},{SetCreatureRef}},
{ " Build " , AssignJobToBuild } ,
}
usetool = defclass ( usetool , gui.Screen )
function usetool : getModeName ( )
local adv = df.global . world.units . active [ 0 ]
if adv.job . current_job then
return string.format ( " %s working(%d) " , ( dig_modes [ ( mode or 0 ) + 1 ] [ 1 ] or " " ) , adv.job . current_job.completion_timer )
else
return dig_modes [ ( mode or 0 ) + 1 ] [ 1 ] or " "
end
end
function usetool : init ( args )
self : addviews {
wid.Label {
frame = { xalign = 0 , yalign = 0 } ,
2012-11-29 02:13:26 -07:00
text = { { key = keybinds.key_prev . key } , { gap = 1 , text = dfhack.curry ( usetool.getModeName , self ) } , { gap = 1 , key = keybinds.key_next . key } }
2012-11-28 17:26:10 -07:00
}
}
end
function usetool : onRenderBody ( dc )
self._native . parent : logic ( )
self : renderParent ( )
end
MOVEMENT_KEYS = {
A_CARE_MOVE_N = { 0 , - 1 , 0 } , A_CARE_MOVE_S = { 0 , 1 , 0 } ,
A_CARE_MOVE_W = { - 1 , 0 , 0 } , A_CARE_MOVE_E = { 1 , 0 , 0 } ,
A_CARE_MOVE_NW = { - 1 , - 1 , 0 } , A_CARE_MOVE_NE = { 1 , - 1 , 0 } ,
A_CARE_MOVE_SW = { - 1 , 1 , 0 } , A_CARE_MOVE_SE = { 1 , 1 , 0 } ,
--[[A_MOVE_N = { 0, -1, 0 }, A_MOVE_S = { 0, 1, 0 },
A_MOVE_W = { - 1 , 0 , 0 } , A_MOVE_E = { 1 , 0 , 0 } ,
A_MOVE_NW = { - 1 , - 1 , 0 } , A_MOVE_NE = { 1 , - 1 , 0 } ,
A_MOVE_SW = { - 1 , 1 , 0 } , A_MOVE_SE = { 1 , 1 , 0 } , --]]
--[[CURSOR_UP_FAST = { 0, -1, 0, true }, CURSOR_DOWN_FAST = { 0, 1, 0, true },
CURSOR_LEFT_FAST = { - 1 , 0 , 0 , true } , CURSOR_RIGHT_FAST = { 1 , 0 , 0 , true } ,
CURSOR_UPLEFT_FAST = { - 1 , - 1 , 0 , true } , CURSOR_UPRIGHT_FAST = { 1 , - 1 , 0 , true } ,
CURSOR_DOWNLEFT_FAST = { - 1 , 1 , 0 , true } , CURSOR_DOWNRIGHT_FAST = { 1 , 1 , 0 , true } , ] ] --
A_CUSTOM_CTRL_D = { 0 , 0 , - 1 } ,
A_CUSTOM_CTRL_E = { 0 , 0 , 1 } ,
CURSOR_UP_Z_AUX = { 0 , 0 , 1 } , CURSOR_DOWN_Z_AUX = { 0 , 0 , - 1 } ,
A_MOVE_SAME_SQUARE = { 0 , 0 , 0 } ,
SELECT = { 0 , 0 , 0 } ,
}
function moddedpos ( pos , delta )
return { x = pos.x + delta [ 1 ] , y = pos.y + delta [ 2 ] , z = pos.z + delta [ 3 ] }
end
function usetool : onDismiss ( )
local adv = df.global . world.units . active [ 0 ]
--TODO: cancel job
--[[if adv and adv.job.current_job then
local cj = adv.job . current_job
adv.jobs . current_job = nil
cj : delete ( )
end ] ]
end
function usetool : onHelp ( )
showHelp ( )
end
function usetool : onInput ( keys )
if keys.LEAVESCREEN then
self : dismiss ( )
elseif keys [ keybinds.key_next . key ] then
mode = ( mode + 1 ) %# dig_modes
elseif keys [ keybinds.key_prev . key ] then
mode = mode - 1
if mode < 0 then mode =# dig_modes - 1 end
--elseif keys.A_LOOK then
-- self:sendInputToParent("A_LOOK")
elseif keys [ keybinds.key_continue . key ] then
ContinueJob ( df.global . world.units . active [ 0 ] )
self : sendInputToParent ( " A_WAIT " )
else
local adv = df.global . world.units . active [ 0 ]
local cur_mode = dig_modes [ ( mode or 0 ) + 1 ]
local failed = false
for code , _ in pairs ( keys ) do
--print(code)
if MOVEMENT_KEYS [ code ] then
local state = { unit = adv , pos = moddedpos ( adv.pos , MOVEMENT_KEYS [ code ] ) , dir = MOVEMENT_KEYS [ code ] ,
old_pos = { x = adv.pos . x , y = adv.pos . y , z = adv.pos . z } }
if code == " SELECT " then
if df.global . cursor.x ~=- 30000 then
state.pos = { x = df.global . cursor.x , y = df.global . cursor.y , z = df.global . cursor.z }
else
break
end
end
for _ , p in pairs ( cur_mode [ 3 ] or { } ) do
local t , v = p ( state )
if t == false then
dfhack.gui . showAnnouncement ( v , 5 , 1 )
failed = true
end
end
if not failed then
if type ( cur_mode [ 2 ] ) == " function " then
cur_mode [ 2 ] ( state )
else
MakeJob ( adv , moddedpos ( adv.pos , MOVEMENT_KEYS [ code ] ) , cur_mode [ 2 ] , adv.pos , cur_mode [ 4 ] )
end
if code == " SELECT " then
self : sendInputToParent ( " LEAVESCREEN " )
end
self : sendInputToParent ( " A_WAIT " )
end
return code
end
if code ~= " _STRING " and code ~= " _MOUSE_L " and code ~= " _MOUSE_R " then
self : sendInputToParent ( code )
end
end
end
end
usetool ( ) : show ( )