1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! Game method implementations on `Position`
use js_sys::{JsString, Object};
use wasm_bindgen::prelude::*;

use crate::{
    constants::{
        look::{LookConstant, LookResult},
        Color, ErrorCode, FindConstant, ReturnCode, StructureType,
    },
    local::{RoomCoordinate, RoomName},
    objects::{CostMatrix, FindPathOptions, Path, RoomPosition},
    pathfinder::RoomCostResult,
    prelude::*,
};

use super::Position;

impl Position {
    /// Creates a [`ConstructionSite`] at this position. If it's a
    /// [`StructureSpawn`], a name can optionally be assigned for the structure.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.createConstructionSite)
    ///
    /// [`ConstructionSite`]: crate::objects::ConstructionSite
    /// [`StructureSpawn`]: crate::objects::StructureSpawn
    #[inline]
    pub fn create_construction_site(
        self,
        ty: StructureType,
        name: Option<&JsString>,
    ) -> ReturnCode {
        RoomPosition::from(self).create_construction_site(ty, name)
    }

    /// Creates a [`Flag`] at this position. If successful, returns the name of
    /// the created flag.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.createFlag)
    ///
    /// [`Flag`]: crate::objects::Flag
    #[inline]
    pub fn create_flag(
        self,
        name: Option<&JsString>,
        color: Option<Color>,
        secondary_color: Option<Color>,
    ) -> Result<JsString, ErrorCode> {
        RoomPosition::from(self).create_flag(name, color, secondary_color)
    }

    // todo typed options and version that allows passing target roomobjects
    /// Find the closest object by path among a list of objects, or use
    /// a [`find` constant] to search for all objects of that type in the room.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.findClosestByPath)
    ///
    /// [`find` constant]: crate::constants::find
    #[inline]
    pub fn find_closest_by_path<T>(self, ty: T, options: Option<&Object>) -> Option<T::Item>
    where
        T: FindConstant,
        <T as FindConstant>::Item: From<JsValue>,
    {
        RoomPosition::from(self).find_closest_by_path(ty, options)
    }

    // todo version for passing target roomobjects
    /// Find the closest object by range among a list of objects, or use
    /// a [`find` constant] to search for all objects of that type in the room.
    /// Will not work for objects in other rooms.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.findClosestByRange)
    ///
    /// [`find` constant]: crate::constants::find
    #[inline]
    pub fn find_closest_by_range<T>(self, ty: T) -> Option<T::Item>
    where
        T: FindConstant,
    {
        RoomPosition::from(self).find_closest_by_range(ty)
    }

    // todo version for passing target roomobjects
    /// Find all relevant objects within a certain range among a list of
    /// objects, or use a [`find` constant] to search all objects of that type
    /// in the room.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.findInRange)
    ///
    /// [`find` constant]: crate::constants::find
    #[inline]
    pub fn find_in_range<T>(self, ty: T, range: u8) -> Vec<T::Item>
    where
        T: FindConstant,
    {
        RoomPosition::from(self).find_in_range(ty, range)
    }

    /// Find a path from this position to a position or room object, with an
    /// optional options object
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.findPathTo)
    #[inline]
    pub fn find_path_to<T, F, R>(&self, target: &T, options: Option<FindPathOptions<F, R>>) -> Path
    where
        T: HasPosition,
        F: FnMut(RoomName, CostMatrix) -> R,
        R: RoomCostResult,
    {
        RoomPosition::from(self).find_path_to(target, options)
    }

    /// Find a path from this position to the given coordinates in the same
    /// room, with an optional options object.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.findPathTo)
    #[inline]
    pub fn find_path_to_xy<F, R>(
        self,
        x: RoomCoordinate,
        y: RoomCoordinate,
        options: Option<FindPathOptions<F, R>>,
    ) -> Path
    where
        F: FnMut(RoomName, CostMatrix) -> R,
        R: RoomCostResult,
    {
        RoomPosition::from(self).find_path_to_xy(x, y, options)
    }

    /// Get all objects at this position.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.look)
    #[inline]
    pub fn look(self) -> Vec<LookResult> {
        RoomPosition::from(self).look()
    }

    /// Get all objects of a given type at this position, if any.
    ///
    /// [Screeps documentation](https://docs.screeps.com/api/#RoomPosition.lookFor)
    #[inline]
    pub fn look_for<T>(self, ty: T) -> Vec<T::Item>
    where
        T: LookConstant,
    {
        RoomPosition::from(self).look_for(ty)
    }
}