From 74fb8de441c68fff92680a48352f6b9b0f6e9271 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 23 Jul 2024 21:27:25 +0200 Subject: add player portals --- server/src/entity/item_portal.rs | 60 ++++++++++++++++++++++++++++++++++++++ server/src/entity/mod.rs | 31 +++++++++++++++----- server/src/entity/player_portal.rs | 48 ++++++++++++++++++++++++++++++ server/src/entity/portal.rs | 60 -------------------------------------- server/src/game.rs | 4 +-- server/src/spatial_index.rs | 8 +++-- 6 files changed, 139 insertions(+), 72 deletions(-) create mode 100644 server/src/entity/item_portal.rs create mode 100644 server/src/entity/player_portal.rs delete mode 100644 server/src/entity/portal.rs (limited to 'server/src') diff --git a/server/src/entity/item_portal.rs b/server/src/entity/item_portal.rs new file mode 100644 index 00000000..f63ff274 --- /dev/null +++ b/server/src/entity/item_portal.rs @@ -0,0 +1,60 @@ +/* + 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 . + +*/ +use super::EntityT; +use crate::game::{interact_effect, Game}; +use anyhow::{anyhow, Result}; +use hurrycurry_protocol::{glam::IVec2, ItemLocation, PacketC}; +use std::collections::VecDeque; + +#[derive(Debug, Default, Clone)] +pub struct ItemPortal { + pub(super) from: IVec2, + pub(super) to: IVec2, +} + +impl EntityT for ItemPortal { + fn tick( + &mut self, + game: &mut Game, + packet_out: &mut VecDeque, + _dt: f32, + ) -> Result<()> { + let [from, to] = game + .tiles + .get_many_mut([&self.from, &self.to]) + .ok_or(anyhow!("conveyor does ends in itself"))?; + + if from.item.is_some() { + interact_effect( + &game.data, + true, + &mut to.item, + ItemLocation::Tile(self.to), + &mut from.item, + ItemLocation::Tile(self.from), + Some(to.kind), + packet_out, + &mut game.score, + &mut game.score_changed, + true, + ); + } + + Ok(()) + } +} 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, 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, speed: Option, }, - Portal { + ItemPortal { from: Option, to: IVec2, }, + PlayerPortal { + from: Option, + to: Vec2, + }, Customers {}, } @@ -75,8 +84,14 @@ pub fn construct_entity( initial_map: &HashMap)>, ) -> Result { 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 . + +*/ +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, + _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/entity/portal.rs b/server/src/entity/portal.rs deleted file mode 100644 index 3ed19719..00000000 --- a/server/src/entity/portal.rs +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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 . - -*/ -use super::EntityT; -use crate::game::{interact_effect, Game}; -use anyhow::{anyhow, Result}; -use hurrycurry_protocol::{glam::IVec2, ItemLocation, PacketC}; -use std::collections::VecDeque; - -#[derive(Debug, Default, Clone)] -pub struct Portal { - pub(super) from: IVec2, - pub(super) to: IVec2, -} - -impl EntityT for Portal { - fn tick( - &mut self, - game: &mut Game, - packet_out: &mut VecDeque, - _dt: f32, - ) -> Result<()> { - let [from, to] = game - .tiles - .get_many_mut([&self.from, &self.to]) - .ok_or(anyhow!("conveyor does ends in itself"))?; - - if from.item.is_some() { - interact_effect( - &game.data, - true, - &mut to.item, - ItemLocation::Tile(self.to), - &mut from.item, - ItemLocation::Tile(self.from), - Some(to.kind), - packet_out, - &mut game.score, - &mut game.score_changed, - true, - ); - } - - 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, pub communicate_persist: Option, - 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, pub walkable: HashSet, pub players: HashMap, - players_spatial_index: SpatialIndex, + pub players_spatial_index: SpatialIndex, entities: Arc>>, end: Option, 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 SpatialIndex { 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 Default for SpatialIndex { -- cgit v1.2.3-70-g09d2