From 1a45b0e0f5de785ddf268d7371f0cdaeafe9daa7 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 20 Jul 2024 19:29:41 +0200 Subject: refactor score code (and break things) --- server/src/entity/conveyor.rs | 2 +- server/src/entity/customers/mod.rs | 8 ++--- server/src/entity/portal.rs | 2 +- server/src/game.rs | 69 ++++++++++++++++++-------------------- server/src/interaction.rs | 10 ++++-- server/src/state.rs | 7 +--- 6 files changed, 47 insertions(+), 51 deletions(-) (limited to 'server/src') diff --git a/server/src/entity/conveyor.rs b/server/src/entity/conveyor.rs index 6067c679..38478db7 100644 --- a/server/src/entity/conveyor.rs +++ b/server/src/entity/conveyor.rs @@ -72,7 +72,7 @@ impl EntityT for Conveyor { ItemLocation::Tile(self.from), Some(to.kind), &mut game.packet_out, - &mut game.points, + &mut game.score, true, ); } diff --git a/server/src/entity/customers/mod.rs b/server/src/entity/customers/mod.rs index 7a8280bc..e8679dc9 100644 --- a/server/src/entity/customers/mod.rs +++ b/server/src/entity/customers/mod.rs @@ -151,8 +151,8 @@ impl EntityT for Customers { ) .expect("no path to exit"); *self.chairs.get_mut(chair).unwrap() = true; - game.demands_failed += 1; - game.points -= 1; + game.score.demands_failed += 1; + game.score.points -= 1; game.score_changed = true; info!("{id:?} -> exiting"); *state = CustomerState::Exiting { path } @@ -232,8 +232,8 @@ impl EntityT for Customers { ) .ok_or(anyhow!("no path to exit"))?; *self.chairs.get_mut(chair).unwrap() = true; - game.demands_completed += 1; - game.points += demand.points; + game.score.demands_completed += 1; + game.score.points += demand.points; game.score_changed = true; info!("{id:?} -> exiting"); *state = CustomerState::Exiting { path } diff --git a/server/src/entity/portal.rs b/server/src/entity/portal.rs index 3aed35ac..2d4a762b 100644 --- a/server/src/entity/portal.rs +++ b/server/src/entity/portal.rs @@ -43,7 +43,7 @@ impl EntityT for Portal { ItemLocation::Tile(self.from), Some(to.kind), &mut game.packet_out, - &mut game.points, + &mut game.score, true, ); } diff --git a/server/src/game.rs b/server/src/game.rs index 9a01e4a3..1f368b00 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -25,8 +25,8 @@ use anyhow::{anyhow, bail, Result}; use hurrycurry_protocol::{ glam::{IVec2, Vec2}, movement::MovementBase, - ClientGamedata, ItemIndex, ItemLocation, Message, PacketC, PacketS, PlayerID, RecipeIndex, - TileIndex, + ClientGamedata, ItemIndex, ItemLocation, Menu, Message, PacketC, PacketS, PlayerID, + RecipeIndex, Score, TileIndex, }; use log::{info, warn}; use std::{ @@ -78,9 +78,7 @@ pub struct Game { pub lobby: bool, pub score_changed: bool, - pub points: i64, - pub demands_failed: usize, - pub demands_completed: usize, + pub score: Score, } impl Default for Game { @@ -101,9 +99,7 @@ impl Game { end: None, entities: Arc::new(RwLock::new(vec![])), players_spatial_index: SpatialIndex::default(), - points: 0, - demands_failed: 0, - demands_completed: 0, + score: Score::default(), score_changed: false, } } @@ -137,7 +133,7 @@ impl Game { self.lobby = gamedata.map_name == "lobby"; self.data = gamedata.into(); - self.points = 0; + self.score = Score::default(); self.end = timer.map(|dur| Instant::now() + dur); self.entities = Arc::new(RwLock::new(self.data.entities.clone())); @@ -187,10 +183,6 @@ impl Game { self.packet_out.extend(self.prime_client()); } - pub fn packet_out(&mut self) -> Option { - self.packet_out.pop_front() - } - pub fn prime_client(&self) -> Vec { let mut out = Vec::new(); out.push(PacketC::Data { @@ -256,7 +248,7 @@ impl Game { }) } } - out.push(self.score()); + out.push(PacketC::Score(self.score.clone())); out.push(PacketC::SetIngame { state: true, lobby: self.lobby, @@ -264,22 +256,12 @@ impl Game { out } - pub fn score(&self) -> PacketC { - PacketC::Score { - time_remaining: self.end.map(|t| (t - Instant::now()).as_secs_f32()), - points: self.points, - demands_failed: self.demands_failed, - demands_completed: self.demands_completed, - } - } pub fn packet_in( &mut self, player: PlayerID, packet: PacketS, replies: &mut Vec, ) -> Result<()> { - let points_before = self.points; - match packet { PacketS::Join { name, character } => { if self.players.contains_key(&player) { @@ -429,7 +411,7 @@ impl Game { ItemLocation::Player(pid), None, &mut self.packet_out, - &mut self.points, + &mut self.score, false, ) } else { @@ -447,7 +429,7 @@ impl Game { ItemLocation::Player(pid), Some(tile.kind), &mut self.packet_out, - &mut self.points, + &mut self.score, false, ) } @@ -481,10 +463,6 @@ impl Game { } PacketS::ReplayTick { .. } => bail!("packet not supported in this session"), } - - if self.points != points_before { - self.packet_out.push_back(self.score()) - } Ok(()) } @@ -492,11 +470,18 @@ impl Game { pub fn tick(&mut self, dt: f32) -> bool { if self.score_changed { self.score_changed = false; - self.packet_out.push_back(self.score()); + self.packet_out + .push_back(PacketC::Score(self.score.clone())); } for (&pos, tile) in &mut self.tiles { - if let Some(effect) = tick_slot(dt, &self.data, Some(tile.kind), &mut tile.item) { + if let Some(effect) = tick_slot( + dt, + &self.data, + Some(tile.kind), + &mut tile.item, + &mut self.score, + ) { match effect { TickEffect::Progress(warn) => self.packet_out.push_back(PacketC::SetProgress { warn, @@ -544,7 +529,8 @@ impl Game { rot: player.movement.rotation, }); - if let Some(effect) = tick_slot(dt, &self.data, None, &mut player.item) { + if let Some(effect) = tick_slot(dt, &self.data, None, &mut player.item, &mut self.score) + { match effect { TickEffect::Progress(warn) => self.packet_out.push_back(PacketC::SetProgress { warn, @@ -591,7 +577,18 @@ impl Game { } } - self.end.map(|t| t < Instant::now()).unwrap_or_default() + if let Some(end) = self.end { + self.score.time_remaining = (end - Instant::now()).as_secs_f64(); + if end < Instant::now() { + self.packet_out + .push_back(PacketC::Menu(Menu::Score(self.score.clone()))); + true + } else { + false + } + } else { + false + } } pub fn count_chefs(&self) -> usize { @@ -617,13 +614,13 @@ pub fn interact_effect( other_loc: ItemLocation, this_tile_kind: Option, packet_out: &mut VecDeque, - points: &mut i64, + score: &mut Score, automated: bool, ) { let this_had_item = this.is_some(); let other_had_item = other.is_some(); - if let Some(effect) = interact(data, edge, this_tile_kind, this, other, points, automated) { + if let Some(effect) = interact(data, edge, this_tile_kind, this, other, score, automated) { match effect { InteractEffect::Put => { info!("put {this_loc} <- {other_loc}"); diff --git a/server/src/interaction.rs b/server/src/interaction.rs index 2f6c940a..71125ac4 100644 --- a/server/src/interaction.rs +++ b/server/src/interaction.rs @@ -19,7 +19,7 @@ use crate::{ data::Gamedata, game::{Involvement, Item}, }; -use hurrycurry_protocol::{ItemIndex, TileIndex}; +use hurrycurry_protocol::{ItemIndex, Score, TileIndex}; use log::info; use serde::{Deserialize, Serialize}; @@ -115,7 +115,7 @@ pub fn interact( tile: Option, this: &mut Option, other: &mut Option, - points: &mut i64, + score: &mut Score, automated: bool, ) -> Option { let interactable = automated @@ -180,6 +180,7 @@ pub fn interact( }); } *this = Some(item); + score.active_recipes += 1; return Some(InteractEffect::Put); } } @@ -200,7 +201,8 @@ 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; + score.points += pd; + score.instant_recipes += 1; return Some(InteractEffect::Produce); } } @@ -234,6 +236,7 @@ pub fn tick_slot( data: &Gamedata, tile: Option, slot: &mut Option, + score: &mut Score, ) -> Option { if let Some(item) = slot { if let Some(a) = &mut item.active { @@ -246,6 +249,7 @@ pub fn tick_slot( if a.progress >= 1. { if let Recipe::Passive { output, .. } = &data.recipe(a.recipe) { *slot = output.map(|kind| Item { kind, active: None }); + score.passive_recipes += 1; return Some(TickEffect::Produce); }; a.progress = 1.; diff --git a/server/src/state.rs b/server/src/state.rs index 61795da4..3492e6e7 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -82,15 +82,10 @@ impl State { pub async fn tick(&mut self, dt: f32) -> anyhow::Result<()> { if self.game.tick(dt) { - self.tx - .send(PacketC::ServerMessage { - text: format!("Game finished. You reached {} points.", self.game.points), - }) - .ok(); self.game .load(self.index.generate("lobby-none".to_string()).await?, None); } - while let Some(p) = self.game.packet_out() { + while let Some(p) = self.game.packet_out.pop_front() { if matches!(p, PacketC::UpdateMap { .. } | PacketC::Position { .. }) { trace!("-> {p:?}"); } else { -- cgit v1.2.3-70-g09d2