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