- Notifications
You must be signed in to change notification settings - Fork201
/
Copy pathassign-beliefs.lua
211 lines (177 loc) · 7.05 KB
/
assign-beliefs.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
-- Change the beliefs of a unit.
--@ module = true
localhelp=[====[
assign-beliefs
==============
A script to change the beliefs (values) of a unit.
Beliefs are defined with the belief token and a number from -3 to 3,
which describes the different levels of belief strength, as explained here:
https://dwarffortresswiki.org/index.php/DF2014:Personality_trait#Beliefs
======== =========
Strength Effect
======== =========
3 Highest
2 Very High
1 High
0 Neutral
-1 Low
-2 Very Low
-3 Lowest
======== =========
Resetting a belief means setting it to a level that does not trigger a
report in the "Thoughts and preferences" screen.
Usage:
``-help``:
print the help page.
``-unit <UNIT_ID>``:
set the target unit ID. If not present, the
currently selected unit will be the target.
``-beliefs [ <BELIEF> <LEVEL> <BELIEF> <LEVEL> <...> ]``:
the beliefs to modify and their levels. The
valid belief tokens can be found in the wiki page
linked above; level values range from -3 to 3.
There must be a space before and after each square
bracket.
``-reset``:
reset all beliefs to a neutral level. If the script is
called with both this option and a list of beliefs/levels,
first all the unit beliefs will be reset and then those
beliefs listed after ``-beliefs`` will be modified.
Example::
assign-beliefs -reset -beliefs [ TRADITION 2 CRAFTSMANSHIP 3 POWER 0 CUNNING -1 ]
Resets all the unit beliefs, then sets the listed beliefs to the following
values:
* Tradition: a random value between 26 and 40 (level 2);
* Craftsmanship: a random value between 41 and 50 (level 3);
* Power: a random value between -10 and 10 (level 0);
* Cunning: a random value between -25 and -11 (level -1).
The final result (for a dwarf) will be: "She personally is a firm believer in
the value of tradition and sees guile and cunning as indirect and somewhat
worthless."
Note that the beliefs aligned with the cultural values of the unit have not
triggered a report.
]====]
localutils=require("utils")
localsetneed=reqscript("modtools/set-need")
localvalid_args=utils.invert({
'help',
'unit',
'beliefs',
'reset',
})
-- ----------------------------------------------- UTILITY FUNCTIONS ------------------------------------------------ --
localfunctionprint_yellow(text)
dfhack.color(COLOR_YELLOW)
print(text)
dfhack.color(-1)
end
-- ------------------------------------------------- ASSIGN BELIEFS ------------------------------------------------- --
-- NOTE: in the game data, beliefs are called values.
--- Assign the given beliefs to a unit, clearing all the other beliefs if requested.
--- :beliefs: nil, or a table. The fields have the belief name as key and its level as value.
--- :unit: a valid unit id, a df.unit object, or nil. If nil, the currently selected unit will be targeted.
--- :reset: boolean, or nil.
functionassign(beliefs,unit,reset)
assert(notbeliefsortype(beliefs)=="table")
assert(notunitortype(unit)=="number"ordf.unit:is_instance(unit))
assert(notresetortype(reset)=="boolean")
beliefs=beliefsor {}
reset=resetorfalse
iftype(unit)=="number"then
unit=df.unit.find(tonumber(unit))--luacheck:retype
end
unit=unitordfhack.gui.getSelectedUnit(true)
ifnotunitthen
qerror("No unit found.")
end
--- Calculate a random value within the desired belief level
localfunctioncalculate_random_belief_value(belief_level)
localbeliefs_levels= {
-- {minimum level value, maximum level value}
{-50,-41 },-- -3: lowest
{-40,-26 },-- -2: very low
{-25,-11 },-- -1: low
{-10,10 },-- 0: neutral
{11,25 },-- 1: high
{26,40 },-- 2: very high
{41,51 }-- 3: highest
}
locallvl=beliefs_levels[belief_level+4]
returnmath.random(lvl[1],lvl[2])
end
-- clear beliefs
ifresetthen
unit.status.current_soul.personality.values= {}
end
--assign beliefs
forbelief,levelinpairs(beliefs)do
assert(type(level)=="number")
belief=belief:upper()
-- there's a typo in the game data
ifbelief=="PERSEVERANCE"then
belief="PERSEVERENCE"
end
ifdf.value_type[belief]then
iflevel>=-3andlevel<=3then
localbelief_value=calculate_random_belief_value(level)
utils.insert_or_update(unit.status.current_soul.personality.values,
{new=true,type=df.value_type[belief],strength=belief_value },
"type")
else
print_yellow("WARNING: level out of range for belief '"..belief.."'. Skipping...")
end
else
print_yellow("WARNING: '"..belief.."' is not a valid belief token. Skipping...")
end
end
setneed.rebuildNeeds(unit)
end
-- ------------------------------------------------------ MAIN ------------------------------------------------------ --
localfunctionmain(...)
localargs=utils.processArgs({...},valid_args)
ifargs.helpthen
print(help)
return
end
localunit
ifargs.unitthen
unit=tonumber(args.unit)
ifnotunitthen
qerror("'"..args.unit.."' is not a valid unit ID.")
end
end
localreset=false
ifargs.resetthen
reset=true
end
-- parse beliefs list
localbeliefs= {}
ifargs.beliefsthen
locali=1
whilei<=#args.beliefsdo
localv=args.beliefs[i]
-- v can be a belief name but it can also be a level value, so we have to check
ifnottonumber(v)then
-- assume it's a valid belief name, for now
localbelief_name=tostring(v):upper()
-- then try to get the level value
locallevel_str=args.beliefs[i+1]
ifnotlevel_strthen
-- we reached the end of the beliefs list
qerror("Missing level value after '"..v.."'.")
end
locallevel_int=tonumber(level_str)
ifnotlevel_intthen
qerror("'"..level_str.."' is not a valid number.")
end
-- assume the level value is in range, for now
beliefs[belief_name]=level_int
end
i=i+1-- skip next arg because we already consumed it
end
end
assign(beliefs,unit,reset)
end
ifnotdfhack_flags.modulethen
main(...)
end