aboutsummaryrefslogtreecommitdiff
path: root/games/rstnode/src/map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'games/rstnode/src/map.rs')
-rw-r--r--games/rstnode/src/map.rs80
1 files changed, 80 insertions, 0 deletions
diff --git a/games/rstnode/src/map.rs b/games/rstnode/src/map.rs
new file mode 100644
index 000000000000..37f758b4a433
--- /dev/null
+++ b/games/rstnode/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()
+ }
+}