diff options
Diffstat (limited to 'server/src/customer.rs')
-rw-r--r-- | server/src/customer.rs | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/server/src/customer.rs b/server/src/customer.rs index 403b891e..b003c935 100644 --- a/server/src/customer.rs +++ b/server/src/customer.rs @@ -4,7 +4,8 @@ use crate::{ protocol::{PacketC, PacketS, PlayerID}, }; use glam::{IVec2, Vec2}; -use log::{error, info}; +use log::{debug, error}; +use rand::thread_rng; use std::{ cmp::Ordering, collections::{BinaryHeap, HashMap, HashSet}, @@ -19,13 +20,13 @@ use tokio::{ struct DemandState { data: Gamedata, walkable: HashSet<IVec2>, - chairs: HashSet<IVec2>, + chairs: HashMap<IVec2, bool>, customers: Vec<Customer>, } enum CustomerState { - WalkingToChair { path: Vec<Vec2> }, - Waiting, + WalkingToChair { path: Vec<Vec2>, chair: IVec2 }, + Waiting { chair: IVec2 }, } struct Customer { @@ -51,11 +52,11 @@ pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<Pack } PacketC::UpdateMap { pos, tile, .. } => { let tilename = &state.data.tile_names[tile]; - if tilename == "floor" || tilename == "door" { + if tilename == "floor" || tilename == "door" || tilename == "chair" { state.walkable.insert(pos); } if tilename == "chair" { - state.chairs.insert(pos); + state.chairs.insert(pos, true); } } _ => (), @@ -94,41 +95,51 @@ impl DemandState { character: 0, }, )); - let path = find_path( - &self.walkable, - self.data.customer_spawn.as_ivec2(), - IVec2::new(20, 1), - ) - .expect("no path"); + let chair = select_chair(&mut self.chairs); + let path = find_path(&self.walkable, self.data.customer_spawn.as_ivec2(), chair) + .expect("no path"); self.customers.push(Customer { id: -1, position: self.data.customer_spawn, facing: Vec2::X, vel: Vec2::ZERO, - state: CustomerState::WalkingToChair { path }, + state: CustomerState::WalkingToChair { path, chair }, }); } for p in &mut self.customers { match &mut p.state { - CustomerState::WalkingToChair { path } => { + CustomerState::WalkingToChair { path, chair } => { if let Some(next) = path.last().copied() { - info!("next {next}"); - if next.distance(p.position) < 0.6 { + debug!("next {next}"); + if next.distance(p.position) < if path.len() == 1 { 0.1 } else { 0.6 } { path.pop(); } packets_out .push((p.id, move_player(p, &self.walkable, next - p.position, dt))); } else { - p.state = CustomerState::Waiting; + p.state = CustomerState::Waiting { chair: *chair }; } } - CustomerState::Waiting => (), + CustomerState::Waiting { chair } => { + debug!("waiting") + } } } } } +pub fn select_chair(chairs: &mut HashMap<IVec2, bool>) -> IVec2 { + use rand::seq::IteratorRandom; + let (chosen, free) = chairs + .iter_mut() + .filter(|(_p, free)| **free) + .choose(&mut thread_rng()) + .unwrap(); + *free = false; + *chosen +} + pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Vec<Vec2>> { #[derive(Debug, PartialEq, Eq)] struct Open(i32, IVec2, IVec2); @@ -170,14 +181,13 @@ pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Vec<Vec let mut path = Vec::new(); let mut c = to; loop { + path.push(c.as_vec2() + 0.5); let cn = visited[&c]; - path.push(cn.as_vec2() + 0.5); if cn == c { break; } c = cn } - Some(path) } |