summaryrefslogtreecommitdiff
path: root/server/src/customer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/customer/mod.rs')
-rw-r--r--server/src/customer/mod.rs78
1 files changed, 48 insertions, 30 deletions
diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs
index 16275227..185133e7 100644
--- a/server/src/customer/mod.rs
+++ b/server/src/customer/mod.rs
@@ -1,19 +1,19 @@
/*
Undercooked - a game about cooking
Copyright 2024 metamuffin
-
+
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, version 3 of the License only.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
-
+
*/
pub mod movement;
mod pathfinding;
@@ -22,6 +22,7 @@ use crate::{
data::Gamedata,
game::Game,
protocol::{DemandIndex, ItemIndex, Message, PacketC, PacketS, PlayerID},
+ state::State,
};
use glam::{IVec2, Vec2};
use log::{debug, error};
@@ -39,6 +40,7 @@ use tokio::{
};
struct CustomerManager {
+ disabled: bool,
walkable: HashSet<IVec2>,
chairs: HashMap<IVec2, bool>,
items: HashMap<IVec2, ItemIndex>,
@@ -77,34 +79,21 @@ struct Customer {
state: CustomerState,
}
-pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<PacketC>) {
+pub async fn customer(gstate: Arc<RwLock<State>>, mut grx: broadcast::Receiver<PacketC>) {
let mut state = CustomerManager {
customer_id_counter: PlayerID(0),
walkable: Default::default(),
chairs: Default::default(),
items: Default::default(),
customers: Default::default(),
+ disabled: true,
demand: DemandState {
data: Gamedata::default(),
},
};
- let initial = game.write().await.prime_client(PlayerID(-1));
- for p in initial {
- match p {
- PacketC::Init { data, .. } => {
- state.demand.data = data;
- }
- PacketC::UpdateMap { pos, tile, .. } => {
- let tilename = state.demand.data.tile_name(tile);
- if !state.demand.data.is_tile_colliding(tile) {
- state.walkable.insert(pos);
- }
- if tilename == "chair" {
- state.chairs.insert(pos, true);
- }
- }
- _ => (),
- }
+ let initial = gstate.write().await.game.prime_client();
+ for packet in initial {
+ state.packet(packet);
}
let mut interval = interval(Duration::from_millis(40));
@@ -112,21 +101,25 @@ pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<Pack
loop {
tokio::select! {
packet = grx.recv() => {
- match packet.unwrap() {
+ let packet = packet.unwrap();
+ match packet {
PacketC::PutItem { .. }
| PacketC::TakeItem { .. }
| PacketC::SetTileItem { .. } => {
- let g = game.read().await;
- update_items(&mut state, &g)
+ let g = gstate.read().await;
+ update_items(&mut state, &g.game)
},
_ => ()
}
+ state.packet(packet);
}
_ = interval.tick() => {
- state.tick(&mut packets_out, 0.04);
- for (player,packet) in packets_out.drain(..) {
- if let Err(e) = game.write().await.packet_in(player, packet) {
- error!("customer misbehaved: {e}")
+ if !state.disabled {
+ state.tick(&mut packets_out, 0.04);
+ for (player,packet) in packets_out.drain(..) {
+ if let Err(e) = gstate.write().await.packet_in(player, packet).await {
+ error!("customer misbehaved: {e}")
+ }
}
}
}
@@ -134,6 +127,7 @@ pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<Pack
}
}
+// TODO very inefficient, please do that incrementally
fn update_items(state: &mut CustomerManager, game: &Game) {
state.items.clear();
for (&pos, tile) in game.tiles() {
@@ -150,12 +144,36 @@ impl DemandState {
}
pub fn generate_demand(&self) -> DemandIndex {
// TODO insert sofa magic formula
-
DemandIndex(random::<usize>() % self.data.demands.len())
}
}
impl CustomerManager {
+ pub fn packet(&mut self, packet: PacketC) {
+ match packet {
+ PacketC::Data { data } => {
+ self.disabled = data.demands.is_empty();
+ self.demand.data = data;
+ }
+ PacketC::RemovePlayer { id } => {
+ self.customers.remove(&id);
+ }
+ PacketC::UpdateMap {
+ tile: pos,
+ kind: Some(tile),
+ ..
+ } => {
+ let tilename = self.demand.data.tile_name(tile);
+ if !self.demand.data.is_tile_colliding(tile) {
+ self.walkable.insert(pos);
+ }
+ if tilename == "chair" {
+ self.chairs.insert(pos, true);
+ }
+ }
+ _ => (),
+ }
+ }
pub fn tick(&mut self, packets_out: &mut Vec<(PlayerID, PacketS)>, dt: f32) {
if self.customers.len() < self.demand.target_customer_count() {
self.customer_id_counter.0 -= 1;