Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: DFHack usage help  (Read 10481 times)

Dame de la Licorne

  • Bay Watcher
  • Cats? Check. FPS? Uh-oh...
    • View Profile
DFHack usage help
« on: June 30, 2016, 11:38:55 am »

Hi!

Can anyone explain exactly how to use the "spawnunit" command of DFHack?  I keep running into trouble trying to spawn a test creature.

As an example:

I figured out that I need to type in "spawnunit [TESTCREATURE] [FEMALE]" (where [TESTCREATURE] is the actual raw entry name), but how do I figure out the civ and group IDs, and what order do they need to go in?

-Dame de la Licorne
Logged
If software was real world, then it'd be something equivalent of hitting a nail with a hammer and having a building collapse on the other side of town.

Don't worry people, sometimes -moments occur

Dirst

  • Bay Watcher
  • [EASILY_DISTRA
    • View Profile
Re: DFHack usage help
« Reply #1 on: June 30, 2016, 12:39:06 pm »

Going forward it looks like the standard will be create-unit rather than spawnunit.

The create-unit in the 0.43 alpha of DFHack has a couple issues but would be fine for working out the syntax.  I'm not in front of my computer now, but I can post the current version here later (which, it must be stressed, is still a beta).  If you're in a hurry, I sent a copy of that version to Meph so it should be in the latest Masterwork.

lethosor is combining improvements and fixes from different places, which should all be together when The next DFHack comes out.
Logged
Just got back, updating:
(0.42 & 0.43) The Earth Strikes Back! v2.15 - Pay attention...  It's a mine!  It's-a not yours!
(0.42 & 0.43) Appearance Tweaks v1.03 - Tease those hippies about their pointy ears.
(0.42 & 0.43) Accessibility Utility v1.04 - Console tools to navigate the map

Dirst

  • Bay Watcher
  • [EASILY_DISTRA
    • View Profile
Re: DFHack usage help
« Reply #2 on: June 30, 2016, 02:41:53 pm »

Here is the latest I have:

Code: (modtools/create-unit.lua) [Select]
-- Creates a unit.  Beta; use at own risk.

-- Originally created by warmist
-- Significant contributions over time by Boltgun, Dirst, Expwnent, lethosor, mifki and Putnam.

-- version 0.55
-- This is a beta version. Use at your own risk.

-- Modifications from 0.5: civ -1 creates are NOT historical figures, mitigated screen-movement bug in createUnit()

--[[
  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
option to attach to an existing wild animal population
option to attach to a map feature
]]

local usage = [====[

modtools/create-unit
====================
Creates a unit.  Usage::

    -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, 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, make it a member of the
        civ associated with the 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, make it a member of the
        group associated with the 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
    -nick nickname
        set the unit's nickname directly
    -location [ x y z ]
        create the unit at the specified coordinates
    -age howOld
        set the birth date of the unitby current age
    -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

]====]

--[[
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 view_x = df.global.window_x
  local view_y = df.global.window_y
  local view_z = df.global.window_z

  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)

  local old_gametype = df.global.gametype
  df.global.gametype = df.game_type.DWARF_ARENA

  gui.simulateInput(dfhack.gui.getCurViewscreen(), 'D_LOOK_ARENA_CREATURE')
  gui.simulateInput(dfhack.gui.getCurViewscreen(), 'SELECT')

  df.global.gametype = old_gametype

  curViewscreen.child = nil
  dwarfmodeScreen:delete()
  df.global.ui.main.mode = oldMode

  local id = df.global.unit_next_id-1
 
  df.global.window_x = view_x
  df.global.window_y = view_y
  df.global.window_z = view_z
 
  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 wild(uid)
  local u = df.unit.find(uid)
  local caste=df.creature_raw.find(u.race).caste[u.caste]
  -- x = df.global.world.world_data.active_site[0].pos.x
  -- y = df.global.world.world_data.active_site[0].pos.y
  -- region = df.global.map.map_blocks[df.global.map.x_count_block*x+y]
  if not(caste.flags.CAN_SPEAK and caste.flags.CAN_LEARN) then
    u.animal.population.region_x = df.global.world.world_data.active_site[0].pos.x
    u.animal.population.region_y = df.global.world.world_data.active_site[0].pos.y
    u.animal.population.unk_28 = -1
    u.animal.population.population_idx = -1  -- Eventually want to make a real population
    u.animal.population.depth = -1  -- Eventually this should be a parameter
u.animal.leave_countdown = 99999  -- Eventually this should be a parameter
u.flags2.roaming_wilderness_population_source = true
u.flags2.roaming_wilderness_population_source_not_a_map_feature = true
-- region = df.global.world.map.map_blocks[df.global.world.map.x_count_block*x+y]
  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',
  'nick',
  'location',
  'age'
})

if moduleMode then
  return
end

local args = utils.processArgs({...}, validArgs)
if args.help then
  print(usage)
  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
if civ_id == -1 then
    unitId = createUnit(raceIndex, casteIndex)
  else
    unitId = createUnitInCiv(raceIndex, casteIndex, civ_id, group_id)
end

if args.domesticate then
  domesticate(unitId, group_id)
 else
  wild(unitId)
end

--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
local u = df.unit.find(unitId)
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
if age or age == 0 then
  if age == 0 then
    u.relations.birth_time = df.global.cur_year_tick
  end
  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
  if u.relations.old_year ~= -1 then
    u.relations.old_year = u.relations.birth_year + oldYearDelta
  end
  if u.flags1.important_historical_figure == true and u.flags2.important_historical_figure == true then
    local hf = df.global.world.history.figures[u.hist_figure_id]
    hf.born_year = u.relations.birth_year
    hf.born_seconds = u.relations.birth_time
    hf.old_year = u.relations.old_year
    hf.old_seconds = u.relations.old_time
  end
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 args.nick and type(args.nick) == 'string' then
  dfhack.units.setNickname(df.unit.find(unitId), args.nick)
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


modtools/create-unit -race DOG -caste MALE -domesticate -age 7

Type modtools/create-unit -help into the console for the full syntax.
Logged
Just got back, updating:
(0.42 & 0.43) The Earth Strikes Back! v2.15 - Pay attention...  It's a mine!  It's-a not yours!
(0.42 & 0.43) Appearance Tweaks v1.03 - Tease those hippies about their pointy ears.
(0.42 & 0.43) Accessibility Utility v1.04 - Console tools to navigate the map

Dame de la Licorne

  • Bay Watcher
  • Cats? Check. FPS? Uh-oh...
    • View Profile
Re: DFHack usage help
« Reply #3 on: June 30, 2016, 06:05:43 pm »

So if I wanted to create a dwarf (keep it easy), I would type:
Code: [Select]
create-unit -race DWARF -caste FEMALE -age 30 and it would automatically be a member of the same civ and group?

If I type:
Code: [Select]
create-unit -race TESTCREATURE -caste WARRIOR -age 52 how can I make it be an enemy of my civ and group?

-Dame de la Licorne
Logged
If software was real world, then it'd be something equivalent of hitting a nail with a hammer and having a building collapse on the other side of town.

Don't worry people, sometimes -moments occur

NCommander

  • Bay Watcher
  • Dwarven Military Master
    • View Profile
    • SoylentNews
Re: DFHack usage help
« Reply #4 on: June 30, 2016, 06:16:19 pm »

Adding it to your civ/site is much harder because you have to create historical links which requires finding a units histfig id, and doing all sorta of evil to it. It's generally easier to retrofit a migrant then make a unit out of "poof"
Logged
Quote from: TheFlame52
Fucking hell man, you aren't just getting the short end of the stick, you're being beaten with it.
Quote from: NRDL
Is your plan really to flush water into hell, and have the CARP marines fight them without threat of flame or disease?  If so, you are awesome, and one of the greatest DF military visionaries I've seen yet ( not that I've seen that many, or any, for that matter )

