summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/map.yaml2
-rw-r--r--server/src/customer.rs69
-rw-r--r--test-client/main.ts11
3 files changed, 54 insertions, 28 deletions
diff --git a/data/map.yaml b/data/map.yaml
index c3564eb8..4e9c2a11 100644
--- a/data/map.yaml
+++ b/data/map.yaml
@@ -10,7 +10,7 @@ map:
- "|c.....ct|##ss#oopp#X|"
- "+---dd---+-----------+"
- "......................"
- - "..................!..."
+ - ".........!............"
- "......................"
tiles:
diff --git a/server/src/customer.rs b/server/src/customer.rs
index 8d843fda..403b891e 100644
--- a/server/src/customer.rs
+++ b/server/src/customer.rs
@@ -4,10 +4,10 @@ use crate::{
protocol::{PacketC, PacketS, PlayerID},
};
use glam::{IVec2, Vec2};
-use log::error;
+use log::{error, info};
use std::{
cmp::Ordering,
- collections::{BinaryHeap, HashMap, HashSet, VecDeque},
+ collections::{BinaryHeap, HashMap, HashSet},
sync::Arc,
time::Duration,
};
@@ -24,7 +24,7 @@ struct DemandState {
}
enum CustomerState {
- WalkingToChair { target: Vec2 },
+ WalkingToChair { path: Vec<Vec2> },
Waiting,
}
@@ -84,7 +84,6 @@ pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<Pack
}
}
-impl DemandState {}
impl DemandState {
pub fn tick(&mut self, packets_out: &mut Vec<(PlayerID, PacketS)>, dt: f32) {
if self.customers.is_empty() {
@@ -95,25 +94,32 @@ impl DemandState {
character: 0,
},
));
+ let path = find_path(
+ &self.walkable,
+ self.data.customer_spawn.as_ivec2(),
+ IVec2::new(20, 1),
+ )
+ .expect("no path");
self.customers.push(Customer {
id: -1,
position: self.data.customer_spawn,
facing: Vec2::X,
vel: Vec2::ZERO,
- state: CustomerState::WalkingToChair {
- target: Vec2::new(2., 2.),
- },
+ state: CustomerState::WalkingToChair { path },
});
}
for p in &mut self.customers {
- match p.state {
- CustomerState::WalkingToChair { target } => {
- packets_out.push((
- p.id,
- move_player(p, &self.walkable, target - p.position, dt),
- ));
- if target.distance(p.position) < 0.5 {
+ match &mut p.state {
+ CustomerState::WalkingToChair { path } => {
+ if let Some(next) = path.last().copied() {
+ info!("next {next}");
+ if next.distance(p.position) < 0.6 {
+ path.pop();
+ }
+ packets_out
+ .push((p.id, move_player(p, &self.walkable, next - p.position, dt)));
+ } else {
p.state = CustomerState::Waiting;
}
}
@@ -123,7 +129,7 @@ impl DemandState {
}
}
-pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> VecDeque<IVec2> {
+pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> Option<Vec<Vec2>> {
#[derive(Debug, PartialEq, Eq)]
struct Open(i32, IVec2, IVec2);
impl PartialOrd for Open {
@@ -141,8 +147,12 @@ pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> VecDeque<IVec2
let mut open = BinaryHeap::new();
open.push(Open(1, from, from));
- while let Some(Open(_, p, f)) = open.pop() {
- if !visited.contains_key(&p) {
+ loop {
+ let Some(Open(_, p, f)) = open.pop() else {
+ eprintln!("{visited:?}");
+ return None;
+ };
+ if visited.contains_key(&p) {
continue;
}
visited.insert(p, f);
@@ -150,22 +160,29 @@ pub fn find_path(map: &HashSet<IVec2>, from: IVec2, to: IVec2) -> VecDeque<IVec2
break;
}
for d in [IVec2::NEG_X, IVec2::NEG_Y, IVec2::X, IVec2::Y] {
- open.push(Open(d.distance_squared(to), p + d, p));
+ let n = p + d;
+ if map.contains(&n) {
+ open.push(Open(-d.distance_squared(to), n, p));
+ }
}
}
- let mut path = VecDeque::new();
- path.push_back(to);
-
- // loop {
- // path.
- // }
+ let mut path = Vec::new();
+ let mut c = to;
+ loop {
+ let cn = visited[&c];
+ path.push(cn.as_vec2() + 0.5);
+ if cn == c {
+ break;
+ }
+ c = cn
+ }
- path
+ Some(path)
}
fn move_player(p: &mut Customer, map: &HashSet<IVec2>, direction: Vec2, dt: f32) -> PacketS {
- let direction = direction.normalize();
+ let direction = direction.normalize_or_zero();
if direction.length() > 0.1 {
p.facing = direction + (p.facing - direction) * (-dt * 10.).exp();
}
diff --git a/test-client/main.ts b/test-client/main.ts
index f208eb34..b189f08b 100644
--- a/test-client/main.ts
+++ b/test-client/main.ts
@@ -70,7 +70,7 @@ let data: Gamedata = { item_names: [], tile_names: [], spawn: [0, 0] }
let my_id: PlayerID = -1
const camera: V2 = { x: 0, y: 0 }
-const camera_zoom = 0.05
+let camera_zoom = 0.1
const interact_target_anim: V2 = { x: 0, y: 0 }
let interacting: V2 | undefined;
let scale = 0
@@ -327,6 +327,15 @@ function draw_ingame() {
draw_interact_target()
ctx.restore()
+
+ if (keys_down.has("KeyP")) {
+ camera_zoom = 0.05
+ ctx.fillStyle = "white"
+ ctx.textAlign = "left"
+ ctx.textBaseline = "bottom"
+ ctx.font = "20px sans-serif"
+ ctx.fillText(`interact = ${JSON.stringify(get_interact_target())}`, 10, 30)
+ } else { camera_zoom = 0.1 }
}
function draw_item(item: ItemData) {