Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: How to extract civ symbols from world data?  (Read 997 times)

Redman9012

  • Bay Watcher
    • View Profile
How to extract civ symbols from world data?
« on: May 21, 2022, 08:56:04 pm »

I want to get the civilization and group symbols on my world for D&D purposes, is there a program or plugin I can use to extract the symbol info or a way to get most of the symbols at once?
Logged

Mobbstar

  • Bay Watcher
  • aka Mossbird
    • View Profile
    • my website
Re: How to extract civ symbols from world data?
« Reply #1 on: May 22, 2022, 02:24:14 am »

PTW, I haven't found any solutions to this yet (not even DFHack plugins).

For dwarves, humans, and goblins, you can spawn an adventurer at one of their forts and look at the decorations on their guards.  This is an unreliable and difficult approach, but at least it proves that the data is available in the game.

A_Curious_Cat

  • Bay Watcher
    • View Profile
Re: How to extract civ symbols from world data?
« Reply #2 on: May 22, 2022, 05:54:50 am »

Have you considered asking in the DFHack thread?
Logged
Really hoping somebody puts this in their signature.

Quietust

  • Bay Watcher
  • Does not suffer fools gladly
    • View Profile
    • QMT Productions
Re: How to extract civ symbols from world data?
« Reply #3 on: May 22, 2022, 10:52:19 pm »

From what I recall, civilization symbols are stored as art image references in [entity].resources.art_image_ids[]/art_image_subids[] where the corresponding art_image_types[] value is zero.

However, Dwarf Fortress only loads art images into memory on demand, so you might need to use some special techniques in order to force it to load them for you. One method that comes to mind (which I haven't actually tested yet but which ought to work reasonably well) would be to instantiate an itemimprovement_art_imagest object, fill in the image.id and image.subid values from above, call the getImage() vmethod on it (which accepts NULL as long as the id/subid values aren't "-1") to return an actual art_image structure, and finally examine the art_image's elements and properties to determine exactly what it depicts.

If you need assistance with figuring out how to do this, I'd recommend checking the DFHack Discord server or the IRC channel on the Libera Chat network.

EDIT: I got bored and wrote a DFHack Lua script to print all civilization symbols.

Code: [Select]
imp = df.itemimprovement_art_imagest:new()
str = df.new('string')
for _,i in pairs(df.global.world.entities.all) do
for j,_ in pairs(i.resources.art_image_types) do
if i.resources.art_image_types[j] == 0 then
imp.image.id = i.resources.art_image_ids[j]
imp.image.subid = i.resources.art_image_subids[j]
img = imp:getImage(nil)
desc = nil
for _,e in pairs(img.elements) do
e:getName1(str, false, true)
if desc == nil then
desc = str.value
else
desc = desc .. " and " .. str.value
end
end
desc = desc .. "."
for _,p in pairs(img.properties) do
-- TODO - once DFHack is updated to 0.47.05-r6 or later, use this line instead of the one below
-- p:getName(str, img, true)
p:getName(str, img, nil)
desc = desc .. " " .. str.value
end
print(desc)
end
end
end

str:delete()
imp:delete()
« Last Edit: May 24, 2022, 10:43:54 am by Quietust »
Logged
P.S. If you don't get this note, let me know and I'll write you another.
It's amazing how dwarves can make a stack of bones completely waterproof and magmaproof.
It's amazing how they can make an entire floodgate out of the bones of 2 cats.

Redman9012

  • Bay Watcher
    • View Profile
Re: How to extract civ symbols from world data?
« Reply #4 on: May 24, 2022, 06:38:22 pm »

Ah, how would i go using this plugin, I don't use DFHack normally.

I already got it installed on the DF copy with the world in question btw.
Logged

Mobbstar

  • Bay Watcher
  • aka Mossbird
    • View Profile
    • my website
Re: How to extract civ symbols from world data?
« Reply #5 on: May 25, 2022, 11:34:03 am »

EDIT: I got bored and wrote a DFHack Lua script to print all civilization symbols.

Thank you so much!  Unfortunately, it doesn't seem to show the entity or symbol names.  I'll see if I can figure out how the data structures work.  Surely there's a function to get the name similar to how it's done for the art properties.

(Edited 30min after posting)  Got it working.  It was a little fun, even!  (There's a bunch of entities at the start that have no name, apparently.  All the regular civs and governments seem to be available.)

Spoiler: civ-symbols.lua (click to show/hide)

Ah, how would i go using this plugin, I don't use DFHack normally.

I already got it installed on the DF copy with the world in question btw.

Put it as a lua file like so:  ./hack/scripts/civ-symbols.lua
Then you can load the savefile and run civ-symbols in DFHack's console.
« Last Edit: May 25, 2022, 12:09:57 pm by Mobbstar »
Logged

Redman9012

  • Bay Watcher
    • View Profile
Re: How to extract civ symbols from world data?
« Reply #6 on: May 25, 2022, 06:27:59 pm »

Tried the script and it works well, too well in fact, as because it prints the symbols of every people group, i can;t see all of the symbols on the command line due to there being way too many symbols on my extra large world haha.

Think I'm gonna see if i can make it blurt out a .txt in windows or something so that i can at least find the symbols i need more easily with a search function.

Thanks a lot for the scripts!

EDIT:

Managed to read some documentation and made it possible for the script to write a file with all the symbol info, it should also overwrite it every time it's used, so no spam with 1000000000 different symbols from multiple worlds every time it's used. It seems the console only managed to get around the last ¼ of the symbols on the world, so this paired with legends mode and legends viewer will let me give to my D&D players all the symbol info we need/want.

Again, thank you all for the help, this has also helped me get a bit more familiar with DFHack to extract info for future campaigns.

Code here:
Code: [Select]
imp = df.itemimprovement_art_imagest:new()
str = df.new('string')
file = io.open("civ-symbols.txt", "w+")
for _,i in pairs(df.global.world.entities.all) do
for j,_ in pairs(i.resources.art_image_types) do
if i.resources.art_image_types[j] == 0 then
imp.image.id = i.resources.art_image_ids[j]
imp.image.subid = i.resources.art_image_subids[j]
img = imp:getImage(nil)
desc = nil
for _,e in pairs(img.elements) do
e:getName1(str, false, true)
if desc == nil then
desc = str.value
else
desc = desc .. " and " .. str.value
end
end
desc = desc .. "."
for _,p in pairs(img.properties) do
-- TODO - once DFHack is updated to 0.47.05-r6 or later, use this line instead of the one below
-- p:getName(str, img, true)
p:getName(str, img, nil)
desc = desc .. " " .. str.value
end
desc = "The symbol of " .. dfhack.TranslateName(i.name, true) .. " is called " .. dfhack.TranslateName(img.name, true) .. ". It depicts " .. desc
print(desc)
file:write(desc .. "\n")
end
end
end
file:close()
str:delete()
imp:delete()
« Last Edit: May 25, 2022, 07:01:51 pm by Redman9012 »
Logged