Merge pull request #684 from expwnent/create-unit

create-unit script, fix tab in RemoteFortressReader.proto, create-item tweak, equip-item script.
develop
expwnent 2015-09-15 03:24:26 -04:00
commit 48d80cfb1a
6 changed files with 723 additions and 66 deletions

@ -27,12 +27,16 @@ DFHack Future
fix-ster: changes fertility/sterility of animals or dwarves
view-item-info: adds information and customisable descriptions to item viewscreens
warn-starving: check for starving, thirsty, or very drowsy units and pause with warning if any are found
modtools/create-unit: create new units from nothing
modtools/equip-item: a script to equip items on units
points: set number of points available at embark screen
New tweaks
embark-profile-name: Allows the use of lowercase letters when saving embark profiles
kitchen-keys: Fixes DF kitchen meal keybindings
kitchen-prefs-color: Changes color of enabled items to green in kitchen preferences
kitchen-prefs-empty: Fixes a layout issue with empty kitchen tabs
scripts/modtools/create-item: arguments are named more clearly, and you can specify the creator to be the unit with id df.global.unit_next_id-1 (useful in conjunction with modtools/create-unit)
scripts/teleport.lua is now compatible with the script_environment/reqscript system.
Fixes
Plugins with vmethod hooks can now be reloaded on OS X
Lua's os.system() now works on OS X

@ -182,7 +182,7 @@ message UnitDefinition
optional uint32 flags1 = 8;
optional uint32 flags2 = 9;
optional uint32 flags3 = 10;
optional bool is_soldier = 11;
optional bool is_soldier = 11;
}
message UnitList

