diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-10-19 20:16:38 +0200 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-10-19 20:16:38 +0200 |
| commit | 239f139e7cdc2ee9f2658a8038d2870293e20aa4 (patch) | |
| tree | 9b54500dd4bcb50088c60376ad1465e3349f8e70 /server | |
| parent | 6979c0a1b6503cb4b4e96e66cba5fc10a2d89b4b (diff) | |
| download | hurrycurry-239f139e7cdc2ee9f2658a8038d2870293e20aa4.tar hurrycurry-239f139e7cdc2ee9f2658a8038d2870293e20aa4.tar.bz2 hurrycurry-239f139e7cdc2ee9f2658a8038d2870293e20aa4.tar.zst | |
Start moving game logic to client-lib. Moved set_tile and gamedata index
Diffstat (limited to 'server')
| -rw-r--r-- | server/client-lib/src/lib.rs | 52 | ||||
| -rw-r--r-- | server/client-lib/src/spatial_index.rs | 2 | ||||
| -rw-r--r-- | server/src/entity/campaign.rs | 6 | ||||
| -rw-r--r-- | server/src/server.rs | 46 | ||||
| -rw-r--r-- | server/src/state.rs | 1 |
5 files changed, 46 insertions, 61 deletions
diff --git a/server/client-lib/src/lib.rs b/server/client-lib/src/lib.rs index f2c47ea0..79c2ed01 100644 --- a/server/client-lib/src/lib.rs +++ b/server/client-lib/src/lib.rs @@ -25,7 +25,7 @@ use hurrycurry_protocol::{ }; use spatial_index::SpatialIndex; use std::{ - collections::{BTreeSet, HashMap, HashSet}, + collections::{BTreeSet, HashMap, HashSet, VecDeque}, sync::Arc, time::Instant, }; @@ -67,17 +67,20 @@ pub struct Player { pub struct Game { pub data: Arc<Gamedata>, pub data_index: GamedataIndex, + pub tiles: HashMap<IVec2, Tile>, - pub walkable: HashSet<IVec2>, pub players: HashMap<PlayerID, Player>, - pub players_spatial_index: SpatialIndex<PlayerID>, pub end: Option<Instant>, pub lobby: bool, - pub environment_effects: HashSet<String>, pub score: Score, - pub player_id_counter: i64, + + pub players_spatial_index: SpatialIndex<PlayerID>, + pub walkable: HashSet<IVec2>, + pub tile_index: HashMap<TileIndex, HashSet<IVec2>>, + + pub events: VecDeque<PacketC>, } impl Game { @@ -164,17 +167,7 @@ impl Game { kind, neighbors: _, } => { - if let Some(kind) = kind { - self.tiles.insert(tile, Tile { kind, item: None }); - if self.data_index.tile_collide[kind.0] { - self.walkable.remove(&tile); - } else { - self.walkable.insert(tile); - } - } else { - self.tiles.remove(&tile); - self.walkable.remove(&tile); - } + self.set_tile(tile, kind); } PacketC::Communicate { player, @@ -200,6 +193,33 @@ impl Game { } } + pub fn set_tile(&mut self, pos: IVec2, kind: Option<TileIndex>) { + self.tiles.remove(&pos); + self.walkable.remove(&pos); + if let Some(prev) = self.tiles.get(&pos) { + if let Some(set) = self.tile_index.get_mut(&prev.kind) { + set.remove(&pos); + } + } + if let Some(kind) = kind { + self.tiles.insert(pos, Tile { kind, item: None }); + if self.data_index.tile_collide[kind.0] { + self.walkable.insert(pos); + } + self.tile_index.entry(kind).or_default().insert(pos); + } + self.events.push_back(PacketC::UpdateMap { + tile: pos, + kind, + neighbors: [ + self.tiles.get(&(pos + IVec2::NEG_Y)).map(|e| e.kind), + self.tiles.get(&(pos + IVec2::NEG_X)).map(|e| e.kind), + self.tiles.get(&(pos + IVec2::Y)).map(|e| e.kind), + self.tiles.get(&(pos + IVec2::X)).map(|e| e.kind), + ], + }); + } + pub fn tick(&mut self, dt: f32) { self.score.time_remaining -= dt as f64; self.score.time_remaining -= self.score.time_remaining.max(0.); diff --git a/server/client-lib/src/spatial_index.rs b/server/client-lib/src/spatial_index.rs index 8b717ca3..8dd0cc22 100644 --- a/server/client-lib/src/spatial_index.rs +++ b/server/client-lib/src/spatial_index.rs @@ -23,8 +23,6 @@ pub struct SpatialIndex<T> { bins: HashMap<IVec2, Vec<T>>, } -// TODO maybe dont use 1x1 bins but something bigger like 10x10 for better perf - impl<T: Eq + Hash + Copy> SpatialIndex<T> { pub fn update_entry(&mut self, id: T, position: Vec2) { self.remove_entry(id); diff --git a/server/src/entity/campaign.rs b/server/src/entity/campaign.rs index ddbdc3bc..1966fc01 100644 --- a/server/src/entity/campaign.rs +++ b/server/src/entity/campaign.rs @@ -16,7 +16,7 @@ */ use super::{Entity, EntityContext}; -use crate::{scoreboard::ScoreboardStore, server::GameServerExt}; +use crate::scoreboard::ScoreboardStore; use anyhow::Result; use hurrycurry_data::entities::GateCondition; use hurrycurry_locale::{TrError, trm}; @@ -60,9 +60,7 @@ impl Entity for Gate { self.active = false; self.unlocked = self.condition.check(c.scoreboard); if !self.unlocked { - c.game - .set_tile(self.pos, Some(self.blocker_tile), c.packet_out); - c.packet_out.push_back(PacketC::FlushMap); // TODO dont send too often + c.game.set_tile(self.pos, Some(self.blocker_tile)); } } Ok(()) diff --git a/server/src/server.rs b/server/src/server.rs index 954d9a2c..1886715d 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -23,7 +23,7 @@ use crate::{ scoreboard::ScoreboardStore, }; use anyhow::{Context, Result}; -use hurrycurry_client_lib::{Game, Involvement, Item, Player, Tile, gamedata_index::GamedataIndex}; +use hurrycurry_client_lib::{Game, Involvement, Item, Player, Tile}; use hurrycurry_data::{Serverdata, index::DataIndex}; use hurrycurry_locale::{ FALLBACK_LOCALE, TrError, @@ -32,7 +32,7 @@ use hurrycurry_locale::{ }; use hurrycurry_protocol::{ Character, Gamedata, Hand, ItemLocation, Menu, MessageTimeout, PacketC, PacketS, PlayerClass, - PlayerID, Score, TileIndex, + PlayerID, Score, glam::{IVec2, Vec2}, movement::MovementBase, }; @@ -74,7 +74,6 @@ pub struct Server { pub index: DataIndex, pub packet_out: VecDeque<PacketC>, pub scoreboard: ScoreboardStore, - pub gamedata_index: GamedataIndex, pub editor_address: Option<String>, } @@ -99,7 +98,6 @@ pub trait GameServerExt { packet_out: Option<&mut VecDeque<PacketC>>, ); fn prime_client(&self) -> Vec<PacketC>; - fn set_tile(&mut self, p: IVec2, t: Option<TileIndex>, packet_out: &mut VecDeque<PacketC>); } impl GameServerExt for Game { fn unload(&mut self, packet_out: &mut VecDeque<PacketC>) { @@ -108,6 +106,7 @@ impl GameServerExt for Game { lobby: false, }); for (id, _) in self.players.drain() { + self.players_spatial_index.remove_entry(id); packet_out.push_back(PacketC::RemovePlayer { id }) } for (pos, _) in self.tiles.drain() { @@ -121,6 +120,7 @@ impl GameServerExt for Game { self.end = None; self.environment_effects.clear(); self.walkable.clear(); + self.tile_index.clear(); } fn load( &mut self, @@ -304,36 +304,6 @@ impl GameServerExt for Game { }); } } - - /// Dont forget to flush - fn set_tile( - &mut self, - tile: IVec2, - kind: Option<TileIndex>, - packet_out: &mut VecDeque<PacketC>, - ) { - if let Some(kind) = kind { - self.tiles.insert(tile, Tile::from(kind)); - if self.data_index.tile_collide[kind.0] { - self.walkable.remove(&tile); - } else { - self.walkable.insert(tile); - } - } else { - self.tiles.remove(&tile); - self.walkable.remove(&tile); - } - packet_out.push_back(PacketC::UpdateMap { - tile, - kind, - neighbors: [ - self.tiles.get(&(tile + IVec2::NEG_Y)).map(|e| e.kind), - self.tiles.get(&(tile + IVec2::NEG_X)).map(|e| e.kind), - self.tiles.get(&(tile + IVec2::Y)).map(|e| e.kind), - self.tiles.get(&(tile + IVec2::X)).map(|e| e.kind), - ], - }); - } } impl Server { @@ -346,7 +316,6 @@ impl Server { packet_out: VecDeque::new(), connections: HashMap::new(), data: Serverdata::default().into(), - gamedata_index: GamedataIndex::default(), entities: Vec::new(), score_changed: false, packet_loopback: VecDeque::new(), @@ -384,7 +353,6 @@ impl Server { timer.or(serverdata.default_timer), &mut self.packet_out, ); - self.gamedata_index.update(&self.game.data); self.entities.clear(); for ed in &serverdata.entity_decls { self.entities.push(construct_entity(ed)); @@ -719,7 +687,7 @@ impl Server { Ok(()) } - /// Returns true if the game should end + /// Returns Some(map) if the game should end pub fn tick(&mut self, dt: f32) -> Option<(String, Option<Duration>)> { if self.score_changed { self.score_changed = false; @@ -731,7 +699,7 @@ impl Server { tick_slot( dt, &self.game.data, - &self.gamedata_index, + &self.game.data_index, Some(tile.kind), &mut tile.item, ItemLocation::Tile(pos), @@ -774,7 +742,7 @@ impl Server { tick_slot( dt, &self.game.data, - &self.gamedata_index, + &self.game.data_index, None, item, ItemLocation::Player(pid, Hand(i)), diff --git a/server/src/state.rs b/server/src/state.rs index dfcccaa5..28ef7235 100644 --- a/server/src/state.rs +++ b/server/src/state.rs @@ -51,6 +51,7 @@ impl Server { _ => (), } + self.packet_out.extend(self.game.events.drain(..)); while let Some(p) = self.packet_out.pop_front() { if matches!(p, PacketC::UpdateMap { .. } | PacketC::Movement { .. }) { trace!("-> {p:?}"); |