1pub mod action_error_codes;
6
7use enum_dispatch::enum_dispatch;
8use wasm_bindgen::{JsCast, JsValue};
9
10use crate::{objects::*, prelude::*, ResourceType, RESOURCES_ALL};
11
12#[enum_dispatch(Attackable)]
13pub enum AttackableObject {
14 Creep,
15 PowerCreep,
16 StructureContainer,
17 StructureExtension,
18 StructureExtractor,
19 StructureFactory,
20 StructureInvaderCore,
21 StructureLab,
22 StructureLink,
23 StructureNuker,
24 StructureObserver,
25 StructurePowerBank,
26 StructurePowerSpawn,
27 StructureRampart,
28 StructureRoad,
29 StructureSpawn,
30 StructureStorage,
31 StructureTerminal,
32 StructureTower,
33 StructureWall,
34}
35
36impl From<AttackableObject> for RoomObject {
37 fn from(attackable: AttackableObject) -> Self {
38 use AttackableObject::*;
39
40 match attackable {
41 Creep(o) => RoomObject::from(o),
42 PowerCreep(o) => RoomObject::from(o),
43 StructureContainer(o) => RoomObject::from(o),
44 StructureExtension(o) => RoomObject::from(o),
45 StructureExtractor(o) => RoomObject::from(o),
46 StructureFactory(o) => RoomObject::from(o),
47 StructureInvaderCore(o) => RoomObject::from(o),
48 StructureLab(o) => RoomObject::from(o),
49 StructureLink(o) => RoomObject::from(o),
50 StructureNuker(o) => RoomObject::from(o),
51 StructureObserver(o) => RoomObject::from(o),
52 StructurePowerBank(o) => RoomObject::from(o),
53 StructurePowerSpawn(o) => RoomObject::from(o),
54 StructureRampart(o) => RoomObject::from(o),
55 StructureRoad(o) => RoomObject::from(o),
56 StructureSpawn(o) => RoomObject::from(o),
57 StructureStorage(o) => RoomObject::from(o),
58 StructureTerminal(o) => RoomObject::from(o),
59 StructureTower(o) => RoomObject::from(o),
60 StructureWall(o) => RoomObject::from(o),
61 }
62 }
63}
64
65impl AsRef<RoomObject> for AttackableObject {
66 fn as_ref(&self) -> &RoomObject {
67 use AttackableObject::*;
68
69 match self {
70 Creep(o) => o.as_ref(),
71 PowerCreep(o) => o.as_ref(),
72 StructureContainer(o) => o.as_ref(),
73 StructureExtension(o) => o.as_ref(),
74 StructureExtractor(o) => o.as_ref(),
75 StructureFactory(o) => o.as_ref(),
76 StructureInvaderCore(o) => o.as_ref(),
77 StructureLab(o) => o.as_ref(),
78 StructureLink(o) => o.as_ref(),
79 StructureNuker(o) => o.as_ref(),
80 StructureObserver(o) => o.as_ref(),
81 StructurePowerBank(o) => o.as_ref(),
82 StructurePowerSpawn(o) => o.as_ref(),
83 StructureRampart(o) => o.as_ref(),
84 StructureRoad(o) => o.as_ref(),
85 StructureSpawn(o) => o.as_ref(),
86 StructureStorage(o) => o.as_ref(),
87 StructureTerminal(o) => o.as_ref(),
88 StructureTower(o) => o.as_ref(),
89 StructureWall(o) => o.as_ref(),
90 }
91 }
92}
93
94#[enum_dispatch(CanDecay)]
95pub enum DecayingObject {
96 Deposit,
97 Ruin,
98 #[cfg(feature = "seasonal-season-1")]
99 ScoreContainer,
100 StructureContainer,
101 StructurePortal,
102 StructurePowerBank,
103 StructureRampart,
104 StructureRoad,
105 #[cfg(feature = "seasonal-season-2")]
106 SymbolContainer,
107 Tombstone,
108}
109
110#[enum_dispatch(HasCooldown)]
111pub enum CooldownObject {
112 Deposit,
113 StructureExtractor,
114 StructureFactory,
115 StructureLab,
116 StructureLink,
117 StructureNuker,
118 StructureTerminal,
119}
120
121#[enum_dispatch(HasPosition)]
122pub enum ObjectWithPosition {
123 ConstructionSite,
124 Creep,
125 Deposit,
126 Flag,
127 Mineral,
128 Nuke,
129 PowerCreep,
130 Resource,
131 RoomPosition,
132 Ruin,
133 #[cfg(feature = "seasonal-season-1")]
134 ScoreCollector,
135 #[cfg(feature = "seasonal-season-1")]
136 ScoreContainer,
137 Source,
138 StructureContainer,
139 StructureController,
140 StructureExtension,
141 StructureExtractor,
142 StructureFactory,
143 StructureInvaderCore,
144 StructureKeeperLair,
145 StructureLab,
146 StructureLink,
147 StructureNuker,
148 StructureObserver,
149 StructurePortal,
150 StructurePowerBank,
151 StructurePowerSpawn,
152 StructureRampart,
153 StructureRoad,
154 StructureSpawn,
155 StructureStorage,
156 StructureTerminal,
157 StructureTower,
158 StructureWall,
159 #[cfg(feature = "seasonal-season-2")]
160 SymbolContainer,
161 #[cfg(feature = "seasonal-season-2")]
162 SymbolDecoder,
163 Tombstone,
164}
165
166#[enum_dispatch(HasStore)]
167pub enum StoreObject {
168 Creep,
169 PowerCreep,
170 #[cfg(feature = "seasonal-season-5")]
171 Reactor,
172 Ruin,
173 #[cfg(feature = "seasonal-season-1")]
174 ScoreCollector,
175 #[cfg(feature = "seasonal-season-1")]
176 ScoreContainer,
177 StructureContainer,
178 StructureExtension,
179 StructureFactory,
180 StructureLab,
181 StructureLink,
182 StructureNuker,
183 StructurePowerSpawn,
184 StructureSpawn,
185 StructureStorage,
186 StructureTerminal,
187 StructureTower,
188 #[cfg(feature = "seasonal-season-2")]
189 SymbolContainer,
190 Tombstone,
191}
192
193impl StoreObject {
194 pub const fn resource_types(&self) -> &'static [ResourceType] {
218 match self {
219 StoreObject::Creep(_) => RESOURCES_ALL,
220 StoreObject::PowerCreep(_) => RESOURCES_ALL,
221 #[cfg(feature = "seasonal-season-5")]
222 StoreObject::Reactor(_) => &[ResourceType::Thorium],
223 StoreObject::Ruin(_) => RESOURCES_ALL,
224 #[cfg(feature = "seasonal-season-1")]
225 StoreObject::ScoreCollector(_) => &[ResourceType::Score],
226 #[cfg(feature = "seasonal-season-1")]
227 StoreObject::ScoreContainer(_) => &[ResourceType::Score],
228 StoreObject::StructureContainer(_) => RESOURCES_ALL,
229 StoreObject::StructureExtension(_) => &[ResourceType::Energy],
230 StoreObject::StructureFactory(_) => RESOURCES_ALL,
231 StoreObject::StructureLab(_) => RESOURCES_ALL,
232 StoreObject::StructureLink(_) => &[ResourceType::Energy],
233 StoreObject::StructureNuker(_) => &[ResourceType::Energy, ResourceType::Ghodium],
234 StoreObject::StructurePowerSpawn(_) => &[ResourceType::Energy, ResourceType::Power],
235 StoreObject::StructureSpawn(_) => &[ResourceType::Energy],
236 StoreObject::StructureStorage(_) => RESOURCES_ALL,
237 StoreObject::StructureTerminal(_) => RESOURCES_ALL,
238 StoreObject::StructureTower(_) => &[ResourceType::Energy],
239 #[cfg(feature = "seasonal-season-2")]
240 StoreObject::SymbolContainer(_) => &crate::constants::seasonal::season_2::SYMBOLS,
241 StoreObject::Tombstone(_) => RESOURCES_ALL,
242 }
243 }
244}
245
246#[enum_dispatch(OwnedStructureProperties)]
249pub enum OwnedStructureObject {
250 StructureController,
251 StructureExtension,
252 StructureExtractor,
253 StructureFactory,
254 StructureInvaderCore,
255 StructureKeeperLair,
256 StructureLab,
257 StructureLink,
258 StructureNuker,
259 StructureObserver,
260 StructurePowerSpawn,
261 StructureRampart,
262 StructureSpawn,
263 StructureStorage,
264 StructureTerminal,
265 StructureTower,
266}
267
268#[enum_dispatch(RoomObjectProperties)]
272pub enum TypedRoomObject {
273 ConstructionSite,
274 Creep,
275 Deposit,
276 Flag,
277 Mineral,
278 Nuke,
279 PowerCreep,
280 Resource,
281 Ruin,
282 #[cfg(feature = "seasonal-season-1")]
283 ScoreCollector,
284 #[cfg(feature = "seasonal-season-1")]
285 ScoreContainer,
286 Source,
287 StructureContainer,
288 StructureController,
289 StructureExtension,
290 StructureExtractor,
291 StructureFactory,
292 StructureInvaderCore,
293 StructureKeeperLair,
294 StructureLab,
295 StructureLink,
296 StructureNuker,
297 StructureObserver,
298 StructurePortal,
299 StructurePowerBank,
300 StructurePowerSpawn,
301 StructureRampart,
302 StructureRoad,
303 StructureSpawn,
304 StructureStorage,
305 StructureTerminal,
306 StructureTower,
307 StructureWall,
308 #[cfg(feature = "seasonal-season-2")]
309 SymbolContainer,
310 #[cfg(feature = "seasonal-season-2")]
311 SymbolDecoder,
312 Tombstone,
313}
314
315#[enum_dispatch(SharedCreepProperties)]
316pub enum MovableObject {
317 Creep,
318 PowerCreep,
319}
320
321#[enum_dispatch(StructureProperties, HasPosition)]
324#[derive(Clone, Debug)]
325pub enum StructureObject {
326 StructureContainer,
327 StructureController,
328 StructureExtension,
329 StructureExtractor,
330 StructureFactory,
331 StructureInvaderCore,
332 StructureKeeperLair,
333 StructureLab,
334 StructureLink,
335 StructureNuker,
336 StructureObserver,
337 StructurePortal,
338 StructurePowerBank,
339 StructurePowerSpawn,
340 StructureRampart,
341 StructureRoad,
342 StructureSpawn,
343 StructureStorage,
344 StructureTerminal,
345 StructureTower,
346 StructureWall,
347}
348
349#[enum_dispatch(Transferable)]
350pub enum TransferableObject {
351 StructureExtension,
352 Creep,
353 StructureContainer,
354 StructureFactory,
355 StructureLab,
356 StructureLink,
357 StructureNuker,
358 StructureSpawn,
359 StructureStorage,
360 StructureTower,
361 StructurePowerSpawn,
362 StructureTerminal,
363 PowerCreep,
364}
365
366impl AsRef<RoomObject> for TransferableObject {
367 fn as_ref(&self) -> &RoomObject {
368 use TransferableObject::*;
369
370 match self {
371 StructureExtension(o) => o.as_ref(),
372 Creep(o) => o.as_ref(),
373 StructureContainer(o) => o.as_ref(),
374 StructureFactory(o) => o.as_ref(),
375 StructureLab(o) => o.as_ref(),
376 StructureLink(o) => o.as_ref(),
377 StructureNuker(o) => o.as_ref(),
378 StructureSpawn(o) => o.as_ref(),
379 StructureStorage(o) => o.as_ref(),
380 StructureTower(o) => o.as_ref(),
381 StructurePowerSpawn(o) => o.as_ref(),
382 StructureTerminal(o) => o.as_ref(),
383 PowerCreep(o) => o.as_ref(),
384 }
385 }
386}
387
388impl From<JsValue> for StructureObject {
389 fn from(reference: JsValue) -> Self {
390 let structure: Structure = reference.unchecked_into();
391
392 structure.into()
393 }
394}
395
396impl JsCollectionFromValue for StructureObject {
397 fn from_value(val: JsValue) -> Self {
398 Self::from(val)
399 }
400}
401
402#[derive(Clone, Copy, Debug)]
403pub enum OwnedStructureConversionError {
404 NotOwnable,
405}
406
407impl TryFrom<StructureObject> for OwnedStructureObject {
408 type Error = OwnedStructureConversionError;
409
410 fn try_from(structure: StructureObject) -> Result<Self, Self::Error> {
411 match structure {
412 StructureObject::StructureController(val) => {
413 Ok(OwnedStructureObject::StructureController(val))
414 }
415 StructureObject::StructureExtension(val) => {
416 Ok(OwnedStructureObject::StructureExtension(val))
417 }
418 StructureObject::StructureExtractor(val) => {
419 Ok(OwnedStructureObject::StructureExtractor(val))
420 }
421 StructureObject::StructureFactory(val) => {
422 Ok(OwnedStructureObject::StructureFactory(val))
423 }
424 StructureObject::StructureInvaderCore(val) => {
425 Ok(OwnedStructureObject::StructureInvaderCore(val))
426 }
427 StructureObject::StructureKeeperLair(val) => {
428 Ok(OwnedStructureObject::StructureKeeperLair(val))
429 }
430 StructureObject::StructureLab(val) => Ok(OwnedStructureObject::StructureLab(val)),
431 StructureObject::StructureLink(val) => Ok(OwnedStructureObject::StructureLink(val)),
432 StructureObject::StructureNuker(val) => Ok(OwnedStructureObject::StructureNuker(val)),
433 StructureObject::StructureObserver(val) => {
434 Ok(OwnedStructureObject::StructureObserver(val))
435 }
436 StructureObject::StructurePowerSpawn(val) => {
437 Ok(OwnedStructureObject::StructurePowerSpawn(val))
438 }
439 StructureObject::StructureRampart(val) => {
440 Ok(OwnedStructureObject::StructureRampart(val))
441 }
442 StructureObject::StructureSpawn(val) => Ok(OwnedStructureObject::StructureSpawn(val)),
443 StructureObject::StructureStorage(val) => {
444 Ok(OwnedStructureObject::StructureStorage(val))
445 }
446 StructureObject::StructureTerminal(val) => {
447 Ok(OwnedStructureObject::StructureTerminal(val))
448 }
449 StructureObject::StructureTower(val) => Ok(OwnedStructureObject::StructureTower(val)),
450 StructureObject::StructureContainer(_)
451 | StructureObject::StructureRoad(_)
452 | StructureObject::StructurePortal(_)
453 | StructureObject::StructurePowerBank(_)
454 | StructureObject::StructureWall(_) => Err(OwnedStructureConversionError::NotOwnable),
455 }
456 }
457}
458
459#[derive(Clone, Copy, Debug)]
460pub enum TransferableObjectConversionError {
461 NotTransferable,
462}
463
464impl TryFrom<StructureObject> for TransferableObject {
465 type Error = TransferableObjectConversionError;
466
467 fn try_from(structure: StructureObject) -> Result<Self, Self::Error> {
468 match structure {
469 StructureObject::StructureExtension(val) => Ok(Self::StructureExtension(val)),
470 StructureObject::StructureContainer(val) => Ok(Self::StructureContainer(val)),
471 StructureObject::StructureFactory(val) => Ok(Self::StructureFactory(val)),
472 StructureObject::StructureLab(val) => Ok(Self::StructureLab(val)),
473 StructureObject::StructureLink(val) => Ok(Self::StructureLink(val)),
474 StructureObject::StructureNuker(val) => Ok(Self::StructureNuker(val)),
475 StructureObject::StructureSpawn(val) => Ok(Self::StructureSpawn(val)),
476 StructureObject::StructureStorage(val) => Ok(Self::StructureStorage(val)),
477 StructureObject::StructureTower(val) => Ok(Self::StructureTower(val)),
478 StructureObject::StructurePowerSpawn(val) => Ok(Self::StructurePowerSpawn(val)),
479 StructureObject::StructureTerminal(val) => Ok(Self::StructureTerminal(val)),
480
481 StructureObject::StructureController(_)
482 | StructureObject::StructureExtractor(_)
483 | StructureObject::StructureInvaderCore(_)
484 | StructureObject::StructureKeeperLair(_)
485 | StructureObject::StructureObserver(_)
486 | StructureObject::StructurePortal(_)
487 | StructureObject::StructurePowerBank(_)
488 | StructureObject::StructureRampart(_)
489 | StructureObject::StructureRoad(_)
490 | StructureObject::StructureWall(_) => {
491 Err(TransferableObjectConversionError::NotTransferable)
492 }
493 }
494 }
495}
496
497#[derive(Clone, Copy, Debug)]
498pub enum StoreObjectConversionError {
499 DoesntHaveStore,
500}
501
502impl TryFrom<StructureObject> for StoreObject {
503 type Error = StoreObjectConversionError;
504
505 fn try_from(structure: StructureObject) -> Result<Self, Self::Error> {
506 match structure {
507 StructureObject::StructureContainer(val) => Ok(Self::StructureContainer(val)),
508 StructureObject::StructureExtension(val) => Ok(Self::StructureExtension(val)),
509 StructureObject::StructureFactory(val) => Ok(Self::StructureFactory(val)),
510 StructureObject::StructureLab(val) => Ok(Self::StructureLab(val)),
511 StructureObject::StructureLink(val) => Ok(Self::StructureLink(val)),
512 StructureObject::StructureNuker(val) => Ok(Self::StructureNuker(val)),
513 StructureObject::StructurePowerSpawn(val) => Ok(Self::StructurePowerSpawn(val)),
514 StructureObject::StructureSpawn(val) => Ok(Self::StructureSpawn(val)),
515 StructureObject::StructureStorage(val) => Ok(Self::StructureStorage(val)),
516 StructureObject::StructureTerminal(val) => Ok(Self::StructureTerminal(val)),
517 StructureObject::StructureTower(val) => Ok(Self::StructureTower(val)),
518
519 StructureObject::StructureController(_)
520 | StructureObject::StructureExtractor(_)
521 | StructureObject::StructureInvaderCore(_)
522 | StructureObject::StructureKeeperLair(_)
523 | StructureObject::StructureObserver(_)
524 | StructureObject::StructurePortal(_)
525 | StructureObject::StructurePowerBank(_)
526 | StructureObject::StructureRampart(_)
527 | StructureObject::StructureRoad(_)
528 | StructureObject::StructureWall(_) => Err(StoreObjectConversionError::DoesntHaveStore),
529 }
530 }
531}
532
533impl From<Structure> for StructureObject {
534 fn from(structure: Structure) -> Self {
535 use crate::constants::StructureType::*;
536
537 match structure.structure_type() {
538 Container => Self::StructureContainer(structure.unchecked_into()),
539 Controller => Self::StructureController(structure.unchecked_into()),
540 Extension => Self::StructureExtension(structure.unchecked_into()),
541 Extractor => Self::StructureExtractor(structure.unchecked_into()),
542 Factory => Self::StructureFactory(structure.unchecked_into()),
543 InvaderCore => Self::StructureInvaderCore(structure.unchecked_into()),
544 KeeperLair => Self::StructureKeeperLair(structure.unchecked_into()),
545 Lab => Self::StructureLab(structure.unchecked_into()),
546 Link => Self::StructureLink(structure.unchecked_into()),
547 Nuker => Self::StructureNuker(structure.unchecked_into()),
548 Observer => Self::StructureObserver(structure.unchecked_into()),
549 Portal => Self::StructurePortal(structure.unchecked_into()),
550 PowerBank => Self::StructurePowerBank(structure.unchecked_into()),
551 PowerSpawn => Self::StructurePowerSpawn(structure.unchecked_into()),
552 Rampart => Self::StructureRampart(structure.unchecked_into()),
553 Road => Self::StructureRoad(structure.unchecked_into()),
554 Spawn => Self::StructureSpawn(structure.unchecked_into()),
555 Storage => Self::StructureStorage(structure.unchecked_into()),
556 Terminal => Self::StructureTerminal(structure.unchecked_into()),
557 Tower => Self::StructureTower(structure.unchecked_into()),
558 Wall => Self::StructureWall(structure.unchecked_into()),
559 _ => panic!("unknown structure type for conversion into enum"),
560 }
561 }
562}
563
564impl StructureObject {
565 pub fn as_structure(&self) -> &Structure {
566 match self {
567 Self::StructureSpawn(s) => s.as_ref(),
568 Self::StructureExtension(s) => s.as_ref(),
569 Self::StructureRoad(s) => s.as_ref(),
570 Self::StructureWall(s) => s.as_ref(),
571 Self::StructureRampart(s) => s.as_ref(),
572 Self::StructureKeeperLair(s) => s.as_ref(),
573 Self::StructurePortal(s) => s.as_ref(),
574 Self::StructureController(s) => s.as_ref(),
575 Self::StructureLink(s) => s.as_ref(),
576 Self::StructureStorage(s) => s.as_ref(),
577 Self::StructureTower(s) => s.as_ref(),
578 Self::StructureObserver(s) => s.as_ref(),
579 Self::StructurePowerBank(s) => s.as_ref(),
580 Self::StructurePowerSpawn(s) => s.as_ref(),
581 Self::StructureExtractor(s) => s.as_ref(),
582 Self::StructureLab(s) => s.as_ref(),
583 Self::StructureTerminal(s) => s.as_ref(),
584 Self::StructureContainer(s) => s.as_ref(),
585 Self::StructureNuker(s) => s.as_ref(),
586 Self::StructureFactory(s) => s.as_ref(),
587 Self::StructureInvaderCore(s) => s.as_ref(),
588 }
589 }
590
591 pub fn as_owned(&self) -> Option<&dyn OwnedStructureProperties> {
592 match self {
593 Self::StructureSpawn(s) => Some(s),
594 Self::StructureExtension(s) => Some(s),
595 Self::StructureRoad(_) => None,
596 Self::StructureWall(_) => None,
597 Self::StructureRampart(s) => Some(s),
598 Self::StructureKeeperLair(s) => Some(s),
599 Self::StructurePortal(_) => None,
600 Self::StructureController(s) => Some(s),
601 Self::StructureLink(s) => Some(s),
602 Self::StructureStorage(s) => Some(s),
603 Self::StructureTower(s) => Some(s),
604 Self::StructureObserver(s) => Some(s),
605 Self::StructurePowerBank(_) => None,
606 Self::StructurePowerSpawn(s) => Some(s),
607 Self::StructureExtractor(s) => Some(s),
608 Self::StructureLab(s) => Some(s),
609 Self::StructureTerminal(s) => Some(s),
610 Self::StructureContainer(_) => None,
611 Self::StructureNuker(s) => Some(s),
612 Self::StructureFactory(s) => Some(s),
613 Self::StructureInvaderCore(s) => Some(s),
614 }
615 }
616
617 pub fn as_has_store(&self) -> Option<&dyn HasStore> {
618 match self {
619 Self::StructureSpawn(s) => Some(s),
620 Self::StructureExtension(s) => Some(s),
621 Self::StructureRoad(_) => None,
622 Self::StructureWall(_) => None,
623 Self::StructureRampart(_) => None,
624 Self::StructureKeeperLair(_) => None,
625 Self::StructurePortal(_) => None,
626 Self::StructureController(_) => None,
627 Self::StructureLink(s) => Some(s),
628 Self::StructureStorage(s) => Some(s),
629 Self::StructureTower(s) => Some(s),
630 Self::StructureObserver(_) => None,
631 Self::StructurePowerBank(_) => None,
632 Self::StructurePowerSpawn(s) => Some(s),
633 Self::StructureExtractor(_) => None,
634 Self::StructureLab(s) => Some(s),
635 Self::StructureTerminal(s) => Some(s),
636 Self::StructureContainer(s) => Some(s),
637 Self::StructureNuker(s) => Some(s),
638 Self::StructureFactory(s) => Some(s),
639 Self::StructureInvaderCore(_) => None,
640 }
641 }
642
643 pub fn as_transferable(&self) -> Option<&dyn Transferable> {
644 match self {
645 Self::StructureSpawn(s) => Some(s),
646 Self::StructureExtension(s) => Some(s),
647 Self::StructureRoad(_) => None,
648 Self::StructureWall(_) => None,
649 Self::StructureRampart(_) => None,
650 Self::StructureKeeperLair(_) => None,
651 Self::StructurePortal(_) => None,
652 Self::StructureController(_) => None,
653 Self::StructureLink(s) => Some(s),
654 Self::StructureStorage(s) => Some(s),
655 Self::StructureTower(s) => Some(s),
656 Self::StructureObserver(_) => None,
657 Self::StructurePowerBank(_) => None,
658 Self::StructurePowerSpawn(s) => Some(s),
659 Self::StructureExtractor(_) => None,
660 Self::StructureLab(s) => Some(s),
661 Self::StructureTerminal(s) => Some(s),
662 Self::StructureContainer(s) => Some(s),
663 Self::StructureNuker(s) => Some(s),
664 Self::StructureFactory(s) => Some(s),
665 Self::StructureInvaderCore(_) => None,
666 }
667 }
668
669 pub fn as_withdrawable(&self) -> Option<&dyn Withdrawable> {
670 match self {
671 Self::StructureSpawn(s) => Some(s),
672 Self::StructureExtension(s) => Some(s),
673 Self::StructureRoad(_) => None,
674 Self::StructureWall(_) => None,
675 Self::StructureRampart(_) => None,
676 Self::StructureKeeperLair(_) => None,
677 Self::StructurePortal(_) => None,
678 Self::StructureController(_) => None,
679 Self::StructureLink(s) => Some(s),
680 Self::StructureStorage(s) => Some(s),
681 Self::StructureTower(s) => Some(s),
682 Self::StructureObserver(_) => None,
683 Self::StructurePowerBank(_) => None,
684 Self::StructurePowerSpawn(s) => Some(s),
685 Self::StructureExtractor(_) => None,
686 Self::StructureLab(s) => Some(s),
687 Self::StructureTerminal(s) => Some(s),
688 Self::StructureContainer(s) => Some(s),
689 Self::StructureNuker(_) => None,
690 Self::StructureFactory(s) => Some(s),
691 Self::StructureInvaderCore(_) => None,
692 }
693 }
694
695 pub fn as_attackable(&self) -> Option<&dyn Attackable> {
696 match self {
697 Self::StructureSpawn(s) => Some(s),
698 Self::StructureExtension(s) => Some(s),
699 Self::StructureRoad(s) => Some(s),
700 Self::StructureWall(s) => Some(s),
701 Self::StructureRampart(s) => Some(s),
702 Self::StructureKeeperLair(s) => Some(s),
703 Self::StructurePortal(_) => None,
704 Self::StructureController(_) => None,
705 Self::StructureLink(s) => Some(s),
706 Self::StructureStorage(s) => Some(s),
707 Self::StructureTower(s) => Some(s),
708 Self::StructureObserver(s) => Some(s),
709 Self::StructurePowerBank(s) => Some(s),
710 Self::StructurePowerSpawn(s) => Some(s),
711 Self::StructureExtractor(s) => Some(s),
712 Self::StructureLab(s) => Some(s),
713 Self::StructureTerminal(s) => Some(s),
714 Self::StructureContainer(s) => Some(s),
715 Self::StructureNuker(s) => Some(s),
716 Self::StructureFactory(s) => Some(s),
717 Self::StructureInvaderCore(s) => Some(s),
718 }
719 }
720
721 pub fn as_repairable(&self) -> Option<&dyn Repairable> {
722 match self {
723 Self::StructureSpawn(s) => Some(s),
724 Self::StructureExtension(s) => Some(s),
725 Self::StructureRoad(s) => Some(s),
726 Self::StructureWall(s) => Some(s),
727 Self::StructureRampart(s) => Some(s),
728 Self::StructureKeeperLair(_) => None,
729 Self::StructurePortal(_) => None,
730 Self::StructureController(_) => None,
731 Self::StructureLink(s) => Some(s),
732 Self::StructureStorage(s) => Some(s),
733 Self::StructureTower(s) => Some(s),
734 Self::StructureObserver(s) => Some(s),
735 Self::StructurePowerBank(s) => Some(s),
736 Self::StructurePowerSpawn(s) => Some(s),
737 Self::StructureExtractor(s) => Some(s),
738 Self::StructureLab(s) => Some(s),
739 Self::StructureTerminal(s) => Some(s),
740 Self::StructureContainer(s) => Some(s),
741 Self::StructureNuker(s) => Some(s),
742 Self::StructureFactory(s) => Some(s),
743 Self::StructureInvaderCore(_) => None,
744 }
745 }
746
747 pub fn as_dismantleable(&self) -> Option<&dyn Dismantleable> {
748 match self {
749 Self::StructureSpawn(s) => Some(s),
750 Self::StructureExtension(s) => Some(s),
751 Self::StructureRoad(s) => Some(s),
752 Self::StructureWall(s) => Some(s),
753 Self::StructureRampart(s) => Some(s),
754 Self::StructureKeeperLair(_) => None,
755 Self::StructurePortal(_) => None,
756 Self::StructureController(_) => None,
757 Self::StructureLink(s) => Some(s),
758 Self::StructureStorage(s) => Some(s),
759 Self::StructureTower(s) => Some(s),
760 Self::StructureObserver(s) => Some(s),
761 Self::StructurePowerBank(s) => Some(s),
762 Self::StructurePowerSpawn(s) => Some(s),
763 Self::StructureExtractor(s) => Some(s),
764 Self::StructureLab(s) => Some(s),
765 Self::StructureTerminal(s) => Some(s),
766 Self::StructureContainer(s) => Some(s),
767 Self::StructureNuker(s) => Some(s),
768 Self::StructureFactory(s) => Some(s),
769 Self::StructureInvaderCore(_) => None,
770 }
771 }
772}