diff options
Diffstat (limited to 'server/src/customer')
| -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; | 
