aboutsummaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'server/src')
-rw-r--r--server/src/entity/campaign.rs2
-rw-r--r--server/src/entity/customers.rs14
-rw-r--r--server/src/entity/player_portal_pair.rs20
-rw-r--r--server/src/entity/tag_minigame.rs6
-rw-r--r--server/src/entity/tutorial.rs49
-rw-r--r--server/src/lib.rs2
-rw-r--r--server/src/server.rs40
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,