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
296
297
298
299
300
301
302
303
304
305
use TokenStream;
use *;
use *;
/// Annotates a struct as a Dantelion2 singleton to be looked up using a single
/// string argument.
///
/// This is only guaranteed to make the struct work with the
/// `fromsoftware_shared::singleton::get_instance` function. Any other added
/// functionality is considered an implementation detail and shouldn't be relied
/// upon.
/// Annotates a trait to automatically generate getters and setters that forward
/// to methods of the same name in various structs.
///
/// This is used to create traits that encapsulate state that's shared across
/// multiple parameter definitions.
///
/// This trait takes as arguments the names of various structs for which it
/// should automatically generate an implementation. It should annotate a trait
/// that contains a `fields!` macro, using the same named field syntax that a
/// struct uses. For each field, a getter and setter is generated both in the
/// trait and in its implementation for each struct.
///
/// ```rs
/// #[multi_param(EQUIP_PARAM_ACCESSORY_ST, EQUIP_PARAM_GOODS_ST)]
/// pub trait EquipParamPassive: EquipParam {
/// fields! {
/// sfx_variation_id: i32,
/// ref_category: u8,
/// sp_effect_category: u8,
/// shop_lv: i16,
/// }
/// }
/// ```
///
/// ## Field Attributes
///
/// This can also be used as to annotate field attributes.
///
/// ### `rename()`
///
/// You can use the `rename()` annotation to rename the field this targets for a
/// particular struct. This can be useful if the same logical field has
/// different names, which sometimes happens due to typos in FromSoftware's
/// internal names.
///
/// The syntax is `#[multi_param(rename(param = ..., name = ...))]`. The struct
/// must exactly match one of the structs passed to the outer annotation, and
/// the `name` must be a valid identifier.
///
/// ```rs
/// #[multi_param(
/// EQUIP_PARAM_ACCESSORY_ST,
/// EQUIP_PARAM_GOODS_ST,
/// EQUIP_PARAM_PROTECTOR_ST,
/// EQUIP_PARAM_WEAPON_ST
/// )]
/// pub trait EquipParam {
/// fields! {
/// weight: f32,
/// basic_price: i32,
/// sell_value: i32,
/// sort_id: i32,
/// vagrant_item_lot_id: i32,
/// #[multi_param(
/// rename(param = EQUIP_PARAM_PROTECTOR_ST, name = "vagrant_bonusene_drop_item_lot_id"),
/// rename(param = EQUIP_PARAM_WEAPON_ST, name = "vagrant_bonusene_drop_item_lot_id"),
/// )]
/// vagrant_bonus_ene_drop_item_lot_id: i32;
/// vagrant_item_ene_drop_item_lot_id: i32,
/// }
/// }
/// ```rs
///
/// ## Enums
///
/// Each trait also generates two enums, one mutable and one immutable, which
/// can be used in contexts where it's relevant *which* param type in particular
/// you have. These enums have a variant for each defined parameter type. The
/// above example would define:
///
/// ```rs
/// pub enum EquipParamStruct<'a> {
/// EQUIP_PARAM_ACCESSORY_ST(&'a EQUIP_PARAM_ACCESSORY_ST),
/// EQUIP_PARAM_GOODS_ST(&'a EQUIP_PARAM_GOODS_ST),
/// EQUIP_PARAM_PROTECTOR_ST(&'a EQUIP_PARAM_PROTECTOR_ST),
/// EQUIP_PARAM_WEAPON_ST(&'a EQUIP_PARAM_WEAPON_ST),
/// }
///
/// impl EquipParamStruct<'_> {
/// pub fn as_dyn(&self) -> &dyn EquipParam;
/// }
///
/// pub enum EquipParamStructMut<'a> {
/// EQUIP_PARAM_ACCESSORY_ST(&'a mut EQUIP_PARAM_ACCESSORY_ST),
/// EQUIP_PARAM_GOODS_ST(&'a mut EQUIP_PARAM_GOODS_ST),
/// EQUIP_PARAM_PROTECTOR_ST(&'a mut EQUIP_PARAM_PROTECTOR_ST),
/// EQUIP_PARAM_WEAPON_ST(&'a mut EQUIP_PARAM_WEAPON_ST),
/// }
///
/// impl EquipParamStructMut<'_> {
/// pub fn as_dyn(&mut self) -> &mut dyn EquipParam;
/// }
/// ```
///
/// You can access these using the `as_enum()` and `as_enum_mut()` methods.
/// A derive macro for `fromsoftware_shared::Subclass`.
///
/// ## Finding the RVA
///
/// This adds an implementation of `Subclass` that gets its VMT address from a
/// standard RVA struct. This assumes:
///
/// * The crate using this contains a `crate::rva` module that exposes a `get()`
/// function.
///
/// * The `get()` function's return value has a public field whose name is a
/// snake-case version of this struct's name, followed by `_vmt`.
///
/// For example, `ChrIns` uses `crate::rva::get().chr_ins_vmt` as its VMT RVA.
///
/// ## Determining the Superclass
///
/// By default, the type of the first field in the subclass is used as the
/// superclass. You can explicitly choose one or more superclasses instead using
/// the `#[subclass(base = SuperclassType)]` attribute on the struct.
///
/// ## Additional Features
///
/// This macro will also add trait implementations for `AsRef<SuperclassType>`,
/// `AsMut<SuperclassType>`, and `TryFrom<&SuperclassType>`.
///
/// It will also implement `Deref<Target = SuperclassType>` and `DerefMut`, but
/// because a type can only have one implementation of these traits, if this
/// declares multiple superclasses they will only be implemented for the first
/// one. Since types can be transitively dereferenced, be sure to order the
/// bottommost superclass first so that all superclass methods can be accessed.
///
/// ## Safety
///
/// The `fromsoftware_shared::Subclass` trait is unsafe, and even though there's
/// currently no way to require that a derive macro be explicitly flagged as
/// unsafe, this does not add any additional safety guarantees beyond a manual
/// implementation. PLease read the `Subclass` documentation carefully to
/// understand the requirements to use this safety.
/// A derive macro for `fromsoftware_shared::Superclass`.
///
/// ## Finding the RVA
///
/// This adds an implementation of `Subclass` that gets its VMT address from a
/// standard RVA struct. This assumes:
///
/// * The crate using this contains a `crate::rva` module that exposes a `get()`
/// function.
///
/// * The `get()` function's return value has a public field whose name is a
/// snake-case version of this struct's name, followed by `_vmt`.
///
/// For example, `ChrIns` uses `crate::rva::get().chr_ins_vmt` as its VMT RVA.
///
/// ## Subclass Enums
///
/// By default, this macro will just generate a straightforward implementation
/// of `Superclass`. But if you want, you can add a
/// `#[superclass(children(ChildName1, ChildName2))]` attribute to the struct.
/// If you do, the macro will also define two enums, one immutable and one
/// mutable.
///
/// For example:
///
/// ```rs
/// #[repr(C)]
/// #[derive(Superclass)]
/// #[superclass(children(Cow, Pig))]
/// pub struct Animal {
/// _vftable: usize,
/// }
/// ```
///
/// will generate
///
/// ```rs
/// pub enum AnimalSubclasses<'sub> {
/// Cow(&'sub Cow),
/// Pig(&'sub Pig),
/// Animal(&'sub Animal),
/// }
///
/// pub enum AnimalSubclassesMut<'sub> {
/// Cow(&'sub mut Cow),
/// Pig(&'sub mut Pig),
/// Animal(&'sub mut Animal),
/// }
///
/// impl AnimalSubclasses<'_> {
/// pub fn superclass(&self) -> &Animal;
/// }
///
/// impl AnimalSubclassesMut<'_> {
/// pub fn superclass(&self) -> &Animal;
/// pub fn superclass_mut(&mut self) -> &mut Animal;
/// }
///
/// impl<'sub> From<AnimalSubclassesMut<'sub>> for AnimalSubclasses<'sub> {}
/// impl<'sub> From<&'sub T> for AnimalSubclasses<'sub> where T: Subclass<Animal> {}
/// impl<'sub> From<&'sub mut T> for AnimalSubclassesMut<'sub> where T: Subclass<Animal> {}
/// ```
///
/// ## Safety
///
/// The `fromsoftware_shared::Superclass` trait is unsafe, and even though
/// there's currently no way to require that a derive macro be explicitly
/// flagged as unsafe, this does not add any additional safety guarantees beyond
/// a manual implementation. PLease read the `Superclass` documentation
/// carefully to understand the requirements to use this safety.
/// A proc macro attribute for defining an extension trait that makes a set of
/// methods available for all subclasses of a superclass.
///
/// This expects to be used on a trait impl whose trait name is **not defined**
/// and whose target is `Subclass<...>`. This impl should include functions.
/// Unlike normal trait implementations, this impl **should have a visibility
/// modifier** (unless you want it to be private). For example:
///
/// ```rs
/// #[for_all_subclasses]
/// pub impl ChrInsExt for Subclass<ChrIns> {
/// fn apply_speffect(&mut self, sp_effect: i32, dont_sync: bool) {
/// let rva = Program::current()
/// .rva_to_va(rva::get().chr_ins_apply_speffect)
/// .unwrap();
///
/// let call = unsafe { transmute::<u64, extern "C" fn(&mut ChrIns, i32, bool) -> u64>(rva) };
/// call(self, sp_effect, dont_sync);
/// }
///
/// fn remove_speffect(&mut self, sp_effect: i32) {
/// let rva = Program::current()
/// .rva_to_va(rva::get().chr_ins_remove_speffect)
/// .unwrap();
///
/// let call = unsafe { transmute::<u64, extern "C" fn(&mut ChrIns, i32) -> u64>(rva) };
/// call(self, sp_effect);
/// }
/// }
/// ```
///
/// This will define a trait with the given name and visibility, then implement
/// it for all subclasses of the given superclass. This allow superclass methods
/// to be freely called on any subclass, delegating to the superclass they
/// contain.