Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HeldItem::set_slot #525

Merged
merged 4 commits into from
Sep 8, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The packet seems to be using 0..8 https://wiki.vg/Protocol#Set_Held_Item

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am aware that the packet uses 0..8, the reason why i'm not using it here is to keep it consistent with the slot() return value, which is 36..44, and changing that is out of scope of this PR imo and backwards-compat breaking. (see line 684 where it gets converted)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea right, weird, but not the scope of the pr

"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
Loading