diff options
Diffstat (limited to 'server/src/entity')
| -rw-r--r-- | server/src/entity/mod.rs | 12 | ||||
| -rw-r--r-- | server/src/entity/player_portal_pair.rs | 97 |
2 files changed, 108 insertions, 1 deletions
diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs index 6e1a618c..ee8a1a74 100644 --- a/server/src/entity/mod.rs +++ b/server/src/entity/mod.rs @@ -25,12 +25,16 @@ mod environment_effect; mod item_portal; mod pedestrians; mod player_portal; +pub mod player_portal_pair; mod tag_minigame; mod tram; pub mod tutorial; use crate::{ - entity::{demand_sink::DemandSink, pedestrians::Pedestrians, tag_minigame::TagMinigame}, + entity::{ + demand_sink::DemandSink, pedestrians::Pedestrians, player_portal_pair::PlayerPortalPair, + tag_minigame::TagMinigame, + }, scoreboard::ScoreboardStore, }; use anyhow::Result; @@ -170,5 +174,11 @@ pub fn construct_entity(decl: &EntityDecl) -> DynEntity { speed: speed.unwrap_or(0.6), }), EntityDecl::DemandSink { pos } => Box::new(DemandSink { pos }), + EntityDecl::PlayerPortalPair { + a, + b, + in_tile, + out_tile, + } => Box::new(PlayerPortalPair::new(a, b, in_tile, out_tile)), } } diff --git a/server/src/entity/player_portal_pair.rs b/server/src/entity/player_portal_pair.rs new file mode 100644 index 00000000..b73f5891 --- /dev/null +++ b/server/src/entity/player_portal_pair.rs @@ -0,0 +1,97 @@ +/* + 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 super::{Entity, EntityContext}; +use anyhow::Result; +use hurrycurry_locale::TrError; +use hurrycurry_protocol::{ + PacketC, TileIndex, + glam::{IVec2, Vec2, vec2}, +}; + +#[derive(Debug, Clone)] +pub struct PlayerPortalPair { + a_i: IVec2, + b_i: IVec2, + a_f: Vec2, + b_f: Vec2, + in_tile: TileIndex, + out_tile: TileIndex, + a_out: bool, + b_out: bool, +} +impl PlayerPortalPair { + pub fn new(a: IVec2, b: IVec2, in_tile: TileIndex, out_tile: TileIndex) -> Self { + Self { + a_i: a, + b_i: b, + a_f: a.as_vec2() + vec2(0.5, 0.5), + b_f: b.as_vec2() + vec2(0.5, 0.5), + in_tile, + out_tile, + a_out: true, + b_out: true, + } + } +} +impl Entity for PlayerPortalPair { + fn tick(&mut self, c: EntityContext) -> Result<(), TrError> { + let qn = |p, r| { + let mut o = None; + c.game + .players_spatial_index + .query(p, r, |pid, _| o = Some(pid)); + o + }; + + if self.a_out && qn(self.a_f, 1.5).is_none() { + c.game.set_tile(self.a_i, Some(self.in_tile)); + self.a_out = false; + return Ok(()); + } + + if self.b_out && qn(self.b_f, 1.5).is_none() { + c.game.set_tile(self.b_i, Some(self.in_tile)); + self.b_out = false; + return Ok(()); + } + + if !self.a_out + && let Some(player) = qn(self.a_f, 0.5) + && let Some(p) = c.game.players.get_mut(&player) + { + p.movement.position = self.b_f; + c.packet_out.push_back(PacketC::MovementSync { player }); + c.game.set_tile(self.b_i, Some(self.out_tile)); + self.b_out = true; + return Ok(()); + } + + if !self.b_out + && let Some(player) = qn(self.b_f, 0.5) + && let Some(p) = c.game.players.get_mut(&player) + { + p.movement.position = self.a_f; + c.packet_out.push_back(PacketC::MovementSync { player }); + c.game.set_tile(self.a_i, Some(self.out_tile)); + self.a_out = true; + return Ok(()); + } + + Ok(()) + } +} |