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
//! Math utilities on `Position` which don't exist in the Screeps API //! proper. use std::ops::{Add, Sub}; use super::Position; impl Position { /// 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 /// /// ``` /// use screeps::Position; /// /// let e21s21 = "E21S21".parse().unwrap(); /// let e21s22 = "E21S22".parse().unwrap(); /// /// let mut pos = Position::new(21, 21, e21s21); /// pos.offset(5, 5); /// assert_eq!(pos, Position::new(26, 26, e21s21)); /// /// pos.offset(0, 49); /// assert_eq!(pos, Position::new(26, 25, e21s22)); /// ``` #[inline] pub fn offset(&mut self, x: i32, y: i32) { *self = *self + (x, y); } } impl Add<(i32, i32)> for Position { type Output = Position; /// 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 /// /// ``` /// use screeps::Position; /// /// let w5s6 = "W5S6".parse().unwrap(); /// let w5s5 = "W5S5".parse().unwrap(); /// /// let pos1 = Position::new(42, 42, w5s6); /// let pos2 = pos1 + (7, 7); /// assert_eq!(pos2, Position::new(49, 49, w5s6)); /// /// let pos3 = pos2 + (0, -59); /// assert_eq!(pos3, Position::new(49, 40, w5s5)); /// /// let pos4 = pos3 - (49, 0); /// assert_eq!(pos4, Position::new(0, 40, w5s5)); /// ``` #[inline] fn add(self, (x, y): (i32, i32)) -> Self { let (wx, wy) = self.world_coords(); Self::from_world_coords(wx + x, wy + y) } } impl Sub<(i32, i32)> for Position { type Output = Position; /// See the implementation of `Add<(i32, i32)>` for [`Position`]. #[inline] fn sub(self, (x, y): (i32, i32)) -> Self { self + (-x, -y) } } impl Sub<Position> for Position { type Output = (i32, i32); /// Subtracts the other room position from this one, extracting the /// difference as the output. /// /// # Example /// /// ``` /// use screeps::Position; /// /// let e5n5 = "E5N5".parse().unwrap(); /// let e5n6 = "E5N6".parse().unwrap(); /// /// let pos1 = Position::new(40, 40, e5n5); /// let pos2 = Position::new(0, 20, e5n6); /// assert_eq!(pos1 - pos2, (40, 70)); /// ``` #[inline] fn sub(self, other: Position) -> (i32, i32) { let (mx, my) = self.world_coords(); let (ox, oy) = other.world_coords(); (mx - ox, my - oy) } }