diff options
author | metamuffin <metamuffin@disroot.org> | 2024-07-23 21:27:25 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-07-25 11:21:48 +0200 |
commit | 74fb8de441c68fff92680a48352f6b9b0f6e9271 (patch) | |
tree | 88e59c1043ac5de7379986eadc7f574e27f6c085 | |
parent | 149c58d54bf9c0eda6e3d978984e5e0365b7395d (diff) | |
download | hurrycurry-74fb8de441c68fff92680a48352f6b9b0f6e9271.tar hurrycurry-74fb8de441c68fff92680a48352f6b9b0f6e9271.tar.bz2 hurrycurry-74fb8de441c68fff92680a48352f6b9b0f6e9271.tar.zst |
add player portals
-rw-r--r-- | data/maps/conveyors_dot_com.yaml | 4 | ||||
-rw-r--r-- | data/maps/debug.yaml | 1 | ||||
-rw-r--r-- | server/src/entity/item_portal.rs (renamed from server/src/entity/portal.rs) | 4 | ||||
-rw-r--r-- | server/src/entity/mod.rs | 31 | ||||
-rw-r--r-- | server/src/entity/player_portal.rs | 48 | ||||
-rw-r--r-- | server/src/game.rs | 4 | ||||
-rw-r--r-- | server/src/spatial_index.rs | 8 | ||||
-rw-r--r-- | test-client/main.ts | 8 |
8 files changed, 88 insertions, 20 deletions
diff --git a/data/maps/conveyors_dot_com.yaml b/data/maps/conveyors_dot_com.yaml index 7c67bc2e..e0b9230b 100644 --- a/data/maps/conveyors_dot_com.yaml +++ b/data/maps/conveyors_dot_com.yaml @@ -77,8 +77,8 @@ tile_entities: "^": !conveyor { dir: [0, -1] } entities: - - !portal { from: [4, 15], to: [4, 7] } - - !portal { from: [17, 7], to: [17, 15] } + - !item_portal { from: [4, 15], to: [4, 7] } + - !item_portal { from: [17, 7], to: [17, 15] } items: "S": pot diff --git a/data/maps/debug.yaml b/data/maps/debug.yaml index f44c4570..c6d60d42 100644 --- a/data/maps/debug.yaml +++ b/data/maps/debug.yaml @@ -85,6 +85,7 @@ items: entities: - !customers + - !player_portal { to: [1.5, 2.5], from: [1.5, 8.5] } tile_entities: "}": !conveyor { dir: [1, 0], filter: dough-foodprocessor } diff --git a/server/src/entity/portal.rs b/server/src/entity/item_portal.rs index 3ed19719..f63ff274 100644 --- a/server/src/entity/portal.rs +++ b/server/src/entity/item_portal.rs @@ -22,12 +22,12 @@ use hurrycurry_protocol::{glam::IVec2, ItemLocation, PacketC}; use std::collections::VecDeque; #[derive(Debug, Default, Clone)] -pub struct Portal { +pub struct ItemPortal { pub(super) from: IVec2, pub(super) to: IVec2, } -impl EntityT for Portal { +impl EntityT for ItemPortal { fn tick( &mut self, game: &mut Game, diff --git a/server/src/entity/mod.rs b/server/src/entity/mod.rs index 95172ed0..ad0bde6f 100644 --- a/server/src/entity/mod.rs +++ b/server/src/entity/mod.rs @@ -17,16 +17,21 @@ */ pub mod conveyor; pub mod customers; -pub mod portal; -use std::collections::{HashMap, HashSet, VecDeque}; +pub mod item_portal; +pub mod player_portal; use crate::{data::ItemTileRegistry, game::Game, interaction::Recipe}; use anyhow::{anyhow, Result}; use conveyor::Conveyor; use customers::{demands::generate_demands, Customers}; -use hurrycurry_protocol::{glam::IVec2, ItemIndex, PacketC, TileIndex}; -use portal::Portal; +use hurrycurry_protocol::{ + glam::{IVec2, Vec2}, + ItemIndex, PacketC, TileIndex, +}; +use item_portal::ItemPortal; +use player_portal::PlayerPortal; use serde::{Deserialize, Serialize}; +use std::collections::{HashMap, HashSet, VecDeque}; pub trait EntityT: Clone { fn tick(&mut self, game: &mut Game, packet_out: &mut VecDeque<PacketC>, dt: f32) -> Result<()>; @@ -44,7 +49,7 @@ macro_rules! entities { }; } -entities!(Conveyor, Portal, Customers); +entities!(Conveyor, ItemPortal, PlayerPortal, Customers); #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] @@ -57,10 +62,14 @@ pub enum EntityDecl { dir: Option<IVec2>, speed: Option<f32>, }, - Portal { + ItemPortal { from: Option<IVec2>, to: IVec2, }, + PlayerPortal { + from: Option<Vec2>, + to: Vec2, + }, Customers {}, } @@ -75,8 +84,14 @@ pub fn construct_entity( initial_map: &HashMap<IVec2, (TileIndex, Option<ItemIndex>)>, ) -> Result<Entity> { Ok(match decl.to_owned() { - EntityDecl::Portal { from, to } => Entity::Portal(Portal { - from: from.or(pos).ok_or(anyhow!("no portla start"))?, + EntityDecl::ItemPortal { from, to } => Entity::ItemPortal(ItemPortal { + from: from.or(pos).ok_or(anyhow!("no item portal start"))?, + to, + }), + EntityDecl::PlayerPortal { from, to } => Entity::PlayerPortal(PlayerPortal { + from: from + .or(pos.map(|v| v.as_vec2())) + .ok_or(anyhow!("no player portal start"))?, to, }), EntityDecl::Conveyor { diff --git a/server/src/entity/player_portal.rs b/server/src/entity/player_portal.rs new file mode 100644 index 00000000..6ee04f15 --- /dev/null +++ b/server/src/entity/player_portal.rs @@ -0,0 +1,48 @@ +/* + Hurry Curry! - a game about cooking + Copyright 2024 metamuffin + + 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::EntityT; +use crate::game::Game; +use anyhow::{anyhow, Result}; +use hurrycurry_protocol::{glam::Vec2, PacketC}; +use std::collections::VecDeque; + +#[derive(Debug, Default, Clone)] +pub struct PlayerPortal { + pub(super) from: Vec2, + pub(super) to: Vec2, +} + +impl EntityT for PlayerPortal { + fn tick( + &mut self, + game: &mut Game, + _packet_out: &mut VecDeque<PacketC>, + _dt: f32, + ) -> Result<()> { + let mut players = Vec::new(); + game.players_spatial_index + .query(self.from, 0.5, |pid, _| players.push(pid)); + + for p in players { + let p = game.players.get_mut(&p).ok_or(anyhow!("player missing"))?; + p.movement.position = self.to; + } + + Ok(()) + } +} diff --git a/server/src/game.rs b/server/src/game.rs index 1692de34..d649d87e 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -60,7 +60,7 @@ pub struct Player { pub item: Option<Item>, pub communicate_persist: Option<Message>, - movement: MovementBase, + pub movement: MovementBase, pub direction: Vec2, pub boost: bool, pub last_position_update: Instant, @@ -71,7 +71,7 @@ pub struct Game { pub tiles: HashMap<IVec2, Tile>, pub walkable: HashSet<IVec2>, pub players: HashMap<PlayerID, Player>, - players_spatial_index: SpatialIndex<PlayerID>, + pub players_spatial_index: SpatialIndex<PlayerID>, entities: Arc<RwLock<Vec<Entity>>>, end: Option<Instant>, pub lobby: bool, diff --git a/server/src/spatial_index.rs b/server/src/spatial_index.rs index a62c80e0..d4bd1776 100644 --- a/server/src/spatial_index.rs +++ b/server/src/spatial_index.rs @@ -35,8 +35,12 @@ impl<T: Eq + Hash + Copy> SpatialIndex<T> { cb(e, pos) } } - pub fn query(&self, _position: Vec2, _radius: f32, cb: impl FnMut(T, Vec2)) { - self.all(cb) + pub fn query(&self, position: Vec2, radius: f32, mut cb: impl FnMut(T, Vec2)) { + self.all(|pl, p| { + if p.distance(position) < radius { + cb(pl, p) + } + }) } } impl<T> Default for SpatialIndex<T> { diff --git a/test-client/main.ts b/test-client/main.ts index db474784..e1313f8c 100644 --- a/test-client/main.ts +++ b/test-client/main.ts @@ -257,10 +257,10 @@ function keyboard(ev: KeyboardEvent, down: boolean) { if (HANDLED_KEYS.includes(ev.code)) ev.preventDefault() if (!keys_down.has(KEY_INTERACT) && ev.code == KEY_INTERACT && down) set_interact(true) if (keys_down.has(KEY_INTERACT) && ev.code == KEY_INTERACT && !down) set_interact(false) - if (down && ev.code == "Numpad1") send({ type: "communicate", message: { text: "/start tiny" }, persist: false }) - if (down && ev.code == "Numpad2") send({ type: "communicate", message: { text: "/start small" }, persist: false }) - if (down && ev.code == "Numpad3") send({ type: "communicate", message: { text: "/start big" }, persist: false }) - if (down && ev.code == "Numpad4") send({ type: "communicate", message: { text: "/start test" }, persist: false }) + if (down && ev.code == "Numpad1") send({ type: "communicate", message: { text: "/start junior" }, persist: false }) + if (down && ev.code == "Numpad2") send({ type: "communicate", message: { text: "/start senior" }, persist: false }) + if (down && ev.code == "Numpad3") send({ type: "communicate", message: { text: "/start sophomore" }, persist: false }) + if (down && ev.code == "Numpad4") send({ type: "communicate", message: { text: "/start debug" }, persist: false }) if (down && ev.code == "Numpad5") send({ type: "communicate", message: { text: "/start bus" }, persist: false }) if (down && ev.code == "Numpad0") send({ type: "communicate", message: { text: "/end" }, persist: false }) if (down) keys_down.add(ev.code) |