mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
inventory/container tracking works
This commit is contained in:
parent
e43cbc09c2
commit
8db5b81f4c
9 changed files with 84 additions and 14 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -309,6 +309,7 @@ dependencies = [
|
|||
"azalea-buf",
|
||||
"azalea-chat",
|
||||
"azalea-nbt",
|
||||
"azalea-registry",
|
||||
"bevy_ecs",
|
||||
"uuid",
|
||||
]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pub use crate::chat::ChatPacket;
|
||||
use crate::{
|
||||
events::{Event, EventPlugin, LocalPlayerEvents},
|
||||
inventory::InventoryComponent,
|
||||
inventory::{InventoryComponent, InventoryPlugin},
|
||||
local_player::{
|
||||
death_event, update_in_loaded_chunk, GameProfileComponent, LocalPlayer, PhysicsState,
|
||||
},
|
||||
|
@ -575,5 +575,6 @@ impl PluginGroup for DefaultPlugins {
|
|||
.add(PhysicsPlugin)
|
||||
.add(EventPlugin)
|
||||
.add(TaskPoolPlugin::default())
|
||||
.add(InventoryPlugin)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,21 @@
|
|||
use azalea_core::Slot;
|
||||
use azalea_ecs::component::Component;
|
||||
use azalea_ecs::{
|
||||
app::{App, Plugin},
|
||||
component::Component,
|
||||
entity::Entity,
|
||||
event::EventReader,
|
||||
system::Query,
|
||||
};
|
||||
use azalea_inventory::Menu;
|
||||
|
||||
pub struct InventoryPlugin;
|
||||
impl Plugin for InventoryPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_event::<ClientSideCloseContainerEvent>()
|
||||
.add_system(handle_client_side_close_container_event);
|
||||
}
|
||||
}
|
||||
|
||||
/// A component present on all local players that have an inventory.
|
||||
#[derive(Component)]
|
||||
pub struct InventoryComponent {
|
||||
|
@ -34,7 +48,19 @@ impl InventoryComponent {
|
|||
/// Returns the currently active menu. If a container is open it'll return
|
||||
/// [`Self::container_menu`], otherwise [`Self::inventory_menu`].
|
||||
pub fn menu(&self) -> &azalea_inventory::Menu {
|
||||
&self.container_menu.unwrap_or(self.inventory_menu)
|
||||
if let Some(menu) = &self.container_menu {
|
||||
menu
|
||||
} else {
|
||||
&self.inventory_menu
|
||||
}
|
||||
}
|
||||
|
||||
pub fn menu_mut(&mut self) -> &mut azalea_inventory::Menu {
|
||||
if let Some(menu) = &mut self.container_menu {
|
||||
menu
|
||||
} else {
|
||||
&mut self.inventory_menu
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Default for InventoryComponent {
|
||||
|
@ -48,3 +74,20 @@ impl Default for InventoryComponent {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Close a container without notifying the server.
|
||||
///
|
||||
/// Note that this also gets fired from [`CloseContainerEvent`].
|
||||
pub struct ClientSideCloseContainerEvent {
|
||||
pub entity: Entity,
|
||||
}
|
||||
fn handle_client_side_close_container_event(
|
||||
mut events: EventReader<ClientSideCloseContainerEvent>,
|
||||
mut query: Query<&mut InventoryComponent>,
|
||||
) {
|
||||
for event in events.iter() {
|
||||
let mut inventory = query.get_mut(event.entity).unwrap();
|
||||
inventory.container_menu = None;
|
||||
inventory.id = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ use parking_lot::Mutex;
|
|||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::{
|
||||
inventory::InventoryComponent,
|
||||
inventory::{ClientSideCloseContainerEvent, InventoryComponent},
|
||||
local_player::{GameProfileComponent, LocalPlayer},
|
||||
ChatPacket, ClientInformation, PlayerInfo,
|
||||
};
|
||||
|
@ -634,7 +634,7 @@ fn handle_packets(ecs: &mut Ecs) {
|
|||
}
|
||||
}
|
||||
} else if inventory.id == p.container_id {
|
||||
let mut menu = inventory.menu();
|
||||
let menu = inventory.menu_mut();
|
||||
for (i, slot) in p.items.iter().enumerate() {
|
||||
if let Some(slot_mut) = menu.slot_mut(i) {
|
||||
*slot_mut = slot.clone();
|
||||
|
@ -644,6 +644,17 @@ fn handle_packets(ecs: &mut Ecs) {
|
|||
}
|
||||
ClientboundGamePacket::ContainerSetData(p) => {
|
||||
debug!("Got container set data packet {:?}", p);
|
||||
// let mut system_state: SystemState<Query<&mut
|
||||
// InventoryComponent>> =
|
||||
// SystemState::new(ecs);
|
||||
// let mut query = system_state.get_mut(ecs);
|
||||
// let mut inventory =
|
||||
// query.get_mut(player_entity).unwrap();
|
||||
|
||||
// TODO: handle ContainerSetData packet
|
||||
// this is used for various things like the furnace progress
|
||||
// bar
|
||||
// see https://wiki.vg/Protocol#Set_Container_Property
|
||||
}
|
||||
ClientboundGamePacket::ContainerSetSlot(p) => {
|
||||
debug!("Got container set slot packet {:?}", p);
|
||||
|
@ -657,7 +668,7 @@ fn handle_packets(ecs: &mut Ecs) {
|
|||
// -1 means carried item
|
||||
inventory.carried = p.item_stack.clone();
|
||||
} else if p.container_id == -2 {
|
||||
if let Some(mut slot) = inventory.inventory_menu.slot_mut(p.slot.into()) {
|
||||
if let Some(slot) = inventory.inventory_menu.slot_mut(p.slot.into()) {
|
||||
*slot = p.item_stack.clone();
|
||||
}
|
||||
} else {
|
||||
|
@ -675,11 +686,23 @@ fn handle_packets(ecs: &mut Ecs) {
|
|||
} else if p.container_id == inventory.id
|
||||
&& (p.container_id != 0 || !is_creative_mode_and_inventory_closed)
|
||||
{
|
||||
var2.containerMenu.setItem(var4, var1.getStateId(), var3);
|
||||
// var2.containerMenu.setItem(var4, var1.getStateId(), var3);
|
||||
if let Some(slot) = inventory.menu_mut().slot_mut(p.slot.into()) {
|
||||
*slot = p.item_stack.clone();
|
||||
inventory.state_id = p.state_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ClientboundGamePacket::ContainerClose(_) => {}
|
||||
ClientboundGamePacket::ContainerClose(_p) => {
|
||||
// there's p.container_id but minecraft doesn't actually check it
|
||||
let mut system_state: SystemState<EventWriter<ClientSideCloseContainerEvent>> =
|
||||
SystemState::new(ecs);
|
||||
let mut client_side_close_container_events = system_state.get_mut(ecs);
|
||||
client_side_close_container_events.send(ClientSideCloseContainerEvent {
|
||||
entity: player_entity,
|
||||
})
|
||||
}
|
||||
ClientboundGamePacket::SetHealth(p) => {
|
||||
debug!("Got set health packet {:?}", p);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ version = "0.5.0"
|
|||
azalea-buf = {path = "../azalea-buf", version = "^0.5.0"}
|
||||
azalea-chat = {path = "../azalea-chat", version = "^0.5.0"}
|
||||
azalea-nbt = {path = "../azalea-nbt", version = "^0.5.0"}
|
||||
azalea-registry = {path = "../azalea-registry", version = "^0.5.0"}
|
||||
bevy_ecs = {version = "0.9.1", default-features = false, optional = true}
|
||||
uuid = "^1.1.2"
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ pub enum Slot {
|
|||
|
||||
#[derive(Debug, Clone, McBuf)]
|
||||
pub struct SlotData {
|
||||
#[var]
|
||||
pub id: u32,
|
||||
pub id: azalea_registry::Item,
|
||||
pub count: u8,
|
||||
pub nbt: Tag,
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ pub fn generate(input: &DeclareMenus) -> TokenStream {
|
|||
#player_fields
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Menu {
|
||||
Player(Player),
|
||||
#variants
|
||||
|
|
|
@ -3,7 +3,7 @@ use azalea_protocol_macros::ClientboundGamePacket;
|
|||
|
||||
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
|
||||
pub struct ClientboundContainerSetDataPacket {
|
||||
pub container_id: u8,
|
||||
pub container_id: i8,
|
||||
pub id: u16,
|
||||
pub value: u16,
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use azalea::ecs::query::With;
|
||||
use azalea::entity::metadata::Player;
|
||||
use azalea::entity::Position;
|
||||
use azalea::inventory::InventoryMenu;
|
||||
use azalea::inventory::InventoryComponent;
|
||||
use azalea::pathfinder::BlockPosGoal;
|
||||
use azalea::{prelude::*, BlockPos, GameProfileComponent, Swarm, SwarmEvent, WalkDirection};
|
||||
use azalea::{Account, Client, Event};
|
||||
|
@ -144,8 +144,9 @@ async fn handle(mut bot: Client, event: Event, _state: State) -> anyhow::Result<
|
|||
std::thread::sleep(Duration::from_millis(1000));
|
||||
}
|
||||
"inventory" => {
|
||||
let inventory = bot.component::<InventoryMenu>();
|
||||
println!("inventory: {inventory:?}");
|
||||
let mut ecs = bot.ecs.lock();
|
||||
let inventory = bot.query::<&InventoryComponent>(&mut ecs);
|
||||
println!("inventory: {:?}", inventory.menu());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue