//! 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, /// 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), } } pub fn update(&mut self, cb: F) -> ServerResult where F: Fn(&mut Map) -> ServerResult, { unimplemented!() } /// 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() } }