@ -4,17 +4,97 @@
local utils = require 'utils'
validArgs = validArgs or utils.invert({
validArgs = --[[validArgs or--]] utils.invert({
'help',
'creator',
'material',
'item',
-- 'creature',
-- 'caste',
'matchingGloves',
'matchingShoes'
'leftHand',
'rightHand',
'quality'
})
organicTypes = organicTypes or utils.invert({
df.item_type.REMAINS,
df.item_type.FISH,
df.item_type.FISH_RAW,
df.item_type.VERMIN,
df.item_type.PET,
df.item_type.EGG,
})
badTypes = badTypes or utils.invert({
df.item_type.CORPSE,
df.item_type.CORPSEPIECE,
df.item_type.FOOD,
})
function createItem(creatorID, item, material, leftHand, rightHand, quality)
local itemQuality = quality and df.item_quality[quality]
print(itemQuality)
local creator = df.unit.find(creatorID)
if not creator then
error 'Invalid creator.'
end
if not item then
error 'Invalid item.'
end
local itemType = dfhack.items.findType(item)
if itemType == -1 then
error 'Invalid item.'
end
local itemSubtype = dfhack.items.findSubtype(item)
if organicTypes[itemType] then
--TODO: look up creature and caste
error 'Not yet supported.'
end
if badTypes[itemType] then
error 'Not supported.'
end
if not material then
error 'Invalid material.'
end
local materialInfo = dfhack.matinfo.find(material)
if not materialInfo then
error 'Invalid material.'
end
local item1 = dfhack.items.createItem(itemType, itemSubtype, materialInfo['type'], materialInfo.index, creator)
local item = df.item.find(item1)
if leftHand then
item:setGloveHandedness(2)
elseif rightHand then
item:setGloveHandedness(1)
end
if itemQuality then
item:setQuality(itemQuality)
end
--[[if matchingGloves or matchingShoes then
if matchingGloves then
item1 = df.item.find(item1)
item1:setGloveHandedness(1);
end
local item2 = dfhack.items.createItem(itemType, itemSubtype, materialInfo['type'], materialInfo.index, creator)
if matchingGloves then
item2 = df.item.find(item2)
item2:setGloveHandedness(2);
end
end --]]
return item1
end
if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs)
if args.help then
@ -24,10 +104,11 @@ arguments:
-help
print this help message
-creator id
specify the id of the unit who will create the item
specify the id of the unit who will create the item, or \\LAST to indicate the unit with id df.global.unit_next_id-1
examples:
0
2
\\LAST
-material matstring
specify the material of the item to be created
examples:
@ -46,65 +127,8 @@ arguments:
return
end
if not args.creator or not tonumber(args.creator) or not df.unit.find(tonumber(args.creator)) then
error 'Invalid creator.'
end
args.creator = df.unit.find(tonumber(args.creator))
if not args.creator then
error 'Invalid creator.'
end
if not args.item then
error 'Invalid item.'
end
local itemType = dfhack.items.findType(args.item)
if itemType == -1 then
error 'Invalid item.'
end
local itemSubtype = dfhack.items.findSubtype(args.item)
organicTypes = organicTypes or utils.invert({
df.item_type.REMAINS,
df.item_type.FISH,
df.item_type.FISH_RAW,
df.item_type.VERMIN,
df.item_type.PET,
df.item_type.EGG,
})
if organicTypes[itemType] then
--TODO: look up creature and caste
error 'Not yet supported.'
end
badTypes = badTypes or utils.invert({
df.item_type.CORPSE,
df.item_type.CORPSEPIECE,
df.item_type.FOOD,
})
if badTypes[itemType] then
error 'Not supported.'
end
if not args.material then
error 'Invalid material.'
end
args.material = dfhack.matinfo.find(args.material)
if not args.material then
error 'Invalid material.'
end
local item1 = dfhack.items.createItem(itemType, itemSubtype, args.material['type'], args.material.index, args.creator)
if args.matchingGloves or args.matchingShoes then
if args.matchingGloves then
item1 = df.item.find(item1)
item1:setGloveHandedness(1);
end
local item2 = dfhack.items.createItem(itemType, itemSubtype, args.material['type'], args.material.index, args.creator)
if args.matchingGloves then
item2 = df.item.find(item2)
item2:setGloveHandedness(2);
end
if args.creator == '\\LAST' then
args.creator = tostring(df.global.unit_next_id-1)
end
createItem(tonumber(args.creator), args.item, args.material, args.leftHand, args.rightHand, args.quality)

@ -0,0 +1,526 @@
-- create-unit.lua
-- Originally created by warmist, edited by Putnam for the dragon ball mod to be used in reactions, modified by Dirst for use in The Earth Strikes Back mod, incorporating fixes discovered by Boltgun then Mifiki wrote the bit where it switches to arena mode briefly to do some of the messy work, then Expwnent combined that with the old script to make it function for histfigs
-- version 0.5
-- This is a beta version. Use at your own risk.
--[[
TODO
children and babies: set child/baby job
confirm body size is computed appropriately for different ages / life stages
incarnate pre-existing historical figures
some sort of invasion helper script
set invasion_id, etc
announcement for fake natural birth if appropriate
]]
--[[
if dfhack.gui.getCurViewscreen()._type ~= df.viewscreen_dwarfmodest or df.global.ui.main.mode ~= df.ui_sidebar_mode.LookAround then
print 'activate loo[k] mode'
return
end
--]]
local utils=require 'utils'
function createUnit(race_id, caste_id)
local curViewscreen = dfhack.gui.getCurViewscreen()
local dwarfmodeScreen = df.viewscreen_dwarfmodest:new()
curViewscreen.child = dwarfmodeScreen
dwarfmodeScreen.parent = curViewscreen
local oldMode = df.global.ui.main.mode
df.global.ui.main.mode = df.ui_sidebar_mode.LookAround
local gui = require 'gui'
df.global.world.arena_spawn.race:resize(0)
df.global.world.arena_spawn.race:insert(0,race_id) --df.global.ui.race_id)
df.global.world.arena_spawn.caste:resize(0)
df.global.world.arena_spawn.caste:insert(0,caste_id)
df.global.world.arena_spawn.creature_cnt:resize(0)
df.global.world.arena_spawn.creature_cnt:insert(0,0)
--df.global.world.arena_spawn.equipment.skills:insert(0,99)
--df.global.world.arena_spawn.equipment.skill_levels:insert(0,0)
df.global.gametype = 4
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'D_LOOK_ARENA_CREATURE')
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'SELECT')
df.global.gametype = 0
curViewscreen.child = nil
dwarfmodeScreen:delete()
df.global.ui.main.mode = oldMode
local id = df.global.unit_next_id-1
return id
end
--local u = df.unit.find(df.global.unit_next_id-1)
--u.civ_id = df.global.ui.civ_id
--u.population_id = df.historical_entity.find(df.global.ui.civ_id).populations[0]
--local group = df.global.ui.group_id
-- Picking a caste or gender at random
function getRandomCasteId(race_id)
local cr = df.creature_raw.find(race_id)
local caste_id, casteMax
casteMax = #cr.caste - 1
if casteMax > 0 then
return math.random(0, casteMax)
end
return 0
end
local function allocateNewChunk(hist_entity)
hist_entity.save_file_id=df.global.unit_chunk_next_id
df.global.unit_chunk_next_id=df.global.unit_chunk_next_id+1
hist_entity.next_member_idx=0
print("allocating chunk:",hist_entity.save_file_id)
end
local function allocateIds(nemesis_record,hist_entity)
if hist_entity.next_member_idx==100 then
allocateNewChunk(hist_entity)
end
nemesis_record.save_file_id=hist_entity.save_file_id
nemesis_record.member_idx=hist_entity.next_member_idx
hist_entity.next_member_idx=hist_entity.next_member_idx+1
end
function createFigure(trgunit,he,he_group)
local hf=df.historical_figure:new()
hf.id=df.global.hist_figure_next_id
hf.race=trgunit.race
hf.caste=trgunit.caste
hf.profession = trgunit.profession
hf.sex = trgunit.sex
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
hf.appeared_year = df.global.cur_year
hf.born_year = trgunit.relations.birth_year
hf.born_seconds = trgunit.relations.birth_time
hf.curse_year = trgunit.relations.curse_year
hf.curse_seconds = trgunit.relations.curse_time
hf.birth_year_bias = trgunit.relations.birth_year_bias
hf.birth_time_bias = trgunit.relations.birth_time_bias
hf.old_year = trgunit.relations.old_year
hf.old_seconds = trgunit.relations.old_time
hf.died_year = -1
hf.died_seconds = -1
hf.name:assign(trgunit.name)
hf.civ_id = trgunit.civ_id
hf.population_id = trgunit.population_id
hf.breed_id = -1
hf.unit_id = trgunit.id
df.global.world.history.figures:insert("#",hf)
hf.info = df.historical_figure_info:new()
hf.info.unk_14 = df.historical_figure_info.T_unk_14:new() -- hf state?
--unk_14.region_id = -1; unk_14.beast_id = -1; unk_14.unk_14 = 0
hf.info.unk_14.unk_18 = -1; hf.info.unk_14.unk_1c = -1
-- set values that seem related to state and do event
--change_state(hf, dfg.ui.site_id, region_pos)
--lets skip skills for now
--local skills = df.historical_figure_info.T_skills:new() -- skills snap shot
-- ...
-- note that innate skills are automaticaly set by DF
hf.info.skills = {new=true}
he.histfig_ids:insert('#', hf.id)
he.hist_figures:insert('#', hf)
if he_group then
he_group.histfig_ids:insert('#', hf.id)
he_group.hist_figures:insert('#', hf)
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=he_group.id,link_strength=100})
end
trgunit.flags1.important_historical_figure = true
trgunit.flags2.important_historical_figure = true
trgunit.hist_figure_id = hf.id
trgunit.hist_figure_id2 = hf.id
hf.entity_links:insert("#",{new=df.histfig_entity_link_memberst,entity_id=trgunit.civ_id,link_strength=100})
--add entity event
local hf_event_id=df.global.hist_event_next_id
df.global.hist_event_next_id=df.global.hist_event_next_id+1
df.global.world.history.events:insert("#",{new=df.history_event_add_hf_entity_linkst,year=trgunit.relations.birth_year,
seconds=trgunit.relations.birth_time,id=hf_event_id,civ=hf.civ_id,histfig=hf.id,link_type=0})
return hf
end
function createNemesis(trgunit,civ_id,group_id)
local id=df.global.nemesis_next_id
local nem=df.nemesis_record:new()
nem.id=id
nem.unit_id=trgunit.id
nem.unit=trgunit
nem.flags:resize(4)
--not sure about these flags...
-- [[
nem.flags[4]=true
nem.flags[5]=true
nem.flags[6]=true
nem.flags[7]=true
nem.flags[8]=true
nem.flags[9]=true
--]]
--[[for k=4,8 do
nem.flags[k]=true
end]]
nem.unk10=-1
nem.unk11=-1
nem.unk12=-1
df.global.world.nemesis.all:insert("#",nem)
df.global.nemesis_next_id=id+1
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
trgunit.flags1.important_historical_figure=true
nem.save_file_id=-1
local he=df.historical_entity.find(civ_id)
he.nemesis_ids:insert("#",id)
he.nemesis:insert("#",nem)
local he_group
if group_id and group_id~=-1 then
he_group=df.historical_entity.find(group_id)
end
if he_group then
he_group.nemesis_ids:insert("#",id)
he_group.nemesis:insert("#",nem)
end
allocateIds(nem,he)
nem.figure=createFigure(trgunit,he,he_group)
end
--createNemesis(u, u.civ_id,group)
function createUnitInCiv(race_id, caste_id, civ_id, group_id)
local uid = createUnit(race_id, caste_id)
local unit = df.unit.find(uid)
if ( civ_id ) then
createNemesis(unit, civ_id, group_id)
end
return uid
end
function createUnitInFortCiv(race_id, caste_id)
return createUnitInCiv(race_id, caste_id, df.global.ui.civ_id)
end
function createUnitInFortCivAndGroup(race_id, caste_id)
return createUnitInCiv(race_id, caste_id, df.global.ui.civ_id, df.global.ui.group_id)
end
function domesticate(uid, group_id)
local u = df.unit.find(uid)
group_id = group_id or df.global.ui.group_id
-- If a friendly animal, make it domesticated. From Boltgun & Dirst
local caste=df.creature_raw.find(u.race).caste[u.caste]
if not(caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN) then
-- Fix friendly animals (from Boltgun)
u.flags2.resident = false;
u.flags3.body_temp_in_range = true;
u.population_id = -1
u.status.current_soul.unit_id = u.id
u.animal.population.region_x = -1
u.animal.population.region_y = -1
u.animal.population.unk_28 = -1
u.animal.population.population_idx = -1
u.animal.population.depth = -1
u.counters.soldier_mood_countdown = -1
u.counters.death_cause = -1
u.enemy.anon_4 = -1
u.enemy.anon_5 = -1
u.enemy.anon_6 = -1
-- And make them tame (from Dirst)
u.flags1.tame = true
u.training_level = 7
end
end
function nameUnit(id, entityRawName, civ_id)
--pick a random appropriate name
--choose three random words in the appropriate things
local unit = df.unit.find(id)
local entity_raw
if entityRawName then
for k,v in ipairs(df.global.world.raws.entities) do
if v.code == entityRawName then
entity_raw = v
break
end
end
else
local entity = df.historical_entity.find(civ_id)
entity_raw = entity.entity_raw
end
if not entity_raw then
error('entity raw = nil: ', id, entityRawName, civ_id)
end
local translation = entity_raw.translation
local translationIndex
for k,v in ipairs(df.global.world.raws.language.translations) do
if v.name == translation then
translationIndex = k
break
end
end
--translation = df.language_translation.find(translation)
local language_word_table = entity_raw.symbols.symbols1[0] --educated guess
function randomWord()
local index = math.random(0, #language_word_table.words[0] - 1)
return index
end
local firstName = randomWord()
local lastName1 = randomWord()
local lastName2 = randomWord()
local name = unit.status.current_soul.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
name = unit.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
if unit.hist_figure_id ~= -1 then
local histfig = df.historical_figure.find(unit.hist_figure_id)
name = histfig.name
name.words[0] = language_word_table.words[0][lastName1]
name.parts_of_speech[0] = language_word_table.parts[0][lastName1]
name.words[1] = language_word_table.words[0][lastName2]
name.parts_of_speech[1] = language_word_table.parts[0][lastName2]
name.first_name = df.language_word.find(language_word_table.words[0][firstName]).forms[language_word_table.parts[0][firstName]]
name.has_name = true
name.language = translationIndex
end
end
validArgs = --[[validArgs or]]utils.invert({
'help',
'race',
'caste',
'domesticate',
'civId',
'groupId',
'flagSet',
'flagClear',
'name',
'location',
'age'
})
if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs)
if args.help then
print(
[[scripts/modtools/create-unit.lua
arguments:
-help
print this help message
-race raceName
specify the race of the unit to be created
examples:
DWARF
HUMAN
-caste casteName
specify the caste of the unit to be created
examples:
MALE
FEMALE
-domesticate
if the unit can't learn or can't speak, then make it a friendly animal
-civId id
make the created unit a member of the specified civ (or none if id = -1)
if id is \\LOCAL, then make it a member of the civ associated with the current fort
otherwise id must be an integer
-groupId id
make the created unit a member of the specified group (or none if id = -1)
if id is \\LOCAL, then make it a member of the group associated with the current fort
otherwise id must be an integer
-name entityRawName
set the unit's name to be a random name appropriate for the given entity
examples:
MOUNTAIN
-location [ x y z ]
create the unit at the specified coordinates
-age howOld
set the birth date of the unit to the specified number of years ago
-flagSet [ flag1 flag2 ... ]
set the specified unit flags in the new unit to true
flags may be selected from df.unit_flags1, df.unit_flags2, or df.unit_flags3
-flagClear [ flag1 flag2 ... ]
set the specified unit flags in the new unit to false
flags may be selected from df.unit_flags1, df.unit_flags2, or df.unit_flags3
]])
return
end
local race
local raceIndex
local casteIndex
if not args.race or not args.caste then
error 'Specfiy a race and caste for the new unit.'
end
--find race
for i,v in ipairs(df.global.world.raws.creatures.all) do
if v.creature_id == args.race then
raceIndex = i
race = v
break
end
end
if not race then
error 'Invalid race.'
end
for i,v in ipairs(race.caste) do
if v.caste_id == args.caste then
casteIndex = i
break
end
end
if not casteIndex then
error 'Invalid caste.'
end
local age
if args.age then
age = tonumber(args.age)
if not age and not age == 0 then
error('Invalid age: ' .. args.age)
end
end
local civ_id
if args.civId == '\\LOCAL' then
civ_id = df.global.ui.civ_id
elseif args.civId and tonumber(args.civId) then
civ_id = tonumber(args.civId)
end
local group_id
if args.groupId == '\\LOCAL' then
group_id = df.global.ui.group_id
elseif args.groupId and tonumber(args.groupId) then
group_id = tonumber(args.groupId)
end
local unitId = createUnitInCiv(raceIndex, casteIndex, civ_id, group_id)
if args.domesticate then
domesticate(unitId, group_id)
end
if age or age == 0 then
local u = df.unit.find(unitId)
local oldYearDelta = u.relations.old_year - u.relations.birth_year
u.relations.birth_year = df.global.cur_year - age
u.relations.old_year = u.relations.birth_year + oldYearDelta
--these flags are an educated guess of how to get the game to compute sizes correctly: use -flagSet and -flagClear arguments to override or supplement
u.flags2.calculated_nerves = false
u.flags2.calculated_bodyparts = false
u.flags3.body_part_relsize_computed = false
u.flags3.size_modifier_computed = false
u.flags3.compute_health = true
u.flags3.weight_computed = false
--TODO: if the unit is a child or baby it will still behave like an adult
end
if args.flagSet or args.flagClear then
local u = df.unit.find(unitId)
local flagsToSet = {}
local flagsToClear = {}
for _,v in ipairs(args.flagSet or {}) do
flagsToSet[v] = true
end
for _,v in ipairs(args.flagClear or {}) do
flagsToClear[v] = true
end
for _,k in ipairs(df.unit_flags1) do
if flagsToSet[k] then
u.flags1[k] = true;
elseif flagsToClear[k] then
u.flags1[k] = false;
end
end
for _,k in ipairs(df.unit_flags2) do
if flagsToSet[k] then
u.flags2[k] = true;
elseif flagsToClear[k] then
u.flags2[k] = false;
end
end
for _,k in ipairs(df.unit_flags3) do
if flagsToSet[k] then
u.flags3[k] = true;
elseif flagsToClear[k] then
u.flags3[k] = false;
end
end
end
if args.name then
nameUnit(unitId, args.name, civ_id)
else
local unit = df.unit.find(unitId)
unit.name.has_name = false
if unit.status.current_soul then
unit.status.current_soul.name.has_name = false
end
--[[if unit.hist_figure_id ~= -1 then
local histfig = df.historical_figure.find(unit.hist_figure_id)
histfig.name.has_name = false
end--]]
end
if civ_id then
local u = df.unit.find(unitId)
u.civ_id = civ_id
end
if args.location then
local u = df.unit.find(unitId)
local pos = df.coord:new()
pos.x = tonumber(args.location[1])
pos.y = tonumber(args.location[2])
pos.z = tonumber(args.location[3])
local teleport = dfhack.script_environment('teleport')
teleport.teleport(u, pos)
end
--[[if group_id then
local u = df.unit.find(unitId)
u.group_id = group_id
end--]]

