aboutsummaryrefslogtreecommitdiff
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
parent15be00667282a253fb438fec9d6347f5af89d9a0 (diff)
downloadhurrycurry-4083df5cfe76e42506c5356cf23d3dc9f3b6e6bf.tar
hurrycurry-4083df5cfe76e42506c5356cf23d3dc9f3b6e6bf.tar.bz2
hurrycurry-4083df5cfe76e42506c5356cf23d3dc9f3b6e6bf.tar.zst
variable hand count
-rw-r--r--client/game.gd14
-rw-r--r--client/global.gd9
-rw-r--r--client/multiplayer.gd3
-rw-r--r--client/player/controllable_player.gd12
-rw-r--r--client/player/player.gd31
-rw-r--r--locale/en.ini1
-rw-r--r--pixel-client/src/game.rs50
-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
16 files changed, 144 insertions, 120 deletions
diff --git a/client/game.gd b/client/game.gd
index 9a6b8808..9502d2fc 100644
--- a/client/game.gd
+++ b/client/game.gd
@@ -144,13 +144,13 @@ func handle_packet(p):
player_instance.position_ = last_position
"move_item":
if "player" in p.from and "player" in p.to:
- players[p.from.player[0]].pass_to(players[p.to.player[0]], p.from.player[1], p.to.player[1])
+ players[p.from.player[0]].pass_to(players[p.to.player[0]], int(p.from.player[1]), int(p.to.player[1]))
elif "tile" in p.from and "player" in p.to:
var t: Tile = map.get_tile_instance(p.from.tile)
- players[p.to.player[0]].take_item(t, p.to.player[1])
+ players[p.to.player[0]].take_item(t, int(p.to.player[1]))
elif "player" in p.from and "tile" in p.to:
var t: Tile = map.get_tile_instance(p.to.tile)
- players[p.from.player[0]].put_item(t, p.from.player[1])
+ players[p.from.player[0]].put_item(t, int(p.from.player[1]))
elif "tile" in p.from and "tile" in p.to:
var from_tile2: Tile = map.get_tile_instance(p.from.tile)
var to_tile2: Tile = map.get_tile_instance(p.to.tile)
@@ -160,13 +160,13 @@ func handle_packet(p):
var t: Tile = map.get_tile_instance(p.item.tile)
t.progress(p.position, p.speed, p.warn, players.get(p.player))
else:
- players[p.item.player[0]].progress(p.position, p.speed, p.warn, p.item.player[1])
+ players[p.item.player[0]].progress(p.position, p.speed, p.warn, int(p.item.player[1]))
"clear_progress":
if "tile" in p.item:
var t: Tile = map.get_tile_instance(p.item.tile)
t.finish()
else:
- players[p.item.player[0]].finish(p.item.player[1])
+ players[p.item.player[0]].finish(int(p.item.player[1]))
"set_item":
var location: Dictionary = p["location"]
if p.item != null:
@@ -180,8 +180,8 @@ func handle_packet(p):
else:
var pl: Player = players[p.location.player[0]]
var h = p.location.player[1]
- var i = ItemFactory.produce(item_names[p.item], pl.hand_base[G.hand_to_index(h)])
- i.position = pl.hand_base[G.hand_to_index(h)].global_position
+ var i = ItemFactory.produce(item_names[p.item], pl.hand_base[h])
+ i.position = pl.hand_base[h].global_position
add_child(i)
i.name = item_names[p.item]
pl.set_item(i, h)
diff --git a/client/global.gd b/client/global.gd
index ce24f85d..93c73e13 100644
--- a/client/global.gd
+++ b/client/global.gd
@@ -269,7 +269,8 @@ func configure_viewport_aa(vp: Viewport, aa: String) -> void:
vp.msaa_3d = Viewport.MSAA_4X
vp.screen_space_aa = Viewport.SCREEN_SPACE_AA_DISABLED
-static func hand_to_index(h):
- match h:
- "left": return 0
- "right": return 1
+static func index_to_hand(i):
+ match i:
+ 0: return "left"
+ 1: return "right"
+ _: return "unknown"
diff --git a/client/multiplayer.gd b/client/multiplayer.gd
index 14eaf482..11a5bd84 100644
--- a/client/multiplayer.gd
+++ b/client/multiplayer.gd
@@ -66,6 +66,7 @@ func fix_packet_types(val):
if typeof(val[k]) == TYPE_ARRAY and val[k].size() == 2 and typeof(val[k][0]) == TYPE_FLOAT and typeof(val[k][1]) == TYPE_FLOAT:
if k in ["tile"]: newval[k] = Vector2i(val[k][0], val[k][1])
elif k in ["pos", "position"]: newval[k] = Vector2(val[k][0], val[k][1])
+ else: newval[k] = val[k]
# TODO reenable when fixed
# elif k in ["player", "id"] and typeof(val[k]) == TYPE_FLOAT:
# newval[k] = int(val[k])
@@ -106,7 +107,7 @@ func send_movement(player, pos: Vector2, direction: Vector2, boost: bool):
"boost": boost
})
-func send_tile_interact(player, pos: Vector2i, edge: bool, hand: String):
+func send_tile_interact(player, pos: Vector2i, edge: bool, hand: int):
@warning_ignore("incompatible_ternary")
send_packet({
"type": "interact",
diff --git a/client/player/controllable_player.gd b/client/player/controllable_player.gd
index d241bc2e..99625762 100644
--- a/client/player/controllable_player.gd
+++ b/client/player/controllable_player.gd
@@ -190,13 +190,13 @@ func _on_vibration_timeout():
Input.vibrate_handheld(100, vibration_strength)
vibration_timer.start()
-func put_item(tile: Tile, h):
+func put_item(tile: Tile, h: int):
super(tile, h)
if Global.get_setting("gameplay.vibration"):
Input.start_joy_vibration(0, 0.1, 0.0, 0.075)
Input.vibrate_handheld(75, 0.1)
-func take_item(tile: Tile, h):
+func take_item(tile: Tile, h: int):
super(tile, h)
if Global.get_setting("gameplay.vibration"):
Input.start_joy_vibration(0, 0.1, 0.0, 0.075)
@@ -210,18 +210,18 @@ func interact():
# clear last interaction if target has moved since
if last_interaction != null and not last_interaction == target:
- game.mp.send_tile_interact(game.player_id, last_interaction, false, "left")
+ game.mp.send_tile_interact(game.player_id, last_interaction, false, 0)
marker.set_interacting(false)
last_interaction = null
marker.set_interactive(game.get_tile_interactive(target))
marker_target = tile.item_base.global_position
- for h in ["left", "right"]:
- if Input.is_action_just_pressed("interact_"+h) and last_interaction == null:
+ for h in [0, 1]:
+ if Input.is_action_just_pressed("interact_"+G.index_to_hand(h)) and last_interaction == null:
last_interaction = target
game.mp.send_tile_interact(game.player_id, target, true, h)
tile.interact()
marker.set_interacting(true)
- if Input.is_action_just_released("interact_"+h):
+ if Input.is_action_just_released("interact_"+G.index_to_hand(h)):
last_interaction = null
game.mp.send_tile_interact(game.player_id, target, false, h)
marker.set_interacting(false)
diff --git a/client/player/player.gd b/client/player/player.gd
index 223d2c88..39b9fb3e 100644
--- a/client/player/player.gd
+++ b/client/player/player.gd
@@ -50,6 +50,7 @@ var current_item_message = null
var _anim_angle: float = 0.0
var hand_base_position = [DEFAULT_HAND_BASE_POSITION_LEFT, DEFAULT_HAND_BASE_POSITION_RIGHT]
+const DEFAULT_HAND_BASE_POSITION_BOTH: Vector3 = Vector3(0, .425, .4)
const DEFAULT_HAND_BASE_POSITION_LEFT: Vector3 = Vector3(.3, .425, .4)
const DEFAULT_HAND_BASE_POSITION_RIGHT: Vector3 = Vector3(-.3, .425, .4)
@@ -100,42 +101,42 @@ func update_username_tag(state):
tag.text = username
tag.visible = state
-func set_item(i: Item, h):
- if hand[G.hand_to_index(h)] != null: hand[G.hand_to_index(h)].remove()
+func set_item(i: Item, h: int):
+ if hand[h] != null: hand[h].remove()
if i != null:
@warning_ignore("static_called_on_instance")
hand_base_position[0] = DEFAULT_HAND_BASE_POSITION_LEFT - Vector3(0.,i.height() * 0.5, 0.)
@warning_ignore("static_called_on_instance")
hand_base_position[1] = DEFAULT_HAND_BASE_POSITION_RIGHT - Vector3(0.,i.height() * 0.5, 0.)
character.holding = i != null
- hand[G.hand_to_index(h)] = i
- if hand[G.hand_to_index(h)] != null: hand[G.hand_to_index(h)].owned_by = hand_base[G.hand_to_index(h)]
+ hand[h] = i
+ if hand[h] != null: hand[h].owned_by = hand_base[h]
-func remove_item(h):
- var i = hand[G.hand_to_index(h)]
+func remove_item(h: int):
+ var i = hand[h]
if i == null: push_error("holding nothing")
- hand[G.hand_to_index(h)] = null
+ hand[h] = null
character.holding = false
return i
-func progress(position__: float, speed: float, warn: bool, h):
- if hand[G.hand_to_index(h)] != null: hand[G.hand_to_index(h)].progress(position__, speed, warn)
+func progress(position__: float, speed: float, warn: bool, h: int):
+ if hand[h] != null: hand[h].progress(position__, speed, warn)
-func finish(h):
- if hand[G.hand_to_index(h)] != null: hand[G.hand_to_index(h)].finish()
+func finish(h: int):
+ if hand[h] != null: hand[h].finish()
-func take_item(tile: Tile, h):
- if hand[G.hand_to_index(h)] != null: push_error("already holding an item")
+func take_item(tile: Tile, h: int):
+ if hand[h] != null: push_error("already holding an item")
var i = tile.take_item()
i.take()
set_item(i, h)
-func put_item(tile: Tile, h):
+func put_item(tile: Tile, h: int):
var i = remove_item(h)
i.put()
tile.put_item(i)
-func pass_to(player: Player, hfrom, hto):
+func pass_to(player: Player, hfrom: int, hto: int):
var i = remove_item(hfrom)
i.player_owned_timer = 0
if player.hand != null:
diff --git a/locale/en.ini b/locale/en.ini
index c99b8e31..041e79bc 100644
--- a/locale/en.ini
+++ b/locale/en.ini
@@ -223,6 +223,7 @@ s.error.must_be_alone=You must be alone in this server to reload
s.error.no_info=No information available.
s.error.no_player=Player does not exist.
s.error.no_tile=Tile does not exist.
+s.error.no_hand=Hand does not exist.
s.error.packet_not_supported=Packet not supported in this session.
s.error.packet_sender_invalid=Packet sent to a player that is not owned by this connection.
s.error.quoting_invalid=Command quoting invalid
diff --git a/pixel-client/src/game.rs b/pixel-client/src/game.rs
index 4dc43b72..cbcc62d5 100644
--- a/pixel-client/src/game.rs
+++ b/pixel-client/src/game.rs
@@ -156,13 +156,13 @@ impl Game {
self.network.queue_out.push_back(PacketS::Interact {
player: self.my_id,
pos: Some(self.players[&self.my_id].movement.get_interact_target()),
- hand: Hand::Left,
+ hand: Hand(0),
});
} else {
self.network.queue_out.push_back(PacketS::Interact {
player: self.my_id,
pos: None,
- hand: Hand::Left,
+ hand: Hand(0),
});
}
self.interacting = interact;
@@ -331,19 +331,23 @@ impl Game {
}
}
PacketC::MoveItem { from, to } => {
- let mut item = self.get_item(from).take();
+ let mut item = self.get_item(from).unwrap().take();
if let Some(item) = &mut item {
item.parent_position = self.get_location_position(to);
}
- *self.get_item(to) = item;
+ *self.get_item(to).unwrap() = item;
}
PacketC::SetItem { location, item } => {
let position = self.get_location_position(location);
let slot = match location {
ItemLocation::Tile(pos) => &mut self.tiles.get_mut(&pos).unwrap().item,
- ItemLocation::Player(pid, hand) => {
- &mut self.players.get_mut(&pid).unwrap().items[hand.index()]
- }
+ ItemLocation::Player(pid, hand) => self
+ .players
+ .get_mut(&pid)
+ .unwrap()
+ .items
+ .get_mut(hand.0)
+ .unwrap(),
};
self.items_removed.extend(slot.take());
*slot = item.map(|kind| Item {
@@ -354,7 +358,13 @@ impl Game {
active: None,
})
}
- PacketC::ClearProgress { item } => self.get_item(item).as_mut().unwrap().active = None,
+ PacketC::ClearProgress { item } => {
+ if let Some(slot) = self.get_item(item) {
+ if let Some(item) = slot {
+ item.active = None;
+ }
+ }
+ }
PacketC::SetProgress {
item,
position,
@@ -362,13 +372,17 @@ impl Game {
player,
warn,
} => {
- self.get_item(item).as_mut().unwrap().active = Some(Involvement {
- position,
- speed,
- player,
- warn,
- recipe: RecipeIndex(0),
- });
+ if let Some(slot) = self.get_item(item) {
+ if let Some(item) = slot {
+ item.active = Some(Involvement {
+ position,
+ speed,
+ player,
+ warn,
+ recipe: RecipeIndex(0),
+ });
+ }
+ }
}
PacketC::ServerMessage { .. } => {
// TODO
@@ -392,11 +406,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/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,