1use crate::{
4 prelude::*, CanFrom, Destructible, DestructibleID, LivingDestructible, LivingDestructibleID,
5};
6use js_sys::{Array, Float64Array, Object};
7use std::convert::TryFrom;
8use wasm_bindgen::prelude::*;
9
10#[wasm_bindgen]
12extern "C" {
13 #[wasm_bindgen(extends = DestructibleID, typescript_type = "SpiritID")]
15 #[derive(Clone, Debug, PartialEq, Eq)]
16 pub type SpiritID;
17
18 #[wasm_bindgen(extends = Destructible, typescript_type = "Spirit")]
22 #[derive(Clone, Debug, PartialEq, Eq)]
23 pub type Spirit;
24
25 #[wasm_bindgen(method, getter)]
26 pub fn id(this: &Spirit) -> SpiritID;
27
28 #[wasm_bindgen(method, getter)]
29 pub fn merged(this: &Spirit) -> Vec<DeadSpiritID>;
30
31 #[wasm_bindgen(method, getter)]
32 pub fn move_speed(this: &Spirit) -> f64;
33
34 #[wasm_bindgen(method, getter)]
35 pub fn mark(this: &Spirit) -> String;
36}
37
38impl CanFrom<Destructible> for Spirit {
39 #[inline]
40 fn can_from(value: &Destructible) -> bool {
41 !<Base as CanFrom<Destructible>>::can_from(value)
42 }
43}
44
45try_can_from!(impl TryFrom<Destructible>, Error = Base for Spirit);
46
47#[wasm_bindgen]
49extern "C" {
50 #[wasm_bindgen(extends = SpiritID, typescript_type = "SpiritID")]
52 #[derive(Clone, Debug, PartialEq, Eq)]
53 pub type FriendlySpiritID;
54
55 #[wasm_bindgen(extends = Spirit, typescript_type = "Spirit")]
59 #[derive(Clone, Debug, PartialEq, Eq)]
60 pub type FriendlySpirit;
61
62 #[wasm_bindgen(method, getter)]
63 pub fn id(this: &FriendlySpirit) -> FriendlySpiritID;
64
65 #[wasm_bindgen(method, getter)]
66 pub fn merged(this: &FriendlySpirit) -> Vec<DeadFriendlySpiritID>;
67}
68
69impl CanFrom<Spirit> for FriendlySpirit {
70 #[inline]
71 fn can_from(value: &Spirit) -> bool {
72 &value.player_id() == this_player_id()
73 }
74}
75
76try_can_from!(impl TryFrom<Spirit>, Error = EnemySpirit for FriendlySpirit);
77
78#[wasm_bindgen]
80extern "C" {
81 #[wasm_bindgen(extends = SpiritID, typescript_type = "SpiritID")]
83 #[derive(Clone, Debug, PartialEq, Eq)]
84 pub type EnemySpiritID;
85
86 #[wasm_bindgen(extends = Spirit, typescript_type = "Spirit")]
90 #[derive(Clone, Debug, PartialEq, Eq)]
91 pub type EnemySpirit;
92
93 #[wasm_bindgen(method, getter)]
94 pub fn id(this: &EnemySpirit) -> EnemySpiritID;
95
96 #[wasm_bindgen(method, getter)]
97 pub fn merged(this: &EnemySpirit) -> Vec<DeadEnemySpiritID>;
98}
99
100impl CanFrom<Spirit> for EnemySpirit {
101 #[inline]
102 fn can_from(value: &Spirit) -> bool {
103 !<FriendlySpirit as CanFrom<Spirit>>::can_from(value)
104 }
105}
106
107try_can_from!(impl TryFrom<Spirit>, Error = FriendlySpirit for EnemySpirit);
108
109#[wasm_bindgen]
111extern "C" {
112 #[wasm_bindgen(extends = SpiritID, extends = LivingDestructibleID, typescript_type = "SpiritID")]
114 #[derive(Clone, Debug, PartialEq, Eq)]
115 pub type LivingSpiritID;
116
117 #[wasm_bindgen(extends = Spirit, extends = LivingDestructible, typescript_type = "Spirit")]
121 #[derive(Clone, Debug, PartialEq, Eq)]
122 pub type LivingSpirit;
123
124 #[wasm_bindgen(method, getter)]
125 pub fn id(this: &LivingSpirit) -> LivingSpiritID;
126}
127
128impl CanFrom<Spirit> for LivingSpirit {
129 #[inline]
130 fn can_from(value: &Spirit) -> bool {
131 value.hp() > 0
132 }
133}
134
135try_can_from!(impl TryFrom<Spirit>, Error = DeadSpirit for LivingSpirit);
136
137impl CanFrom<LivingDestructible> for LivingSpirit {
138 #[inline]
139 fn can_from(value: &LivingDestructible) -> bool {
140 !<Base as CanFrom<LivingDestructible>>::can_from(value)
141 }
142}
143
144try_can_from!(impl TryFrom<LivingDestructible>, Error = Base for LivingSpirit);
145
146#[wasm_bindgen]
148extern "C" {
149 #[wasm_bindgen(extends = SpiritID, typescript_type = "SpiritID")]
151 #[derive(Clone, Debug, PartialEq, Eq)]
152 pub type DeadSpiritID;
153
154 #[wasm_bindgen(extends = Spirit, typescript_type = "Spirit")]
158 #[derive(Clone, Debug, PartialEq, Eq)]
159 pub type DeadSpirit;
160
161 #[wasm_bindgen(method, getter)]
162 pub fn id(this: &DeadSpirit) -> DeadSpiritID;
163}
164
165impl CanFrom<Spirit> for DeadSpirit {
166 #[inline]
167 fn can_from(value: &Spirit) -> bool {
168 !<LivingSpirit as CanFrom<Spirit>>::can_from(value)
169 }
170}
171
172try_can_from!(impl TryFrom<Spirit>, Error = LivingSpirit for DeadSpirit);
173
174#[cfg(any(
176 doc,
177 not(any(feature = "circles", feature = "squares", feature = "triangles"))
178))]
179#[wasm_bindgen]
180extern "C" {
181 #[wasm_bindgen(extends = FriendlySpirit, extends = LivingSpirit, typescript_type = "Spirit")]
186 #[derive(Clone, Debug, PartialEq, Eq)]
187 pub type OperableSpirit;
188}
189
190#[cfg(all(feature = "circles", not(doc)))]
191#[wasm_bindgen]
192extern "C" {
193 #[wasm_bindgen(extends = FriendlySpirit, extends = LivingSpirit, typescript_type = "CircleSpirit")]
194 #[derive(Clone, Debug, PartialEq, Eq)]
195 pub type OperableSpirit;
196}
197
198#[cfg(all(feature = "squares", not(any(doc, feature = "circles"))))]
199#[wasm_bindgen]
200extern "C" {
201 #[wasm_bindgen(extends = FriendlySpirit, extends = LivingSpirit, typescript_type = "SquareSpirit")]
202 #[derive(Clone, Debug, PartialEq, Eq)]
203 pub type OperableSpirit;
204}
205
206#[cfg(all(
207 feature = "triangles",
208 not(any(doc, feature = "circles", feature = "squares"))
209))]
210#[wasm_bindgen]
211extern "C" {
212 #[wasm_bindgen(extends = FriendlySpirit, extends = LivingSpirit, typescript_type = "SquareSpirit")]
213 #[derive(Clone, Debug, PartialEq, Eq)]
214 pub type OperableSpirit;
215}
216
217#[wasm_bindgen]
218extern "C" {
219 #[wasm_bindgen(extends = FriendlySpiritID, extends = LivingSpiritID, typescript_type = "Spirit")]
221 #[derive(Clone, Debug, PartialEq, Eq)]
222 pub type OperableSpiritID;
223
224 #[wasm_bindgen(method, js_name = "move")]
225 fn r#move(this: &OperableSpirit, target: &Array);
226
227 #[wasm_bindgen(method)]
228 pub fn energize(this: &OperableSpirit, target: &Entity);
229
230 #[cfg(feature = "circles")]
232 #[wasm_bindgen(method)]
233 pub fn merge(this: &OperableSpirit, target: &Spirit);
234
235 #[cfg(feature = "circles")]
237 #[wasm_bindgen(method)]
238 pub fn divide(this: &OperableSpirit);
239
240 #[cfg(feature = "squares")]
242 #[wasm_bindgen(method)]
243 pub fn jump(this: &OperableSpirit, target: &Position);
244
245 #[cfg(feature = "triangles")]
247 #[wasm_bindgen(method)]
248 pub fn explode(this: &OperableSpirit, target: &Position);
249
250 #[wasm_bindgen(method)]
251 pub fn shout(this: &OperableSpirit, message: &str);
252
253 #[wasm_bindgen(method)]
254 pub fn set_mark(this: &OperableSpirit, label: &str);
255}
256
257pub type LivingFriendlySpirit = OperableSpirit;
258pub type LivingFriendlySpiritID = OperableSpiritID;
259
260impl OperableSpirit {
261 pub fn move_to_pos(&self, pos: &Position) {
263 let float_arr = Float64Array::new_with_length(2);
264 float_arr.copy_from(pos);
265 self.r#move(&Array::from(float_arr.as_ref()));
266 }
267}
268
269impl CanFrom<LivingSpirit> for LivingFriendlySpirit {
270 #[inline]
271 fn can_from(value: &LivingSpirit) -> bool {
272 <FriendlySpirit as CanFrom<Spirit>>::can_from(value)
273 }
274}
275
276try_can_from!(impl TryFrom<LivingSpirit>, Error = LivingEnemySpirit for LivingFriendlySpirit);
277
278impl CanFrom<FriendlySpirit> for LivingFriendlySpirit {
279 #[inline]
280 fn can_from(value: &FriendlySpirit) -> bool {
281 <LivingSpirit as CanFrom<Spirit>>::can_from(value)
282 }
283}
284
285try_can_from!(impl TryFrom<FriendlySpirit>, Error = DeadFriendlySpirit for LivingFriendlySpirit);
286
287impl CanFrom<Spirit> for LivingFriendlySpirit {
288 #[inline]
289 fn can_from(value: &Spirit) -> bool {
290 <LivingSpirit as CanFrom<Spirit>>::can_from(value)
291 && <FriendlySpirit as CanFrom<Spirit>>::can_from(value)
292 }
293}
294
295try_can_from!(impl TryFrom<Spirit>, Error = Spirit for LivingFriendlySpirit);
296
297impl AsRef<Spirit> for LivingFriendlySpirit {
298 #[inline]
299 fn as_ref(&self) -> &Spirit {
300 <LivingFriendlySpirit as AsRef<FriendlySpirit>>::as_ref(self).as_ref()
301 }
302}
303
304#[wasm_bindgen]
306extern "C" {
307 #[wasm_bindgen(extends = FriendlySpiritID, extends = DeadSpiritID, typescript_type = "SpiritID")]
309 #[derive(Clone, Debug, PartialEq, Eq)]
310 pub type DeadFriendlySpiritID;
311
312 #[wasm_bindgen(extends = FriendlySpirit, extends = DeadSpirit, typescript_type = "Spirit")]
316 #[derive(Clone, Debug, PartialEq, Eq)]
317 pub type DeadFriendlySpirit;
318
319 #[wasm_bindgen(method, getter)]
320 pub fn id(this: &DeadFriendlySpirit) -> DeadFriendlySpiritID;
321}
322
323impl CanFrom<FriendlySpirit> for DeadFriendlySpirit {
324 #[inline]
325 fn can_from(value: &FriendlySpirit) -> bool {
326 <DeadSpirit as CanFrom<Spirit>>::can_from(value)
327 }
328}
329
330try_can_from!(impl TryFrom<FriendlySpirit>, Error = LivingFriendlySpirit for DeadFriendlySpirit);
331
332impl CanFrom<DeadSpirit> for DeadFriendlySpirit {
333 #[inline]
334 fn can_from(value: &DeadSpirit) -> bool {
335 <FriendlySpirit as CanFrom<Spirit>>::can_from(value)
336 }
337}
338
339try_can_from!(impl TryFrom<DeadSpirit>, Error = DeadEnemySpirit for DeadFriendlySpirit);
340
341impl CanFrom<Spirit> for DeadFriendlySpirit {
342 #[inline]
343 fn can_from(value: &Spirit) -> bool {
344 <DeadSpirit as CanFrom<Spirit>>::can_from(value)
345 && <FriendlySpirit as CanFrom<Spirit>>::can_from(value)
346 }
347}
348
349try_can_from!(impl TryFrom<Spirit>, Error = Spirit for DeadFriendlySpirit);
350
351impl AsRef<Spirit> for DeadFriendlySpirit {
352 #[inline]
353 fn as_ref(&self) -> &Spirit {
354 <DeadFriendlySpirit as AsRef<FriendlySpirit>>::as_ref(self).as_ref()
355 }
356}
357
358#[wasm_bindgen]
360extern "C" {
361 #[wasm_bindgen(extends = EnemySpiritID, extends = LivingSpiritID, typescript_type = "SpiritID")]
363 #[derive(Clone, Debug, PartialEq, Eq)]
364 pub type LivingEnemySpiritID;
365
366 #[wasm_bindgen(extends = EnemySpirit, extends = LivingSpirit, typescript_type = "Spirit")]
370 #[derive(Clone, Debug, PartialEq, Eq)]
371 pub type LivingEnemySpirit;
372
373 #[wasm_bindgen(method, getter)]
374 pub fn id(this: &LivingEnemySpirit) -> LivingEnemySpiritID;
375}
376
377impl CanFrom<EnemySpirit> for LivingEnemySpirit {
378 #[inline]
379 fn can_from(value: &EnemySpirit) -> bool {
380 <LivingSpirit as CanFrom<Spirit>>::can_from(value)
381 }
382}
383
384try_can_from!(impl TryFrom<EnemySpirit>, Error = DeadEnemySpirit for LivingEnemySpirit);
385
386impl CanFrom<LivingSpirit> for LivingEnemySpirit {
387 #[inline]
388 fn can_from(value: &LivingSpirit) -> bool {
389 <EnemySpirit as CanFrom<Spirit>>::can_from(value)
390 }
391}
392
393try_can_from!(impl TryFrom<LivingSpirit>, Error = LivingFriendlySpirit for LivingEnemySpirit);
394
395impl CanFrom<Spirit> for LivingEnemySpirit {
396 #[inline]
397 fn can_from(value: &Spirit) -> bool {
398 <LivingSpirit as CanFrom<Spirit>>::can_from(value)
399 && <EnemySpirit as CanFrom<Spirit>>::can_from(value)
400 }
401}
402
403try_can_from!(impl TryFrom<Spirit>, Error = Spirit for LivingEnemySpirit);
404
405impl AsRef<Spirit> for LivingEnemySpirit {
406 #[inline]
407 fn as_ref(&self) -> &Spirit {
408 <LivingEnemySpirit as AsRef<EnemySpirit>>::as_ref(self).as_ref()
409 }
410}
411
412#[wasm_bindgen]
414extern "C" {
415 #[wasm_bindgen(extends = EnemySpiritID, extends = DeadSpiritID, typescript_type = "SpiritID")]
417 #[derive(Clone, Debug, PartialEq, Eq)]
418 pub type DeadEnemySpiritID;
419
420 #[wasm_bindgen(extends = EnemySpirit, extends = DeadSpirit, typescript_type = "Spirit")]
424 #[derive(Clone, Debug, PartialEq, Eq)]
425 pub type DeadEnemySpirit;
426
427 #[wasm_bindgen(method, getter)]
428 pub fn id(this: &DeadEnemySpirit) -> DeadEnemySpiritID;
429}
430
431impl CanFrom<EnemySpirit> for DeadEnemySpirit {
432 #[inline]
433 fn can_from(value: &EnemySpirit) -> bool {
434 <DeadSpirit as CanFrom<Spirit>>::can_from(value)
435 }
436}
437
438try_can_from!(impl TryFrom<EnemySpirit>, Error = LivingEnemySpirit for DeadEnemySpirit);
439
440impl CanFrom<DeadSpirit> for DeadEnemySpirit {
441 #[inline]
442 fn can_from(value: &DeadSpirit) -> bool {
443 <EnemySpirit as CanFrom<Spirit>>::can_from(value)
444 }
445}
446
447try_can_from!(impl TryFrom<DeadSpirit>, Error = DeadFriendlySpirit for DeadEnemySpirit);
448
449impl CanFrom<Spirit> for DeadEnemySpirit {
450 #[inline]
451 fn can_from(value: &Spirit) -> bool {
452 <DeadSpirit as CanFrom<Spirit>>::can_from(value)
453 && <EnemySpirit as CanFrom<Spirit>>::can_from(value)
454 }
455}
456
457try_can_from!(impl TryFrom<Spirit>, Error = Spirit for DeadEnemySpirit);
458
459impl AsRef<Spirit> for DeadEnemySpirit {
460 #[inline]
461 fn as_ref(&self) -> &Spirit {
462 <DeadEnemySpirit as AsRef<EnemySpirit>>::as_ref(self).as_ref()
463 }
464}
465
466#[wasm_bindgen]
468extern "C" {
469 #[wasm_bindgen(extends = Object, typescript_type = "(typeof spirits)")]
470 #[derive(Clone, Debug)]
471 pub type Spirits;
472
473 #[wasm_bindgen(js_name = "spirits")]
474 static _spirits: Spirits;
475}
476
477impl TryGetByID<EntityID, Spirit> for Spirits {}
478impl TryGetByID<DestructibleID, Spirit> for Spirits {}
479impl TryGetByID<LivingDestructibleID, LivingSpirit> for Spirits {}
480impl GetByID<SpiritID, Spirit> for Spirits {}
481impl EnumerateByID<SpiritID, Spirit> for Spirits {}
482impl GetByID<LivingSpiritID, LivingSpirit> for Spirits {}
483impl GetByID<DeadSpiritID, DeadSpirit> for Spirits {}
484impl GetByID<FriendlySpiritID, FriendlySpirit> for Spirits {}
485impl GetByID<EnemySpiritID, EnemySpirit> for Spirits {}
486impl GetByID<OperableSpiritID, OperableSpirit> for Spirits {}
487impl GetByID<DeadFriendlySpiritID, DeadFriendlySpirit> for Spirits {}
488impl GetByID<LivingEnemySpiritID, LivingEnemySpirit> for Spirits {}
489impl GetByID<DeadEnemySpiritID, DeadEnemySpirit> for Spirits {}
490
491#[inline(always)]
495pub fn spirits() -> &'static Spirits {
496 &_spirits
497}
498
499#[wasm_bindgen]
501extern "C" {
502 #[wasm_bindgen(method, getter, js_name = "my_spirits")]
503 static _my_spirits: Vec<FriendlySpirit>;
504}
505
506#[inline(always)]
510pub fn my_spirits() -> &'static Vec<FriendlySpirit> {
511 &_my_spirits
512}