diff options
author | metamuffin <metamuffin@noreply.codeberg.org> | 2024-12-25 19:05:05 +0000 |
---|---|---|
committer | metamuffin <metamuffin@noreply.codeberg.org> | 2024-12-25 19:05:05 +0000 |
commit | cc6b50debb9d5b740adbe6f803755413c972659a (patch) | |
tree | b34a0a5669707992f1334f88a1959d5b1e120415 /server/src | |
parent | 2ceeea0e5fc245602618ec47f6ff1f91a094e130 (diff) | |
parent | 53cf167c08986caf346957d1f357cefaee1bd6b5 (diff) | |
download | hurrycurry-cc6b50debb9d5b740adbe6f803755413c972659a.tar hurrycurry-cc6b50debb9d5b740adbe6f803755413c972659a.tar.bz2 hurrycurry-cc6b50debb9d5b740adbe6f803755413c972659a.tar.zst |
Merge pull request 'Two-handed players' (#236) from two-handed into master
Reviewed-on: https://codeberg.org/hurrycurry/hurrycurry/pulls/236
Diffstat (limited to 'server/src')
-rw-r--r-- | server/src/data/mod.rs | 2 | ||||
-rw-r--r-- | server/src/entity/bot.rs | 3 | ||||
-rw-r--r-- | server/src/entity/tutorial.rs | 4 | ||||
-rw-r--r-- | server/src/server.rs | 142 |
4 files changed, 90 insertions, 61 deletions
diff --git a/server/src/data/mod.rs b/server/src/data/mod.rs index 57051fe9..64f40217 100644 --- a/server/src/data/mod.rs +++ b/server/src/data/mod.rs @@ -73,6 +73,7 @@ pub struct MapDecl { walkable: Vec<String>, chef_spawn: char, customer_spawn: char, + #[serde(default)] hand_count: Option<usize>, #[serde(default)] entities: Vec<EntityDecl>, #[serde(default)] tile_entities: HashMap<char, EntityDecl>, #[serde(default)] score_baseline: i64, @@ -314,6 +315,7 @@ pub fn build_data( item_names, demands, tile_names, + hand_count: map_in.hand_count.unwrap_or(1), }, Serverdata { initial_map, diff --git a/server/src/entity/bot.rs b/server/src/entity/bot.rs index fe4d711f..6e6c9162 100644 --- a/server/src/entity/bot.rs +++ b/server/src/entity/bot.rs @@ -18,7 +18,7 @@ use super::{Entity, EntityContext}; use anyhow::Result; use hurrycurry_bot::{BotAlgo, DynBotAlgo}; -use hurrycurry_protocol::{PacketS, PlayerClass, PlayerID}; +use hurrycurry_protocol::{Hand, PacketS, PlayerClass, PlayerID}; use log::info; use rand::random; use std::any::Any; @@ -72,6 +72,7 @@ impl<T: BotAlgo + Any> Entity for BotDriver<T> { c.packet_in.push_back(PacketS::Interact { player: self.id, pos: input.interact, + hand: Hand(0), }) } c.packet_in.push_back(PacketS::Movement { diff --git a/server/src/entity/tutorial.rs b/server/src/entity/tutorial.rs index 44244862..33c0e507 100644 --- a/server/src/entity/tutorial.rs +++ b/server/src/entity/tutorial.rs @@ -144,7 +144,7 @@ impl StepContext<'_> { .game .players .get(&self.player) - .is_some_and(|p| p.item.as_ref().is_some_and(|i| i.kind == item)) + .is_some_and(|p| p.items.iter().flatten().any(|i| i.kind == item)) } pub fn find_demand(&self, item: ItemIndex) -> Option<IVec2> { self.ent @@ -228,7 +228,7 @@ impl StepContext<'_> { .game .players .get(&self.player) - .is_some_and(|p| p.item.as_ref().is_some_and(|i| i.kind == item)) + .is_some_and(|p| p.items.iter().flatten().any(|i| i.kind == item)) { if let Some(pos) = self.find_demand(item) { Err((Some(pos), trm!("s.tutorial.serve"))) diff --git a/server/src/server.rs b/server/src/server.rs index 462e95d4..0889cd71 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -28,8 +28,8 @@ use hurrycurry_client_lib::{Game, Involvement, Item, Player, Tile}; use hurrycurry_protocol::{ glam::{IVec2, Vec2}, movement::MovementBase, - Gamedata, ItemLocation, Menu, MessageTimeout, PacketC, PacketS, PlayerClass, PlayerID, Score, - TileIndex, + Gamedata, Hand, ItemLocation, Menu, MessageTimeout, PacketC, PacketS, PlayerClass, PlayerID, + Score, TileIndex, }; use log::{info, warn}; use rand::random; @@ -163,26 +163,28 @@ impl GameServerExt for Game { character: player.character, name: player.name.clone(), }); - if let Some(item) = &player.item { - out.push(PacketC::SetItem { - location: ItemLocation::Player(id), - item: Some(item.kind), - }); - if let Some(Involvement { - player, - position, - speed, - warn, - .. - }) = item.active - { - out.push(PacketC::SetProgress { + for (i, item) in player.items.iter().enumerate() { + if let Some(item) = &item { + out.push(PacketC::SetItem { + location: ItemLocation::Player(id, Hand(i)), + item: Some(item.kind), + }); + if let Some(Involvement { player, - item: ItemLocation::Player(id), position, speed, warn, - }); + .. + }) = item.active + { + out.push(PacketC::SetProgress { + player, + item: ItemLocation::Player(id, Hand(i)), + position, + speed, + warn, + }); + } } } if let Some((message, timeout)) = &player.communicate_persist { @@ -252,7 +254,7 @@ impl GameServerExt for Game { self.players.insert( id, Player { - item: None, + items: (0..self.data.hand_count).map(|_| None).collect(), character, class, movement: MovementBase::new(position), @@ -403,15 +405,18 @@ impl Server { self.game.players_spatial_index.remove_entry(player); - if let Some(item) = p.item { - let pos = p.movement.position.floor().as_ivec2(); - if let Some(tile) = self.game.tiles.get_mut(&pos) { - if tile.item.is_none() { - self.packet_out.push_back(PacketC::SetItem { - location: ItemLocation::Tile(pos), - item: Some(item.kind), - }); - tile.item = Some(item); + // TODO if holding two, one is destroyed + for item in p.items { + if let Some(item) = item { + let pos = p.movement.position.floor().as_ivec2(); + if let Some(tile) = self.game.tiles.get_mut(&pos) { + if tile.item.is_none() { + self.packet_out.push_back(PacketC::SetItem { + location: ItemLocation::Tile(pos), + item: Some(item.kind), + }); + tile.item = Some(item); + } } } } @@ -449,7 +454,7 @@ impl Server { } } } - PacketS::Interact { pos, player } => { + PacketS::Interact { pos, player, hand } => { for e in &mut self.entities { if e.interact( EntityContext { @@ -477,7 +482,9 @@ impl Server { .get_mut(&pid) .ok_or(tre!("s.error.no_player"))?; - let (pos, edge) = match (pos, player.interacting) { + let pos = pos.map(|p| (p, hand)); + + let ((pos, hand), edge) = match (pos, player.interacting) { (None, None) => return Ok(()), // this is silent because of auto release (None, Some(pos)) => (pos, false), (Some(pos), None) => (pos, true), @@ -497,7 +504,7 @@ impl Server { // No going back from here on - player.interacting = if edge { Some(pos) } else { None }; + player.interacting = if edge { Some((pos, hand)) } else { None }; let other_pid = if !self.game.data.is_tile_interactable(tile.kind) { self.game @@ -523,15 +530,18 @@ impl Server { 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(hand.0).ok_or(tre!("s.error.no_hand"))?; + interact( &self.game.data, edge, None, Some(pid), - &mut this.item, - ItemLocation::Player(base_pid), - &mut other.item, - ItemLocation::Player(pid), + this_hslot, + ItemLocation::Player(base_pid, hand), + other_hslot, + ItemLocation::Player(pid, hand), &mut self.game.score, &mut self.score_changed, false, @@ -544,6 +554,11 @@ impl Server { .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"))?; + interact( &self.game.data, edge, @@ -551,8 +566,8 @@ impl Server { Some(pid), &mut tile.item, ItemLocation::Tile(pos), - &mut player.item, - ItemLocation::Player(pid), + hslot, + ItemLocation::Player(pid, hand), &mut self.game.score, &mut self.score_changed, false, @@ -592,14 +607,16 @@ impl Server { timeout, }); } - PacketS::ReplaceHand { item, player } => { + PacketS::ReplaceHand { item, player, hand } => { let pdata = self.game.players.get_mut(&player).ok_or(tre!(""))?; - pdata.item = item.map(|i| Item { - kind: i, - active: None, - }); + if let Some(slot) = pdata.items.get_mut(hand.0) { + *slot = item.map(|i| Item { + kind: i, + active: None, + }); + } self.packet_out.push_back(PacketC::SetItem { - location: ItemLocation::Player(player), + location: ItemLocation::Player(player, hand), item, }) } @@ -665,17 +682,19 @@ impl Server { rot: player.movement.rotation, }); - tick_slot( - dt, - &self.game.data, - &self.gamedata_index, - None, - &mut player.item, - ItemLocation::Player(pid), - &mut self.game.score, - &mut self.score_changed, - &mut self.packet_out, - ); + for (i, item) in player.items.iter_mut().enumerate() { + tick_slot( + dt, + &self.game.data, + &self.gamedata_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(); @@ -686,20 +705,27 @@ impl Server { player.communicate_persist = None; } } - if let Some(pos) = player.interacting { + if let Some((pos, hand)) = player.interacting { if let Some(tile) = self.game.tiles.get(&pos) { if let Some(item) = &tile.item { if let Some(involvement) = &item.active { if involvement.position >= 1. { - players_auto_release.push(*pid); + players_auto_release.push((*pid, hand)); } } } } } } - for player in players_auto_release.drain(..) { - let _ = self.packet_in(PacketS::Interact { pos: None, player }, &mut vec![]); + for (player, hand) in players_auto_release.drain(..) { + let _ = self.packet_in( + PacketS::Interact { + pos: None, + player, + hand, + }, + &mut vec![], + ); } let mut load_map = None; |