diff options
Diffstat (limited to 'server/src')
| -rw-r--r-- | server/src/entity/campaign.rs | 2 | ||||
| -rw-r--r-- | server/src/entity/customers.rs | 14 | ||||
| -rw-r--r-- | server/src/entity/player_portal_pair.rs | 20 | ||||
| -rw-r--r-- | server/src/entity/tag_minigame.rs | 6 | ||||
| -rw-r--r-- | server/src/entity/tutorial.rs | 49 | ||||
| -rw-r--r-- | server/src/lib.rs | 2 | ||||
| -rw-r--r-- | server/src/server.rs | 40 |
7 files changed, 75 insertions, 58 deletions
diff --git a/server/src/entity/campaign.rs b/server/src/entity/campaign.rs index b7d7d8db..af6de391 100644 --- a/server/src/entity/campaign.rs +++ b/server/src/entity/campaign.rs @@ -60,7 +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.game.set_tile(self.pos, vec![self.blocker_tile]); } } Ok(()) diff --git a/server/src/entity/customers.rs b/server/src/entity/customers.rs index c1bfb525..2e2f82af 100644 --- a/server/src/entity/customers.rs +++ b/server/src/entity/customers.rs @@ -20,7 +20,7 @@ use crate::random_float; use anyhow::Result; use hurrycurry_bot::algos::Customer; use hurrycurry_locale::TrError; -use hurrycurry_protocol::{Character, PlayerClass}; +use hurrycurry_protocol::{Character, PlayerClass, TileIndex}; use std::random::random; pub struct Customers { @@ -47,10 +47,14 @@ impl Entity for Customers { fn tick(&mut self, mut c: EntityContext) -> Result<(), TrError> { let chairs = *self.chair_count.get_or_insert_with(|| { c.game - .tiles - .values() - .filter(|t| c.game.data.tile_name(t.kind) == "chair") - .count() + .tile_index + .get( + &c.game + .data + .get_tile_by_name("chair") + .unwrap_or(TileIndex(0)), + ) + .map_or(0, |c| c.len()) }); let max_count = (self.scaling_factor * chairs as f32).max(1.) as usize; diff --git a/server/src/entity/player_portal_pair.rs b/server/src/entity/player_portal_pair.rs index fd28b774..b525f4ca 100644 --- a/server/src/entity/player_portal_pair.rs +++ b/server/src/entity/player_portal_pair.rs @@ -76,23 +76,31 @@ impl Entity for PlayerPortalPair { if (self.state == 1 && near_b.is_none() && in_a.is_none()) || (self.state == -1 && near_a.is_none() && in_b.is_none()) { - c.game.set_tile(self.b_i, Some(self.neutral_tile)); - c.game.set_tile(self.a_i, Some(self.neutral_tile)); + c.game.remove_tile_part(self.a_i, self.in_tile); + c.game.remove_tile_part(self.a_i, self.out_tile); + c.game.add_tile_part(self.a_i, self.neutral_tile); + c.game.remove_tile_part(self.b_i, self.in_tile); + c.game.remove_tile_part(self.b_i, self.out_tile); + c.game.add_tile_part(self.b_i, self.neutral_tile); self.state = 0; return Ok(()); } if self.state == 0 && in_a.is_some() { - c.game.set_tile(self.a_i, Some(self.in_tile)); - c.game.set_tile(self.b_i, Some(self.out_tile)); + c.game.remove_tile_part(self.a_i, self.neutral_tile); + c.game.remove_tile_part(self.b_i, self.neutral_tile); + c.game.add_tile_part(self.a_i, self.in_tile); + c.game.add_tile_part(self.b_i, self.out_tile); self.state = 1; self.delay = 0.2; return Ok(()); } if self.state == 0 && in_b.is_some() { - c.game.set_tile(self.b_i, Some(self.in_tile)); - c.game.set_tile(self.a_i, Some(self.out_tile)); + c.game.remove_tile_part(self.b_i, self.neutral_tile); + c.game.remove_tile_part(self.a_i, self.neutral_tile); + c.game.add_tile_part(self.b_i, self.in_tile); + c.game.add_tile_part(self.a_i, self.out_tile); self.state = -1; self.delay = 0.2; return Ok(()); diff --git a/server/src/entity/tag_minigame.rs b/server/src/entity/tag_minigame.rs index e45422b7..48558b41 100644 --- a/server/src/entity/tag_minigame.rs +++ b/server/src/entity/tag_minigame.rs @@ -100,7 +100,7 @@ impl Entity for TagMinigame { .filter(|(_, v)| **v <= 0.) .for_each(|(&pos, _)| { self.wall_remove_timeouts.insert(pos, 3.); - c.game.set_tile(pos, Some(self.blocker_tile)); + c.game.add_tile_part(pos, self.blocker_tile); }); self.wall_place_delays.retain(|_, v| *v > 0.); @@ -111,9 +111,7 @@ impl Entity for TagMinigame { .iter() .filter(|(_, v)| **v <= 0.) .for_each(|(&pos, _)| { - if let Some(&(tile, _)) = c.serverdata.initial_map.get(&pos) { - c.game.set_tile(pos, Some(tile)); - } + c.game.remove_tile_part(pos, self.blocker_tile); }); self.wall_remove_timeouts.retain(|_, v| *v > 0.); diff --git a/server/src/entity/tutorial.rs b/server/src/entity/tutorial.rs index d1390b20..87896a09 100644 --- a/server/src/entity/tutorial.rs +++ b/server/src/entity/tutorial.rs @@ -169,10 +169,9 @@ impl StepContext<'_> { fn find_tile(&self, tile: TileIndex) -> Option<IVec2> { self.ent .game - .tiles - .iter() - .find(|(_, t)| t.kind == tile) - .map(|(p, _)| *p) + .tile_index + .get(&tile) + .and_then(|s| s.iter().next().copied()) } fn aquire_placed_item(&mut self, item: ItemIndex) -> Result<IVec2, (Option<IVec2>, Message)> { debug!( @@ -193,9 +192,14 @@ impl StepContext<'_> { }) { Err(( Some(*pos), - match self.ent.game.data.tile_name(tile.kind) { - "stove" | "oven" => trm!("s.tutorial.prevent_burning"), - _ => trm!("s.tutorial.take_now"), + if tile + .parts + .iter() + .any(|p| matches!(self.ent.game.data.tile_name(*p), "stove" | "oven")) + { + trm!("s.tutorial.prevent_burning") + } else { + trm!("s.tutorial.take_now") }, )) } else { @@ -288,11 +292,16 @@ impl StepContext<'_> { speed, .. } => { - for (pos, tile) in self.ent.game.tiles.iter().filter(|(_, t)| t.kind == *tile) { - if let Some(item) = &tile.item - && item.kind == *input - { - return Err((Some(*pos), trm!("s.tutorial.hold_interact"))); + if let Some(tiles) = self.ent.game.tile_index.get(tile) { + for pos in tiles { + let Some(tile) = self.ent.game.tiles.get(pos) else { + continue; + }; + if let Some(item) = &tile.item + && item.kind == *input + { + return Err((Some(*pos), trm!("s.tutorial.hold_interact"))); + } } } if let Some(pos) = self.find_tile(*tile) { @@ -312,12 +321,16 @@ impl StepContext<'_> { input, .. } => { - for (_pos, tile) in self.ent.game.tiles.iter().filter(|(_, t)| t.kind == *tile) - { - if let Some(item) = &tile.item - && item.kind == *input - { - return Err((None, trm!("s.tutorial.wait_finish"))); + if let Some(tiles) = self.ent.game.tile_index.get(tile) { + for pos in tiles { + let Some(tile) = self.ent.game.tiles.get(pos) else { + continue; + }; + if let Some(item) = &tile.item + && item.kind == *input + { + return Err((None, trm!("s.tutorial.wait_finish"))); + } } } if let Some(pos) = self.find_tile(*tile) { diff --git a/server/src/lib.rs b/server/src/lib.rs index e5b78644..c166e665 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -16,13 +16,13 @@ */ #![feature(if_let_guard, iterator_try_collect, stmt_expr_attributes, random)] +pub mod benchmark; pub mod commands; pub mod entity; pub mod network; pub mod scoreboard; pub mod server; pub mod state; -pub mod benchmark; use hurrycurry_protocol::glam::Vec2; use std::{fmt::Display, random::random}; diff --git a/server/src/server.rs b/server/src/server.rs index 49b9cbd7..bd1d0f86 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -32,7 +32,7 @@ use hurrycurry_locale::{ use hurrycurry_protocol::{ Character, Gamedata, Hand, ItemLocation, Menu, MessageTimeout, PacketC, PacketS, PlayerClass, PlayerID, Score, - glam::{IVec2, Vec2}, + glam::Vec2, movement::MovementBase, }; use log::{info, warn}; @@ -155,13 +155,9 @@ impl GameServerExt for Game { self.players_spatial_index.remove_entry(id); packet_out.push_back(PacketC::RemovePlayer { id }) } - for (pos, _) in self.tiles.drain() { - packet_out.push_back(PacketC::UpdateMap { - tile: pos, - kind: None, - neighbors: [None, None, None, None], - }) - } + packet_out.push_back(PacketC::UpdateMap { + changes: self.tiles.keys().map(|&p| (p, Vec::new())).collect(), + }); self.score = Score::default(); self.environment_effects.clear(); self.walkable.clear(); @@ -193,21 +189,23 @@ impl GameServerExt for Game { ..Default::default() }; - for (&p, (tile, item)) in &serverdata.initial_map { + for (&p, (tiles, item)) in &serverdata.initial_map { self.tiles.insert( p, Tile { - kind: *tile, + parts: tiles.to_vec(), item: item.map(|i| Item { kind: i, active: None, }), }, ); - if !self.data_index.tile_collide[tile.0] { + if !self.data.walkable(tiles) { self.walkable.insert(p); } - self.tile_index.entry(*tile).or_default().insert(p); + for tile in tiles { + self.tile_index.entry(*tile).or_default().insert(p); + } if item.is_some() { self.item_locations_index.insert(ItemLocation::Tile(p)); } @@ -272,17 +270,14 @@ impl GameServerExt for Game { }) } } + out.push(PacketC::UpdateMap { + changes: self + .tiles + .iter() + .map(|(pos, tile)| (*pos, tile.parts.clone())) + .collect(), + }); for (&tile, tdata) in &self.tiles { - out.push(PacketC::UpdateMap { - tile, - 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), - ], - kind: Some(tdata.kind), - }); if let Some(item) = &tdata.item { out.push(PacketC::SetItem { location: ItemLocation::Tile(tile), @@ -306,7 +301,6 @@ impl GameServerExt for Game { } } } - out.push(PacketC::FlushMap); out.push(PacketC::Score(self.score.clone())); out.push(PacketC::SetIngame { state: true, |