diff options
| author | metamuffin <metamuffin@disroot.org> | 2025-12-16 01:07:41 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2025-12-16 01:07:41 +0100 |
| commit | e2efb15aa58477d898f92c8959242c0da3ce62bc (patch) | |
| tree | dbea74993c73c2f3f43fcf771c01dbd8d2607c5d | |
| parent | 48d7482ded28ce9d3d4ff52517b48665ff1b8ebd (diff) | |
| download | hurrycurry-e2efb15aa58477d898f92c8959242c0da3ce62bc.tar hurrycurry-e2efb15aa58477d898f92c8959242c0da3ce62bc.tar.bz2 hurrycurry-e2efb15aa58477d898f92c8959242c0da3ce62bc.tar.zst | |
Add player portal pair entity; fix tile/item remapping
| -rw-r--r-- | data/maps/debug2.yaml | 21 | ||||
| -rw-r--r-- | server/data/src/entities.rs | 8 | ||||
| -rw-r--r-- | server/data/src/lib.rs | 7 | ||||
| -rw-r--r-- | server/data/src/registry.rs | 31 | ||||
| -rw-r--r-- | server/src/entity/mod.rs | 12 | ||||
| -rw-r--r-- | server/src/entity/player_portal_pair.rs | 97 |
6 files changed, 161 insertions, 15 deletions
diff --git a/data/maps/debug2.yaml b/data/maps/debug2.yaml index b4a578da..fb5ca879 100644 --- a/data/maps/debug2.yaml +++ b/data/maps/debug2.yaml @@ -51,15 +51,16 @@ tiles: "D": house-door -c entities: + - !player_portal_pair { a: [5, 8], b: [10, 8] } - !environment_effect { name: rain, on: 60, off: 40 } - !environment_effect { name: wind, on: 60, off: 40 } - - !tram - length: 4 - character: 52 - points: [[5, 5], [23, 3], [23, 15], [3, 15]] - smoothing: 3. - spacing: 0.3625 - - !pedestrians - points: [[7, 7], [19, 7], [19, 13], [7, 13]] - spawn_delay: 0.5 - spawn_delay_stdev: 1 + # - !tram + # length: 4 + # character: 52 + # points: [[5, 5], [23, 3], [23, 15], [3, 15]] + # smoothing: 3. + # spacing: 0.3625 + # - !pedestrians + # points: [[7, 7], [19, 7], [19, 13], [7, 13]] + # spawn_delay: 0.5 + # spawn_delay_stdev: 1 diff --git a/server/data/src/entities.rs b/server/data/src/entities.rs index 1b0d4548..62947b05 100644 --- a/server/data/src/entities.rs +++ b/server/data/src/entities.rs @@ -38,6 +38,14 @@ pub enum EntityDecl { from: Vec2, to: Vec2, }, + PlayerPortalPair { + a: IVec2, + b: IVec2, + #[serde(default = "default_tile")] + in_tile: TileIndex, + #[serde(default = "default_tile")] + out_tile: TileIndex, + }, Customers { scaling_factor: Option<f32>, spawn_cooldown: Option<f32>, diff --git a/server/data/src/lib.rs b/server/data/src/lib.rs index a677bffd..d06aadd1 100644 --- a/server/data/src/lib.rs +++ b/server/data/src/lib.rs @@ -224,6 +224,13 @@ fn build_data( *blocker_tile = reg.register_tile("conveyor".to_owned()); exclusive_tiles.entry(*blocker_tile).or_default(); } + EntityDecl::PlayerPortalPair { + in_tile, out_tile, .. + } => { + *in_tile = reg.register_tile("black-hole".to_owned()); + *out_tile = reg.register_tile("white-hole".to_owned()); + tile_walkable.extend([*in_tile, *out_tile]); + } _ => (), } entities.push(e); diff --git a/server/data/src/registry.rs b/server/data/src/registry.rs index 6c92ecb5..372df653 100644 --- a/server/data/src/registry.rs +++ b/server/data/src/registry.rs @@ -83,16 +83,19 @@ pub(crate) fn filter_unused_tiles_and_items(data: &mut Gamedata, serverdata: &mu EntityDecl::Gate { blocker_tile: blocker, .. - } => used_tiles.insert(*blocker), - EntityDecl::Customers { unknown_order, .. } => used_items.insert(*unknown_order), + } => used_tiles.extend([*blocker]), + EntityDecl::Customers { unknown_order, .. } => used_items.extend([*unknown_order]), EntityDecl::TagMinigame { tag_item, blocker_tile, } => { used_items.insert(*tag_item); - used_tiles.insert(*blocker_tile) + used_tiles.insert(*blocker_tile); } - _ => false, + EntityDecl::PlayerPortalPair { + in_tile, out_tile, .. + } => used_tiles.extend([*in_tile, *out_tile]), + _ => (), }; } @@ -182,6 +185,26 @@ pub(crate) fn filter_unused_tiles_and_items(data: &mut Gamedata, serverdata: &mu *item = item_map[item] } } + for e in &mut serverdata.entity_decls { + match e { + EntityDecl::Gate { blocker_tile, .. } => *blocker_tile = tile_map[blocker_tile], + EntityDecl::Customers { unknown_order, .. } => *unknown_order = item_map[unknown_order], + EntityDecl::TagMinigame { + tag_item, + blocker_tile, + } => { + *tag_item = item_map[tag_item]; + *blocker_tile = tile_map[blocker_tile]; + } + EntityDecl::PlayerPortalPair { + in_tile, out_tile, .. + } => { + *in_tile = tile_map[in_tile]; + *out_tile = tile_map[out_tile]; + } + _ => (), + }; + } data.tile_walkable = data .tile_walkable .clone() 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(()) + } +} |