Dame de la Licorne

  • Bay Watcher
  • Cats? Check. FPS? Uh-oh...
    • View Profile
Re: DFHack usage help
« Reply #5 on: June 30, 2016, 07:05:33 pm »

Adding it to your civ/site is much harder because you have to create historical links which requires finding a units histfig id, and doing all sorta of evil to it. It's generally easier to retrofit a migrant then make a unit out of "poof"

How do you do that?  And can you "retrofit" a migrant into a different species?

-Dame de la Licorne
Logged
If software was real world, then it'd be something equivalent of hitting a nail with a hammer and having a building collapse on the other side of town.

Don't worry people, sometimes -moments occur

Putnam

  • Bay Watcher
  • DAT WIZARD
    • View Profile
Re: DFHack usage help
« Reply #6 on: June 30, 2016, 07:58:41 pm »

Adding it to your civ/site is much harder because you have to create historical links which requires finding a units histfig id, and doing all sorta of evil to it. It's generally easier to retrofit a migrant then make a unit out of "poof"
You don't find the unit's histfig ID, you make one based on the next histfig id (which the game conveniently provides) then make a new histfig from scratch. Really, it's about as hard as creating the unit in the first place.

Dame de la Licorne

  • Bay Watcher
  • Cats? Check. FPS? Uh-oh...
    • View Profile
Re: DFHack usage help
« Reply #7 on: June 30, 2016, 08:11:04 pm »

