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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
use df_ls_core::{Choose, Reference, ReferenceTo, Referenceable};
use df_ls_syntax_analysis::TokenDeserialize;
use serde::{Deserialize, Serialize};
use crate::StandardPluralEnum;
#[derive(Serialize, Deserialize, Clone, Debug, TokenDeserialize, PartialEq, Eq)]
pub enum BodyObjectToken {
#[token_de(token = "BODY")]
BodyToken(BodyToken),
#[token_de(token = "BODYGLOSS")]
BodyGlossToken(BodyGlossToken),
}
impl Default for BodyObjectToken {
fn default() -> Self {
Self::BodyToken(BodyToken::default())
}
}
#[derive(
Serialize, Deserialize, Clone, Debug, Default, TokenDeserialize, PartialEq, Eq, Referenceable,
)]
pub struct BodyGlossToken {
/// Arguments of `[BODYGLOSS:...]`
#[token_de(token = "BODYGLOSS", on_duplicate_to_parent, primary_token)]
#[referenceable(self_reference)]
pub bodygloss: Option<(ReferenceTo<Self>, String, String, String, String)>,
}
#[derive(
Serialize, Deserialize, Clone, Debug, Default, TokenDeserialize, PartialEq, Eq, Referenceable,
)]
pub struct BodyToken {
/// Argument 1 of `[BODY:...]`
#[token_de(token = "BODY", on_duplicate_to_parent, primary_token)]
#[referenceable(self_reference)]
pub reference: Option<ReferenceTo<Self>>,
/// A list of body parts in this body token.
#[token_de(token = "BP")]
pub bp: Vec<BodyPartToken>,
}
/// "STP stands for "Standard Plural" and it just adds an 's' to the singular word to save some
/// typing. If you don't add something in that slot, the body part won't even load."
///
/// --Toady
#[derive(Serialize, Deserialize, Clone, Debug, Default, TokenDeserialize, PartialEq, Eq)]
pub struct BodyPartToken {
/// Arguments of `[BP:...]`
#[token_de(token = "BP", on_duplicate_to_parent, primary_token)]
// TODO: the below `Reference` should be a `ReferenceTo` for `[CON:...]`
pub bp: Option<(Reference, String, Choose<StandardPluralEnum, String>)>,
/// Marks the body part as an opening in the body. If it is `[EMBEDDED]`, it cannot be gouged.
#[token_de(token = "APERTURE")]
pub aperture: Option<()>,
/// Body part is used to breathe. If all body parts with `[BREATHE]` are damaged or destroyed,
/// the creature will suffocate unless it has the `[NOBREATHE]` tag. Note that bruising counts
/// as (fast-healing) damage.
#[token_de(token = "BREATHE")]
pub breathe: Option<()>,
/// Assigns the body part to a user-defined category. Used by `[CON_CAT]` to attach to other
/// body parts.
#[token_de(token = "CATEGORY")]
pub category: Option<Reference>, // TODO: ref is referred to by `CON_CAT` in other body parts
/// Connects the body part to a specific other body part.
#[token_de(token = "CON")]
pub con: Option<Reference>, // TODO: ref is a BP
/// Connects the body part to all other body parts having the specified `[CATEGORY]`.
#[token_de(token = "CON_CAT")]
pub con_cat: Option<Reference>, // TODO: ref is a body part `[CATEGORY:...]`
/// Connects the body part to all other body parts having the specified type token.
#[token_de(token = "CONTYPE")]
pub contype: Option<ConTypeEnum>,
/// Body part is responsible for blood circulation. Exact effects not known.
#[token_de(token = "CIRCULATION")]
pub circulation: Option<()>,
/// Body part is used to connect other body parts together. Used for the neck and lower spine.
#[token_de(token = "CONNECTOR")]
pub connector: Option<()>,
/// This command establishes the relative size of body parts within a creature. The numbers have
/// no absolute meaning or units.
#[token_de(token = "DEFAULT_RELSIZE")]
pub default_relsize: Option<u32>,
/// Defines part as a digit. Body parts that are digits, or have them as direct sub-parts, can
/// perform gouging attacks within a wrestling hold.
#[token_de(token = "DIGIT")]
pub digit: Option<()>,
/// Body part with this tag is embedded on the surface of parent body part. i.e.: eyes and mouth
/// on head. It cannot be chopped off, can't be used to wrestle enemies and can't be grabbed by
/// them.
#[token_de(token = "EMBEDDED")]
pub embedded: Option<()>,
/// Flags the body part as being needed for flight. Damage to a certain number of `FLIER` body
/// parts will prevent the creature from flying.
///
/// Note that a creature can only fly if the creature has the `[FLIER]` tag in its creature
/// definition, and that a flying creature does not actually need any `FLIER` body parts.
/// This tag's only purpose is to identify body parts which will cause a creature to lose the
/// ability to fly when damaged.
#[token_de(token = "FLIER")]
pub flier: Option<()>,
/// Creatures with a body part containing this token may be gelded, which prevents them
/// reproducing. Gelding may also occur during combat if this body part is damaged sufficiently.
#[token_de(token = "GELDABLE")]
pub geldable: Option<()>,
/// Creature can wield a picked-up weapon with the body part, and can use the part to initiate
/// almost all wrestling moves.
///
/// When creatures are spawned with a weapon and shield, one `GRASP` part will hold a weapon
/// while all others will hold shields.
///
/// A grasp-able bodypart is needed for Grasp-attacks, which are in turn needed to start a fist
/// fight. Creatures throwing a tantrum, but missing a bodypart with the grasp-property, will
/// be cancelling their fist fight, due to being 'too injured'.
#[token_de(token = "GRASP")]
pub grasp: Option<()>,
/// Body part is susceptible to low blows. Used for guts. Damage to this body part causes nausea
/// and may make the creature lose turns, vomiting uncontrollably.
#[token_de(token = "GUTS")]
pub guts: Option<()>,
/// Flags the body part as being able to wear head clothing like hats, helms, etc. If all heads
/// are chopped off, the creature dies. Multiple heads are redundant - for example, hydras can
/// survive with several missing heads.
#[token_de(token = "HEAD")]
pub head: Option<()>,
/// Body part is used to hear. May be a requirement for the body part to wear earrings.
#[token_de(token = "HEAR")]
pub hear: Option<()>,
/// Adding individual names tells the game what to call each individual part in a bodypart
/// using a `NUMBER` token. This token replaces "first upper front tooth" for example.
#[token_de(token = "INDIVIDUAL_NAME")]
pub individual_name: Vec<(String, Choose<StandardPluralEnum, String>)>,
/// Marks the body part as being inside the body. It is behind all the other tissues of the body
/// part, cannot be severed, nor used for wrestling. It cannot be targeted directly in combat,
/// but can be damaged by attacks to the parent body part.
#[token_de(token = "INTERNAL")]
pub internal: Option<()>,
/// Body part is a joint. If the limb it's in is grabbed in a wrestling hold, it can be broken
/// with bending force, disabling the parent limb. If the joint is modded to sit outside the
/// body, grabbing and breaking it snaps the entire limb right off.
#[token_de(token = "JOINT")]
pub joint: Option<()>,
/// Body part is a limb. It can be used to initiate most wrestling moves.
///
/// If it is located between an `[UPPERBODY]` part and a `[GRASP]` body part, it is eligible to
/// be covered by certain types of armor (body armors and gauntlets).
///
/// If it is located between a `[LOWERBODY]` part and a `[STANCE]` body part, it is eligible to
/// be covered by other types of armor (Leg armors like pants, etc.; trailing body armors like
/// mail shirts and robes; and high boots).
#[token_de(token = "LIMB")]
pub limb: Option<()>,
/// Flags the body part as being able to wear lower body clothing like skirts, pants, etc.
///
/// If all parts with this token are chopped off or pulped, the creature dies. If the creature
/// has multiple parts with this token, they will not die until all parts with this token have
/// been pulped or severed. No such creature exists in the base game, however.
#[token_de(token = "LOWERBODY")]
pub lowerbody: Option<()>,
/// Marks body part as on the left side of the body and vulnerable to attacks from the left.
/// Used in conjunction with tags in the vanilla `b_detail_plan_default` raw.
#[token_de(token = "LEFT")]
pub left: Option<()>,
/// Body part is a mouth. Implications unknown.
#[token_de(token = "MOUTH")]
pub mouth: Option<()>,
/// The number lets you stack identical body parts. These can be individually damaged by
/// wounds, but you don't have to define them explicitly one by one.
/// If you don't give them individual names (see teeth) they'll be preceded by ordinal numbers
/// (first, second, etc.).
///
/// In practice, though, they cannot be individually damaged - if you knock out one tooth, the
/// entire group will be knocked out at once (and will be scattered across the area). Butchering
/// doesn't respect this and produces only a single body part per group. The value is capped at
/// 32.
#[token_de(token = "NUMBER")]
pub number: Option<u8>,
/// Body part is the hub of nervous function. Used for the parts of the spine. Damage disables
/// everything in the parent bodypart and what's below it, causing death by suffocation in most
/// cases.
#[token_de(token = "NERVOUS")]
pub nervous: Option<()>,
/// Body part must be destroyed in order for the attached parent object to be considered
/// destroyed. Found on skulls and spinal columns.
#[token_de(token = "PREVENTS_PARENT_COLLAPSE")]
pub prevents_parent_collapse: Option<()>,
/// Marks body part as on the right side of the body and vulnerable to attacks from the right.
/// Used in conjunction with tags in the vanilla `b_detail_plan_default` raw.
#[token_de(token = "RIGHT")]
pub right: Option<()>,
/// Body part is part of the creature's skeleton.
#[token_de(token = "SKELETON")]
pub skeleton: Option<()>,
/// Allows the creature to stand. Damage or loss of these body parts will cause creature to fall
/// over. Loss of one `STANCE` part can be substituted with a crutch. Does not give the body
/// part an ability to initiate wrestling moves, unlike `[GRASP]` or `[LIMB]`.
#[token_de(token = "STANCE")]
pub stance: Option<()>,
/// Body part is used to see with. If the creature has no `SIGHT` body parts, or if all its
/// sight body parts are damaged or destroyed, it can't see unless it has the `[EXTRAVISION]`
/// tag in its creature definition.
#[token_de(token = "SIGHT")]
pub sight: Option<()>,
/// Body part is used to smell. No known function. (could possibly control reactions to miasma
/// in fortress mode?)
#[token_de(token = "SMELL")]
pub smell: Option<()>,
/// "`SMALL` means that the part isn't displayed as part of the overall displayed body part lists.
/// They can't be splinted. They are more often targeted for torture (although those situations
/// might not occur anymore). They are removed in skeletons if they aren't specifically
/// skeletons/joints/digits/apertures. They are more easily lost in world gen duels. They are
/// the only gougable/pinchable parts (note: at least this is no longer the case.). `SMALL` is
/// an old tag, so it has accumulated some weird functions which'll get split off over time. "
///
/// --Toady
#[token_de(token = "SMALL")]
pub small: Option<()>,
/// Body part breaks off and goes flying if broken, even with blunt force. Used on teeth to make
/// them easy to knock out. Rendered invalid by `[INTERNAL]`.
#[token_de(token = "SOCKET")]
pub socket: Option<()>,
/// Body part can be strangled. Latching bites that hit the head have a chance to target this
/// instead. Note: this tag doesn't control any bleeding behavior.
#[token_de(token = "THROAT")]
pub throat: Option<()>,
/// The central core of the body. Used with the brain. Damage causes instant death unless the
/// creature has `[NO_THOUGHT_CENTER_FOR_MOVEMENT]`/`[NOTHOUGHT]`.
#[token_de(token = "THOUGHT")]
pub thought: Option<()>,
/// This bodypart can be turned into a totem by craftsmen. Always drops from slaughtered
/// creatures, no matter how small.
#[token_de(token = "TOTEMABLE")]
pub totemable: Option<()>,
/// Flags the body part as being able to wear upper body clothing like coats, breastplates etc.
///
/// If all parts with this token are pulped or chopped off, the creature dies. Multiple
/// `UPPERBODY` parts are redundant, but no such creatures exist in the base game.
/// All default creatures with bodies have the upper body as the root of the body tree, making
/// it impossible to chop off.
#[token_de(token = "UPPERBODY")]
pub upperbody: Option<()>,
/// Makes the body part pop out of the body when cut through. Used on guts. Body part shows up
/// as "~" and drags behind the victim when spilled.
#[token_de(token = "UNDER_PRESSURE")]
pub under_pressure: Option<()>,
/// Allows the item to be obtained from butchered or rotted vermin. Used with shells.
#[token_de(token = "VERMIN_BUTCHER_ITEM")]
pub vermin_butcher_item: Option<()>,
}
#[derive(Serialize, Deserialize, Clone, Debug, TokenDeserialize, PartialEq, Eq)]
#[token_de(enum_value)]
pub enum ConTypeEnum {
/// Flags the body part as being able to wear upper body clothing like coats, breastplates etc.
///
/// If all parts with this token are pulped or chopped off, the creature dies. Multiple
/// `UPPERBODY` parts are redundant, but no such creatures exist in the base game.
/// All default creatures with bodies have the upper body as the root of the body tree, making
/// it impossible to chop off.
#[token_de(token = "UPPERBODY")]
Upperbody,
/// Flags the body part as being able to wear lower body clothing like skirts, pants, etc.
///
/// If all parts with this token are chopped off or pulped, the creature dies. If the creature
/// has multiple parts with this token, they will not die until all parts with this token have
/// been pulped or severed. No such creature exists in the base game, however.
#[token_de(token = "LOWERBODY")]
Lowerbody,
/// Flags the body part as being able to wear head clothing like hats, helms, etc. If all heads
/// are chopped off, the creature dies. Multiple heads are redundant - for example, hydras can
/// survive with several missing heads.
#[token_de(token = "HEAD")]
Head,
/// Creature can wield a picked-up weapon with the body part, and can use the part to initiate
/// almost all wrestling moves.
///
/// When creatures are spawned with a weapon and shield, one `GRASP` part will hold a weapon
/// while all others will hold shields.
///
/// A grasp-able bodypart is needed for Grasp-attacks, which are in turn needed to start a fist
/// fight. Creatures throwing a tantrum, but missing a bodypart with the grasp-property, will
/// be cancelling their fist fight, due to being 'too injured'.
#[token_de(token = "GRASP")]
Grasp,
/// Allows the creature to stand. Damage or loss of these body parts will cause creature to fall
/// over. Loss of one `STANCE` part can be substituted with a crutch. Does not give the body
/// part an ability to initiate wrestling moves, unlike `[GRASP]` or `[LIMB]`.
#[token_de(token = "STANCE")]
Stance,
}
impl Default for ConTypeEnum {
fn default() -> Self {
Self::Upperbody
}
}