@ -0,0 +1,99 @@
-- modtools/equip-item.lua
-- equip an item on a unit with a particular body part
local utils = require 'utils'
function equipItem(unit, item, bodyPart, mode)
--it is assumed that the item is on the ground
item.flags.on_ground = false
item.flags.in_inventory = true
local block = dfhack.maps.getTileBlock(item.pos)
local occupancy = block.occupancy[item.pos.x%16][item.pos.y%16]
for k,v in ipairs(block.items) do
--local blockItem = df.item.find(v)
if v == item.id then
block.items:erase(k)
break
end
end
local foundItem = false
for k,v in ipairs(block.items) do
local blockItem = df.item.find(v)
if blockItem.pos.x == item.pos.x and blockItem.pos.y == item.pos.y then
foundItem = true
break
end
end
if not foundItem then
occupancy.item = false
end
local inventoryItem = df.unit_inventory_item:new()
inventoryItem.item = item
inventoryItem.mode = mode
inventoryItem.body_part_id = bodyPart
unit.inventory:insert(#unit.inventory,inventoryItem)
end
validArgs = --[[validArgs or--]] utils.invert({
'help',
'unit',
'item',
'bodyPart',
'mode'
})
if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs)
if args.help then
print(
[[scripts/modtools/equip-item.lua
arguments:
-help
print this help message
]])
return
end
local unitId = tonumber(args.unit) or ((args.unit == '\\LAST') and (df.global.unit_next_id-1))
local unit = df.unit.find(unitId)
if not unit then
error('invalid unit!', args.unit)
end
local itemId = tonumber(args.item) or ((args.item == '\\LAST') and (df.global.item_next_id-1))
local item = df.item.find(itemId)
if not item then
error('invalid item!', args.item)
end
local bodyPartName = args.bodyPart
local creature_raw = df.global.world.raws.creatures.all[unit.race]
local caste_raw = creature_raw.caste[unit.caste]
local body_info = caste_raw.body_info
local partId
local part
for k,v in ipairs(body_info.body_parts) do
if v.token == bodyPartName then
partId = k
part = v
break
end
end
if not part then
error('invalid body part name: ', bodyPartName)
end
local mode = args.mode
mode = df.unit_inventory_item.T_mode[mode]
equipItem(unit, item, partId, mode)

@ -3,7 +3,7 @@
-- author Putnam
-- edited by expwnent
local function teleport(unit,pos)
function teleport(unit,pos)
local unitoccupancy = dfhack.maps.getTileBlock(unit.pos).occupancy[unit.pos.x%16][unit.pos.y%16]
local newoccupancy = dfhack.maps.getTileBlock(pos).occupancy[pos.x%16][pos.y%16]
if newoccupancy.unit then
@ -26,6 +26,10 @@ validArgs = validArgs or utils.invert({
'showpos'
})
if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs)
if args.showunitid or args.showpos then