diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/bin/graph.rs | 22 | ||||
-rw-r--r-- | server/src/customer/mod.rs | 16 | ||||
-rw-r--r-- | server/src/data.rs | 19 | ||||
-rw-r--r-- | server/src/game.rs | 44 | ||||
-rw-r--r-- | server/src/interaction.rs | 8 | ||||
-rw-r--r-- | server/src/protocol.rs | 1 |
6 files changed, 82 insertions, 28 deletions
diff --git a/server/src/bin/graph.rs b/server/src/bin/graph.rs index deae2034..024512c6 100644 --- a/server/src/bin/graph.rs +++ b/server/src/bin/graph.rs @@ -17,7 +17,7 @@ */ use anyhow::{anyhow, Result}; use undercooked::{ - data::DataIndex, + data::{DataIndex, Demand}, interaction::Recipe, protocol::{ItemIndex, RecipeIndex}, }; @@ -59,14 +59,24 @@ fn main() -> Result<()> { } } - for (di, d) in data.demands.iter().enumerate() { + for ( + di, + Demand { + duration, + from: ItemIndex(from), + to, + points, + }, + ) in data.demands.iter().enumerate() + { let color = "#c4422b"; println!( - "d{di} [label=\"Demand\\ntakes {}s\" shape=box color={color:?} fillcolor={color:?} style=filled]", - d.duration + "d{di} [label=\"Demand\\ntakes {duration}s\\n{points} points\" shape=box color={color:?} fillcolor={color:?} style=filled]", ); - println!("i{} -> d{di}", d.from.0); - println!("d{di} -> i{}", d.to.0); + println!("i{from} -> d{di}"); + if let Some(ItemIndex(to)) = to { + println!("d{di} -> i{to}"); + } } println!("}}"); diff --git a/server/src/customer/mod.rs b/server/src/customer/mod.rs index 9e474b8f..d1f49655 100644 --- a/server/src/customer/mod.rs +++ b/server/src/customer/mod.rs @@ -104,6 +104,7 @@ impl DemandState { tiles: &mut HashMap<IVec2, Tile>, data: &Gamedata, dt: f32, + points: &mut i64, ) -> Result<()> { if self.customers.len() < 5 { self.customer_id_counter.0 -= 1; @@ -165,6 +166,7 @@ impl DemandState { .expect("no path to exit"); *self.chairs.get_mut(&chair).unwrap() = true; self.failed += 1; + *points -= 1; self.score_changed = true; p.state = CustomerState::Exiting { path } } else { @@ -212,14 +214,11 @@ impl DemandState { let demand = data.demand(*demand); *progress += dt / demand.duration; if *progress >= 1. { - packets_out.push(( - id, - PacketS::ReplaceHand { - item: Some(demand.to), - }, - )); - for edge in [true, false] { - packets_out.push((id, PacketS::Interact { pos: *target, edge })) + packets_out.push((id, PacketS::ReplaceHand { item: demand.to })); + if demand.to.is_some() { + for edge in [true, false] { + packets_out.push((id, PacketS::Interact { pos: *target, edge })) + } } let path = find_path( &self.walkable, @@ -229,6 +228,7 @@ impl DemandState { .ok_or(anyhow!("no path to exit"))?; *self.chairs.get_mut(&chair).unwrap() = true; self.completed += 1; + *points += demand.points; self.score_changed = true; p.state = CustomerState::Exiting { path } } diff --git a/server/src/data.rs b/server/src/data.rs index 763a67bc..46f7ed28 100644 --- a/server/src/data.rs +++ b/server/src/data.rs @@ -56,6 +56,8 @@ pub struct RecipeDecl { revert_duration: Option<f32>, #[serde(default)] duration: Option<f32>, + #[serde(default)] + points: Option<i64>, } #[derive(Debug, Clone, Deserialize)] @@ -72,15 +74,17 @@ pub struct InitialMap { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DemandDecl { from: String, - to: String, + to: Option<String>, duration: f32, + points: i64, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Demand { pub from: ItemIndex, - pub to: ItemIndex, + pub to: Option<ItemIndex>, pub duration: f32, + pub points: i64, } #[derive(Debug, Clone, Serialize, Deserialize, Default)] @@ -161,7 +165,7 @@ impl Gamedata { let mut recipes = Vec::new(); let mut demands = Vec::new(); - for r in recipes_in { + for mut r in recipes_in { let r2 = r.clone(); let mut inputs = r .inputs @@ -190,21 +194,24 @@ impl Gamedata { }), Action::Instant => { recipes.push(Recipe::Instant { + points: r.points.take().unwrap_or(0), tile, inputs: [inputs.next(), inputs.next()], outputs: [outputs.next(), outputs.next()], }); } } - assert_eq!(inputs.next(), None, "{r2:?}"); - assert_eq!(outputs.next(), None, "{r2:?}"); + assert_eq!(inputs.next(), None, "{r2:?} inputs left over"); + assert_eq!(outputs.next(), None, "{r2:?} outputs left over"); + assert_eq!(r.points, None, "points specified where not possible") } for d in demands_in { demands.push(Demand { from: ItemIndex(register(&item_names, d.from)), - to: ItemIndex(register(&item_names, d.to)), + to: d.to.map(|to| ItemIndex(register(&item_names, to))), duration: d.duration, + points: d.points, }) } diff --git a/server/src/game.rs b/server/src/game.rs index 23900559..72f653c4 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -65,6 +65,7 @@ pub struct Game { players: HashMap<PlayerID, Player>, packet_out: VecDeque<PacketC>, demand: Option<DemandState>, + points: i64, } impl Game { @@ -75,11 +76,13 @@ impl Game { players: Default::default(), tiles: Default::default(), demand: None, + points: 0, } } fn unload(&mut self) { - self.packet_out.push_back(PacketC::SetIngame { state: false }); + self.packet_out + .push_back(PacketC::SetIngame { state: false }); for (id, _) in self.players.drain() { self.packet_out.push_back(PacketC::RemovePlayer { id }) } @@ -189,18 +192,22 @@ impl Game { }) } } - out.push(PacketC::Score { + out.push(self.score()); + out.push(PacketC::SetIngame { state: true }); + out + } + + pub fn score(&self) -> PacketC { + PacketC::Score { + points: self.points, demands_failed: self.demand.as_ref().map(|d| d.failed).unwrap_or_default(), demands_completed: self .demand .as_ref() .map(|d| d.completed) .unwrap_or_default(), - }); - out.push(PacketC::SetIngame { state: true }); - out + } } - pub fn packet_in(&mut self, player: PlayerID, packet: PacketS) -> Result<()> { match packet { PacketS::Join { name, character } => { @@ -315,6 +322,7 @@ impl Game { tile.kind, &mut tile.item, &mut player.item, + &mut self.points, ) { match effect { InteractEffect::Put => self.packet_out.push_back(PacketC::PutItem { @@ -363,6 +371,21 @@ impl Game { item: Some(i.kind), }); } + self.packet_out.push_back({ + PacketC::Score { + points: self.points, + demands_failed: self + .demand + .as_ref() + .map(|d| d.failed) + .unwrap_or_default(), + demands_completed: self + .demand + .as_ref() + .map(|d| d.completed) + .unwrap_or_default(), + } + }) } } } @@ -396,11 +419,18 @@ impl Game { pub fn tick(&mut self, dt: f32) { if let Some(demand) = &mut self.demand { let mut packet_out = Vec::new(); - if let Err(err) = demand.tick(&mut packet_out, &mut self.tiles, &self.data, dt) { + if let Err(err) = demand.tick( + &mut packet_out, + &mut self.tiles, + &self.data, + dt, + &mut self.points, + ) { warn!("demand tick {err}"); } if demand.score_changed { self.packet_out.push_back(PacketC::Score { + points: self.points, demands_failed: demand.failed, demands_completed: demand.completed, }); diff --git a/server/src/interaction.rs b/server/src/interaction.rs index e3dccfba..69fc9e70 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -43,6 +43,7 @@ pub enum Recipe { tile: Option<TileIndex>, inputs: [Option<ItemIndex>; 2], outputs: [Option<ItemIndex>; 2], + points: i64, }, } @@ -120,6 +121,7 @@ pub fn interact( tile_kind: TileIndex, this: &mut Option<Item>, other: &mut Option<Item>, + points: &mut i64, ) -> Option<InteractEffect> { let interactable = data.is_tile_interactable(tile_kind); if interactable && other.is_none() { @@ -188,7 +190,10 @@ pub fn interact( } } Recipe::Instant { - inputs, outputs, .. + inputs, + outputs, + points: pd, + .. } => { let on_tile = this.as_ref().map(|i| i.kind); let in_hand = other.as_ref().map(|i| i.kind); @@ -199,6 +204,7 @@ pub fn interact( let ok_rev = ok_rev as usize; *other = outputs[1 - ok_rev].map(|kind| Item { kind, active: None }); *this = outputs[ok_rev].map(|kind| Item { kind, active: None }); + *points += pd; return Some(InteractEffect::Produce); } } diff --git a/server/src/protocol.rs b/server/src/protocol.rs index 16c379b9..9355f90a 100644 --- a/server/src/protocol.rs +++ b/server/src/protocol.rs @@ -131,6 +131,7 @@ pub enum PacketC { message: Option<Message>, }, Score { + points: i64, demands_failed: usize, demands_completed: usize, }, |