My personal project and infrastructure archive
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
nomicon/games/rstnode/src/map.rs

80 lines
2.2 KiB

//! 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()
}
}