mirror of
https://github.com/italicsjenga/valence.git
synced 2024-12-24 06:51:30 +11:00
refactor handle_click_slot to primarily emit ClickSlot events, and handle those in a new system
This commit is contained in:
parent
6338fc6300
commit
475639dec0
|
@ -25,6 +25,7 @@ use std::ops::Range;
|
||||||
|
|
||||||
use bevy_app::prelude::*;
|
use bevy_app::prelude::*;
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
|
use menu::OpenMenu;
|
||||||
use packet::{
|
use packet::{
|
||||||
ClickMode, ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s,
|
ClickMode, ClickSlotC2s, CloseHandledScreenC2s, CloseScreenS2c, CreativeInventoryActionC2s,
|
||||||
InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s,
|
InventoryS2c, OpenScreenS2c, ScreenHandlerSlotUpdateS2c, SlotChange, UpdateSelectedSlotC2s,
|
||||||
|
@ -40,6 +41,7 @@ use valence_core::protocol::encode::WritePacket;
|
||||||
use valence_core::protocol::var_int::VarInt;
|
use valence_core::protocol::var_int::VarInt;
|
||||||
use valence_core::text::Text;
|
use valence_core::text::Text;
|
||||||
|
|
||||||
|
pub mod menu;
|
||||||
pub mod packet;
|
pub mod packet;
|
||||||
mod validate;
|
mod validate;
|
||||||
|
|
||||||
|
@ -65,7 +67,8 @@ impl Plugin for InventoryPlugin {
|
||||||
.add_systems(
|
.add_systems(
|
||||||
(
|
(
|
||||||
handle_update_selected_slot,
|
handle_update_selected_slot,
|
||||||
handle_click_slot,
|
emit_events_from_packets,
|
||||||
|
handle_click_slot.after(emit_events_from_packets),
|
||||||
handle_creative_inventory_action,
|
handle_creative_inventory_action,
|
||||||
handle_close_handled_screen,
|
handle_close_handled_screen,
|
||||||
handle_player_actions,
|
handle_player_actions,
|
||||||
|
@ -332,11 +335,11 @@ pub struct ClientInventoryState {
|
||||||
state_id: Wrapping<i32>,
|
state_id: Wrapping<i32>,
|
||||||
/// Tracks what slots have been changed by this client in this tick, so we
|
/// Tracks what slots have been changed by this client in this tick, so we
|
||||||
/// don't need to send updates for them.
|
/// don't need to send updates for them.
|
||||||
slots_changed: u64,
|
pub(crate) slots_changed: u64,
|
||||||
/// Whether the client has updated the cursor item in this tick. This is not
|
/// Whether the client has updated the cursor item in this tick. This is not
|
||||||
/// on the `CursorItem` component to make maintaining accurate change
|
/// on the `CursorItem` component to make maintaining accurate change
|
||||||
/// detection for end users easier.
|
/// detection for end users easier.
|
||||||
client_updated_cursor_item: bool,
|
pub(crate) client_updated_cursor_item: bool,
|
||||||
// TODO: make this a separate modifiable component.
|
// TODO: make this a separate modifiable component.
|
||||||
held_item_slot: u16,
|
held_item_slot: u16,
|
||||||
}
|
}
|
||||||
|
@ -754,7 +757,7 @@ pub struct DropItemStack {
|
||||||
pub stack: ItemStack,
|
pub stack: ItemStack,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_click_slot(
|
fn emit_events_from_packets(
|
||||||
mut packets: EventReader<PacketEvent>,
|
mut packets: EventReader<PacketEvent>,
|
||||||
mut clients: Query<(
|
mut clients: Query<(
|
||||||
&mut Client,
|
&mut Client,
|
||||||
|
@ -969,22 +972,6 @@ fn handle_click_slot(
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_item.set_if_neq(CursorItem(pkt.carried_item.clone()));
|
|
||||||
|
|
||||||
for slot in pkt.slot_changes.clone() {
|
|
||||||
if (0i16..target_inventory.slot_count() as i16).contains(&slot.idx) {
|
|
||||||
// The client is interacting with a slot in the target inventory.
|
|
||||||
target_inventory.set_slot(slot.idx as u16, slot.item);
|
|
||||||
open_inventory.client_changed |= 1 << slot.idx;
|
|
||||||
} else {
|
|
||||||
// The client is interacting with a slot in their own inventory.
|
|
||||||
let slot_id =
|
|
||||||
convert_to_player_slot_id(target_inventory.kind, slot.idx as u16);
|
|
||||||
client_inv.set_slot(slot_id, slot.item);
|
|
||||||
inv_state.slots_changed |= 1 << slot_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// The client is interacting with their own inventory.
|
// The client is interacting with their own inventory.
|
||||||
|
|
||||||
|
@ -1004,23 +991,6 @@ fn handle_click_slot(
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor_item.set_if_neq(CursorItem(pkt.carried_item.clone()));
|
|
||||||
inv_state.client_updated_cursor_item = true;
|
|
||||||
|
|
||||||
for slot in pkt.slot_changes.clone() {
|
|
||||||
if (0i16..client_inv.slot_count() as i16).contains(&slot.idx) {
|
|
||||||
client_inv.set_slot(slot.idx as u16, slot.item);
|
|
||||||
inv_state.slots_changed |= 1 << slot.idx;
|
|
||||||
} else {
|
|
||||||
// The client is trying to interact with a slot that does not exist,
|
|
||||||
// ignore.
|
|
||||||
warn!(
|
|
||||||
"Client attempted to interact with slot {} which does not exist",
|
|
||||||
slot.idx
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
click_slot_events.send(ClickSlot {
|
click_slot_events.send(ClickSlot {
|
||||||
|
@ -1037,6 +1007,75 @@ fn handle_click_slot(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_click_slot(
|
||||||
|
mut click_slots: EventReader<ClickSlot>,
|
||||||
|
mut clients: Query<(
|
||||||
|
&mut Client,
|
||||||
|
&mut Inventory,
|
||||||
|
&mut ClientInventoryState,
|
||||||
|
Option<&mut OpenInventory>,
|
||||||
|
&mut CursorItem,
|
||||||
|
)>,
|
||||||
|
mut inventories: Query<&mut Inventory, Without<Client>>,
|
||||||
|
) {
|
||||||
|
for click in click_slots.iter() {
|
||||||
|
// The player is clicking a slot in an inventory.
|
||||||
|
let Ok((
|
||||||
|
mut client,
|
||||||
|
mut client_inv,
|
||||||
|
mut inv_state,
|
||||||
|
open_inventory,
|
||||||
|
mut cursor_item
|
||||||
|
)) = clients.get_mut(click.client) else {
|
||||||
|
// The client does not exist, ignore.
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(mut open_inventory) = open_inventory {
|
||||||
|
// The player is interacting with an inventory that is open.
|
||||||
|
|
||||||
|
let Ok(mut target_inventory) = inventories.get_mut(open_inventory.entity) else {
|
||||||
|
// The inventory does not exist, ignore.
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
cursor_item.set_if_neq(CursorItem(click.carried_item.clone()));
|
||||||
|
inv_state.client_updated_cursor_item = true;
|
||||||
|
|
||||||
|
for slot in click.slot_changes.clone() {
|
||||||
|
if (0i16..target_inventory.slot_count() as i16).contains(&slot.idx) {
|
||||||
|
// The client is interacting with a slot in the target inventory.
|
||||||
|
target_inventory.set_slot(slot.idx as u16, slot.item);
|
||||||
|
open_inventory.client_changed |= 1 << slot.idx;
|
||||||
|
} else {
|
||||||
|
// The client is interacting with a slot in their own inventory.
|
||||||
|
let slot_id = convert_to_player_slot_id(target_inventory.kind, slot.idx as u16);
|
||||||
|
client_inv.set_slot(slot_id, slot.item);
|
||||||
|
inv_state.slots_changed |= 1 << slot_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The client is interacting with their own inventory.
|
||||||
|
cursor_item.set_if_neq(CursorItem(click.carried_item.clone()));
|
||||||
|
inv_state.client_updated_cursor_item = true;
|
||||||
|
|
||||||
|
for slot in click.slot_changes.clone() {
|
||||||
|
if (0i16..client_inv.slot_count() as i16).contains(&slot.idx) {
|
||||||
|
client_inv.set_slot(slot.idx as u16, slot.item);
|
||||||
|
inv_state.slots_changed |= 1 << slot.idx;
|
||||||
|
} else {
|
||||||
|
// The client is trying to interact with a slot that does not exist,
|
||||||
|
// ignore.
|
||||||
|
warn!(
|
||||||
|
"Client attempted to interact with slot {} which does not exist",
|
||||||
|
slot.idx
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_player_actions(
|
fn handle_player_actions(
|
||||||
mut packets: EventReader<PacketEvent>,
|
mut packets: EventReader<PacketEvent>,
|
||||||
mut clients: Query<(&mut Inventory, &mut ClientInventoryState)>,
|
mut clients: Query<(&mut Inventory, &mut ClientInventoryState)>,
|
||||||
|
|
Loading…
Reference in a new issue