aboutsummaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/customer.rs50
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)
}