diff options
Diffstat (limited to 'server/src/customer/mod.rs')
-rw-r--r-- | server/src/customer/mod.rs | 78 |
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; |