Dwarf Fortress > DF Modding

Can I...?

(1/1)

CptAWatts22:
Edit my adventurers group into a Civ through a save file?

Asin:
Not possible.

CptAWatts22:
damn, ok.

Atkana:
While I don't know about editing saves, I do know this is possible with dfhack. My most recent bit of dfhackery had me learning a bit about how entities work so I've managed to create a couple of scripts to do this. This comes with caveats, of course: what I know about entities is still very limited and it might require more than what my scripts currently do to have the game treat your group properly (it's lacking things like diplomacy, historical events, site links, and other stuff that might be important) - all I know is it's enough for Legends Viewer to mention the group as part of the civilization. Also it might corrupt saves (I just assume anything I code does that).

The first script is used to get the IDs of the Entities (Your adventuring group, The civilization) using their names:
Spoiler (click to show/hide)find-entity.lua

--- Code: -----Prints the ID of an Entity to console using the given entity name
--Not sure why I named it like this was going to be one comprehensive script
--This all hinges on an assumption that DF won't let 2 entities have the same name

local usage = [====[

find-entity
=====================
Tells the user the id of an entity

Arguments:

-entityName
the name of the entity, held inside quotes.
examples:
"The Style of Yells"
"The Heroic Meadow"

]====]

local utils = require 'utils'

validArgs = validArgs or utils.invert({
'help',
'entityName'
})

local args = utils.processArgs({...},validArgs)

if args.help then
print(usage)
return
end

if not args.entityName or args.entityName == "" then
print('Please specify the name of the group, surrounded in quotes, with -entityName')
return
end

--
for i = 1, #df.global.world.entities.all, 1 do
local alti = i-1
local current = df.global.world.entities.all[alti]

if string.lower(dfhack.TranslateName(current.name, true)) == string.lower(args.entityName) then
--Match found!
print("The Entity ID for " .. args.entityName .. " is: " .. current.id)
return
end
end

--Otherwise, none found.
print("Couldn't find an entity by the name of " .. args.entityName)
return
--- End code ---

The second script does the actual linking. There's no checking to see if the group and civ aren't already linked, so that part's on the user if they link something already link and break everything :P
Spoiler (click to show/hide)addGroupToCiv.lua

--- Code: -----Add an chosen entity to another chosen entity as a child
--Again, not sure why I'm taking the time to make this all proper-looking :P

--[[
IMPORTANT NOTES: This script does no checking to see if the two entities were already linked to begin with - stuff will probably screw up if you try to do that. In fact, the script might just screw things up even if it works correctly. It's all built on a very limited knowledge of how entities work.
This script is at least enough that Legends viewer treats the group as part of the Civ. In order to make a 'proper' link that the game uses, there might have to be some things done with diplomacy, historical events, site links, etc. This script only just does the bare minimum.
]]


local usage = [====[

addGroupToCiv
=====================
Adds a Group as a child to a parent Civ (technically, any entity type)

Arguements:
-groupId
the id of the entity you want to attatch to a civ
-civId
the id of the civ you want the entity to be attatched to
]====]

local utils = require 'utils'

validArgs = validArgs or utils.invert({
'help',
'groupId',
'civId'
})

local args = utils.processArgs({...}, validArgs)

if args.help then
print(usage)
return
end

if not args.groupId then
print("Please provide a groupId")
return
end

if not args.civId then
print("Please provide a civId")
return
end

local groupId = args.groupId
local civId = args.civId

local group = df.historical_entity.find(groupId)
local civ = df.historical_entity.find(civId)

--Update the civ
civ.entity_links:insert("#",{new = df.entity_entity_link, type = 1, target = group.id, strength=100})
civ.children:insert("#", group.id)
--Update the group
group.entity_links:insert("#", {new = df.entity_entity_link, type = 0, target = civ.id, strength = 100})

--Screw error checking, let's just assume we've done it and say something to that effect!
print("Successfully joined " .. dfhack.TranslateName(group.name, true) .. " to " .. dfhack.TranslateName(civ.name, true))
--- End code ---

This all assumes you've got some familiarity with dfhack, but hey - if you were willing to learn how to edit save files, then you're probably willing to learn how to use/install dfhack :P

Navigation

[0] Message Index

Go to full version