Skip to content

Commit

Permalink
Add HeldItem::set_slot (#525)
Browse files Browse the repository at this point in the history
# Objective

This PR adds functionality to allow the server to change the users
selected hotbar slot using `HeldItem::set_slot(36..44)`

---------

Co-authored-by: Carson McManus <[email protected]>
  • Loading branch information
AviiNL and dyc3 authored Sep 8, 2023
1 parent 1ddde71 commit c3d112d
Showing 1 changed file with 26 additions and 1 deletion.
27 changes: 26 additions & 1 deletion crates/valence_inventory/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub use valence_server::protocol::packets::play::player_action_c2s::PlayerAction
use valence_server::protocol::packets::play::{
ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s, InventoryS2c,
OpenScreenS2c, PlayerActionC2s, ScreenHandlerSlotUpdateS2c, UpdateSelectedSlotC2s,
UpdateSelectedSlotS2c,
};
use valence_server::protocol::{VarInt, WritePacket};
use valence_server::text::IntoText;
Expand All @@ -54,6 +55,7 @@ impl Plugin for InventoryPlugin {
PostUpdate,
(
update_client_on_close_inventory.before(update_open_inventories),
update_player_selected_slot,
update_open_inventories,
update_player_inventories,
)
Expand Down Expand Up @@ -405,6 +407,16 @@ impl HeldItem {
pub fn slot(&self) -> u16 {
self.held_item_slot
}

pub fn set_slot(&mut self, slot: u16) {
// temp
assert!(
(36..=44).contains(&slot),
"slot index of {slot} out of bounds"
);

self.held_item_slot = slot;
}
}

/// The item stack that the client thinks it's holding under the mouse
Expand Down Expand Up @@ -1216,18 +1228,31 @@ pub struct UpdateSelectedSlotEvent {
pub slot: u8,
}

/// Handles the `HeldItem` component being changed on a client entity, which
/// indicates that the server has changed the selected hotbar slot.
fn update_player_selected_slot(mut clients: Query<(&mut Client, &HeldItem), Changed<HeldItem>>) {
for (mut client, held_item) in &mut clients {
client.write_packet(&UpdateSelectedSlotS2c {
slot: (held_item.held_item_slot - PLAYER_INVENTORY_MAIN_SLOTS_COUNT) as u8,
});
}
}

/// Client to Server HeldItem Slot
fn handle_update_selected_slot(
mut packets: EventReader<PacketEvent>,
mut clients: Query<&mut HeldItem>,
mut events: EventWriter<UpdateSelectedSlotEvent>,
) {
for packet in packets.iter() {
if let Some(pkt) = packet.decode::<UpdateSelectedSlotC2s>() {
if let Ok(mut held) = clients.get_mut(packet.client) {
if let Ok(mut mut_held) = clients.get_mut(packet.client) {
let held = mut_held.bypass_change_detection();
if pkt.slot > 8 {
// The client is trying to interact with a slot that does not exist, ignore.
continue;
}

held.held_item_slot = convert_hotbar_slot_id(pkt.slot);

events.send(UpdateSelectedSlotEvent {
Expand Down

0 comments on commit c3d112d

Please sign in to comment.