df-structures
df-structures copied to clipboard
df.world.xml:incident_sub6 field determination investigation
I've tried to determine some of the parameters of the _sub6 struct and believe I've had some success. This is what I've concluded:
<struct-type type-name='incident_sub6' comment='Performance incident parameters'>
<int32_t name='performance_event' type-name='performance_event_type'/>
<stl-vector name='participants'>
<pointer>
<int32_t/>
<int32_t/>
<compound type-name='incident_hfid'/>
<int32_t/>
</pointer>
</stl-vector>
<int32_t name='reference_id' comment='history_event id/poetic_form id/musical_form id/dance_form_id or -1'/>
<int32_t name='written_content id or -1'/>
<int32_t/>
<int32_t/>
<int32_t/>
<int32_t/>
</struct-type>
-- There ought to be either a type specific reference or a written content one. Not both.
-- Story has only been seen with a history event id, not a written content one, but the sample was small.
-- Poem has been seen with either a poetic form or a written content reference.
-- Music has been seen only with a music form reference, but the sample was small.
-- Music has been seen to be "sang" and "spoke" in DF displayed thoughts, but no instrument playing
-- or simulation. It's still unknown how to determine what action participants took.
-- Dance has been seen only with a dance form reference, but the sample was small.
I've used the following script to extract data from a small number of saves:
function x ()
local civ_id = df.global.world.world_data.active_site [0].entity_links [0].entity_id
local count = 0
for i, incident in ipairs (df.global.world.incidents.all) do
if incident.subtype == 6 then
local active = false
for k, participant in ipairs (incident.unk_v42_1.t6.anon_2) do
local hf = df.historical_figure.find (participant.anon_3.hfid)
if hf and hf.civ_id == civ_id then
local unit = df.unit.find (hf.unit_id)
if unit then
for l, emotion in ipairs (unit.status.current_soul.personality.emotions) do
if emotion.thought == df.unit_thought_type.Perform and
emotion.subthought == incident.id then
if not active then
count = count + 1
end
dfhack.print ("Incident " .. tostring (incident.id))
dfhack.print (", " .. dfhack.TranslateName (unit.name, false))
dfhack.print (", Emotion " .. tostring (l) .. ", anon_1: " .. tostring (incident.unk_v42_1.t6.anon_1))
dfhack.print (", anon_1: " .. tostring (participant.anon_1) .. ", anon_4: " .. tostring (participant.anon_4))
-- incident.unk_v42_1.t6.anon_1 = df.performance_event_type
if incident.unk_v42_1.t6.anon_1 == 0 then -- History event story. anon_3 = event id, anon_4 = written contents id?
dfhack.println (", Tell History Event Story. anon_3: " .. tostring (incident.unk_v42_1.t6.anon_3))
elseif incident.unk_v42_1.t6.anon_1 == 1 then -- Recite poem. anon_3 = poetry form, anon_4 = written contents id
if incident.unk_v42_1.t6.anon_3 == -1 then
dfhack.println (", Recite: Type: " .. tostring (df.written_content_type [df.written_content.find (incident.unk_v42_1.t6.anon_4).type]))
else
dfhack.println (", Recite Poetic Form: " .. dfhack.TranslateName (df.poetic_form.find (incident.unk_v42_1.t6.anon_3).name, true))
end
elseif incident.unk_v42_1.t6.anon_1 == 2 then -- Musical composition. anon_3 = music form?, anon_4 = written contents id
if incident.unk_v42_1.t6.anon_3 == -1 then
dfhack.println (", Speak/Sing: Type: " .. tostring (df.written_content_type [df.written_content.find (incident.unk_v42_1.t6.anon_4).type]))
-- Sang: anon_5: 0, anon_6: -1, anon_7: 137, anon_8: -1
-- anon_1: 2, anon_2: 0, anon_4: 14
-- Spoke:anon_5: -1, anon_6: -1, anon_7: 0, anon_8: -1
-- anon_1: 2, anon_2: 0, anon_4: 0
-- Spoke:anon_5: -1, anon_6: -1, anon_7: 17, anon_8: -1
-- anon_1: 2, anon_2: 0, anon_4: 0
--### anon_5: -1 = Speak, , 0 = Sing, 1+ = instrument? Should be per participant, not individual?
else
dfhack.println (", Music: " .. dfhack.TranslateName (df.musical_form.find (incident.unk_v42_1.t6.anon_3).name, true))
end
elseif incident.unk_v42_1.t6.anon_1 == 3 then -- Dance. anon_3 = dance form id, anon_4 = written contents id?
dfhack.println (", anon_3: " .. tostring (incident.unk_v42_1.t6.anon_3))
else
dfhack.println (", Unmapped type: " .. tostring (incident.unk_v42_1.t6.anon_1))
end
active = true
end
end
end
end
end
end
end
dfhack.println ("Active performance incidents: " .. tostring (count))
end
x ()
The script used the "official" layout, not the one above (which hasn't yet been processed, so it may contain syntactic errors). The output of the script has been processed by looking up the listed citizens and DFHack the specified "emotion" entry to have the "unk2" and "strength" fields both set to 100 (and the flags [5] flag reset, if set; that's the "remembered" field). When that is done that emotion gets promoted to the one shown with extra details at the top on the unit's "Thoughts and Preferences" screen (which has to be refreshed for the changes to take effect). Obviously another 100/100 pair can trump the one you want, although I've seen that only with my own manipulations not being withdrawn. The thought has then been compared to what the parameters would produce, eventually leading to the conclusions above. I haven't gone through every poetry case (there were a lot of those), but each of the others (of which there were fewer than I'd like).
df.meetings.xml:activity_event_performancest seems to indicate that only poetry can reference written contents, not any of the other performance forms. I've seen nothing to contradict that conclusion, but there are written contents with types that might work as targets for stories, music, and dances, so the scripts tries to cater for such cases.