//! Implements a map graph and world logic use crate::{ data::{Link, Node, NodeId}, wire::Response, }; use async_std::sync::Arc; use quadtree_rs::{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, /// Link IDs mapped to link objects _links: BTreeMap>, /// A coordinate map for the network coord: Quadtree>, } impl Map { pub fn new() -> Self { Self { nodes: BTreeMap::new(), _links: BTreeMap::new(), coord: Quadtree::new(2), } } /// Get the position of a node by its ID pub fn node_position(&self, id: NodeId) -> Option<(i64, i64)> { self.nodes.get(&id).cloned() } /// Get all objects that can be selected by a single point pub fn get_by_point(&self, x: i64, y: i64) -> Option> { 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> { self.coord .query( AreaBuilder::default() .anchor(Point::from((x, y))) .dimensions((w, h)) .build() .ok()?, ) .map(|entry| Some(entry.value_ref().inner.id)) .collect() } }