aboutsummaryrefslogtreecommitdiff
path: root/server/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-10-19 23:50:23 +0200
committermetamuffin <metamuffin@disroot.org>2025-10-19 23:50:23 +0200
commitab83f982601d93b2399102c4d030fd6e13c4c735 (patch)
treec0536ca9e328707d6b4f4cfc7a2307713466a5be /server/src
parent231a5ce21fcee9195fcc504ee672e4464d627c47 (diff)
downloadhurrycurry-ab83f982601d93b2399102c4d030fd6e13c4c735.tar
hurrycurry-ab83f982601d93b2399102c4d030fd6e13c4c735.tar.bz2
hurrycurry-ab83f982601d93b2399102c4d030fd6e13c4c735.tar.zst
Refactor and move interaction code
Diffstat (limited to 'server/src')
-rw-r--r--server/src/entity/bot.rs3
-rw-r--r--server/src/entity/campaign.rs4
-rw-r--r--server/src/entity/conveyor.rs31
-rw-r--r--server/src/entity/customers.rs9
-rw-r--r--server/src/entity/environment_effect.rs3
-rw-r--r--server/src/entity/item_portal.rs32
-rw-r--r--server/src/entity/mod.rs4
-rw-r--r--server/src/entity/pedestrians.rs3
-rw-r--r--server/src/entity/player_portal.rs7
-rw-r--r--server/src/entity/tag_minigame.rs3
-rw-r--r--server/src/entity/tram.rs3
-rw-r--r--server/src/entity/tutorial.rs4
-rw-r--r--server/src/interaction.rs354
-rw-r--r--server/src/lib.rs1
-rw-r--r--server/src/server.rs111
15 files changed, 49 insertions, 523 deletions
diff --git a/server/src/entity/bot.rs b/server/src/entity/bot.rs
index 9627bb76..51a09b62 100644
--- a/server/src/entity/bot.rs
+++ b/server/src/entity/bot.rs
@@ -18,6 +18,7 @@
use super::{Entity, EntityContext};
use anyhow::Result;
use hurrycurry_bot::{BotAlgo, DynBotAlgo};
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{Character, Hand, ItemLocation, PacketS, PlayerClass, PlayerID};
use log::debug;
use std::any::Any;
@@ -47,7 +48,7 @@ impl<T: BotAlgo + Any> Entity for BotDriver<T> {
fn finished(&self) -> bool {
self.left
}
- fn tick(&mut self, c: EntityContext<'_>) -> Result<()> {
+ fn tick(&mut self, c: EntityContext<'_>) -> Result<(), TrError> {
if let Some((name, character, class)) = self.join_data.take() {
self.id = c.game.get_unused_player_id(); // TODO clashes when multiple bots join in the same tick
debug!("join {}", self.id);
diff --git a/server/src/entity/campaign.rs b/server/src/entity/campaign.rs
index 1966fc01..b7d7d8db 100644
--- a/server/src/entity/campaign.rs
+++ b/server/src/entity/campaign.rs
@@ -32,7 +32,7 @@ pub struct Map {
}
impl Entity for Map {
- fn tick(&mut self, c: EntityContext) -> Result<()> {
+ fn tick(&mut self, c: EntityContext) -> Result<(), TrError> {
let mut activate = false;
c.game
.players_spatial_index
@@ -55,7 +55,7 @@ pub struct Gate {
pub condition: GateCondition,
}
impl Entity for Gate {
- fn tick(&mut self, c: EntityContext<'_>) -> Result<()> {
+ fn tick(&mut self, c: EntityContext<'_>) -> Result<(), TrError> {
if self.active {
self.active = false;
self.unlocked = self.condition.check(c.scoreboard);
diff --git a/server/src/entity/conveyor.rs b/server/src/entity/conveyor.rs
index 9534b045..6757ed43 100644
--- a/server/src/entity/conveyor.rs
+++ b/server/src/entity/conveyor.rs
@@ -16,8 +16,8 @@
*/
use super::{Entity, EntityContext};
-use crate::interaction::interact;
-use anyhow::{Result, anyhow, bail};
+use anyhow::Result;
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{ItemLocation, glam::IVec2};
#[derive(Debug, Clone)]
@@ -29,12 +29,12 @@ pub struct Conveyor {
}
impl Entity for Conveyor {
- fn tick(&mut self, c: EntityContext) -> Result<()> {
+ fn tick(&mut self, c: EntityContext) -> Result<(), TrError> {
let from = c
.game
.tiles
.get(&self.from)
- .ok_or(anyhow!("conveyor from missing"))?;
+ .ok_or(TrError::Plain("conveyor from missing".into()))?;
if from.item.is_some() {
self.cooldown += c.dt;
@@ -43,28 +43,11 @@ impl Entity for Conveyor {
}
self.cooldown = 0.;
- if self.from == self.to {
- bail!("conveyor does ends in itself")
- }
- let [Some(from), Some(to)] = c.game.tiles.get_disjoint_mut([&self.from, &self.to])
- else {
- bail!("at least one conveyor end not on map");
- };
-
- interact(
- &c.game.data,
- true,
- Some(to.kind),
- None,
- &mut to.item,
- ItemLocation::Tile(self.to),
- &mut from.item,
+ c.game.interact(
ItemLocation::Tile(self.from),
- &mut c.game.score,
- c.score_changed,
+ ItemLocation::Tile(self.to),
true,
- c.packet_out,
- );
+ )?;
}
Ok(())
diff --git a/server/src/entity/customers.rs b/server/src/entity/customers.rs
index 1e795ac5..36afe24a 100644
--- a/server/src/entity/customers.rs
+++ b/server/src/entity/customers.rs
@@ -1,7 +1,3 @@
-use std::random::random;
-
-use crate::random_float;
-
/*
Hurry Curry! - a game about cooking
Copyright (C) 2025 Hurry Curry! Contributors
@@ -20,9 +16,12 @@ use crate::random_float;
*/
use super::{Entity, EntityContext, bot::BotDriver};
+use crate::random_float;
use anyhow::Result;
use hurrycurry_bot::algos::{Customer, CustomerConfig};
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{Character, PlayerClass};
+use std::random::random;
pub struct Customers {
customers: Vec<BotDriver<Customer>>,
@@ -43,7 +42,7 @@ impl Customers {
}
impl Entity for Customers {
- fn tick(&mut self, c: EntityContext) -> Result<()> {
+ fn tick(&mut self, c: EntityContext) -> Result<(), TrError> {
let chairs = *self.chair_count.get_or_insert_with(|| {
c.game
.tiles
diff --git a/server/src/entity/environment_effect.rs b/server/src/entity/environment_effect.rs
index b5344a27..e50a65ff 100644
--- a/server/src/entity/environment_effect.rs
+++ b/server/src/entity/environment_effect.rs
@@ -19,6 +19,7 @@ use crate::random_float;
*/
use super::{Entity, EntityContext};
use hurrycurry_data::entities::EnvironmentEffect;
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::PacketC;
use std::time::{Duration, Instant};
@@ -39,7 +40,7 @@ impl EnvironmentEffectController {
}
}
impl Entity for EnvironmentEffectController {
- fn tick(&mut self, c: EntityContext) -> anyhow::Result<()> {
+ fn tick(&mut self, c: EntityContext) -> Result<(), TrError> {
if self.next_transition < Instant::now() {
if self.active {
self.next_transition +=
diff --git a/server/src/entity/item_portal.rs b/server/src/entity/item_portal.rs
index f0472802..4335a659 100644
--- a/server/src/entity/item_portal.rs
+++ b/server/src/entity/item_portal.rs
@@ -16,8 +16,8 @@
*/
use super::{Entity, EntityContext};
-use crate::interaction::interact;
-use anyhow::{Result, bail};
+use anyhow::Result;
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{ItemLocation, glam::IVec2};
#[derive(Debug, Default, Clone)]
@@ -27,29 +27,19 @@ pub struct ItemPortal {
}
impl Entity for ItemPortal {
- fn tick(&mut self, c: EntityContext) -> Result<()> {
- if self.from == self.to {
- bail!("item portal ends in itself")
- }
- let [Some(from), Some(to)] = c.game.tiles.get_disjoint_mut([&self.from, &self.to]) else {
- bail!("at least one item portal end not on map");
- };
+ fn tick(&mut self, c: EntityContext) -> Result<(), TrError> {
+ let from = c
+ .game
+ .tiles
+ .get(&self.from)
+ .ok_or(TrError::Plain("portal from missing".into()))?;
if from.item.is_some() {
- interact(
- &c.game.data,
- true,
- Some(to.kind),
- None,
- &mut to.item,
- ItemLocation::Tile(self.to),
- &mut from.item,
+ c.game.interact(
ItemLocation::Tile(self.from),
- &mut c.game.score,
- c.score_changed,
+ ItemLocation::Tile(self.to),
true,
- c.packet_out,
- );
+ )?;
}
Ok(())
diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs
index 34815d0d..2e235c95 100644
--- a/server/src/entity/mod.rs
+++ b/server/src/entity/mod.rs
@@ -38,8 +38,8 @@ use campaign::{Gate, Map};
use conveyor::Conveyor;
use customers::Customers;
use environment_effect::{EnvironmentController, EnvironmentEffectController};
-use hurrycurry_game_core::Game;
use hurrycurry_data::{Serverdata, entities::EntityDecl};
+use hurrycurry_game_core::Game;
use hurrycurry_locale::TrError;
use hurrycurry_protocol::{Character, ItemLocation, PacketC, PacketS, PlayerID};
use item_portal::ItemPortal;
@@ -66,7 +66,7 @@ pub struct EntityContext<'a> {
}
pub trait Entity: Any {
- fn tick(&mut self, _c: EntityContext<'_>) -> Result<()> {
+ fn tick(&mut self, _c: EntityContext<'_>) -> Result<(), TrError> {
Ok(())
}
fn finished(&self) -> bool {
diff --git a/server/src/entity/pedestrians.rs b/server/src/entity/pedestrians.rs
index edfe5ca3..0d33bfd0 100644
--- a/server/src/entity/pedestrians.rs
+++ b/server/src/entity/pedestrians.rs
@@ -19,6 +19,7 @@ use crate::random_gauss;
*/
use super::{Entity, EntityContext};
use anyhow::Result;
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{Character, PacketS, PlayerClass, PlayerID, glam::Vec2};
use std::{collections::HashMap, random::random};
@@ -35,7 +36,7 @@ impl Entity for Pedestrians {
fn finished(&self) -> bool {
false
}
- fn tick(&mut self, c: EntityContext<'_>) -> Result<()> {
+ fn tick(&mut self, c: EntityContext<'_>) -> Result<(), TrError> {
self.cooldown -= c.dt;
if self.cooldown <= 0. && self.players.len() < 32 {
let id = c.game.get_unused_player_id();
diff --git a/server/src/entity/player_portal.rs b/server/src/entity/player_portal.rs
index 1717002a..a2653900 100644
--- a/server/src/entity/player_portal.rs
+++ b/server/src/entity/player_portal.rs
@@ -16,7 +16,8 @@
*/
use super::{Entity, EntityContext};
-use anyhow::{Result, anyhow};
+use anyhow::Result;
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{PacketC, glam::Vec2};
#[derive(Debug, Default, Clone)]
@@ -26,7 +27,7 @@ pub struct PlayerPortal {
}
impl Entity for PlayerPortal {
- fn tick(&mut self, c: EntityContext) -> Result<()> {
+ fn tick(&mut self, c: EntityContext) -> Result<(), TrError> {
let mut players = Vec::new();
c.game
.players_spatial_index
@@ -37,7 +38,7 @@ impl Entity for PlayerPortal {
.game
.players
.get_mut(&pid)
- .ok_or(anyhow!("Player is missing"))?;
+ .ok_or(TrError::Plain("Player is missing".to_string()))?;
p.movement.position = self.to;
c.packet_out
.push_back(PacketC::MovementSync { player: pid });
diff --git a/server/src/entity/tag_minigame.rs b/server/src/entity/tag_minigame.rs
index a76b0511..089fd49e 100644
--- a/server/src/entity/tag_minigame.rs
+++ b/server/src/entity/tag_minigame.rs
@@ -18,6 +18,7 @@
use super::{Entity, EntityContext};
use anyhow::Result;
use hurrycurry_game_core::{Item, Tile};
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{
Hand, ItemIndex, ItemLocation, Message, PacketC, PlayerID, TileIndex, glam::IVec2,
};
@@ -49,7 +50,7 @@ impl TagMinigame {
}
}
impl Entity for TagMinigame {
- fn tick(&mut self, c: EntityContext) -> Result<()> {
+ fn tick(&mut self, c: EntityContext) -> Result<(), TrError> {
if !self.init_done {
self.init_done = true;
// Hand out the item to some player(s)
diff --git a/server/src/entity/tram.rs b/server/src/entity/tram.rs
index 2d6aa8c1..20fe8120 100644
--- a/server/src/entity/tram.rs
+++ b/server/src/entity/tram.rs
@@ -17,6 +17,7 @@
*/
use super::{Entity, EntityContext};
use anyhow::Result;
+use hurrycurry_locale::TrError;
use hurrycurry_protocol::{Character, PacketS, PlayerClass, PlayerID, glam::Vec2};
pub struct Tram {
@@ -33,7 +34,7 @@ impl Entity for Tram {
fn finished(&self) -> bool {
false
}
- fn tick(&mut self, c: EntityContext<'_>) -> Result<()> {
+ fn tick(&mut self, c: EntityContext<'_>) -> Result<(), TrError> {
if self.ids.len() < self.length {
let id = c.game.get_unused_player_id();
c.packet_in.push_back(PacketS::Join {
diff --git a/server/src/entity/tutorial.rs b/server/src/entity/tutorial.rs
index 8cc896ac..46b2a0db 100644
--- a/server/src/entity/tutorial.rs
+++ b/server/src/entity/tutorial.rs
@@ -17,7 +17,7 @@
*/
use super::{Entity, EntityContext};
use anyhow::Result;
-use hurrycurry_locale::trm;
+use hurrycurry_locale::{TrError, trm};
use hurrycurry_protocol::{
ItemIndex, Message, PacketC, PlayerID, Recipe, RecipeIndex, TileIndex, glam::IVec2,
};
@@ -67,7 +67,7 @@ impl Entity for Tutorial {
success: false,
});
}
- fn tick(&mut self, c: EntityContext<'_>) -> Result<()> {
+ fn tick(&mut self, c: EntityContext<'_>) -> Result<(), TrError> {
if self.ended {
return Ok(());
}
diff --git a/server/src/interaction.rs b/server/src/interaction.rs
deleted file mode 100644
index a2e8643a..00000000
--- a/server/src/interaction.rs
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- Hurry Curry! - a game about cooking
- Copyright (C) 2025 Hurry Curry! Contributors
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, version 3 of the License only.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-*/
-use hurrycurry_game_core::{Involvement, Item, gamedata_index::GamedataIndex};
-use hurrycurry_protocol::{Gamedata, ItemLocation, PacketC, PlayerID, Recipe, Score, TileIndex};
-use log::info;
-use std::collections::{BTreeSet, VecDeque};
-
-#[allow(clippy::too_many_arguments)]
-pub fn interact(
- data: &Gamedata,
- edge: bool,
- tile: Option<TileIndex>,
- player: Option<PlayerID>,
- this: &mut Option<Item>,
- this_loc: ItemLocation,
- other: &mut Option<Item>,
- other_loc: ItemLocation,
- score: &mut Score,
- score_changed: &mut bool,
- automated: bool,
- packet_out: &mut VecDeque<PacketC>,
-) {
- if other.is_none()
- && let Some(item) = this
- && let Some(inv) = &mut item.active
- {
- let recipe = &data.recipe(inv.recipe);
- if recipe.supports_tile(tile)
- && let Recipe::Active { outputs, speed, .. } = recipe
- {
- if edge {
- inv.players.extend(player);
- } else {
- if let Some(player) = player {
- inv.players.remove(&player);
- }
- }
- inv.speed = speed * inv.players.len() as f32;
-
- if inv.position >= 1. {
- let this_had_item = this.is_some();
- let other_had_item = other.is_some();
- *other = outputs[0].map(|kind| Item { kind, active: None });
- *this = outputs[1].map(|kind| Item { kind, active: None });
- produce(
- this_had_item,
- other_had_item,
- this,
- this_loc,
- other,
- other_loc,
- score_changed,
- packet_out,
- );
- } else {
- packet_out.push_back(PacketC::SetProgress {
- players: inv.players.clone(),
- item: this_loc,
- position: inv.position,
- speed: inv.speed,
- warn: inv.warn,
- });
- }
- return;
- }
- }
- if !edge {
- return;
- }
- for (ri, recipe) in data.recipes() {
- if !recipe.supports_tile(tile) {
- continue;
- }
- match recipe {
- Recipe::Active { input, speed, .. } => {
- if other.is_none()
- && let Some(item) = this
- && item.kind == *input
- && item.active.is_none()
- {
- info!("start active {ri}");
- item.active = Some(Involvement {
- players: player.into_iter().collect(),
- recipe: ri,
- speed: *speed,
- position: 0.,
- warn: false,
- });
- }
- if this.is_none()
- && let Some(item) = &other
- && item.kind == *input
- && item.active.is_none()
- {
- let mut item = other.take().unwrap();
- info!("start active {ri}");
- item.active = Some(Involvement {
- players: player.into_iter().collect(),
- recipe: ri,
- speed: *speed,
- position: 0.,
- warn: false,
- });
- *this = Some(item);
- score.active_recipes += 1;
- packet_out.push_back(PacketC::MoveItem {
- from: other_loc,
- to: this_loc,
- });
- packet_out.push_back(PacketC::SetProgress {
- players: player.into_iter().collect(),
- item: this_loc,
- position: 0.,
- speed: *speed,
- warn: false,
- });
- return;
- }
- }
- Recipe::Instant {
- inputs,
- outputs,
- points: pd,
- ..
- } => {
- let on_tile = this.as_ref().map(|i| i.kind);
- let in_hand = other.as_ref().map(|i| i.kind);
- let ok = inputs[0] == on_tile && inputs[1] == in_hand;
- let ok_rev = inputs[1] == on_tile && inputs[0] == in_hand;
- if ok || ok_rev {
- info!("instant {ri} reversed={ok_rev}");
- let ok_rev = ok_rev as usize;
- let this_had_item = this.is_some();
- let other_had_item = other.is_some();
- *other = outputs[1 - ok_rev].map(|kind| Item { kind, active: None });
- *this = outputs[ok_rev].map(|kind| Item { kind, active: None });
- score.points += pd;
- score.instant_recipes += 1;
- *score_changed = true;
- produce(
- this_had_item,
- other_had_item,
- this,
- this_loc,
- other,
- other_loc,
- score_changed,
- packet_out,
- );
- return;
- }
- }
- _ => (),
- }
- }
-
- let can_place = automated
- || tile.is_none_or(|tile| {
- other.as_ref().is_some_and(|other| {
- data.tile_placeable_items
- .get(&tile)
- .is_none_or(|pl| pl.contains(&other.kind))
- })
- });
-
- if can_place
- && this.is_none()
- && let Some(item) = other.take()
- {
- *this = Some(item);
- packet_out.push_back(PacketC::MoveItem {
- from: other_loc,
- to: this_loc,
- });
- return;
- }
- if other.is_none()
- && let Some(item) = this.take()
- {
- *other = Some(item);
- packet_out.push_back(PacketC::MoveItem {
- from: this_loc,
- to: other_loc,
- });
- }
-}
-
-pub enum TickEffect {
- Progress {
- speed: f32,
- position: f32,
- warn: bool,
- },
- ClearProgress,
- Produce,
-}
-
-#[allow(clippy::too_many_arguments)]
-pub fn tick_slot(
- dt: f32,
- data: &Gamedata,
- data_index: &GamedataIndex,
- tile: Option<TileIndex>,
- slot: &mut Option<Item>,
- slot_loc: ItemLocation,
- score: &mut Score,
- score_changed: &mut bool,
- packet_out: &mut VecDeque<PacketC>,
-) {
- if let Some(item) = slot {
- if let Some(a) = &mut item.active {
- let r = &data.recipe(a.recipe);
- let prev_speed = a.speed;
-
- if r.supports_tile(tile) {
- if a.speed <= 0.
- && let Recipe::Passive { speed, .. } = &data.recipe(a.recipe)
- {
- a.speed = *speed;
- }
- } else if let Some(revert_speed) = r.revert_speed() {
- a.speed = -revert_speed
- } else {
- a.speed = 0.;
- }
-
- if a.position < 0. {
- item.active = None;
- packet_out.push_back(PacketC::ClearProgress { item: slot_loc });
- return;
- }
- if a.position >= 1.
- && let Recipe::Passive { output, warn, .. } = &data.recipe(a.recipe)
- {
- *slot = output.map(|kind| Item { kind, active: None });
- score.passive_recipes += 1;
- *score_changed = true;
- packet_out.push_back(PacketC::SetProgress {
- players: BTreeSet::new(),
- warn: *warn,
- item: slot_loc,
- position: 1.,
- speed: 0.,
- });
- packet_out.push_back(PacketC::SetItem {
- location: slot_loc,
- item: slot.as_ref().map(|i| i.kind),
- });
- return;
- };
-
- a.position += dt * a.speed;
- a.position = a.position.min(1.);
-
- if a.speed != prev_speed {
- packet_out.push_back(PacketC::SetProgress {
- players: a.players.clone(),
- position: a.position,
- speed: a.speed,
- warn: a.warn,
- item: slot_loc,
- });
- }
- } else if let Some(recipes) = data_index.recipe_passive_by_input.get(&item.kind) {
- for &ri in recipes {
- let recipe = data.recipe(ri);
- if recipe.supports_tile(tile)
- && let Recipe::Passive {
- input, warn, speed, ..
- } = recipe
- && *input == item.kind
- {
- item.active = Some(Involvement {
- players: BTreeSet::new(),
- recipe: ri,
- position: 0.,
- warn: *warn,
- speed: *speed,
- });
- packet_out.push_back(PacketC::SetProgress {
- players: BTreeSet::new(),
- position: 0.,
- speed: *speed,
- warn: *warn,
- item: slot_loc,
- });
- return;
- }
- }
- }
- }
-}
-
-#[allow(clippy::too_many_arguments)]
-fn produce(
- this_had_item: bool,
- other_had_item: bool,
- this: &Option<Item>,
- this_loc: ItemLocation,
- other: &Option<Item>,
- other_loc: ItemLocation,
- score_changed: &mut bool,
- packet_out: &mut VecDeque<PacketC>,
-) {
- info!("produce {this_loc} <~ {other_loc}");
- *score_changed = true;
- if this_had_item {
- packet_out.push_back(PacketC::SetItem {
- location: this_loc,
- item: None,
- });
- }
- if other_had_item {
- packet_out.push_back(PacketC::MoveItem {
- from: other_loc,
- to: this_loc,
- });
- packet_out.push_back(PacketC::SetItem {
- location: this_loc,
- item: None,
- });
- }
- if let Some(i) = &other {
- packet_out.push_back(PacketC::SetItem {
- location: this_loc,
- item: Some(i.kind),
- });
- packet_out.push_back(PacketC::MoveItem {
- from: this_loc,
- to: other_loc,
- })
- }
- if let Some(i) = &this {
- packet_out.push_back(PacketC::SetItem {
- location: this_loc,
- item: Some(i.kind),
- });
- }
-}
diff --git a/server/src/lib.rs b/server/src/lib.rs
index 260221da..0f591851 100644
--- a/server/src/lib.rs
+++ b/server/src/lib.rs
@@ -18,7 +18,6 @@
#![feature(if_let_guard, iterator_try_collect, stmt_expr_attributes, random)]
pub mod commands;
pub mod entity;
-pub mod interaction;
pub mod network;
pub mod scoreboard;
pub mod server;
diff --git a/server/src/server.rs b/server/src/server.rs
index 7ded8eb7..45f31e0b 100644
--- a/server/src/server.rs
+++ b/server/src/server.rs
@@ -18,13 +18,12 @@
use crate::{
ConnectionID,
entity::{Entities, EntityContext, construct_entity},
- interaction::{interact, tick_slot},
random_float,
scoreboard::ScoreboardStore,
};
use anyhow::{Context, Result};
-use hurrycurry_game_core::{Game, Involvement, Item, Player, Tile};
use hurrycurry_data::{Serverdata, index::DataIndex};
+use hurrycurry_game_core::{Game, Involvement, Item, Player, Tile};
use hurrycurry_locale::{
FALLBACK_LOCALE, TrError,
message::{COLORED, MessageDisplayExt},
@@ -546,83 +545,9 @@ impl Server {
return Err(tre!("s.error.interacting_too_far"));
}
- // No going back from here on
-
player.interacting = if edge { Some((loc, hand)) } else { None };
-
- match loc {
- ItemLocation::Tile(pos) => {
- let player = self
- .game
- .players
- .get_mut(&pid)
- .ok_or(tre!("s.error.no_player"))?;
-
- let hslot = player
- .items
- .get_mut(hand.0)
- .ok_or(tre!("s.error.no_hand"))?;
-
- let tile = self
- .game
- .tiles
- .get_mut(&pos)
- .ok_or(tre!("s.error.no_tile"))?;
-
- interact(
- &self.game.data,
- edge,
- Some(tile.kind),
- Some(pid),
- &mut tile.item,
- ItemLocation::Tile(pos),
- hslot,
- ItemLocation::Player(pid, hand),
- &mut self.game.score,
- &mut self.score_changed,
- false,
- &mut self.packet_out,
- )
- }
- ItemLocation::Player(other_pid, other_hand) => {
- if pid == other_pid {
- return Err(tre!("s.error.self_interact"));
- }
- let [Some(other), Some(this)] =
- self.game.players.get_disjoint_mut([&pid, &other_pid])
- else {
- return Err(tre!("s.error.no_player"));
- };
-
- if this.class == PlayerClass::Customer
- || other.class == PlayerClass::Customer
- {
- return Err(tre!("s.error.customer_interact"));
- }
-
- let this_hslot =
- this.items.get_mut(hand.0).ok_or(tre!("s.error.no_hand"))?;
- let other_hslot = other
- .items
- .get_mut(other_hand.0)
- .ok_or(tre!("s.error.no_hand"))?;
-
- interact(
- &self.game.data,
- edge,
- None,
- Some(pid),
- this_hslot,
- ItemLocation::Player(other_pid, hand),
- other_hslot,
- ItemLocation::Player(pid, hand),
- &mut self.game.score,
- &mut self.score_changed,
- false,
- &mut self.packet_out,
- )
- }
- }
+ self.game
+ .interact(loc, ItemLocation::Player(pid, hand), edge)?;
}
PacketS::Communicate {
message,
@@ -695,18 +620,10 @@ impl Server {
.push_back(PacketC::Score(self.game.score.clone()));
}
- for (&pos, tile) in &mut self.game.tiles {
- tick_slot(
- dt,
- &self.game.data,
- &self.game.data_index,
- Some(tile.kind),
- &mut tile.item,
- ItemLocation::Tile(pos),
- &mut self.game.score,
- &mut self.score_changed,
- &mut self.packet_out,
- );
+ for loc in self.game.item_locations_index.clone() {
+ if let Err(e) = self.game.tick_slot(loc, dt) {
+ warn!("Slot tick failed: {}", e.to_string());
+ }
}
for (&pid, player) in &mut self.game.players {
@@ -737,20 +654,6 @@ impl Server {
boost: player.movement.boosting,
rot: player.movement.rotation,
});
-
- for (i, item) in player.items.iter_mut().enumerate() {
- tick_slot(
- dt,
- &self.game.data,
- &self.game.data_index,
- None,
- item,
- ItemLocation::Player(pid, Hand(i)),
- &mut self.game.score,
- &mut self.score_changed,
- &mut self.packet_out,
- );
- }
}
let mut players_auto_release = Vec::new();