Skip to main content

screeps/objects/impls/
room_terrain.rs

1use js_sys::{JsString, Uint8Array};
2use wasm_bindgen::prelude::*;
3
4use crate::{
5    constants::{ErrorCode, Terrain},
6    local::{RoomName, RoomXY},
7    prelude::*,
8};
9
10#[wasm_bindgen]
11extern "C" {
12    /// A matrix representing the terrain of a room, held in the JavaScript
13    /// heap.
14    ///
15    /// Use [`LocalRoomTerrain`] to store and access the same data in Rust
16    /// memory.
17    ///
18    /// [Screeps documentation](https://docs.screeps.com/api/#Room-Terrain)
19    ///
20    /// [`LocalRoomTerrain`]: crate::local::LocalRoomTerrain
21    #[wasm_bindgen(js_namespace = Room, js_name = Terrain)]
22    pub type RoomTerrain;
23
24    #[wasm_bindgen(constructor, js_namespace = Room, js_class = Terrain, catch)]
25    fn new_internal(room_name: &JsString) -> Result<RoomTerrain, JsValue>;
26
27    /// Get the type of terrain at given coordinates.
28    ///
29    /// [Screeps documentation](https://docs.screeps.com/api/#Room.Terrain.get)
30    #[wasm_bindgen(method)]
31    pub fn get(this: &RoomTerrain, x: u8, y: u8) -> Terrain;
32
33    // when called without a destination array, can't fail - no error code possible
34    #[wasm_bindgen(method, js_name = getRawBuffer)]
35    fn get_raw_buffer_internal(this: &RoomTerrain) -> Uint8Array;
36
37    // and when called with a destination, it can only ever return a return code int
38    #[wasm_bindgen(method, js_name = getRawBuffer)]
39    fn get_raw_buffer_to_array_internal(this: &RoomTerrain, destination: &Uint8Array) -> JsValue;
40}
41
42impl RoomTerrain {
43    /// Gets the terrain for any room by name, regardless of current visibility
44    /// of the room.
45    ///
46    /// [Screeps documentation](https://docs.screeps.com/api/#Room.Terrain.constructor)
47    pub fn new(room_name: RoomName) -> Option<RoomTerrain> {
48        let name = room_name.into();
49
50        Self::new_internal(&name).ok()
51    }
52
53    /// Get a copy of the underlying Uint8Array with the data about the room's
54    /// terrain.
55    ///
56    /// [Screeps documentation](https://docs.screeps.com/api/#Room.Terrain.getRawBuffer)
57    #[inline]
58    pub fn get_raw_buffer(&self) -> Uint8Array {
59        self.get_raw_buffer_internal()
60    }
61
62    /// Copy the data about the room's terrain into an existing [`Uint8Array`].
63    ///
64    /// [Screeps documentation](https://docs.screeps.com/api/#Room.Terrain.getRawBuffer)
65    #[inline]
66    pub fn get_raw_buffer_to_array(&self, destination: &Uint8Array) -> Result<(), ErrorCode> {
67        let val = self.get_raw_buffer_to_array_internal(destination);
68
69        // val is integer if error; if object it's another reference to the Uint8Array;
70        // function was successful in that case
71        match val.as_f64() {
72            Some(n) => ErrorCode::result_from_i8(n as i8),
73            None => Ok(()),
74        }
75    }
76
77    /// Get the type of terrain at the given [`RoomXY`].
78    #[inline]
79    pub fn get_xy(&mut self, xy: RoomXY) -> Terrain {
80        self.get(xy.x.u8(), xy.y.u8())
81    }
82}