diff options
-rw-r--r-- | data/demands.yaml | 6 | ||||
-rw-r--r-- | data/recipes.yaml | 6 | ||||
-rw-r--r-- | server/src/customer/mod.rs | 57 | ||||
-rw-r--r-- | server/src/data.rs | 13 | ||||
-rw-r--r-- | server/src/main.rs | 1 | ||||
-rw-r--r-- | test-client/tiles.ts | 5 |
6 files changed, 67 insertions, 21 deletions
diff --git a/data/demands.yaml b/data/demands.yaml index 8b137891..80679e29 100644 --- a/data/demands.yaml +++ b/data/demands.yaml @@ -1 +1,5 @@ - +- burger-meal +- tomatoburger-meal +- tomatosteak-meal +- steak-meal +- sliced-tomato-meal diff --git a/data/recipes.yaml b/data/recipes.yaml index 46210a7e..98de3a9c 100644 --- a/data/recipes.yaml +++ b/data/recipes.yaml @@ -24,7 +24,7 @@ - tile: cuttingboard inputs: [tomato] outputs: [sliced-tomato] - action: !active 3 + action: !active 2 - tile: counter inputs: [sliced-tomato, plate] outputs: [sliced-tomato-meal] @@ -36,7 +36,7 @@ - tile: counter inputs: [flour] outputs: [dough] - action: !active 5 + action: !active 3 - tile: oven inputs: [dough] outputs: [bread] @@ -94,4 +94,4 @@ - tile: sink inputs: [dirty-plate] outputs: [plate] - action: !active 5 + action: !active 3 diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs index ab3accdd..7c6cd235 100644 --- a/server/src/customer/mod.rs +++ b/server/src/customer/mod.rs @@ -21,12 +21,17 @@ use tokio::{ time::interval, }; -struct DemandState { - data: Gamedata, +struct CustomerManager { walkable: HashSet<IVec2>, chairs: HashMap<IVec2, bool>, items: HashMap<IVec2, ItemIndex>, customers: HashMap<PlayerID, Customer>, + customer_id_counter: PlayerID, + demand: DemandState, +} + +struct DemandState { + data: Gamedata, } enum CustomerState { @@ -41,21 +46,24 @@ struct Customer { } pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<PacketC>) { - let mut state = DemandState { + let mut state = CustomerManager { + customer_id_counter: 0, walkable: Default::default(), chairs: Default::default(), items: Default::default(), customers: Default::default(), - data: Gamedata::default(), + demand: DemandState { + data: Gamedata::default(), + }, }; let initial = game.write().await.prime_client(-1); for p in initial { match p { PacketC::Init { data, .. } => { - state.data = data; + state.demand.data = data; } PacketC::UpdateMap { pos, tile, .. } => { - let tilename = &state.data.tile_names[tile]; + let tilename = &state.demand.data.tile_names[tile]; if tilename == "floor" || tilename == "door" || tilename == "chair" { state.walkable.insert(pos); } @@ -95,7 +103,7 @@ pub async fn customer(game: Arc<RwLock<Game>>, mut grx: broadcast::Receiver<Pack } } -fn update_items(state: &mut DemandState, game: &Game) { +fn update_items(state: &mut CustomerManager, game: &Game) { state.items.clear(); for (&pos, tile) in game.tiles() { if let Some(item) = &tile.item { @@ -105,9 +113,22 @@ fn update_items(state: &mut DemandState, game: &Game) { } impl DemandState { + pub fn target_customer_count(&self) -> usize { + // TODO insert sofa magic formula + 5 + } + pub fn generate_demand(&self) -> usize { + // TODO insert sofa magic formula + use rand::seq::IndexedRandom; + *self.data.demands.choose(&mut thread_rng()).unwrap() + } +} + +impl CustomerManager { pub fn tick(&mut self, packets_out: &mut Vec<(PlayerID, PacketS)>, dt: f32) { - if self.customers.is_empty() { - let id = -1; + if self.customers.len() < self.demand.target_customer_count() { + self.customer_id_counter -= 1; + let id = self.customer_id_counter; packets_out.push(( id, PacketS::Join { @@ -116,13 +137,17 @@ impl DemandState { }, )); let chair = select_chair(&mut self.chairs); - let path = find_path(&self.walkable, self.data.customer_spawn.as_ivec2(), chair) - .expect("no path"); + let path = find_path( + &self.walkable, + self.demand.data.customer_spawn.as_ivec2(), + chair, + ) + .expect("no path"); self.customers.insert( id, Customer { movement: MovementBase { - position: self.data.customer_spawn, + position: self.demand.data.customer_spawn, facing: Vec2::X, vel: Vec2::ZERO, }, @@ -136,7 +161,7 @@ impl DemandState { CustomerState::WalkingToChair { path, chair } => { packets_out.push((id, path.execute_tick(&mut p.movement, &self.walkable, dt))); if path.is_done() { - let demand = self.data.get_item("tomato").unwrap(); + let demand = self.demand.generate_demand(); packets_out.push(( id, PacketS::Communicate { @@ -163,12 +188,16 @@ impl DemandState { if let Some(pos) = demand_pos { if self.items.get(&pos) == Some(demand) { packets_out.push((id, PacketS::Communicate { message: None })); + for edge in [true, false] { + packets_out.push((id, PacketS::Interact { pos, edge })) + } let path = find_path( &self.walkable, p.movement.position.as_ivec2(), - self.data.customer_spawn.as_ivec2(), + self.demand.data.customer_spawn.as_ivec2(), ) .expect("no path to exit"); + *self.chairs.get_mut(&chair).unwrap() = true; p.state = CustomerState::Exiting { path } } } diff --git a/server/src/data.rs b/server/src/data.rs index d138f360..3526d786 100644 --- a/server/src/data.rs +++ b/server/src/data.rs @@ -40,12 +40,18 @@ pub struct Gamedata { pub initial_map: HashMap<IVec2, TileIndex>, pub chef_spawn: Vec2, pub customer_spawn: Vec2, + pub demands: Vec<usize>, } -pub fn build_gamedata(recipes_in: Vec<RecipeDecl>, map_in: InitialMap) -> Gamedata { +pub fn build_gamedata( + recipes_in: Vec<RecipeDecl>, + map_in: InitialMap, + demands_in: Vec<String>, +) -> Gamedata { let item_names = RwLock::new(Vec::new()); let tile_names = RwLock::new(Vec::new()); let mut recipes = Vec::new(); + let mut demands = Vec::new(); for r in recipes_in { let r2 = r.clone(); @@ -78,6 +84,10 @@ pub fn build_gamedata(recipes_in: Vec<RecipeDecl>, map_in: InitialMap) -> Gameda assert_eq!(outputs.next(), None, "{r2:?}"); } + for d in demands_in { + demands.push(register(&item_names, d)) + } + let mut chef_spawn = Vec2::new(0., 0.); let mut customer_spawn = Vec2::new(0., 0.); let mut initial_map = HashMap::new(); @@ -99,6 +109,7 @@ pub fn build_gamedata(recipes_in: Vec<RecipeDecl>, map_in: InitialMap) -> Gameda } Gamedata { + demands, recipes, initial_map, item_names: item_names.into_inner().unwrap(), diff --git a/server/src/main.rs b/server/src/main.rs index e505195c..4d761b0c 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -31,6 +31,7 @@ async fn main() -> Result<()> { let data = build_gamedata( serde_yaml::from_reader(File::open("data/recipes.yaml").unwrap()).unwrap(), serde_yaml::from_reader(File::open("data/map.yaml").unwrap()).unwrap(), + serde_yaml::from_reader(File::open("data/demands.yaml").unwrap()).unwrap(), ); let game = Arc::new(RwLock::new(Game::new(data.into()))); diff --git a/test-client/tiles.ts b/test-client/tiles.ts index 5a6769ed..a7fe0911 100644 --- a/test-client/tiles.ts +++ b/test-client/tiles.ts @@ -102,11 +102,12 @@ export const ITEMS: { [key: string]: Component[] } = { "bread": [circle(0.3, "#853e20")], "tomato": [circle(0.3, "#d63838")], "sliced-tomato": [circle(0.3, "#d16363", "#d63838", 0.08)], - "dirty-plate": [circle(0.4, "#947a6f", "#d3a187", 0.02)], "plate": plate, + "dirty-plate": [circle(0.4, "#947a6f", "#d3a187", 0.02)], "steak-meal": [...plate, ...arrange_items("steak")], - "sliced-tomato-meal": [...plate, ...arrange_items("sliced-tomato")], "burger-meal": [...plate, ...arrange_items("bread", "steak")], + "sliced-tomato-meal": [...plate, ...arrange_items("sliced-tomato")], + "tomatosteak-meal": [...plate, ...arrange_items("tomato", "steak")], "tomatoburger-meal": [...plate, ...arrange_items("bread", "steak", "tomato")], } |