1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

add clip function

This commit is contained in:
mat 2023-03-11 21:09:34 -06:00
parent b70d9aa489
commit 34f647781f
31 changed files with 298 additions and 126 deletions

8
Cargo.lock generated
View file

@ -319,6 +319,7 @@ version = "0.6.0"
dependencies = [
"azalea-buf",
"azalea-chat",
"azalea-inventory",
"azalea-nbt",
"azalea-registry",
"bevy_ecs",
@ -346,8 +347,10 @@ dependencies = [
name = "azalea-inventory"
version = "0.1.0"
dependencies = [
"azalea-core",
"azalea-buf",
"azalea-inventory-macros",
"azalea-nbt",
"azalea-registry",
]
[[package]]
@ -389,6 +392,7 @@ version = "0.6.0"
dependencies = [
"azalea-block",
"azalea-core",
"azalea-inventory",
"azalea-registry",
"azalea-world",
"bevy_app",
@ -413,6 +417,7 @@ dependencies = [
"azalea-chat",
"azalea-core",
"azalea-crypto",
"azalea-inventory",
"azalea-nbt",
"azalea-protocol-macros",
"azalea-registry",
@ -471,6 +476,7 @@ dependencies = [
"azalea-buf",
"azalea-chat",
"azalea-core",
"azalea-inventory",
"azalea-nbt",
"azalea-registry",
"bevy_app",

View file

@ -1,5 +1,4 @@
use azalea_core::Slot;
use azalea_inventory::Menu;
use azalea_inventory::{ItemSlot, Menu};
use bevy_app::{App, Plugin};
use bevy_ecs::{component::Component, entity::Entity, event::EventReader, system::Query};
@ -31,7 +30,7 @@ pub struct InventoryComponent {
pub container_menu: Option<azalea_inventory::Menu>,
/// The item that is currently held by the cursor. `Slot::Empty` if nothing
/// is currently being held.
pub carried: Slot,
pub carried: ItemSlot,
/// An identifier used by the server to track client inventory desyncs.
pub state_id: u32,
// minecraft also has these fields, but i don't need they're necessary?:
@ -65,7 +64,7 @@ impl Default for InventoryComponent {
inventory_menu: Menu::Player(azalea_inventory::Player::default()),
id: 0,
container_menu: None,
carried: Slot::Empty,
carried: ItemSlot::Empty,
state_id: 0,
}
}

View file

@ -11,6 +11,7 @@ version = "0.6.0"
[dependencies]
azalea-buf = { path = "../azalea-buf", version = "^0.6.0" }
azalea-chat = { path = "../azalea-chat", version = "^0.6.0" }
azalea-inventory = { version = "0.1.0", path = "../azalea-inventory" }
azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0" }
azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
bevy_ecs = { version = "0.10.0", default-features = false, optional = true }

View file

@ -227,12 +227,11 @@ impl AABB {
pub fn clip(&self, min: &Vec3, max: &Vec3) -> Option<Vec3> {
let mut t = 1.0;
let delta = max - min;
let _dir = self.get_direction(self, min, &mut t, None, &delta)?;
let _dir = Self::get_direction(self, min, &mut t, None, &delta)?;
Some(min + &(delta * t))
}
pub fn clip_iterable(
&self,
boxes: &Vec<AABB>,
from: &Vec3,
to: &Vec3,
@ -243,7 +242,7 @@ impl AABB {
let delta = to - from;
for aabb in boxes {
dir = self.get_direction(aabb, from, &mut t, dir, &delta);
dir = Self::get_direction(aabb, from, &mut t, dir, &delta);
}
let dir = dir?;
Some(BlockHitResult {
@ -256,7 +255,6 @@ impl AABB {
}
fn get_direction(
&self,
aabb: &AABB,
from: &Vec3,
t: &mut f64,
@ -264,7 +262,7 @@ impl AABB {
delta: &Vec3,
) -> Option<Direction> {
if delta.x > EPSILON {
return self.clip_point(ClipPointOpts {
return Self::clip_point(ClipPointOpts {
t,
approach_dir: dir,
delta,
@ -277,7 +275,7 @@ impl AABB {
start: from,
});
} else if delta.x < -EPSILON {
return self.clip_point(ClipPointOpts {
return Self::clip_point(ClipPointOpts {
t,
approach_dir: dir,
delta,
@ -292,7 +290,7 @@ impl AABB {
}
if delta.y > EPSILON {
return self.clip_point(ClipPointOpts {
return Self::clip_point(ClipPointOpts {
t,
approach_dir: dir,
delta: &Vec3 {
@ -313,7 +311,7 @@ impl AABB {
},
});
} else if delta.y < -EPSILON {
return self.clip_point(ClipPointOpts {
return Self::clip_point(ClipPointOpts {
t,
approach_dir: dir,
delta: &Vec3 {
@ -336,7 +334,7 @@ impl AABB {
}
if delta.z > EPSILON {
return self.clip_point(ClipPointOpts {
return Self::clip_point(ClipPointOpts {
t,
approach_dir: dir,
delta: &Vec3 {
@ -357,7 +355,7 @@ impl AABB {
},
});
} else if delta.z < -EPSILON {
return self.clip_point(ClipPointOpts {
return Self::clip_point(ClipPointOpts {
t,
approach_dir: dir,
delta: &Vec3 {
@ -382,7 +380,7 @@ impl AABB {
dir
}
fn clip_point(&self, opts: ClipPointOpts) -> Option<Direction> {
fn clip_point(opts: ClipPointOpts) -> Option<Direction> {
let t_x = (opts.begin - opts.start.x) / opts.delta.x;
let t_y = (opts.start.y + t_x) / opts.delta.y;
let t_z = (opts.start.z + t_x) / opts.delta.z;

View file

@ -19,4 +19,11 @@ impl BlockHitResult {
inside: false,
}
}
pub fn with_direction(&self, direction: Direction) -> Self {
Self { direction, ..*self }
}
pub fn with_position(&self, block_pos: BlockPos) -> Self {
Self { block_pos, ..*self }
}
}

View file

@ -48,6 +48,17 @@ impl Direction {
Direction::East => Vec3::new(1.0, 0.0, 0.0),
}
}
pub fn opposite(self) -> Direction {
match self {
Direction::Down => Direction::Up,
Direction::Up => Direction::Down,
Direction::North => Direction::South,
Direction::South => Direction::North,
Direction::West => Direction::East,
Direction::East => Direction::West,
}
}
}
// TODO: make azalea_block use this instead of FacingCardinal

View file

@ -12,9 +12,6 @@ pub use resource_location::*;
mod game_type;
pub use game_type::*;
mod slot;
pub use slot::*;
mod position;
pub use position::*;

View file

@ -1,5 +1,6 @@
use crate::{BlockPos, Slot};
use crate::BlockPos;
use azalea_buf::McBuf;
use azalea_inventory::ItemSlot;
#[cfg_attr(feature = "bevy_ecs", derive(bevy_ecs::component::Component))]
#[derive(Debug, Clone, McBuf, Default)]
@ -139,7 +140,7 @@ pub struct DustColorTransitionParticle {
#[derive(Debug, Clone, McBuf)]
pub struct ItemParticle {
pub item: Slot,
pub item: ItemSlot,
}
#[derive(Debug, Clone, McBuf)]

View file

@ -18,6 +18,12 @@ macro_rules! vec3_impl {
self.x * self.x + self.y * self.y + self.z * self.z
}
/// Get the squared distance from this position to another position.
/// Equivalent to `(self - other).length_sqr()`.
pub fn distance_to_sqr(&self, other: &Self) -> $type {
(self - other).length_sqr()
}
/// Return a new instance of this position with the y coordinate
/// decreased by the given number.
pub fn down(&self, y: $type) -> Self {

View file

@ -6,5 +6,7 @@ version = "0.1.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
azalea-core = { version = "0.6.0", path = "../azalea-core" }
azalea-buf = { version = "0.6.0", path = "../azalea-buf" }
azalea-inventory-macros = { version = "0.1.0", path = "./azalea-inventory-macros" }
azalea-nbt = { version = "0.6.0", path = "../azalea-nbt" }
azalea-registry = { version = "0.6.0", path = "../azalea-registry" }

View file

@ -32,11 +32,11 @@ pub fn generate(input: &DeclareMenus) -> TokenStream {
}
/// Player {
/// craft_result: Slot,
/// craft: [Slot; 4],
/// armor: [Slot; 4],
/// inventory: [Slot; 36],
/// offhand: Slot,
/// craft_result: ItemSlot,
/// craft: [ItemSlot; 4],
/// armor: [ItemSlot; 4],
/// inventory: [ItemSlot; 36],
/// offhand: ItemSlot,
/// },
fn generate_variant_for_menu(menu: &Menu) -> TokenStream {
let name = &menu.name;
@ -54,7 +54,7 @@ fn generate_fields(fields: &[Field], public: bool) -> TokenStream {
for field in fields {
let field_length = field.length;
let field_type = if field.length == 1 {
quote! { Slot }
quote! { ItemSlot }
} else {
quote! { SlotList<#field_length> }
};

View file

@ -40,10 +40,10 @@ pub fn generate(input: &DeclareMenus) -> TokenStream {
}
impl Menu {
/// Get a mutable reference to the [`Slot`] at the given protocol index. If
/// Get a mutable reference to the [`ItemSlot`] at the given protocol index. If
/// you're trying to get an item in a menu normally, you should just
/// `match` it and index the `[Slot]` you get
pub fn slot_mut(&mut self, i: usize) -> Option<&mut Slot> {
/// `match` it and index the [`ItemSlot`] you get
pub fn slot_mut(&mut self, i: usize) -> Option<&mut ItemSlot> {
Some(match self {
#slot_mut_match_variants
})

View file

@ -1,15 +1,17 @@
mod slot;
use std::ops::{Deref, DerefMut};
use azalea_core::Slot;
use azalea_inventory_macros::declare_menus;
pub use slot::{ItemSlot, ItemSlotData};
// TODO: remove this here and in azalea-inventory-macros when rust makes
// Default be implemented for all array sizes (since right now it's only up to
// 32)
#[derive(Debug, Clone)]
pub struct SlotList<const N: usize>([Slot; N]);
pub struct SlotList<const N: usize>([ItemSlot; N]);
impl<const N: usize> Deref for SlotList<N> {
type Target = [Slot; N];
type Target = [ItemSlot; N];
fn deref(&self) -> &Self::Target {
&self.0
}
@ -21,7 +23,7 @@ impl<const N: usize> DerefMut for SlotList<N> {
}
impl<const N: usize> Default for SlotList<N> {
fn default() -> Self {
SlotList([(); N].map(|_| Slot::Empty))
SlotList([(); N].map(|_| ItemSlot::Empty))
}
}

View file

@ -1,35 +1,36 @@
// TODO: have an azalea-inventory or azalea-container crate and put this there
use azalea_buf::{BufReadError, McBuf, McBufReadable, McBufWritable};
use azalea_nbt::Tag;
use std::io::{Cursor, Write};
/// Either an item in an inventory or nothing.
#[derive(Debug, Clone, Default)]
pub enum Slot {
pub enum ItemSlot {
#[default]
Empty,
Present(SlotData),
Present(ItemSlotData),
}
/// An item in an inventory, with a count and NBT. Usually you want [`ItemSlot`]
/// or [`azalea_registry::Item`] instead.
#[derive(Debug, Clone, McBuf)]
pub struct SlotData {
pub struct ItemSlotData {
pub id: azalea_registry::Item,
pub count: u8,
pub nbt: Tag,
}
impl McBufReadable for Slot {
impl McBufReadable for ItemSlot {
fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
let slot = Option::<SlotData>::read_from(buf)?;
Ok(slot.map_or(Slot::Empty, Slot::Present))
let slot = Option::<ItemSlotData>::read_from(buf)?;
Ok(slot.map_or(ItemSlot::Empty, ItemSlot::Present))
}
}
impl McBufWritable for Slot {
impl McBufWritable for ItemSlot {
fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
match self {
Slot::Empty => false.write_into(buf)?,
Slot::Present(i) => {
ItemSlot::Empty => false.write_into(buf)?,
ItemSlot::Present(i) => {
true.write_into(buf)?;
i.write_into(buf)?;
}

View file

@ -11,6 +11,7 @@ version = "0.6.0"
[dependencies]
azalea-block = { path = "../azalea-block", version = "^0.6.0" }
azalea-core = { path = "../azalea-core", version = "^0.6.0" }
azalea-inventory = { version = "0.1.0", path = "../azalea-inventory" }
azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
azalea-world = { path = "../azalea-world", version = "^0.6.0" }
bevy_app = "0.10.0"

View file

@ -1,19 +1,56 @@
use azalea_block::BlockState;
use azalea_core::{lerp, BlockHitResult, BlockPos, Direction, Vec3, EPSILON};
use azalea_inventory::ItemSlot;
use azalea_world::ChunkStorage;
use bevy_ecs::entity::Entity;
use crate::collision::{BlockWithShape, VoxelShape};
#[derive(Debug, Clone)]
pub struct ClipContext {
pub from: Vec3,
pub to: Vec3,
pub block: BlockClipContext,
pub fluid: FluidClipContext,
pub collision_context: CollisionContext,
pub block: BlockShapeGetter,
pub fluid: CanPickFluid,
pub collision_context: EntityCollisionContext,
}
impl ClipContext {
// minecraft passes in the world and blockpos here... but it doesn't actually
// seem necessary?
pub fn block_shape(&self, block_state: BlockState) -> &VoxelShape {
// TODO: implement the other shape getters
// (see the ClipContext.Block class in the vanilla source)
match self.block {
BlockShapeGetter::Collider => block_state.shape(),
BlockShapeGetter::Outline => block_state.shape(),
BlockShapeGetter::Visual => block_state.shape(),
BlockShapeGetter::FallDamageResetting => block_state.shape(),
}
}
}
pub struct BlockClipContext {
pub shape_getter
#[derive(Debug, Copy, Clone)]
pub enum BlockShapeGetter {
Collider,
Outline,
Visual,
FallDamageResetting,
}
#[derive(Debug, Copy, Clone)]
pub enum CanPickFluid {
None,
SourceOnly,
Any,
Water,
}
#[derive(Debug, Clone)]
pub struct EntityCollisionContext {
pub descending: bool,
pub entity_bottom: f64,
pub held_item: ItemSlot,
// pub can_stand_on_fluid: Box<dyn Fn(&FluidState) -> bool>,
pub entity: Entity,
}
pub struct FluidClipContext {}
pub struct CollisionContext {}
pub fn clip(chunk_storage: &mut ChunkStorage, context: ClipContext) -> BlockHitResult {
traverse_blocks(
@ -21,14 +58,23 @@ pub fn clip(chunk_storage: &mut ChunkStorage, context: ClipContext) -> BlockHitR
context.to,
context,
|context, block_pos| {
let block_state = chunk_storage.get_block_state(block_pos);
let block_state = chunk_storage.get_block_state(block_pos).unwrap_or_default();
// TODO: add fluid stuff to this (see getFluidState in vanilla source)
let block_shape = context.block_shape(block_state, chunk_storage, block_pos);
let block_hit_result =
chunk_storage.clip_with_interaction_override(context.from, context.to, block_pos);
// let block_distance =
let block_shape = context.block_shape(block_state);
let block_hit_result = clip_with_interaction_override(
&context.from,
&context.to,
block_pos,
block_shape,
&block_state,
);
// let block_distance = if let Some(block_hit_result) = block_hit_result {
// context.from.distance_to_sqr(&block_hit_result.location)
// } else {
// f64::MAX
// };
None
block_hit_result
},
|context| {
let vec = context.from - context.to;
@ -41,6 +87,49 @@ pub fn clip(chunk_storage: &mut ChunkStorage, context: ClipContext) -> BlockHitR
)
}
// default BlockHitResult clipWithInteractionOverride(Vec3 world, Vec3 from,
// BlockPos to, VoxelShape shape, BlockState block) {
// BlockHitResult blockHitResult = shape.clip(world, from, to);
// if (blockHitResult != null) {
// BlockHitResult var7 = block.getInteractionShape(this, to).clip(world,
// from, to); if (var7 != null
// && var7.getLocation().subtract(world).lengthSqr() <
// blockHitResult.getLocation().subtract(world).lengthSqr()) { return
// blockHitResult.withDirection(var7.getDirection()); }
// }
// return blockHitResult;
// }
fn clip_with_interaction_override(
from: &Vec3,
to: &Vec3,
block_pos: &BlockPos,
block_shape: &VoxelShape,
block_state: &BlockState,
) -> Option<BlockHitResult> {
let block_hit_result = block_shape.clip(from, to, block_pos);
if let Some(mut block_hit_result) = block_hit_result {
// TODO: minecraft calls .getInteractionShape here
// are there even any blocks that have a physics shape different from the
// interaction shape???
// (if not then you can delete this comment)
// (if there are then you have to implement BlockState::interaction_shape, lol
// have fun)
let interaction_shape = block_state.shape();
let interaction_hit_result = interaction_shape.clip(from, to, block_pos);
if let Some(interaction_hit_result) = interaction_hit_result {
if interaction_hit_result.location.distance_to_sqr(from)
< block_hit_result.location.distance_to_sqr(from)
{
return Some(block_hit_result.with_direction(interaction_hit_result.direction));
}
}
Some(block_hit_result)
} else {
None
}
}
pub fn traverse_blocks<C, T>(
from: Vec3,
to: Vec3,

View file

@ -1,9 +1,11 @@
use super::mergers::IndexMerger;
use crate::collision::{BitSetDiscreteVoxelShape, DiscreteVoxelShape, AABB};
use azalea_core::{binary_search, Axis, AxisCycle, EPSILON};
use azalea_core::{
binary_search, Axis, AxisCycle, BlockHitResult, BlockPos, Direction, Vec3, EPSILON,
};
use std::{cmp, num::NonZeroU32};
pub struct Shapes {}
pub struct Shapes;
pub fn block_shape() -> VoxelShape {
let mut shape = BitSetDiscreteVoxelShape::new(1, 1, 1);
@ -390,6 +392,33 @@ impl VoxelShape {
}
}
pub fn clip(&self, from: &Vec3, to: &Vec3, block_pos: &BlockPos) -> Option<BlockHitResult> {
if self.is_empty() {
return None;
}
let vector = to - from;
if vector.length_sqr() < EPSILON {
return None;
}
let right_after_start = from + &(vector * 0.0001);
if self.shape().is_full_wide(
self.find_index(Axis::X, right_after_start.x - block_pos.x as f64),
self.find_index(Axis::Y, right_after_start.y - block_pos.y as f64),
self.find_index(Axis::Z, right_after_start.z - block_pos.z as f64),
) {
Some(BlockHitResult {
block_pos: *block_pos,
direction: Direction::nearest(vector).opposite(),
location: right_after_start,
inside: true,
miss: false,
})
} else {
AABB::clip_iterable(&self.to_aabbs(), &from, &to, &block_pos)
}
}
pub fn collide(&self, axis: &Axis, entity_box: &AABB, movement: f64) -> f64 {
self.collide_x(AxisCycle::between(*axis, Axis::X), entity_box, movement)
}
@ -531,19 +560,34 @@ impl VoxelShape {
let y_coords = self.get_coords(Axis::Y);
let z_coords = self.get_coords(Axis::Z);
self.shape().for_all_boxes(
|var4x, var5, var6, var7, var8, var9| {
|min_x, min_y, min_z, max_x, max_y, max_z| {
consumer(
x_coords[var4x as usize],
y_coords[var5 as usize],
z_coords[var6 as usize],
x_coords[var7 as usize],
y_coords[var8 as usize],
z_coords[var9 as usize],
x_coords[min_x as usize],
y_coords[min_y as usize],
z_coords[min_z as usize],
x_coords[max_x as usize],
y_coords[max_y as usize],
z_coords[max_z as usize],
);
},
true,
);
}
pub fn to_aabbs(&self) -> Vec<AABB> {
let mut aabbs = Vec::new();
self.for_all_boxes(|min_x, min_y, min_z, max_x, max_y, max_z| {
aabbs.push(AABB {
min_x,
min_y,
min_z,
max_x,
max_y,
max_z,
});
});
aabbs
}
}
impl From<AABB> for VoxelShape {

View file

@ -25,6 +25,7 @@ azalea-core = { path = "../azalea-core", optional = true, version = "^0.6.0", fe
"serde",
] }
azalea-crypto = { path = "../azalea-crypto", version = "^0.6.0" }
azalea-inventory = { version = "0.1.0", path = "../azalea-inventory" }
azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0", features = [
"serde",
] }

View file

@ -1,5 +1,5 @@
use azalea_buf::McBuf;
use azalea_core::Slot;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
@ -7,6 +7,6 @@ pub struct ClientboundContainerSetContentPacket {
pub container_id: i8,
#[var]
pub state_id: u32,
pub items: Vec<Slot>,
pub carried_item: Slot,
pub items: Vec<ItemSlot>,
pub carried_item: ItemSlot,
}

View file

@ -1,5 +1,5 @@
use azalea_buf::McBuf;
use azalea_core::Slot;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
@ -8,5 +8,5 @@ pub struct ClientboundContainerSetSlotPacket {
#[var]
pub state_id: u32,
pub slot: u16,
pub item_stack: Slot,
pub item_stack: ItemSlot,
}

View file

@ -1,5 +1,5 @@
use azalea_buf::McBuf;
use azalea_core::Slot;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket;
#[derive(Clone, Debug, McBuf, ClientboundGamePacket)]
@ -17,9 +17,9 @@ pub struct ClientboundMerchantOffersPacket {
#[derive(Clone, Debug, McBuf)]
pub struct MerchantOffer {
pub base_cost_a: Slot,
pub result: Slot,
pub cost_b: Slot,
pub base_cost_a: ItemSlot,
pub result: ItemSlot,
pub cost_b: ItemSlot,
pub out_of_stock: bool,
pub uses: u32,
pub max_uses: u32,

View file

@ -1,6 +1,6 @@
use azalea_buf::{BufReadError, McBuf};
use azalea_buf::{McBufReadable, McBufWritable};
use azalea_core::Slot;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket;
use std::io::Cursor;
@ -13,7 +13,7 @@ pub struct ClientboundSetEquipmentPacket {
#[derive(Clone, Debug)]
pub struct EquipmentSlots {
pub slots: Vec<(EquipmentSlot, Slot)>,
pub slots: Vec<(EquipmentSlot, ItemSlot)>,
}
impl McBufReadable for EquipmentSlots {
@ -28,7 +28,7 @@ impl McBufReadable for EquipmentSlots {
id: equipment_byte.into(),
}
})?;
let item = Slot::read_from(buf)?;
let item = ItemSlot::read_from(buf)?;
slots.push((equipment_slot, item));
if equipment_byte & 128 == 0 {
break;

View file

@ -1,6 +1,7 @@
use azalea_buf::McBuf;
use azalea_chat::FormattedText;
use azalea_core::{ResourceLocation, Slot};
use azalea_core::ResourceLocation;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket;
use std::collections::HashMap;
use std::io::Cursor;
@ -25,7 +26,7 @@ pub struct Advancement {
pub struct DisplayInfo {
pub title: FormattedText,
pub description: FormattedText,
pub icon: Slot,
pub icon: ItemSlot,
pub frame: FrameType,
pub show_toast: bool,
pub hidden: bool,
@ -130,7 +131,7 @@ mod tests {
display: Some(DisplayInfo {
title: FormattedText::from("title".to_string()),
description: FormattedText::from("description".to_string()),
icon: Slot::Empty,
icon: ItemSlot::Empty,
frame: FrameType::Task,
show_toast: true,
hidden: false,

View file

@ -1,7 +1,8 @@
use azalea_buf::{
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
};
use azalea_core::{ResourceLocation, Slot};
use azalea_core::ResourceLocation;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ClientboundGamePacket;
use std::io::{Cursor, Write};
@ -23,7 +24,7 @@ pub struct ShapelessRecipe {
pub group: String,
pub category: CraftingBookCategory,
pub ingredients: Vec<Ingredient>,
pub result: Slot,
pub result: ItemSlot,
}
#[derive(Clone, Debug)]
pub struct ShapedRecipe {
@ -32,7 +33,7 @@ pub struct ShapedRecipe {
pub group: String,
pub category: CraftingBookCategory,
pub ingredients: Vec<Ingredient>,
pub result: Slot,
pub result: ItemSlot,
}
#[derive(Clone, Debug, Copy, McBuf)]
@ -67,7 +68,7 @@ impl McBufReadable for ShapedRecipe {
for _ in 0..width * height {
ingredients.push(Ingredient::read_from(buf)?);
}
let result = Slot::read_from(buf)?;
let result = ItemSlot::read_from(buf)?;
Ok(ShapedRecipe {
width,
@ -85,7 +86,7 @@ pub struct CookingRecipe {
pub group: String,
pub category: CraftingBookCategory,
pub ingredient: Ingredient,
pub result: Slot,
pub result: ItemSlot,
pub experience: f32,
#[var]
pub cooking_time: u32,
@ -94,13 +95,13 @@ pub struct CookingRecipe {
pub struct StoneCutterRecipe {
pub group: String,
pub ingredient: Ingredient,
pub result: Slot,
pub result: ItemSlot,
}
#[derive(Clone, Debug, McBuf)]
pub struct SmithingRecipe {
pub base: Ingredient,
pub addition: Ingredient,
pub result: Slot,
pub result: ItemSlot,
}
#[derive(Clone, Debug, McBuf)]
@ -136,7 +137,7 @@ pub enum RecipeData {
#[derive(Clone, Debug, McBuf)]
pub struct Ingredient {
pub allowed: Vec<Slot>,
pub allowed: Vec<ItemSlot>,
}
impl McBufWritable for Recipe {

View file

@ -1,5 +1,5 @@
use azalea_buf::McBuf;
use azalea_core::Slot;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ServerboundGamePacket;
use std::collections::HashMap;
@ -11,8 +11,8 @@ pub struct ServerboundContainerClickPacket {
pub slot_num: u16,
pub button_num: u8,
pub click_type: ClickType,
pub changed_slots: HashMap<u16, Slot>,
pub carried_item: Slot,
pub changed_slots: HashMap<u16, ItemSlot>,
pub carried_item: ItemSlot,
}
#[derive(McBuf, Clone, Copy, Debug)]

View file

@ -1,9 +1,9 @@
use azalea_buf::McBuf;
use azalea_core::Slot;
use azalea_inventory::ItemSlot;
use azalea_protocol_macros::ServerboundGamePacket;
#[derive(Clone, Debug, McBuf, ServerboundGamePacket)]
pub struct ServerboundSetCreativeModeSlotPacket {
pub slot_num: u16,
pub item_stack: Slot,
pub item_stack: ItemSlot,
}

View file

@ -56,7 +56,7 @@ pub async fn resolve_address(address: &ServerAddress) -> Result<SocketAddr, Reso
return Ok(SocketAddr::new(
lookup_ip.iter().next().unwrap(),
redirect_address.port,
))
));
}
// debug!("redirecting to {:?}", redirect_address);

View file

@ -15,6 +15,7 @@ azalea-chat = { path = "../azalea-chat", version = "^0.6.0" }
azalea-core = { path = "../azalea-core", version = "^0.6.0", features = [
"bevy_ecs",
] }
azalea-inventory = { version = "0.1.0", path = "../azalea-inventory" }
azalea-nbt = { path = "../azalea-nbt", version = "^0.6.0" }
azalea-registry = { path = "../azalea-registry", version = "^0.6.0" }
bevy_app = "0.10.0"

View file

@ -5,7 +5,8 @@ use azalea_buf::{
BufReadError, McBuf, McBufReadable, McBufVarReadable, McBufVarWritable, McBufWritable,
};
use azalea_chat::FormattedText;
use azalea_core::{BlockPos, Direction, GlobalPos, Particle, Slot};
use azalea_core::{BlockPos, Direction, GlobalPos, Particle};
use azalea_inventory::ItemSlot;
use bevy_ecs::component::Component;
use derive_more::Deref;
use enum_as_inner::EnumAsInner;
@ -59,7 +60,7 @@ pub enum EntityDataValue {
String(String),
FormattedText(FormattedText),
OptionalFormattedText(Option<FormattedText>),
ItemStack(Slot),
ItemStack(ItemSlot),
Boolean(bool),
Rotations(Rotations),
BlockPos(BlockPos),

View file

@ -6,7 +6,8 @@
use super::{EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Rotations, VillagerData};
use azalea_block::BlockState;
use azalea_chat::FormattedText;
use azalea_core::{BlockPos, Direction, Particle, Slot};
use azalea_core::{BlockPos, Direction, Particle};
use azalea_inventory::ItemSlot;
use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use thiserror::Error;
@ -1978,7 +1979,7 @@ impl Default for DrownedMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct EggItemStack(pub Slot);
pub struct EggItemStack(pub ItemSlot);
#[derive(Component)]
pub struct Egg;
impl Egg {
@ -2024,7 +2025,7 @@ impl Default for EggMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
egg_item_stack: EggItemStack(Slot::Empty),
egg_item_stack: EggItemStack(ItemSlot::Empty),
}
}
}
@ -2235,7 +2236,7 @@ impl Default for EnderDragonMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct EnderPearlItemStack(pub Slot);
pub struct EnderPearlItemStack(pub ItemSlot);
#[derive(Component)]
pub struct EnderPearl;
impl EnderPearl {
@ -2281,7 +2282,7 @@ impl Default for EnderPearlMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
ender_pearl_item_stack: EnderPearlItemStack(Slot::Empty),
ender_pearl_item_stack: EnderPearlItemStack(ItemSlot::Empty),
}
}
}
@ -2571,7 +2572,7 @@ impl Default for EvokerFangsMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct ExperienceBottleItemStack(pub Slot);
pub struct ExperienceBottleItemStack(pub ItemSlot);
#[derive(Component)]
pub struct ExperienceBottle;
impl ExperienceBottle {
@ -2617,7 +2618,7 @@ impl Default for ExperienceBottleMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
experience_bottle_item_stack: ExperienceBottleItemStack(Slot::Empty),
experience_bottle_item_stack: ExperienceBottleItemStack(ItemSlot::Empty),
}
}
}
@ -2668,7 +2669,7 @@ impl Default for ExperienceOrbMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct EyeOfEnderItemStack(pub Slot);
pub struct EyeOfEnderItemStack(pub ItemSlot);
#[derive(Component)]
pub struct EyeOfEnder;
impl EyeOfEnder {
@ -2714,7 +2715,7 @@ impl Default for EyeOfEnderMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
eye_of_ender_item_stack: EyeOfEnderItemStack(Slot::Empty),
eye_of_ender_item_stack: EyeOfEnderItemStack(ItemSlot::Empty),
}
}
}
@ -2772,7 +2773,7 @@ impl Default for FallingBlockMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct FireballItemStack(pub Slot);
pub struct FireballItemStack(pub ItemSlot);
#[derive(Component)]
pub struct Fireball;
impl Fireball {
@ -2818,13 +2819,13 @@ impl Default for FireballMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
fireball_item_stack: FireballItemStack(Slot::Empty),
fireball_item_stack: FireballItemStack(ItemSlot::Empty),
}
}
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct FireworksItem(pub Slot);
pub struct FireworksItem(pub ItemSlot);
#[derive(Component, Deref, DerefMut, Clone)]
pub struct AttachedToTarget(pub OptionalUnsignedInt);
#[derive(Component, Deref, DerefMut, Clone)]
@ -2882,7 +2883,7 @@ impl Default for FireworkRocketMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
fireworks_item: FireworksItem(Slot::Empty),
fireworks_item: FireworksItem(ItemSlot::Empty),
attached_to_target: AttachedToTarget(OptionalUnsignedInt(None)),
shot_at_angle: ShotAtAngle(false),
}
@ -3359,7 +3360,7 @@ impl Default for GiantMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct ItemFrameItem(pub Slot);
pub struct ItemFrameItem(pub ItemSlot);
#[derive(Component, Deref, DerefMut, Clone)]
pub struct Rotation(pub i32);
#[derive(Component)]
@ -3405,7 +3406,7 @@ impl Default for GlowItemFrameMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
item_frame_item: ItemFrameItem(Slot::Empty),
item_frame_item: ItemFrameItem(ItemSlot::Empty),
rotation: Rotation(0),
},
}
@ -4135,7 +4136,7 @@ impl Default for IronGolemMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct ItemItem(pub Slot);
pub struct ItemItem(pub ItemSlot);
#[derive(Component)]
pub struct Item;
impl Item {
@ -4181,7 +4182,7 @@ impl Default for ItemMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
item_item: ItemItem(Slot::Empty),
item_item: ItemItem(ItemSlot::Empty),
}
}
}
@ -4235,7 +4236,7 @@ impl Default for ItemFrameMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
item_frame_item: ItemFrameItem(Slot::Empty),
item_frame_item: ItemFrameItem(ItemSlot::Empty),
rotation: Rotation(0),
}
}
@ -5806,7 +5807,7 @@ impl Default for PolarBearMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct PotionItemStack(pub Slot);
pub struct PotionItemStack(pub ItemSlot);
#[derive(Component)]
pub struct Potion;
impl Potion {
@ -5852,7 +5853,7 @@ impl Default for PotionMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
potion_item_stack: PotionItemStack(Slot::Empty),
potion_item_stack: PotionItemStack(ItemSlot::Empty),
}
}
}
@ -6691,7 +6692,7 @@ impl Default for SlimeMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct SmallFireballItemStack(pub Slot);
pub struct SmallFireballItemStack(pub ItemSlot);
#[derive(Component)]
pub struct SmallFireball;
impl SmallFireball {
@ -6737,7 +6738,7 @@ impl Default for SmallFireballMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
small_fireball_item_stack: SmallFireballItemStack(Slot::Empty),
small_fireball_item_stack: SmallFireballItemStack(ItemSlot::Empty),
}
}
}
@ -6816,7 +6817,7 @@ impl Default for SnowGolemMetadataBundle {
}
#[derive(Component, Deref, DerefMut, Clone)]
pub struct SnowballItemStack(pub Slot);
pub struct SnowballItemStack(pub ItemSlot);
#[derive(Component)]
pub struct Snowball;
impl Snowball {
@ -6862,7 +6863,7 @@ impl Default for SnowballMetadataBundle {
pose: Pose::default(),
ticks_frozen: TicksFrozen(0),
},
snowball_item_stack: SnowballItemStack(Slot::Empty),
snowball_item_stack: SnowballItemStack(ItemSlot::Empty),
}
}
}

View file

@ -17,7 +17,7 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings):
{'name': 'String', 'type': 'String'},
{'name': 'FormattedText', 'type': 'FormattedText'},
{'name': 'OptionalFormattedText', 'type': 'Option<FormattedText>'},
{'name': 'ItemStack', 'type': 'Slot'},
{'name': 'ItemStack', 'type': 'ItemSlot'},
{'name': 'Boolean', 'type': 'bool'},
{'name': 'Rotations', 'type': 'Rotations'},
{'name': 'BlockPos', 'type': 'BlockPos'},
@ -45,7 +45,8 @@ def generate_entity_metadata(burger_entity_data: dict, mappings: Mappings):
use super::{EntityDataItem, EntityDataValue, OptionalUnsignedInt, Pose, Rotations, VillagerData};
use azalea_block::BlockState;
use azalea_chat::FormattedText;
use azalea_core::{BlockPos, Direction, Particle, Slot};
use azalea_core::{BlockPos, Direction, Particle};
use azalea_inventory::ItemSlot;
use bevy_ecs::{bundle::Bundle, component::Component};
use derive_more::{Deref, DerefMut};
use thiserror::Error;
@ -365,7 +366,7 @@ impl From<EntityDataValue> for UpdateMetadataError {
elif type_name == 'OptionalUnsignedInt':
default = f'OptionalUnsignedInt(Some({default}))' if default != 'Empty' else 'OptionalUnsignedInt(None)'
elif type_name == 'ItemStack':
default = f'Slot::Present({default})' if default != 'Empty' else 'Slot::Empty'
default = f'ItemSlot::Present({default})' if default != 'Empty' else 'ItemSlot::Empty'
elif type_name == 'BlockState':
default = f'{default}' if default != 'Empty' else 'BlockState::AIR'
elif type_name == 'OptionalFormattedText':