#[repr(transparent)]pub struct Position { /* private fields */ }Expand description
Represents a position in a particular room in Screeps.
Note: This is analogous to the RoomPosition JavaScript type.
We’ve renamed this type to Position in screeps-game-api to reflect the
fact that it’s implemented entirely as a local type, and does represent a
position located within an entire shard, not only within a single room.
This should be a very efficient type to use in most if not all situations.
It’s represented by a single u32, all math operations are implemented in
pure-Rust code, and uploading to / downloading from JavaScript only requires
transferring a single i32.
Using Position
You can retrieve a Position by getting the position of a game object using
RoomObject::pos, or by creating one from coordinates with
Position::new.
You can use any of the math methods available on this page to manipulate
Position, and you can pass it to any game methods expecting a position
or something with a position.
Serialization
Position implements both serde::Serialize and
serde::Deserialize.
When serializing, it will use the format {roomName: String, x: u32, y: u32} in “human readable” formats like JSON, and will serialize as a single
i32 in “non-human readable” formats like bincode.
If you need a reference to a RoomPosition in JavaScript,
convert the native Position to a RoomPosition:
use screeps::{Position, RoomCoordinate, RoomPosition};
use std::convert::TryFrom;
let pos = Position::new(
RoomCoordinate::try_from(20).unwrap(),
RoomCoordinate::try_from(21).unwrap(),
"E5N6".parse().unwrap(),
);
let js_pos = RoomPosition::from(pos);
let result = js_pos.room_name();Deserialization
Position implements TryFrom<Value>, allowing conversion from values
retrieved from JavaScript. The implementation is fairly lenient, and will
try to accept the value as any of the following things, in order:
- an integer representing the packedPos
- this can be produced by retrieving the
__packedPosfield of aRoomPosition
- this can be produced by retrieving the
- an object with a
__packedPosproperty- this allows converting from a JavaScript
RoomPositionto aPositionwithout referencing__packedPosmanually, but is less efficient since it requires an extra callback into JavaScript to grab that field from within the conversion code
- this allows converting from a JavaScript
- an object with
x,yandroomNameproperties- this is mainly intended to decode
Positions which were previously sent to JavaScript using@{}injs!{}, or serialized usingserde::Serialize - this will also understand
RoomPositions in private servers versions3.2.1and below, prior to when__packedPoswas added
- this is mainly intended to decode
World vs. in-room coordinates
When converting Position to integer x/y coordinates, there are two main
methods. The first is to use x/y as “in room” coordinates, which are
bounded within 0..=49. These coordinates only identify the location within
a given room name. These are used by Position::x, Position::y,
Position::new as well as Position::coords,
Position::coords_signed and the various implementations of Into<([ui*], [ui*])> for Position.
The second is to use x/y as “world” coordinates, which are coordinates
spread across the world. To ensures they agree with in-room coordinates,
south is positive y, north is negative y, east is positive x and west
is negative x. One way to think of them is as extending the room
coordinates of the room E0S0 throughout the entire map.
World coordinates are used by Position::world_x, Position::world_y,
Position::world_coords, Position::from_world_coords, and by all
implementations which allow adding or subtracting positions (see Addition
and subtraction).
Method Behavior
While this corresponds with the JavaScript RoomPosition type, it is not
identical. In particular, all “calculation” methods which take in another
position are re-implemented in pure Rust code, and some behave slightly
different.
For instance, Position::get_range_to operates on positions as world
coordinates, and will return accurate distances for positions in different
rooms. This is in contrast to RoomPosition.getRangeTo in JavaScript, which
will return Infinity for positions from different rooms.
Position::in_range_to has a similar difference.
Besides extending behavior to work between rooms, we’ve tried to keep methods as in-sync with the JavaScript versions as possible. Everything will “just work”, and there should be some speed advantage because of not having to call into JavaScript to perform calculations.
Addition and subtraction
Position implements Add<(i32, i32)>, Sub<(i32, i32)> and
Sub<Position>. All of these implementations work on positions as world
positions, and will treat positions from different rooms just as if they’re
further apart.
The Add implementation can be used to add an offset to a position:
let pos1 = Position::new(
RoomCoordinate::try_from(0).unwrap(),
RoomCoordinate::try_from(0).unwrap(),
"E1N1".parse().unwrap(),
);
let pos2 = Position::new(
RoomCoordinate::try_from(40).unwrap(),
RoomCoordinate::try_from(20).unwrap(),
"E1N1".parse().unwrap(),
);
assert_eq!(pos1 + (40, 20), pos2);And the Sub implementation can be used to get the offset between two
positions:
let pos1 = Position::new(
RoomCoordinate::try_from(4).unwrap(),
RoomCoordinate::try_from(20).unwrap(),
"E20S21".parse().unwrap(),
);
let pos2 = Position::new(
RoomCoordinate::try_from(4).unwrap(),
RoomCoordinate::try_from(30).unwrap(),
"E20S22".parse().unwrap(),
);
assert_eq!(pos2 - pos1, (0, 60));
let pos3 = Position::new(
RoomCoordinate::try_from(0).unwrap(),
RoomCoordinate::try_from(0).unwrap(),
"E20S21".parse().unwrap(),
);
assert_eq!(pos3 - pos1, (-4, -20));Ordering
To facilitate use as a key in a BTreeMap or other similar data
structures, Position implements PartialOrd and Ord.
Positions are ordered first by ascending world y position, then by
ascending world x position. World x and y here simply extend the x,y
coords within the room E0S0 throughout the map.
Looking at positions as tuples (world_x, world_y), the sorting obeys rules
such as:
(a, 0) < (b, 1)for anya,b(0, c) < (1, c)for anyc
This follows left-to-right reading order when looking at the Screeps map from above.
Implementations§
source§impl Position
impl Position
sourcepub fn towards(self, target: Position, distance_towards_target: i32) -> Position
pub fn towards(self, target: Position, distance_towards_target: i32) -> Position
Calculates an approximate midpoint between this point and the target.
In case of a tie, rounds towards this point.
If distance_towards_target is bigger than the distance to the target,
the target is returned.
sourcepub fn between(self, target: Position, distance_from_target: i32) -> Position
pub fn between(self, target: Position, distance_from_target: i32) -> Position
Calculates an approximate midpoint between this point and the target.
In case of a tie, rounds towards the target.
If distance_from_target is bigger than the distance to the target,
this position is returned.
sourcepub fn midpoint_between(self, target: Position) -> Position
pub fn midpoint_between(self, target: Position) -> Position
Calculates an approximate midpoint between this point and the target.
In case of a tie, rounds towards the target.
source§impl Position
impl Position
sourcepub fn offset(&mut self, x: i32, y: i32)
pub fn offset(&mut self, x: i32, y: i32)
Returns a new position offset from this position by the specified x coords and y coords.
This function operates on world coordinates, and will wrap between rooms if necessary.
To return a new position rather than modifying in place, use pos + (x, y). See the implementation of Add<(i32, i32)> for
Position further down on this page.
Panics
Will panic if the new position overflows the world. See
Position::from_world_coords.
Example
let e21s21 = "E21S21".parse().unwrap();
let e21s22 = "E21S22".parse().unwrap();
let mut pos = Position::new(
RoomCoordinate::try_from(21).unwrap(),
RoomCoordinate::try_from(21).unwrap(),
e21s21,
);
pos.offset(5, 5);
assert_eq!(
pos,
Position::new(
RoomCoordinate::try_from(26).unwrap(),
RoomCoordinate::try_from(26).unwrap(),
e21s21
)
);
pos.offset(0, 49);
assert_eq!(
pos,
Position::new(
RoomCoordinate::try_from(26).unwrap(),
RoomCoordinate::try_from(25).unwrap(),
e21s22
)
);source§impl Position
impl Position
sourcepub fn get_direction_to(self, target: Position) -> Option<Direction>
pub fn get_direction_to(self, target: Position) -> Option<Direction>
Gets linear direction to the specified position.
Note that this chooses between Top/Bottom/Left/Right and
TopLeft/TopRight/BottomLeft/BottomRight by the magnitude in both
directions. For instance, Direction::Top can be returned even
if the target has a slightly different x coordinate.
sourcepub fn get_range_to(self, target: Position) -> u32
pub fn get_range_to(self, target: Position) -> u32
Gets linear range to the specified position.
This operates on positions as “world positions”, and will return an
accurate range for positions in different rooms. Note that the
corresponding JavaScript method, RoomPosition.getRangeTo returns
Infinity if given positions in different rooms.
sourcepub fn in_range_to(self, target: Position, range: u32) -> bool
pub fn in_range_to(self, target: Position, range: u32) -> bool
Checks whether this position is in the given range of another position.
This operates on positions as “world positions”, and may return true for
positions in different rooms which are still within the given range.
Note that the corresponding JavaScript method, RoomPosition.inRangeTo,
will always return false for positions from different rooms.
sourcepub fn is_equal_to(self, target: Position) -> bool
pub fn is_equal_to(self, target: Position) -> bool
Checks whether this position is the same as the specified position.
Note that this is equivalent to this_pos == target.pos().
sourcepub fn is_near_to(self, target: Position) -> bool
pub fn is_near_to(self, target: Position) -> bool
True if this position is in the same room as the target, and the range is at most 1.
source§impl Position
impl Position
sourcepub fn create_construction_site(
self,
ty: StructureType,
name: Option<&JsString>
) -> ReturnCode
pub fn create_construction_site( self, ty: StructureType, name: Option<&JsString> ) -> ReturnCode
Creates a ConstructionSite at this position. If it’s a
StructureSpawn, a name can optionally be assigned for the structure.
sourcepub fn create_flag(
self,
name: Option<&JsString>,
color: Option<Color>,
secondary_color: Option<Color>
) -> Result<JsString, ErrorCode>
pub fn create_flag( self, name: Option<&JsString>, color: Option<Color>, secondary_color: Option<Color> ) -> Result<JsString, ErrorCode>
Creates a Flag at this position. If successful, returns the name of
the created flag.
sourcepub fn find_closest_by_path<T>(
self,
ty: T,
options: Option<&Object>
) -> Option<T::Item>where
T: FindConstant,
<T as FindConstant>::Item: From<JsValue>,
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>,
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.
sourcepub fn find_closest_by_range<T>(self, ty: T) -> Option<T::Item>where
T: FindConstant,
pub fn find_closest_by_range<T>(self, ty: T) -> Option<T::Item>where T: FindConstant,
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.
sourcepub fn find_in_range<T>(self, ty: T, range: u8) -> Vec<T::Item>where
T: FindConstant,
pub fn find_in_range<T>(self, ty: T, range: u8) -> Vec<T::Item>where T: FindConstant,
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.
sourcepub fn find_path_to<T, F, R>(
&self,
target: &T,
options: Option<FindPathOptions<F, R>>
) -> Pathwhere
T: HasPosition,
F: FnMut(RoomName, CostMatrix) -> R,
R: RoomCostResult,
pub fn find_path_to<T, F, R>( &self, target: &T, options: Option<FindPathOptions<F, R>> ) -> Pathwhere T: HasPosition, F: FnMut(RoomName, CostMatrix) -> R, R: RoomCostResult,
Find a path from this position to a position or room object, with an optional options object
sourcepub fn find_path_to_xy<F, R>(
self,
x: RoomCoordinate,
y: RoomCoordinate,
options: Option<FindPathOptions<F, R>>
) -> Pathwhere
F: FnMut(RoomName, CostMatrix) -> R,
R: RoomCostResult,
pub fn find_path_to_xy<F, R>( self, x: RoomCoordinate, y: RoomCoordinate, options: Option<FindPathOptions<F, R>> ) -> Pathwhere F: FnMut(RoomName, CostMatrix) -> R, R: RoomCostResult,
Find a path from this position to the given coordinates in the same room, with an optional options object.
sourcepub fn look(self) -> Vec<LookResult>
pub fn look(self) -> Vec<LookResult>
Get all objects at this position.
sourcepub fn look_for<T>(self, ty: T) -> Vec<T::Item>where
T: LookConstant,
pub fn look_for<T>(self, ty: T) -> Vec<T::Item>where T: LookConstant,
Get all objects of a given type at this position, if any.
source§impl Position
impl Position
sourcepub fn world_x(self) -> i32
pub fn world_x(self) -> i32
Returns this position’s horizontal “world coordinate”.
The value is equal to 50 * room_x + x, where room_x is defined as
room_x = -xx - 1 for Wxx rooms and as room_x = xx for Exx rooms.
sourcepub fn world_y(self) -> i32
pub fn world_y(self) -> i32
Returns this position’s vertical “world coordinate”.
The value is equal to 50 * room_y + y, where room_y is defined as
room_y = -yy - 1 for Nyy rooms and as room_y = yy for Syy rooms.
sourcepub fn world_coords(self) -> (i32, i32)
pub fn world_coords(self) -> (i32, i32)
Returns this position’s “world coordinates”.
The first value is equal to 50 * room_x + x, where room_x is defined
as room_x = -xx - 1 for Wxx rooms and as room_x = xx for Exx
rooms.
The second value is equal to 50 * room_y + y, where room_y is
defined as room_y = -yy - 1 for Nyy rooms and as room_y = yy
for Syy rooms.
See also Position::world_x and
Position::world_y.
sourcepub fn from_world_coords(x: i32, y: i32) -> Self
pub fn from_world_coords(x: i32, y: i32) -> Self
Creates a room position from world coords.
Panics
Panics if either x or y is out of the range -128 * 50 .. +128 * 50.
source§impl Position
impl Position
sourcepub fn new(x: RoomCoordinate, y: RoomCoordinate, room_name: RoomName) -> Self
pub fn new(x: RoomCoordinate, y: RoomCoordinate, room_name: RoomName) -> Self
Create a new Position
Panics
Will panic if either x or y is larger than 49, or if room_name is
outside of the range E127N127 - W127S127.
pub fn packed_repr(self) -> u32
pub fn from_packed(packed: u32) -> Self
sourcepub fn x(self) -> RoomCoordinate
pub fn x(self) -> RoomCoordinate
Gets this position’s in-room x coordinate.
sourcepub fn y(self) -> RoomCoordinate
pub fn y(self) -> RoomCoordinate
Gets this position’s in-room y coordinate.
pub fn room_name(self) -> RoomName
pub fn set_x(&mut self, x: RoomCoordinate)
pub fn set_y(&mut self, y: RoomCoordinate)
pub fn set_room_name(&mut self, room_name: RoomName)
pub fn with_x(self, x: RoomCoordinate) -> Self
pub fn with_y(self, y: RoomCoordinate) -> Self
pub fn with_room_name(self, room_name: RoomName) -> Self
Trait Implementations§
source§impl Add<(i32, i32)> for Position
impl Add<(i32, i32)> for Position
source§fn add(self, (x, y): (i32, i32)) -> Self
fn add(self, (x, y): (i32, i32)) -> Self
Adds an (x, y) pair to this room position’s world coordinates.
Will change rooms if necessary.
Panics
Will panic if the new position’s room is outside bounds. See
Position::from_world_coords.
Example
let w5s6 = "W5S6".parse().unwrap();
let w5s5 = "W5S5".parse().unwrap();
let pos1 = Position::new(
RoomCoordinate::try_from(42).unwrap(),
RoomCoordinate::try_from(42).unwrap(),
w5s6,
);
let pos2 = pos1 + (7, 7);
assert_eq!(
pos2,
Position::new(
RoomCoordinate::try_from(49).unwrap(),
RoomCoordinate::try_from(49).unwrap(),
w5s6
)
);
let pos3 = pos2 + (0, -59);
assert_eq!(
pos3,
Position::new(
RoomCoordinate::try_from(49).unwrap(),
RoomCoordinate::try_from(40).unwrap(),
w5s5
)
);
let pos4 = pos3 - (49, 0);
assert_eq!(
pos4,
Position::new(
RoomCoordinate::try_from(0).unwrap(),
RoomCoordinate::try_from(40).unwrap(),
w5s5
)
);source§impl<'de> Deserialize<'de> for Position
impl<'de> Deserialize<'de> for Position
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where D: Deserializer<'de>,
source§impl From<&Position> for RoomPosition
impl From<&Position> for RoomPosition
source§impl From<&RoomPosition> for Position
impl From<&RoomPosition> for Position
source§fn from(js_pos: &RoomPosition) -> Self
fn from(js_pos: &RoomPosition) -> Self
source§impl From<Position> for RoomPosition
impl From<Position> for RoomPosition
source§impl From<RoomPosition> for Position
impl From<RoomPosition> for Position
source§fn from(js_pos: RoomPosition) -> Self
fn from(js_pos: RoomPosition) -> Self
source§impl Index<Position> for LocalCostMatrix
impl Index<Position> for LocalCostMatrix
source§impl IndexMut<Position> for LocalCostMatrix
impl IndexMut<Position> for LocalCostMatrix
source§impl Ord for Position
impl Ord for Position
source§impl PartialEq<Position> for Position
impl PartialEq<Position> for Position
source§impl PartialOrd<Position> for Position
impl PartialOrd<Position> for Position
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self and other) and is used by the <=
operator. Read moresource§impl Sub<Position> for Position
impl Sub<Position> for Position
source§fn sub(self, other: Position) -> (i32, i32)
fn sub(self, other: Position) -> (i32, i32)
Subtracts the other room position from this one, extracting the difference as the output.
Example
let e5n5 = "E5N5".parse().unwrap();
let e5n6 = "E5N6".parse().unwrap();
let pos1 = Position::new(
RoomCoordinate::try_from(40).unwrap(),
RoomCoordinate::try_from(40).unwrap(),
e5n5,
);
let pos2 = Position::new(
RoomCoordinate::try_from(0).unwrap(),
RoomCoordinate::try_from(20).unwrap(),
e5n6,
);
assert_eq!(pos1 - pos2, (40, 70));