screeps/constants/
find.rs

1//! Constants for use with the [`Room::find`] function.
2//!
3//! *Note:* Types in this module have purposefully ambiguous names, and are
4//! intended to be used as, for example, `find::CREEPS`, not `CREEPS`.
5//!
6//! You can do this my importing the module itself, rather than any individual
7//! constant, and then just referring to the constants relative to the module.
8//!
9//! # Example
10//!
11//! ```no_run
12//! use screeps::{find, game, Room};
13//!
14//! let room: Room = game::rooms().get("E23S55".parse().unwrap()).unwrap();
15//!
16//! let creeps = room.find(find::CREEPS, None);
17//! # let _ = creeps;
18//! ```
19//!
20//! [`Room::find`]: crate::Room::find
21//! [`objects::RoomObject`]: crate::RoomObject
22use enum_iterator::Sequence;
23use serde::{Deserialize, Serialize};
24use wasm_bindgen::prelude::*;
25
26use crate::{enums::StructureObject, objects::*};
27
28/// Translates `FIND_*` constants for interal API calls
29///
30/// Unless you're storing the type of find constant to be used for a call, you
31/// likely want the constants which implement the `FindConstant` trait to make
32/// calls to find methods.
33///
34/// This is hidden from the documentation to avoid confusion due to its narrow
35/// use case, but wasm_bindgen requires it remain public.
36#[doc(hidden)]
37#[wasm_bindgen]
38#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, Sequence)]
39#[repr(u16)]
40pub enum Find {
41    /// Find all exit positions at the top of the room
42    ExitTop = 1,
43    ExitRight = 3,
44    ExitBottom = 5,
45    ExitLeft = 7,
46    Exit = 10,
47    Creeps = 101,
48    MyCreeps = 102,
49    HostileCreeps = 103,
50    SourcesActive = 104,
51    Sources = 105,
52    DroppedResources = 106,
53    Structures = 107,
54    MyStructures = 108,
55    HostileStructures = 109,
56    Flags = 110,
57    ConstructionSites = 111,
58    MySpawns = 112,
59    HostileSpawns = 113,
60    MyConstructionSites = 114,
61    HostileConstructionSites = 115,
62    Minerals = 116,
63    Nukes = 117,
64    Tombstones = 118,
65    PowerCreeps = 119,
66    MyPowerCreeps = 120,
67    HostilePowerCreeps = 121,
68    Deposits = 122,
69    Ruins = 123,
70    // todo these seem to not work when conditionally compiled out - they're not hurting to leave
71    // in but need to figure that out
72    //#[cfg(feature = "seasonal-season-1")]
73    ScoreContainers = 10011,
74    //#[cfg(feature = "seasonal-season-1")]
75    ScoreCollectors = 10012,
76    //#[cfg(feature = "seasonal-season-2")]
77    SymbolContainers = 10021,
78    //#[cfg(feature = "seasonal-season-2")]
79    SymbolDecoders = 10022,
80    //#[cfg(feature = "seasonal-season-5")]
81    Reactors = 10051,
82}
83
84/// Trait representing things which can be used in the 'find' function.
85///
86/// Typically used with zero-sized structs in the
87/// [`find`][crate::constants::find] module.
88pub trait FindConstant {
89    type Item: From<JsValue>;
90
91    fn convert_and_check_item(reference: JsValue) -> Self::Item;
92
93    fn find_code(&self) -> Find;
94}
95
96/// Useful for finding any [`RoomObject`] with
97/// a dynamically-chosen find constant.
98///
99/// If you know ahead of time what constant you'll use, then the
100/// all-upper-case constants in [this module][crate::constants::find] will
101/// be more helpful, and won't require casting the result types.
102///
103/// *Note*: To avoid ambiguity with [`RoomObject`], you should refer to this
104/// enum as `find::RoomObject` rather than importing it directly.
105///
106/// [`RoomObject`]: crate::objects::RoomObject
107#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
108#[repr(i16)]
109pub enum RoomObject {
110    Creeps = 101,
111    MyCreeps = 102,
112    HostileCreeps = 103,
113    SourcesActive = 104,
114    Sources = 105,
115    DroppedResources = 106,
116    Structures = 107,
117    MyStructures = 108,
118    HostileStructures = 109,
119    Flags = 110,
120    ConstructionSites = 111,
121    MySpawns = 112,
122    HostileSpawns = 113,
123    MyConstructionSites = 114,
124    HostileConstructionSites = 115,
125    Minerals = 116,
126    Nukes = 117,
127    Tombstones = 118,
128    PowerCreeps = 119,
129    MyPowerCreeps = 120,
130    HostilePowerCreeps = 121,
131    Deposits = 122,
132    Ruins = 123,
133    #[cfg(feature = "seasonal-season-1")]
134    ScoreContainers = 10011,
135    #[cfg(feature = "seasonal-season-1")]
136    ScoreCollectors = 10012,
137    #[cfg(feature = "seasonal-season-2")]
138    SymbolContainers = 10021,
139    #[cfg(feature = "seasonal-season-2")]
140    SymbolDecoders = 10022,
141    #[cfg(feature = "seasonal-season-5")]
142    Reactors = 10051,
143}
144
145impl From<RoomObject> for Find {
146    fn from(obj: RoomObject) -> Find {
147        match obj {
148            RoomObject::Creeps => Find::Creeps,
149            RoomObject::MyCreeps => Find::MyCreeps,
150            RoomObject::HostileCreeps => Find::HostileCreeps,
151            RoomObject::SourcesActive => Find::SourcesActive,
152            RoomObject::Sources => Find::Sources,
153            RoomObject::DroppedResources => Find::DroppedResources,
154            RoomObject::Structures => Find::Structures,
155            RoomObject::MyStructures => Find::MyStructures,
156            RoomObject::HostileStructures => Find::HostileStructures,
157            RoomObject::Flags => Find::Flags,
158            RoomObject::ConstructionSites => Find::ConstructionSites,
159            RoomObject::MySpawns => Find::MySpawns,
160            RoomObject::HostileSpawns => Find::HostileSpawns,
161            RoomObject::MyConstructionSites => Find::MyConstructionSites,
162            RoomObject::HostileConstructionSites => Find::HostileConstructionSites,
163            RoomObject::Minerals => Find::Minerals,
164            RoomObject::Nukes => Find::Nukes,
165            RoomObject::Tombstones => Find::Tombstones,
166            RoomObject::PowerCreeps => Find::PowerCreeps,
167            RoomObject::MyPowerCreeps => Find::MyPowerCreeps,
168            RoomObject::HostilePowerCreeps => Find::HostilePowerCreeps,
169            RoomObject::Deposits => Find::Deposits,
170            RoomObject::Ruins => Find::Ruins,
171            #[cfg(feature = "seasonal-season-1")]
172            RoomObject::ScoreContainers => Find::ScoreContainers,
173            #[cfg(feature = "seasonal-season-1")]
174            RoomObject::ScoreCollectors => Find::ScoreCollectors,
175            #[cfg(feature = "seasonal-season-2")]
176            RoomObject::SymbolContainers => Find::SymbolContainers,
177            #[cfg(feature = "seasonal-season-2")]
178            RoomObject::SymbolDecoders => Find::SymbolDecoders,
179            #[cfg(feature = "seasonal-season-5")]
180            RoomObject::Reactors => Find::Reactors,
181        }
182    }
183}
184
185impl FindConstant for RoomObject {
186    type Item = crate::objects::RoomObject;
187
188    fn convert_and_check_item(reference: JsValue) -> Self::Item {
189        Into::into(reference)
190    }
191
192    #[inline]
193    fn find_code(&self) -> Find {
194        (*self).into()
195    }
196}
197
198#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
199#[repr(i16)]
200pub enum Exit {
201    Top = 1,
202    Right = 3,
203    Bottom = 5,
204    Left = 7,
205    All = 10,
206}
207
208impl Exit {
209    #[inline]
210    pub const fn top() -> Self {
211        Exit::Top
212    }
213
214    #[inline]
215    pub const fn right() -> Self {
216        Exit::Right
217    }
218
219    #[inline]
220    pub const fn bottom() -> Self {
221        Exit::Bottom
222    }
223
224    #[inline]
225    pub const fn left() -> Self {
226        Exit::Left
227    }
228
229    #[inline]
230    pub const fn all() -> Self {
231        Exit::All
232    }
233}
234
235impl From<Exit> for Find {
236    fn from(exit: Exit) -> Find {
237        match exit {
238            Exit::Top => Find::ExitTop,
239            Exit::Right => Find::ExitRight,
240            Exit::Bottom => Find::ExitBottom,
241            Exit::Left => Find::ExitLeft,
242            Exit::All => Find::Exit,
243        }
244    }
245}
246
247impl FindConstant for Exit {
248    //TODO: wiarchbe: Check this is correct?
249    type Item = RoomPosition;
250
251    fn convert_and_check_item(reference: JsValue) -> Self::Item {
252        Into::into(reference)
253    }
254
255    #[inline]
256    fn find_code(&self) -> Find {
257        (*self).into()
258    }
259}
260
261//TODO: wiarchbe: Add back in calculated doc.
262macro_rules! typesafe_find_constants {
263    (
264        $(
265            $vis:vis struct $constant_name:ident = ($value:expr, $result:path, $conversion_method:expr);
266        )*
267    ) => (
268        $(
269            #[allow(bad_style)]
270            $vis struct $constant_name;
271            impl FindConstant for $constant_name {
272                type Item = $result;
273
274                fn convert_and_check_item(reference: JsValue) -> Self::Item {
275                    $conversion_method(reference)
276                }
277
278                #[inline]
279                fn find_code(&self) -> Find {
280                    $value
281                }
282            }
283        )*
284    );
285}
286
287typesafe_find_constants! {
288    pub struct CREEPS = (Find::Creeps, Creep, Into::into);
289    pub struct MY_CREEPS = (Find::MyCreeps, Creep, Into::into);
290    pub struct HOSTILE_CREEPS = (Find::HostileCreeps, Creep, Into::into);
291    pub struct SOURCES_ACTIVE = (Find::SourcesActive, Source, Into::into);
292    pub struct SOURCES = (Find::Sources, Source, Into::into);
293    pub struct DROPPED_RESOURCES = (Find::DroppedResources, Resource, Into::into);
294    pub struct STRUCTURES = (Find::Structures, StructureObject, Into::into);
295    pub struct MY_STRUCTURES = (Find::MyStructures, StructureObject, Into::into);
296    pub struct HOSTILE_STRUCTURES = (Find::HostileStructures, StructureObject, Into::into);
297    pub struct FLAGS = (Find::Flags, Flag, Into::into);
298    pub struct CONSTRUCTION_SITES = (Find::ConstructionSites, ConstructionSite, Into::into);
299    pub struct MY_SPAWNS = (Find::MySpawns, StructureSpawn, Into::into);
300    pub struct HOSTILE_SPAWNS = (Find::HostileSpawns, StructureSpawn, Into::into);
301    pub struct MY_CONSTRUCTION_SITES = (Find::MyConstructionSites, ConstructionSite, Into::into);
302    pub struct HOSTILE_CONSTRUCTION_SITES = (Find::HostileConstructionSites, ConstructionSite, Into::into);
303    pub struct MINERALS = (Find::Minerals, Mineral, Into::into);
304    pub struct NUKES = (Find::Nukes, Nuke, Into::into);
305    pub struct TOMBSTONES = (Find::Tombstones, Tombstone, Into::into);
306    pub struct POWER_CREEPS = (Find::PowerCreeps, PowerCreep, Into::into);
307    pub struct MY_POWER_CREEPS = (Find::MyPowerCreeps, PowerCreep, Into::into);
308    pub struct HOSTILE_POWER_CREEPS = (Find::HostilePowerCreeps, PowerCreep, Into::into);
309    pub struct DEPOSITS = (Find::Deposits, Deposit, Into::into);
310    pub struct RUINS = (Find::Ruins, Ruin, Into::into);
311    pub struct EXIT_TOP = (Find::ExitTop, RoomPosition, Into::into);
312    pub struct EXIT_RIGHT = (Find::ExitRight, RoomPosition, Into::into);
313    pub struct EXIT_BOTTOM = (Find::ExitBottom, RoomPosition, Into::into);
314    pub struct EXIT_LEFT = (Find::ExitLeft, RoomPosition, Into::into);
315    pub struct EXIT = (Find::Exit, RoomPosition, Into::into);
316}
317
318#[cfg(feature = "seasonal-season-1")]
319typesafe_find_constants! {
320    pub struct SCORE_CONTAINERS = (Find::ScoreContainers, ScoreContainer, Into::into);
321    pub struct SCORE_COLLECTORS = (Find::ScoreCollectors, ScoreCollector, Into::into);
322}
323
324#[cfg(feature = "seasonal-season-2")]
325typesafe_find_constants! {
326    pub struct SYMBOL_CONTAINERS = (Find::SymbolContainers, SymbolContainer, Into::into);
327    pub struct SYMBOL_DECODERS = (Find::SymbolDecoders, SymbolDecoder, Into::into);
328}
329
330#[cfg(feature = "seasonal-season-5")]
331typesafe_find_constants! {
332    pub struct REACTORS = (Find::Reactors, Reactor, Into::into);
333}