summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2024-12-25 19:37:20 +0100
committermetamuffin <metamuffin@disroot.org>2024-12-25 20:01:43 +0100
commit4083df5cfe76e42506c5356cf23d3dc9f3b6e6bf (patch)
tree5ec12de003c38f0891c215721593c7ea49ff2c16 /server
parent15be00667282a253fb438fec9d6347f5af89d9a0 (diff)
downloadhurrycurry-4083df5cfe76e42506c5356cf23d3dc9f3b6e6bf.tar
hurrycurry-4083df5cfe76e42506c5356cf23d3dc9f3b6e6bf.tar.bz2
hurrycurry-4083df5cfe76e42506c5356cf23d3dc9f3b6e6bf.tar.zst
variable hand count
Diffstat (limited to 'server')
-rw-r--r--server/bot/src/algos/customer.rs13
-rw-r--r--server/bot/src/algos/simple.rs13
-rw-r--r--server/bot/src/main.rs2
-rw-r--r--server/client-lib/src/lib.rs51
-rw-r--r--server/protocol/src/helpers.rs21
-rw-r--r--server/protocol/src/lib.rs8
-rw-r--r--server/src/data/mod.rs1
-rw-r--r--server/src/entity/bot.rs2
-rw-r--r--server/src/server.rs33
9 files changed, 75 insertions, 69 deletions
diff --git a/server/bot/src/algos/customer.rs b/server/bot/src/algos/customer.rs
index 826ab534..b0ece9dd 100644
--- a/server/bot/src/algos/customer.rs
+++ b/server/bot/src/algos/customer.rs
@@ -313,7 +313,7 @@ impl CustomerState {
PacketS::Interact {
pos: Some(pos),
player: me,
- hand: Hand::Left,
+ hand: Hand(0),
},
PacketS::ApplyScore(Score {
demands_completed: 1,
@@ -323,7 +323,7 @@ impl CustomerState {
PacketS::Interact {
pos: None,
player: me,
- hand: Hand::Left,
+ hand: Hand(0),
},
],
..Default::default()
@@ -356,7 +356,7 @@ impl CustomerState {
extra: vec![PacketS::ReplaceHand {
player: me,
item: demand.output,
- hand: Hand::Left,
+ hand: Hand(0),
}],
..Default::default()
};
@@ -375,7 +375,8 @@ impl CustomerState {
if game
.players
.get(&me)
- .is_some_and(|pl| pl.items[Hand::Left.index()].is_none())
+ .is_some_and(|pl| pl.items[0].is_none())
+ // TODO index out of bounds?
{
if let Some(path) = find_path(&game.walkable, pos.as_ivec2(), *origin) {
*self = CustomerState::Exiting { path };
@@ -390,12 +391,12 @@ impl CustomerState {
PacketS::Interact {
player: me,
pos: Some(*table),
- hand: Hand::Left,
+ hand: Hand(0),
},
PacketS::Interact {
player: me,
pos: None,
- hand: Hand::Left,
+ hand: Hand(0),
},
],
direction,
diff --git a/server/bot/src/algos/simple.rs b/server/bot/src/algos/simple.rs
index 5a7e61a0..452f59d3 100644
--- a/server/bot/src/algos/simple.rs
+++ b/server/bot/src/algos/simple.rs
@@ -21,7 +21,7 @@ use crate::{
};
use hurrycurry_client_lib::Game;
use hurrycurry_protocol::{
- glam::IVec2, Hand, ItemIndex, Message, PlayerID, Recipe, RecipeIndex, TileIndex,
+ glam::IVec2, ItemIndex, Message, PlayerID, Recipe, RecipeIndex, TileIndex,
};
use log::{debug, warn};
@@ -106,17 +106,16 @@ impl State for Simple {
impl<S> Context<'_, S> {
pub fn is_hand_item(&self, item: ItemIndex) -> bool {
- self.game.players.get(&self.me).is_some_and(|p| {
- p.items[Hand::Left.index()]
- .as_ref()
- .is_some_and(|i| i.kind == item)
- })
+ self.game
+ .players
+ .get(&self.me)
+ .is_some_and(|p| p.items[0].as_ref().is_some_and(|i| i.kind == item))
}
pub fn is_hand_occupied(&self) -> bool {
self.game
.players
.get(&self.me)
- .map(|p| p.items[Hand::Left.index()].is_some())
+ .map(|p| p.items[0].is_some())
.unwrap_or(false)
}
pub fn find_demand(&self) -> Option<(ItemIndex, IVec2)> {
diff --git a/server/bot/src/main.rs b/server/bot/src/main.rs
index 0ffbf4b6..918be7e1 100644
--- a/server/bot/src/main.rs
+++ b/server/bot/src/main.rs
@@ -109,7 +109,7 @@ fn main() -> Result<()> {
network.queue_out.push_back(PacketS::Interact {
player: b.id,
pos: interact,
- hand: Hand::Left,
+ hand: Hand(0),
})
}
network.queue_out.push_back(PacketS::Movement {
diff --git a/server/client-lib/src/lib.rs b/server/client-lib/src/lib.rs
index 54c7cd6e..a40eafc1 100644
--- a/server/client-lib/src/lib.rs
+++ b/server/client-lib/src/lib.rs
@@ -20,7 +20,8 @@ pub mod network;
pub mod spatial_index;
use hurrycurry_protocol::{
- glam::IVec2, movement::MovementBase, Gamedata, Hand, ItemIndex, ItemLocation, Message, MessageTimeout, PacketC, PlayerClass, PlayerID, RecipeIndex, Score, TileIndex
+ glam::IVec2, movement::MovementBase, Gamedata, Hand, ItemIndex, ItemLocation, Message,
+ MessageTimeout, PacketC, PlayerClass, PlayerID, RecipeIndex, Score, TileIndex,
};
use spatial_index::SpatialIndex;
use std::{
@@ -54,7 +55,7 @@ pub struct Player {
pub class: PlayerClass,
pub character: i32,
pub interacting: Option<(IVec2, Hand)>,
- pub items: [Option<Item>; 2],
+ pub items: Vec<Option<Item>>,
pub communicate_persist: Option<(Message, MessageTimeout)>,
pub movement: MovementBase,
@@ -94,7 +95,7 @@ impl Game {
character,
class,
interacting: None,
- items: [const { None }; 2],
+ items: (0..self.data.hand_count).map(|_| None).collect(),
communicate_persist: None,
movement: MovementBase::new(position),
},
@@ -116,15 +117,27 @@ impl Game {
p.movement.rotation = rot;
}
}
-
PacketC::MoveItem { from, to } => {
- *self.get_item(to) = self.get_item(from).take();
+ if let Some(item) = self.get_item(to).map(|e| e.take()) {
+ if let Some(to) = self.get_item(from) {
+ *to = item;
+ } else {
+ // TODO perhaps restore to original position?
+ }
+ }
}
PacketC::SetItem { location, item } => {
- *self.get_item(location) = item.map(|kind| Item { kind, active: None });
+ let location = self.get_item(location);
+ if let Some(location) = location {
+ *location = item.map(|kind| Item { kind, active: None });
+ }
}
PacketC::ClearProgress { item } => {
- self.get_item(item).as_mut().unwrap().active = None;
+ if let Some(slot) = self.get_item(item) {
+ if let Some(item) = slot {
+ item.active = None;
+ }
+ }
}
PacketC::SetProgress {
item,
@@ -133,13 +146,17 @@ impl Game {
speed,
warn,
} => {
- self.get_item(item).as_mut().unwrap().active = Some(Involvement {
- player,
- speed,
- warn,
- position,
- recipe: RecipeIndex(0),
- });
+ if let Some(slot) = self.get_item(item) {
+ if let Some(item) = slot {
+ item.active = Some(Involvement {
+ player,
+ speed,
+ warn,
+ position,
+ recipe: RecipeIndex(0),
+ });
+ }
+ }
}
PacketC::UpdateMap {
tile,
@@ -224,11 +241,11 @@ impl Game {
});
}
- pub fn get_item(&mut self, location: ItemLocation) -> &mut Option<Item> {
+ pub fn get_item(&mut self, location: ItemLocation) -> Option<&mut Option<Item>> {
match location {
- ItemLocation::Tile(pos) => &mut self.tiles.get_mut(&pos).unwrap().item,
+ ItemLocation::Tile(pos) => Some(&mut self.tiles.get_mut(&pos)?.item),
ItemLocation::Player(pid, hand) => {
- &mut self.players.get_mut(&pid).unwrap().items[hand.index()]
+ Some(self.players.get_mut(&pid)?.items.get_mut(hand.0)?)
}
}
}
diff --git a/server/protocol/src/helpers.rs b/server/protocol/src/helpers.rs
index 21835101..b85c2f84 100644
--- a/server/protocol/src/helpers.rs
+++ b/server/protocol/src/helpers.rs
@@ -106,26 +106,7 @@ impl Display for ItemLocation {
impl Display for Hand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.write_str(match self {
- Hand::Left => "left",
- Hand::Right => "right",
- })
- }
-}
-
-impl Hand {
- pub fn index(&self) -> usize {
- match self {
- Hand::Left => 0,
- Hand::Right => 1,
- }
- }
- pub fn from_index(i: usize) -> Self {
- match i {
- 0 => Hand::Left,
- 1 => Hand::Right,
- _ => Hand::Left,
- }
+ write!(f, "h{}", self.0)
}
}
diff --git a/server/protocol/src/lib.rs b/server/protocol/src/lib.rs
index 5c7ddeb5..74d463a1 100644
--- a/server/protocol/src/lib.rs
+++ b/server/protocol/src/lib.rs
@@ -72,11 +72,8 @@ pub struct RecipeIndex(pub usize);
pub struct DemandIndex(pub usize);
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Encode, Decode, PartialEq, Eq, Hash)]
-#[serde(rename_all = "snake_case")]
-pub enum Hand {
- Left,
- Right,
-}
+#[serde(transparent)]
+pub struct Hand(pub usize);
#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
pub struct MapMetadata {
@@ -105,6 +102,7 @@ pub struct Gamedata {
pub bot_algos: Vec<String>,
pub recipes: Vec<Recipe>,
pub demands: Vec<Demand>,
+ pub hand_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
diff --git a/server/src/data/mod.rs b/server/src/data/mod.rs
index 57051fe9..15fdfa6b 100644
--- a/server/src/data/mod.rs
+++ b/server/src/data/mod.rs
@@ -314,6 +314,7 @@ pub fn build_data(
item_names,
demands,
tile_names,
+ hand_count: 2,
},
Serverdata {
initial_map,
diff --git a/server/src/entity/bot.rs b/server/src/entity/bot.rs
index 368f8c9d..6e6c9162 100644
--- a/server/src/entity/bot.rs
+++ b/server/src/entity/bot.rs
@@ -72,7 +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::Left,
+ hand: Hand(0),
})
}
c.packet_in.push_back(PacketS::Movement {
diff --git a/server/src/server.rs b/server/src/server.rs
index 19153864..0889cd71 100644
--- a/server/src/server.rs
+++ b/server/src/server.rs
@@ -164,10 +164,9 @@ impl GameServerExt for Game {
name: player.name.clone(),
});
for (i, item) in player.items.iter().enumerate() {
- let hand = Hand::from_index(i);
if let Some(item) = &item {
out.push(PacketC::SetItem {
- location: ItemLocation::Player(id, hand),
+ location: ItemLocation::Player(id, Hand(i)),
item: Some(item.kind),
});
if let Some(Involvement {
@@ -180,7 +179,7 @@ impl GameServerExt for Game {
{
out.push(PacketC::SetProgress {
player,
- item: ItemLocation::Player(id, hand),
+ item: ItemLocation::Player(id, Hand(i)),
position,
speed,
warn,
@@ -255,7 +254,7 @@ impl GameServerExt for Game {
self.players.insert(
id,
Player {
- items: [const { None }; 2],
+ items: (0..self.data.hand_count).map(|_| None).collect(),
character,
class,
movement: MovementBase::new(position),
@@ -531,14 +530,17 @@ 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.items[hand.index()],
+ this_hslot,
ItemLocation::Player(base_pid, hand),
- &mut other.items[hand.index()],
+ other_hslot,
ItemLocation::Player(pid, hand),
&mut self.game.score,
&mut self.score_changed,
@@ -552,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,
@@ -559,7 +566,7 @@ impl Server {
Some(pid),
&mut tile.item,
ItemLocation::Tile(pos),
- &mut player.items[hand.index()],
+ hslot,
ItemLocation::Player(pid, hand),
&mut self.game.score,
&mut self.score_changed,
@@ -602,10 +609,12 @@ impl Server {
}
PacketS::ReplaceHand { item, player, hand } => {
let pdata = self.game.players.get_mut(&player).ok_or(tre!(""))?;
- pdata.items[hand.index()] = 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, hand),
item,
@@ -680,7 +689,7 @@ impl Server {
&self.gamedata_index,
None,
item,
- ItemLocation::Player(pid, Hand::from_index(i)),
+ ItemLocation::Player(pid, Hand(i)),
&mut self.game.score,
&mut self.score_changed,
&mut self.packet_out,