You don't find the unit's histfig ID, you make one based on the next histfig id (which the game conveniently provides) then make a new histfig from scratch. Really, it's about as hard as creating the unit in the first place.

And how do you do each of those?  Exactly (assume I know nothing about DFHack other than how to download and open the program).

-Dame de la Licorne
Logged
If software was real world, then it'd be something equivalent of hitting a nail with a hammer and having a building collapse on the other side of town.

Don't worry people, sometimes -moments occur

Dirst

  • Bay Watcher
  • [EASILY_DISTRA
    • View Profile
Re: DFHack usage help
« Reply #8 on: June 30, 2016, 08:20:53 pm »

Some typical cases, all of which spawn the unit at the current cursor location...

To make a citizen (who will not have any relationships):

modtools/create-unit -race DWARF -caste FEMALE -name MOUNTAIN -age 30 -civId \\LOCAL -groupId \\LOCAL

(Try one or two leading backslashes; the correct answer can depend on whether you running from a script, an init file or the console)

To make a domesticated animal:

modtools/create-unit -race DOG -caste MALE -age 5 -domesticate

(Domesticate should automatically make it a member of your fort or your Adventurer's faction.  Domesticating an animal to another civ takes more work.)

To make a wild animal:

modtools/create-unit -race GIANT_GOAT_MOUNTAIN -caste MALE -civId \\-1 -flagSet [ marauder ]

(Again check single and double backslashes.  Also note the spacing around the brackets... you're providing a list of flags, but this list is one item long.)

You can try to make "invaders" but they won't be attached to a proper siege.  At the moment you also can't properly attach a creature to a map feature (e.g., a river or cavern layer) but that doesn't seem to cause any visible problems.
Logged
Just got back, updating:
(0.42 & 0.43) The Earth Strikes Back! v2.15 - Pay attention...  It's a mine!  It's-a not yours!
(0.42 & 0.43) Appearance Tweaks v1.03 - Tease those hippies about their pointy ears.
(0.42 & 0.43) Accessibility Utility v1.04 - Console tools to navigate the map

Dame de la Licorne

  • Bay Watcher
  • Cats? Check. FPS? Uh-oh...
    • View Profile
Re: DFHack usage help
« Reply #9 on: June 30, 2016, 09:39:05 pm »

You can try to make "invaders" but they won't be attached to a proper siege.  At the moment you also can't properly attach a creature to a map feature (e.g., a river or cavern layer) but that doesn't seem to cause any visible problems.

Shoot.  There goes that idea.

For the rest of it, thanks!  I was using the wrong syntax (which I knew), but I would never have come up with the correct syntax, so arigato, kind sensei.

-Dame de la Licorne
Logged
If software was real world, then it'd be something equivalent of hitting a nail with a hammer and having a building collapse on the other side of town.

Don't worry people, sometimes -moments occur

lethosor

  • Bay Watcher
    • View Profile
Re: DFHack usage help
« Reply #10 on: June 30, 2016, 10:47:05 pm »

Note that in recent versions of DFHack (around 0.40+), spawnunit is actually a wrapper around create-unit, just with slightly different syntax that matches the old spawnunit script in 0.34. It should still have the same functionality. From "spawnunit help":
Code: [Select]
spawnunit
=========
Provides a simpler interface to `modtools/create-unit`, for creating units.

Usage:  ``spawnunit [-command] RACE CASTE [NAME] [x y z] [...]``

The ``-command`` flag prints the generated `modtools/create-unit` command
instead of running it.  ``RACE`` and ``CASTE`` specify the race and caste
of the unit to be created.  The name and coordinates of the unit are optional.
Any further arguments are simply passed on to `modtools/create-unit`.

So any additional arguments besides RACE, CASTE, NAME, and possibly x/y/z get passed directly to modtools/create-unit (and if you throw in "-command" at the beginning, it'll show you the equivalent create-unit command instead of running it).
Logged
DFHack - Dwarf Manipulator (Lua) - DF Wiki talk

There was a typo in the siegers' campfire code. When the fires went out, so did the game.

TheImmortalRyukan

  • Bay Watcher
  • Master Story Weaver
    • View Profile
Re: DFHack usage help
« Reply #11 on: February 21, 2017, 02:25:36 pm »

Ah thanks for clearing up the "backslash" "frontslash" thing... I was panicking.


So I have managed to "poof" in 3 nude elves in my fortress's Tavern that I haned picks to and told them to mine...

Elf slave fort, I should do that one in the future...
Logged
The Tale of Runlance - A Succession Fort in a Dying World

While the drink stocks run low and violence is rampant, the narcissistic tyrant demands a monument to his name