diff options
Diffstat (limited to 'games/rstnode/rst-core/src/map.rs')
-rw-r--r-- | games/rstnode/rst-core/src/map.rs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/games/rstnode/rst-core/src/map.rs b/games/rstnode/rst-core/src/map.rs new file mode 100644 index 000000000000..37f758b4a433 --- /dev/null +++ b/games/rstnode/rst-core/src/map.rs @@ -0,0 +1,80 @@ +//! Implements a map graph and world logic + +use crate::{ + config::{LinkCfg, MapCfg, NodeCfg}, + data::{Link, Node, NodeId}, + server::{ServerErr, ServerResult}, + wire::Response, +}; +use async_std::sync::Arc; +use quadtree_rs::{ + area::{Area, AreaBuilder}, + point::Point, + Quadtree, +}; +use std::collections::BTreeMap; + +pub struct MapNode { + pub pos: (f64, f64), + pub inner: Node, +} + +/// A map that people fight on +/// +/// A map is defined by it's graph relationships, but also where on +/// the map nodes are placed, how much spacing there is, etc. All +/// this information is encoded in the same structs because it's +/// static, and just more convenient. +pub struct Map { + /// Node IDs mapped to coordinates + nodes: BTreeMap<NodeId, (i64, i64)>, + /// Link IDs mapped to link objects + links: BTreeMap<u16, Arc<Link>>, + /// A coordinate map for the network + coord: Quadtree<i64, Arc<MapNode>>, +} + +impl Map { + pub fn new() -> Self { + Self { + nodes: BTreeMap::new(), + links: BTreeMap::new(), + coord: Quadtree::new(2), + } + } + + pub fn update<F>(&mut self, cb: F) -> ServerResult<Response> + where + F: Fn(&mut Map) -> ServerResult<Response>, + { + unimplemented!() + } + + /// Get all objects that can be selected by a single point + pub fn get_by_point(&self, x: i64, y: i64) -> Option<Vec<NodeId>> { + self.coord + .query( + AreaBuilder::default() + .anchor(Point::from((x, y))) + .dimensions((1, 1)) + .build() + .ok()?, + ) + .map(|entry| Some(entry.value_ref().inner.id)) + .collect() + } + + /// Get all objects that can be selected by a 2d area + pub fn get_by_area(&self, x: i64, y: i64, w: i64, h: i64) -> Option<Vec<NodeId>> { + self.coord + .query( + AreaBuilder::default() + .anchor(Point::from((x, y))) + .dimensions((w, h)) + .build() + .ok()?, + ) + .map(|entry| Some(entry.value_ref().inner.id)) + .collect() + } +} |