Skip to content

Commit 9ded4ff

Browse files
committed
Added many forum scripts, and a makeshift onReport/onStrike event that will be merged into eventful/EventManager later.
1 parent 078b882 commit 9ded4ff

22 files changed

Lines changed: 3742 additions & 0 deletions

ShowUnitSyndromes.rb

Lines changed: 1013 additions & 0 deletions
Large diffs are not rendered by default.

Spawnunit.lua

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
--Spawnunit.lua
2+
--create unit at pointer. Usage e.g. "spawnunit DWARF 0 Dwarfy"
3+
--author Warmist, Runrusher?
4+
--edited by expwnent
5+
6+
function findCasteIndex(race_id,casteName)
7+
local cr=df.creature_raw.find(race_id)
8+
for casteIndex,caste in ipairs(cr.caste) do
9+
if caste.caste_id == casteName then
10+
return casteIndex
11+
end
12+
end
13+
return nil
14+
end
15+
function getCaste(race_id,caste_id)
16+
local cr=df.creature_raw.find(race_id)
17+
return cr.caste[caste_id]
18+
end
19+
function genBodyModifier(body_app_mod)
20+
local a=math.random(0,#body_app_mod.ranges-2)
21+
return math.random(body_app_mod.ranges[a],body_app_mod.ranges[a+1])
22+
end
23+
function getBodySize(caste,time)
24+
--todo real body size...
25+
return caste.body_size_1[#caste.body_size_1-1] --returns last body size
26+
end
27+
function genAttribute(array)
28+
local a=math.random(0,#array-2)
29+
return math.random(array[a],array[a+1])
30+
end
31+
function norm()
32+
return math.sqrt((-2)*math.log(math.random()))*math.cos(2*math.pi*math.random())
33+
end
34+
function normalDistributed(mean,sigma)
35+
return mean+sigma*norm()
36+
end
37+
function clampedNormal(min,median,max)
38+
local val=normalDistributed(median,math.sqrt(max-min))
39+
if val<min then return min end
40+
if val>max then return max end
41+
return val
42+
end
43+
function makeSoul(unit,caste)
44+
local tmp_soul=df.unit_soul:new()
45+
tmp_soul.unit_id=unit.id
46+
tmp_soul.name:assign(unit.name)
47+
tmp_soul.race=unit.race
48+
tmp_soul.sex=unit.sex
49+
tmp_soul.caste=unit.caste
50+
--todo skills,preferences,traits.
51+
local attrs=caste.attributes
52+
for k,v in pairs(attrs.ment_att_range) do
53+
local max_percent=attrs.ment_att_cap_perc[k]/100
54+
local cvalue=genAttribute(v)
55+
tmp_soul.mental_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
56+
end
57+
for k,v in pairs(tmp_soul.traits) do
58+
local min,mean,max
59+
min=caste.personality.a[k]
60+
mean=caste.personality.b[k]
61+
max=caste.personality.c[k]
62+
tmp_soul.traits[k]=clampedNormal(min,mean,max)
63+
end
64+
unit.status.souls:insert("#",tmp_soul)
65+
unit.status.current_soul=tmp_soul
66+
end
67+
function CreateUnit(race_id,caste_id)
68+
local race=df.creature_raw.find(race_id)
69+
if race==nil then error("Invalid race_id") end
70+
local caste=getCaste(race_id,caste_id)
71+
local unit=df.unit:new()
72+
unit.race=race_id
73+
unit.caste=caste_id
74+
unit.id=df.global.unit_next_id
75+
df.global.unit_next_id=df.global.unit_next_id+1
76+
if caste.misc.maxage_max==-1 then
77+
unit.relations.old_year=-1
78+
else
79+
unit.relations.old_year=math.random(caste.misc.maxage_min,caste.misc.maxage_max)
80+
end
81+
unit.sex=caste.gender
82+
local body=unit.body
83+
body.body_plan=caste.body_info
84+
local body_part_count=#body.body_plan.body_parts
85+
local layer_count=#body.body_plan.layer_part
86+
--components
87+
unit.relations.birth_year=df.global.cur_year
88+
--unit.relations.birth_time=??
89+
90+
--unit.relations.old_time=?? --TODO add normal age
91+
local cp=body.components
92+
cp.body_part_status:resize(body_part_count)
93+
cp.numbered_masks:resize(#body.body_plan.numbered_masks)
94+
for num,v in ipairs(body.body_plan.numbered_masks) do
95+
cp.numbered_masks[num]=v
96+
end
97+
98+
cp.layer_status:resize(layer_count)
99+
cp.layer_wound_area:resize(layer_count)
100+
cp.layer_cut_fraction:resize(layer_count)
101+
cp.layer_dent_fraction:resize(layer_count)
102+
cp.layer_effect_fraction:resize(layer_count)
103+
local attrs=caste.attributes
104+
for k,v in pairs(attrs.phys_att_range) do
105+
local max_percent=attrs.phys_att_cap_perc[k]/100
106+
local cvalue=genAttribute(v)
107+
unit.body.physical_attrs[k]={value=cvalue,max_value=cvalue*max_percent}
108+
--unit.body.physical_attrs:insert(k,{new=true,max_value=genMaxAttribute(v),value=genAttribute(v)})
109+
end
110+
111+
body.blood_max=getBodySize(caste,0) --TODO normal values
112+
body.blood_count=body.blood_max
113+
body.infection_level=0
114+
unit.status2.body_part_temperature:resize(body_part_count)
115+
for k,v in pairs(unit.status2.body_part_temperature) do
116+
unit.status2.body_part_temperature[k]={new=true,whole=10067,fraction=0}
117+
end
118+
--------------------
119+
local stuff=unit.enemy
120+
stuff.body_part_878:resize(body_part_count) -- all = 3
121+
stuff.body_part_888:resize(body_part_count) -- all = 3
122+
stuff.body_part_relsize:resize(body_part_count) -- all =0
123+
124+
--TODO add correct sizes. (calculate from age)
125+
local size=caste.body_size_2[#caste.body_size_2-1]
126+
body.size_info.size_cur=size
127+
body.size_info.size_base=size
128+
body.size_info.area_cur=math.pow(size,0.666)
129+
body.size_info.area_base=math.pow(size,0.666)
130+
body.size_info.area_cur=math.pow(size*10000,0.333)
131+
body.size_info.area_base=math.pow(size*10000,0.333)
132+
133+
stuff.were_race=race_id
134+
stuff.were_caste=caste_id
135+
stuff.normal_race=race_id
136+
stuff.normal_caste=caste_id
137+
stuff.body_part_8a8:resize(body_part_count) -- all = 1
138+
stuff.body_part_base_ins:resize(body_part_count)
139+
stuff.body_part_clothing_ins:resize(body_part_count)
140+
stuff.body_part_8d8:resize(body_part_count)
141+
unit.recuperation.healing_rate:resize(layer_count)
142+
--appearance
143+
144+
local app=unit.appearance
145+
app.body_modifiers:resize(#caste.body_appearance_modifiers) --3
146+
for k,v in pairs(app.body_modifiers) do
147+
app.body_modifiers[k]=genBodyModifier(caste.body_appearance_modifiers[k])
148+
end
149+
app.bp_modifiers:resize(#caste.bp_appearance.modifier_idx) --0
150+
for k,v in pairs(app.bp_modifiers) do
151+
app.bp_modifiers[k]=genBodyModifier(caste.bp_appearance.modifiers[caste.bp_appearance.modifier_idx[k]])
152+
end
153+
--app.unk_4c8:resize(33)--33
154+
app.tissue_style:resize(#caste.bp_appearance.style_part_idx)
155+
app.tissue_style_civ_id:resize(#caste.bp_appearance.style_part_idx)
156+
app.tissue_style_id:resize(#caste.bp_appearance.style_part_idx)
157+
app.tissue_style_type:resize(#caste.bp_appearance.style_part_idx)
158+
app.tissue_length:resize(#caste.bp_appearance.style_part_idx)
159+
app.genes.appearance:resize(#caste.body_appearance_modifiers+#caste.bp_appearance.modifiers) --3
160+
app.genes.colors:resize(#caste.color_modifiers*2) --???
161+
app.colors:resize(#caste.color_modifiers)--3
162+
163+
makeSoul(unit,caste)
164+
165+
df.global.world.units.all:insert("#",unit)
166+
df.global.world.units.active:insert("#",unit)
167+
--todo set weapon bodypart
168+
169+
local num_inter=#caste.body_info.interactions
170+
--used to be anon_5 and anon_6: I guessed at what those were before the df-structures update. It seems to work at least a bit. ~expwnent
171+
unit.curse.own_interaction:resize(num_inter)
172+
unit.curse.own_interaction_delay:resize(num_inter)
173+
return unit
174+
end
175+
function findRace(name)
176+
for k,v in pairs(df.global.world.raws.creatures.all) do
177+
if v.creature_id==name then
178+
return k
179+
end
180+
end
181+
qerror("Race:"..name.." not found!")
182+
end
183+
function PlaceUnit(raceName,casteName,name,position)
184+
local pos
185+
if position.x==-30000 then
186+
pos = copyall(df.global.cursor)
187+
else
188+
pos = position
189+
end
190+
if pos.x==-30000 then
191+
qerror("Spawnunit: specify location or place the cursor where you want the unit to be created.")
192+
end
193+
local race=findRace(raceName)
194+
local caste=findCasteIndex(race,casteName)
195+
local u=CreateUnit(race,tonumber(caste) or 0)
196+
u.pos:assign(pos)
197+
if name then
198+
u.name.first_name=name
199+
u.name.has_name=true
200+
end
201+
u.civ_id=df.global.ui.civ_id
202+
203+
local desig,ocupan=dfhack.maps.getTileFlags(pos)
204+
ocupan.unit=true
205+
--createNemesis(u)
206+
end
207+
function createFigure(trgunit)
208+
local hf=df.historical_figure:new()
209+
hf.id=df.global.hist_figure_next_id
210+
hf.race=trgunit.race
211+
hf.caste=trgunit.caste
212+
df.global.hist_figure_next_id=df.global.hist_figure_next_id+1
213+
hf.name.first_name=trgunit.name.first_name
214+
hf.name.has_name=true
215+
df.global.world.history.figures:insert("#",hf)
216+
return hf
217+
end
218+
function createNemesis(trgunit)
219+
local id=df.global.nemesis_next_id
220+
local nem=df.nemesis_record:new()
221+
nem.id=id
222+
nem.unit_id=trgunit.id
223+
nem.unit=trgunit
224+
nem.flags:resize(1)
225+
nem.flags[4]=true
226+
nem.flags[5]=true
227+
nem.flags[6]=true
228+
nem.flags[7]=true
229+
nem.flags[8]=true
230+
nem.flags[9]=true
231+
--[[for k=4,8 do
232+
nem.flags[k]=true
233+
end]]
234+
df.global.world.nemesis.all:insert("#",nem)
235+
df.global.nemesis_next_id=id+1
236+
trgunit.general_refs:insert("#",{new=df.general_ref_is_nemesisst,nemesis_id=id})
237+
trgunit.flags1.important_historical_figure=true
238+
local gen=df.global.world.worldgen
239+
nem.save_file_id=gen.next_unit_chunk_id;
240+
gen.next_unit_chunk_id=gen.next_unit_chunk_id+1
241+
gen.next_unit_chunk_offset=gen.next_unit_chunk_offset+1
242+
243+
--[[ local gen=df.global.world.worldgen
244+
gen.next_unit_chunk_id
245+
gen.next_unit_chunk_offset
246+
]]
247+
nem.figure=createFigure(trgunit)
248+
end
249+
250+
args={...}
251+
252+
pos = df.new(df.coord)
253+
if #args > 3 then
254+
pos.x = tonumber(args[4]) or -30000
255+
pos.y = tonumber(args[5]) or -30000
256+
pos.z = tonumber(args[6]) or -30000
257+
end
258+
259+
PlaceUnit(args[1],args[2],args[3],pos)
260+

blooddel.lua

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--blooddel.lua
2+
--makes it so that civs won't come with barrels full of blood, ichor, or goo
3+
--author Urist Da Vinci
4+
--edited by expwnent
5+
6+
local my_entity=df.historical_entity.find(df.global.ui.civ_id)
7+
local sText=" "
8+
local k=0
9+
local v=1
10+
11+
for x,y in pairs(df.global.world.entities.all) do
12+
my_entity=y
13+
k=0
14+
while k < #my_entity.resources.misc_mat.extracts.mat_index do
15+
v=my_entity.resources.misc_mat.extracts.mat_type[k]
16+
sText=dfhack.matinfo.decode(v,my_entity.resources.misc_mat.extracts.mat_index[k])
17+
if (sText==nil) then
18+
--LIQUID barrels
19+
my_entity.resources.misc_mat.extracts.mat_type:erase(k)
20+
my_entity.resources.misc_mat.extracts.mat_index:erase(k)
21+
k=k-1
22+
else
23+
if(sText.material.id=="BLOOD") then
24+
my_entity.resources.misc_mat.extracts.mat_type:erase(k)
25+
my_entity.resources.misc_mat.extracts.mat_index:erase(k)
26+
k=k-1
27+
end
28+
if(sText.material.id=="ICHOR") then
29+
my_entity.resources.misc_mat.extracts.mat_type:erase(k)
30+
my_entity.resources.misc_mat.extracts.mat_index:erase(k)
31+
k=k-1
32+
end
33+
if(sText.material.id=="GOO") then
34+
my_entity.resources.misc_mat.extracts.mat_type:erase(k)
35+
my_entity.resources.misc_mat.extracts.mat_index:erase(k)
36+
k=k-1
37+
end
38+
--VENOM
39+
--POISON
40+
--FLUID
41+
--MILK
42+
--EXTRACT
43+
44+
end
45+
k=k+1
46+
end
47+
end
48+

feeding-timers.lua

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
-- feeding-timers.lua
2+
-- original author: tejón
3+
-- rewritten by expwnent
4+
-- see repeat.lua for how to run this every so often automatically
5+
6+
local args = {...}
7+
if args[1] ~= nil then
8+
print("feeding-timers usage")
9+
print(" feeding-timers")
10+
print(" reset the feeding timers of all units as appropriate")
11+
print(" feeding-timers help")
12+
print(" print this help message")
13+
print(" repeat enable [n] [years/months/ticks/days/etc] feeding-timers")
14+
print(" run this script every n time units")
15+
print(" repeat disable feeding-timers")
16+
print(" stop automatically running this script")
17+
return
18+
end
19+
20+
local fixcount = 0
21+
for _,unit in ipairs(df.global.world.units.all) do
22+
if dfhack.units.isCitizen(unit) and not (unit.flags1.dead) then
23+
for _,v in pairs(unit.status.misc_traits) do
24+
local didfix = 0
25+
if v.id == 0 then -- I think this should have additional conditions...
26+
v.value = 0 -- GiveWater cooldown set to zero
27+
didfix = 1
28+
end
29+
if v.id == 1 then -- I think this should have additional conditions...
30+
v.value = 0 -- GiveFood cooldown set to zero
31+
didfix = 1
32+
end
33+
fixcount = fixcount + didfix
34+
end
35+
end
36+
end
37+
print("Fixed feeding timers for " .. fixcount .. " citizens.")

0 commit comments

Comments
 (0)