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

start implementing data driven registries

This commit is contained in:
mat 2025-02-02 21:15:45 +00:00
parent cdb68dfb70
commit b08d3d55d7
14 changed files with 254 additions and 278 deletions

1
Cargo.lock generated
View file

@ -373,6 +373,7 @@ dependencies = [
"azalea-chat",
"azalea-registry",
"bevy_ecs",
"indexmap",
"nohash-hasher",
"num-traits",
"serde",

View file

@ -386,3 +386,9 @@ where
Ok(Box::new(T::azalea_read(buf)?))
}
}
impl<A: AzaleaRead, B: AzaleaRead> AzaleaRead for (A, B) {
fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
Ok((A::azalea_read(buf)?, B::azalea_read(buf)?))
}
}

View file

@ -1,14 +1,13 @@
use std::{collections::HashMap, io::Write};
use std::{
collections::HashMap,
io::{self, Write},
};
use byteorder::{BigEndian, WriteBytesExt};
use super::{UnsizedByteArray, MAX_STRING_LENGTH};
fn write_utf_with_len(
buf: &mut impl Write,
string: &str,
len: usize,
) -> Result<(), std::io::Error> {
fn write_utf_with_len(buf: &mut impl Write, string: &str, len: usize) -> Result<(), io::Error> {
if string.len() > len {
panic!(
"String too big (was {} bytes encoded, max {})",
@ -21,21 +20,21 @@ fn write_utf_with_len(
}
pub trait AzaleaWrite {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error>;
}
pub trait AzaleaWriteVar {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error>;
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error>;
}
impl AzaleaWrite for i32 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
WriteBytesExt::write_i32::<BigEndian>(buf, *self)
}
}
impl AzaleaWriteVar for i32 {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
let mut buffer = [0];
let mut value = *self;
if value == 0 {
@ -54,19 +53,19 @@ impl AzaleaWriteVar for i32 {
}
impl AzaleaWrite for UnsizedByteArray {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
buf.write_all(self)
}
}
impl<T: AzaleaWrite> AzaleaWrite for Vec<T> {
default fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
default fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
self[..].azalea_write(buf)
}
}
impl<T: AzaleaWrite> AzaleaWrite for [T] {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
(self.len() as u32).azalea_write_var(buf)?;
for item in self {
T::azalea_write(item, buf)?;
@ -76,7 +75,7 @@ impl<T: AzaleaWrite> AzaleaWrite for [T] {
}
impl<K: AzaleaWrite, V: AzaleaWrite> AzaleaWrite for HashMap<K, V> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
u32::azalea_write_var(&(self.len() as u32), buf)?;
for (key, value) in self {
key.azalea_write(buf)?;
@ -88,7 +87,7 @@ impl<K: AzaleaWrite, V: AzaleaWrite> AzaleaWrite for HashMap<K, V> {
}
impl<K: AzaleaWrite, V: AzaleaWriteVar> AzaleaWriteVar for HashMap<K, V> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
u32::azalea_write_var(&(self.len() as u32), buf)?;
for (key, value) in self {
key.azalea_write(buf)?;
@ -100,38 +99,38 @@ impl<K: AzaleaWrite, V: AzaleaWriteVar> AzaleaWriteVar for HashMap<K, V> {
}
impl AzaleaWrite for Vec<u8> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
(self.len() as u32).azalea_write_var(buf)?;
buf.write_all(self)
}
}
impl AzaleaWrite for String {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
write_utf_with_len(buf, self, MAX_STRING_LENGTH.into())
}
}
impl AzaleaWrite for &str {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
write_utf_with_len(buf, self, MAX_STRING_LENGTH.into())
}
}
impl AzaleaWrite for u32 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
i32::azalea_write(&(*self as i32), buf)
}
}
impl AzaleaWriteVar for u32 {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
i32::azalea_write_var(&(*self as i32), buf)
}
}
impl AzaleaWriteVar for i64 {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
let mut buffer = [0];
let mut value = *self;
if value == 0 {
@ -150,25 +149,25 @@ impl AzaleaWriteVar for i64 {
}
impl AzaleaWriteVar for u64 {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
i64::azalea_write_var(&(*self as i64), buf)
}
}
impl AzaleaWrite for u16 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
i16::azalea_write(&(*self as i16), buf)
}
}
impl AzaleaWriteVar for u16 {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
i32::azalea_write_var(&(*self as i32), buf)
}
}
impl<T: AzaleaWriteVar> AzaleaWriteVar for Vec<T> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
u32::azalea_write_var(&(self.len() as u32), buf)?;
for i in self {
i.azalea_write_var(buf)?;
@ -178,56 +177,56 @@ impl<T: AzaleaWriteVar> AzaleaWriteVar for Vec<T> {
}
impl AzaleaWrite for u8 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
WriteBytesExt::write_u8(buf, *self)
}
}
impl AzaleaWrite for i16 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
WriteBytesExt::write_i16::<BigEndian>(buf, *self)
}
}
impl AzaleaWrite for i64 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
WriteBytesExt::write_i64::<BigEndian>(buf, *self)
}
}
impl AzaleaWrite for u64 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
i64::azalea_write(&(*self as i64), buf)
}
}
impl AzaleaWrite for bool {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
let byte = u8::from(*self);
byte.azalea_write(buf)
}
}
impl AzaleaWrite for i8 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
(*self as u8).azalea_write(buf)
}
}
impl AzaleaWrite for f32 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
WriteBytesExt::write_f32::<BigEndian>(buf, *self)
}
}
impl AzaleaWrite for f64 {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
WriteBytesExt::write_f64::<BigEndian>(buf, *self)
}
}
impl<T: AzaleaWrite> AzaleaWrite for Option<T> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
if let Some(s) = self {
true.azalea_write(buf)?;
s.azalea_write(buf)?;
@ -239,7 +238,7 @@ impl<T: AzaleaWrite> AzaleaWrite for Option<T> {
}
impl<T: AzaleaWriteVar> AzaleaWriteVar for Option<T> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write_var(&self, buf: &mut impl Write) -> Result<(), io::Error> {
if let Some(s) = self {
true.azalea_write(buf)?;
s.azalea_write_var(buf)?;
@ -252,7 +251,7 @@ impl<T: AzaleaWriteVar> AzaleaWriteVar for Option<T> {
// [T; N]
impl<T: AzaleaWrite, const N: usize> AzaleaWrite for [T; N] {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
for i in self {
i.azalea_write(buf)?;
}
@ -261,7 +260,7 @@ impl<T: AzaleaWrite, const N: usize> AzaleaWrite for [T; N] {
}
impl AzaleaWrite for simdnbt::owned::NbtTag {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
let mut data = Vec::new();
self.write(&mut data);
buf.write_all(&data)
@ -269,7 +268,7 @@ impl AzaleaWrite for simdnbt::owned::NbtTag {
}
impl AzaleaWrite for simdnbt::owned::NbtCompound {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
let mut data = Vec::new();
simdnbt::owned::NbtTag::Compound(self.clone()).write(&mut data);
buf.write_all(&data)
@ -277,7 +276,7 @@ impl AzaleaWrite for simdnbt::owned::NbtCompound {
}
impl AzaleaWrite for simdnbt::owned::Nbt {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
let mut data = Vec::new();
self.write_unnamed(&mut data);
buf.write_all(&data)
@ -288,7 +287,14 @@ impl<T> AzaleaWrite for Box<T>
where
T: AzaleaWrite,
{
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
T::azalea_write(&**self, buf)
}
}
impl<A: AzaleaWrite, B: AzaleaWrite> AzaleaWrite for (A, B) {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
self.0.azalea_write(buf)?;
self.1.azalea_write(buf)
}
}

View file

@ -9,7 +9,10 @@ use std::{
use azalea_auth::{game_profile::GameProfile, sessionserver::ClientSessionServerError};
use azalea_chat::FormattedText;
use azalea_core::{position::Vec3, tick::GameTick};
use azalea_core::{
data_registry::ResolvableDataRegistry, position::Vec3, resource_location::ResourceLocation,
tick::GameTick,
};
use azalea_entity::{
indexing::{EntityIdIndex, EntityUuidIndex},
metadata::Health,
@ -48,6 +51,7 @@ use bevy_ecs::{
use bevy_time::TimePlugin;
use derive_more::Deref;
use parking_lot::{Mutex, RwLock};
use simdnbt::owned::NbtCompound;
use thiserror::Error;
use tokio::{
sync::{broadcast, mpsc},
@ -715,6 +719,52 @@ impl Client {
pub fn tab_list(&self) -> HashMap<Uuid, PlayerInfo> {
self.component::<TabList>().deref().clone()
}
/// Call the given function with the client's [`RegistryHolder`].
///
/// The player's instance (aka world) will be locked during this time, which
/// may result in a deadlock if you try to access the instance again while
/// in the function.
pub fn with_registry_holder<R>(
&self,
f: impl FnOnce(&azalea_core::registry_holder::RegistryHolder) -> R,
) -> R {
let instance = self.world();
let registries = &instance.read().registries;
f(registries)
}
/// Resolve the given registry to its name.
///
/// This is necessary for data-driven registries like [`Enchantment`].
///
/// [`Enchantment`]: azalea_registry::Enchantment
pub fn resolve_registry_name(
&self,
registry: &impl ResolvableDataRegistry,
) -> Option<ResourceLocation> {
self.with_registry_holder(|registries| registry.resolve_name(registries))
}
/// Resolve the given registry to its name and data and call the given
/// function with it.
///
/// This is necessary for data-driven registries like [`Enchantment`].
///
/// If you just want the value name, use [`Self::resolve_registry_name`]
/// instead.
///
/// [`Enchantment`]: azalea_registry::Enchantment
pub fn with_resolved_registry<R>(
&self,
registry: impl ResolvableDataRegistry,
f: impl FnOnce(&ResourceLocation, &NbtCompound) -> R,
) -> Option<R> {
self.with_registry_holder(|registries| {
registry
.resolve(registries)
.map(|(name, data)| f(name, data))
})
}
}
/// The bundle of components that's shared when we're either in the

View file

@ -16,6 +16,7 @@ serde = { workspace = true, optional = true }
simdnbt = { workspace = true }
tracing = { workspace = true }
azalea-chat = { path = "../azalea-chat", version = "0.11.0" }
indexmap = { workspace = true }
[features]
bevy_ecs = ["dep:bevy_ecs"]

View file

@ -0,0 +1,27 @@
use std::str::FromStr;
use azalea_registry::DataRegistry;
use simdnbt::owned::NbtCompound;
use crate::{registry_holder::RegistryHolder, resource_location::ResourceLocation};
pub trait ResolvableDataRegistry: DataRegistry {
fn resolve_name(&self, registries: &RegistryHolder) -> Option<ResourceLocation> {
self.resolve(registries).map(|(name, _)| name.clone())
}
fn resolve<'a>(
&self,
registries: &'a RegistryHolder,
) -> Option<(&'a ResourceLocation, &'a NbtCompound)> {
let name_resourcelocation = ResourceLocation::from_str(Self::NAME).unwrap_or_else(|_| {
panic!(
"Name for registry should be a valid ResourceLocation: {}",
Self::NAME
)
});
let registry_values = registries.map.get(&name_resourcelocation)?;
let resolved = registry_values.get_index(self.protocol_id() as usize)?;
Some(resolved)
}
}
impl<T: DataRegistry> ResolvableDataRegistry for T {}

View file

@ -7,6 +7,7 @@ pub mod bitset;
pub mod block_hit_result;
pub mod color;
pub mod cursor3d;
pub mod data_registry;
pub mod delta;
pub mod difficulty;
pub mod direction;

View file

@ -7,6 +7,7 @@
use std::{collections::HashMap, io::Cursor};
use indexmap::IndexMap;
use simdnbt::{
owned::{NbtCompound, NbtTag},
Deserialize, FromNbtTag, Serialize, ToNbtTag,
@ -20,21 +21,21 @@ use crate::resource_location::ResourceLocation;
/// This is the registry that is sent to the client upon login.
#[derive(Default, Debug, Clone)]
pub struct RegistryHolder {
pub map: HashMap<ResourceLocation, HashMap<ResourceLocation, NbtCompound>>,
pub map: HashMap<ResourceLocation, IndexMap<ResourceLocation, NbtCompound>>,
}
impl RegistryHolder {
pub fn append(
&mut self,
id: ResourceLocation,
entries: HashMap<ResourceLocation, Option<NbtCompound>>,
entries: Vec<(ResourceLocation, Option<NbtCompound>)>,
) {
let map = self.map.entry(id).or_default();
for (key, value) in entries {
if let Some(value) = value {
map.insert(key, value);
} else {
map.remove(&key);
map.shift_remove(&key);
}
}
}

View file

@ -1,8 +1,8 @@
use azalea_block::{fluid_state::FluidKind, Block, BlockBehavior};
use azalea_block::{Block, BlockBehavior};
use azalea_core::tier::get_item_tier;
use azalea_registry as registry;
use crate::{effects, enchantments, FluidOnEyes, Physics};
use crate::{effects, FluidOnEyes, Physics};
/// How much progress is made towards mining the block per tick, as a
/// percentage. If this is 1 then the block gets broken instantly.
@ -83,13 +83,14 @@ fn destroy_speed(
let mut base_destroy_speed = base_destroy_speed(block, tool);
// add efficiency enchantment
if base_destroy_speed > 1. {
let efficiency_level =
enchantments::get_enchant_level(registry::Enchantment::Efficiency, player_inventory);
if efficiency_level > 0 && tool != registry::Item::Air {
base_destroy_speed += (efficiency_level * efficiency_level + 1) as f32;
}
}
// TODO
// if base_destroy_speed > 1. {
// let efficiency_level =
// enchantments::get_enchant_level(registry::Enchantment::Efficiency,
// player_inventory); if efficiency_level > 0 && tool !=
// registry::Item::Air { base_destroy_speed += (efficiency_level *
// efficiency_level + 1) as f32; }
// }
if let Some(dig_speed_amplifier) = effects::get_dig_speed_amplifier() {
base_destroy_speed *= 1. + (dig_speed_amplifier + 1) as f32 * 0.2;
@ -105,12 +106,13 @@ fn destroy_speed(
base_destroy_speed *= multiplier;
}
if **fluid_on_eyes == FluidKind::Water
&& enchantments::get_enchant_level(registry::Enchantment::AquaAffinity, player_inventory)
== 0
{
base_destroy_speed /= 5.;
}
// TODO
// if **fluid_on_eyes == FluidKind::Water
// && enchantments::get_enchant_level(registry::Enchantment::AquaAffinity,
// player_inventory) == 0
// {
// base_destroy_speed /= 5.;
// }
if !physics.on_ground {
base_destroy_speed /= 5.;

View file

@ -1,5 +1,3 @@
use std::collections::HashMap;
use azalea_buf::AzBuf;
use azalea_core::resource_location::ResourceLocation;
use azalea_protocol_macros::ClientboundConfigPacket;
@ -8,5 +6,5 @@ use simdnbt::owned::NbtCompound;
#[derive(Clone, Debug, AzBuf, ClientboundConfigPacket)]
pub struct ClientboundRegistryData {
pub registry_id: ResourceLocation,
pub entries: HashMap<ResourceLocation, Option<NbtCompound>>,
pub entries: Vec<(ResourceLocation, Option<NbtCompound>)>,
}

View file

@ -0,0 +1,24 @@
use azalea_buf::AzBuf;
/// A registry which has its values decided by the server in the
/// `ClientboundRegistryData` packet.
///
/// These can be resolved into their actual values with
/// `ResolvableDataRegistry` from azalea-core.
pub trait DataRegistry {
const NAME: &'static str;
fn protocol_id(&self) -> u32;
}
#[derive(Debug, Clone, Copy, AzBuf, PartialEq, Eq, Hash)]
pub struct Enchantment {
#[var]
id: u32,
}
impl DataRegistry for Enchantment {
const NAME: &'static str = "enchantment";
fn protocol_id(&self) -> u32 {
self.id
}
}

View file

@ -131,3 +131,51 @@ impl ChatType {
}
}
}
registry! {
enum Instrument {
PonderGoatHorn => "minecraft:ponder_goat_horn",
SingGoatHorn => "minecraft:sing_goat_horn",
SeekGoatHorn => "minecraft:seek_goat_horn",
FeelGoatHorn => "minecraft:feel_goat_horn",
AdmireGoatHorn => "minecraft:admire_goat_horn",
CallGoatHorn => "minecraft:call_goat_horn",
YearnGoatHorn => "minecraft:yearn_goat_horn",
DreamGoatHorn => "minecraft:dream_goat_horn",
}
}
registry! {
enum PaintingVariant {
Kebab => "minecraft:kebab",
Aztec => "minecraft:aztec",
Alban => "minecraft:alban",
Aztec2 => "minecraft:aztec2",
Bomb => "minecraft:bomb",
Plant => "minecraft:plant",
Wasteland => "minecraft:wasteland",
Pool => "minecraft:pool",
Courbet => "minecraft:courbet",
Sea => "minecraft:sea",
Sunset => "minecraft:sunset",
Creebet => "minecraft:creebet",
Wanderer => "minecraft:wanderer",
Graham => "minecraft:graham",
Match => "minecraft:match",
Bust => "minecraft:bust",
Stage => "minecraft:stage",
Void => "minecraft:void",
SkullAndRoses => "minecraft:skull_and_roses",
Wither => "minecraft:wither",
Fighters => "minecraft:fighters",
Pointer => "minecraft:pointer",
Pigscene => "minecraft:pigscene",
BurningSkull => "minecraft:burning_skull",
Skeleton => "minecraft:skeleton",
Earth => "minecraft:earth",
Wind => "minecraft:wind",
Water => "minecraft:water",
Fire => "minecraft:fire",
DonkeyKong => "minecraft:donkey_kong",
}
}

View file

@ -3,16 +3,18 @@
// The contents of the macros below are generated in
// codegen/lib/code/registry.py, though the rest of the file isn't
// auto-generated (so you can add doc comments to the registry enums if you
// want)
// want).
mod data;
mod extra;
pub mod tags;
use std::fmt::{self, Debug};
use std::io::{Cursor, Write};
use std::io::{self, Cursor, Write};
use azalea_buf::{AzaleaRead, AzaleaReadVar, AzaleaWrite, AzaleaWriteVar, BufReadError};
use azalea_registry_macros::registry;
pub use data::*;
pub use extra::*;
pub trait Registry: AzaleaRead + AzaleaWrite
@ -65,7 +67,7 @@ impl<D: Registry, C: AzaleaRead + AzaleaWrite> AzaleaRead for CustomRegistry<D,
}
}
impl<D: Registry, C: AzaleaRead + AzaleaWrite> AzaleaWrite for CustomRegistry<D, C> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), std::io::Error> {
fn azalea_write(&self, buf: &mut impl Write) -> Result<(), io::Error> {
match self {
CustomRegistry::Direct(direct_registry) => {
// write the id + 1
@ -262,52 +264,6 @@ enum Attribute {
}
}
registry! {
enum BannerPattern {
Base => "minecraft:base",
SquareBottomLeft => "minecraft:square_bottom_left",
SquareBottomRight => "minecraft:square_bottom_right",
SquareTopLeft => "minecraft:square_top_left",
SquareTopRight => "minecraft:square_top_right",
StripeBottom => "minecraft:stripe_bottom",
StripeTop => "minecraft:stripe_top",
StripeLeft => "minecraft:stripe_left",
StripeRight => "minecraft:stripe_right",
StripeCenter => "minecraft:stripe_center",
StripeMiddle => "minecraft:stripe_middle",
StripeDownright => "minecraft:stripe_downright",
StripeDownleft => "minecraft:stripe_downleft",
SmallStripes => "minecraft:small_stripes",
Cross => "minecraft:cross",
StraightCross => "minecraft:straight_cross",
TriangleBottom => "minecraft:triangle_bottom",
TriangleTop => "minecraft:triangle_top",
TrianglesBottom => "minecraft:triangles_bottom",
TrianglesTop => "minecraft:triangles_top",
DiagonalLeft => "minecraft:diagonal_left",
DiagonalUpRight => "minecraft:diagonal_up_right",
DiagonalUpLeft => "minecraft:diagonal_up_left",
DiagonalRight => "minecraft:diagonal_right",
Circle => "minecraft:circle",
Rhombus => "minecraft:rhombus",
HalfVertical => "minecraft:half_vertical",
HalfHorizontal => "minecraft:half_horizontal",
HalfVerticalRight => "minecraft:half_vertical_right",
HalfHorizontalBottom => "minecraft:half_horizontal_bottom",
Border => "minecraft:border",
CurlyBorder => "minecraft:curly_border",
Gradient => "minecraft:gradient",
GradientUp => "minecraft:gradient_up",
Bricks => "minecraft:bricks",
Globe => "minecraft:globe",
Creeper => "minecraft:creeper",
Skull => "minecraft:skull",
Flower => "minecraft:flower",
Mojang => "minecraft:mojang",
Piglin => "minecraft:piglin",
}
}
registry! {
/// An enum of every type of block in the game. To represent a block *state*,
/// use [`azalea_block::BlockState`] or the [`azalea_block::Block`] trait.
@ -1656,53 +1612,6 @@ enum CustomStat {
}
}
registry! {
enum Enchantment {
Protection => "minecraft:protection",
FireProtection => "minecraft:fire_protection",
FeatherFalling => "minecraft:feather_falling",
BlastProtection => "minecraft:blast_protection",
ProjectileProtection => "minecraft:projectile_protection",
Respiration => "minecraft:respiration",
AquaAffinity => "minecraft:aqua_affinity",
Thorns => "minecraft:thorns",
DepthStrider => "minecraft:depth_strider",
FrostWalker => "minecraft:frost_walker",
BindingCurse => "minecraft:binding_curse",
SoulSpeed => "minecraft:soul_speed",
SwiftSneak => "minecraft:swift_sneak",
Sharpness => "minecraft:sharpness",
Smite => "minecraft:smite",
BaneOfArthropods => "minecraft:bane_of_arthropods",
Knockback => "minecraft:knockback",
FireAspect => "minecraft:fire_aspect",
Looting => "minecraft:looting",
SweepingEdge => "minecraft:sweeping_edge",
Efficiency => "minecraft:efficiency",
SilkTouch => "minecraft:silk_touch",
Unbreaking => "minecraft:unbreaking",
Fortune => "minecraft:fortune",
Power => "minecraft:power",
Punch => "minecraft:punch",
Flame => "minecraft:flame",
Infinity => "minecraft:infinity",
LuckOfTheSea => "minecraft:luck_of_the_sea",
Lure => "minecraft:lure",
Loyalty => "minecraft:loyalty",
Impaling => "minecraft:impaling",
Riptide => "minecraft:riptide",
Channeling => "minecraft:channeling",
Multishot => "minecraft:multishot",
QuickCharge => "minecraft:quick_charge",
Piercing => "minecraft:piercing",
Density => "minecraft:density",
Breach => "minecraft:breach",
WindBurst => "minecraft:wind_burst",
Mending => "minecraft:mending",
VanishingCurse => "minecraft:vanishing_curse",
}
}
registry! {
/// An enum that contains every type of entity.
enum EntityKind {
@ -1961,19 +1870,6 @@ enum HeightProviderKind {
}
}
registry! {
enum Instrument {
PonderGoatHorn => "minecraft:ponder_goat_horn",
SingGoatHorn => "minecraft:sing_goat_horn",
SeekGoatHorn => "minecraft:seek_goat_horn",
FeelGoatHorn => "minecraft:feel_goat_horn",
AdmireGoatHorn => "minecraft:admire_goat_horn",
CallGoatHorn => "minecraft:call_goat_horn",
YearnGoatHorn => "minecraft:yearn_goat_horn",
DreamGoatHorn => "minecraft:dream_goat_horn",
}
}
registry! {
enum IntProviderKind {
Constant => "minecraft:constant",
@ -3593,35 +3489,6 @@ enum MemoryModuleKind {
}
}
registry! {
enum Menu {
Generic9x1 => "minecraft:generic_9x1",
Generic9x2 => "minecraft:generic_9x2",
Generic9x3 => "minecraft:generic_9x3",
Generic9x4 => "minecraft:generic_9x4",
Generic9x5 => "minecraft:generic_9x5",
Generic9x6 => "minecraft:generic_9x6",
Generic3x3 => "minecraft:generic_3x3",
Anvil => "minecraft:anvil",
Beacon => "minecraft:beacon",
BlastFurnace => "minecraft:blast_furnace",
BrewingStand => "minecraft:brewing_stand",
Crafting => "minecraft:crafting",
Enchantment => "minecraft:enchantment",
Furnace => "minecraft:furnace",
Grindstone => "minecraft:grindstone",
Hopper => "minecraft:hopper",
Lectern => "minecraft:lectern",
Loom => "minecraft:loom",
Merchant => "minecraft:merchant",
ShulkerBox => "minecraft:shulker_box",
Smithing => "minecraft:smithing",
Smoker => "minecraft:smoker",
CartographyTable => "minecraft:cartography_table",
Stonecutter => "minecraft:stonecutter",
}
}
registry! {
enum MobEffect {
Speed => "minecraft:speed",
@ -3666,41 +3533,6 @@ enum MobEffect {
}
}
registry! {
enum PaintingVariant {
Kebab => "minecraft:kebab",
Aztec => "minecraft:aztec",
Alban => "minecraft:alban",
Aztec2 => "minecraft:aztec2",
Bomb => "minecraft:bomb",
Plant => "minecraft:plant",
Wasteland => "minecraft:wasteland",
Pool => "minecraft:pool",
Courbet => "minecraft:courbet",
Sea => "minecraft:sea",
Sunset => "minecraft:sunset",
Creebet => "minecraft:creebet",
Wanderer => "minecraft:wanderer",
Graham => "minecraft:graham",
Match => "minecraft:match",
Bust => "minecraft:bust",
Stage => "minecraft:stage",
Void => "minecraft:void",
SkullAndRoses => "minecraft:skull_and_roses",
Wither => "minecraft:wither",
Fighters => "minecraft:fighters",
Pointer => "minecraft:pointer",
Pigscene => "minecraft:pigscene",
BurningSkull => "minecraft:burning_skull",
Skeleton => "minecraft:skeleton",
Earth => "minecraft:earth",
Wind => "minecraft:wind",
Water => "minecraft:water",
Fire => "minecraft:fire",
DonkeyKong => "minecraft:donkey_kong",
}
}
registry! {
enum ParticleKind {
AngryVillager => "minecraft:angry_villager",
@ -6058,36 +5890,6 @@ enum WorldgenTrunkPlacerKind {
}
}
registry! {
enum DecoratedPotPatterns {
DecoratedPotSide => "minecraft:decorated_pot_side",
AnglerPotteryPattern => "minecraft:angler_pottery_pattern",
ArcherPotteryPattern => "minecraft:archer_pottery_pattern",
ArmsUpPotteryPattern => "minecraft:arms_up_pottery_pattern",
BladePotteryPattern => "minecraft:blade_pottery_pattern",
BrewerPotteryPattern => "minecraft:brewer_pottery_pattern",
BurnPotteryPattern => "minecraft:burn_pottery_pattern",
DangerPotteryPattern => "minecraft:danger_pottery_pattern",
ExplorerPotteryPattern => "minecraft:explorer_pottery_pattern",
FlowPotteryPattern => "minecraft:flow_pottery_pattern",
FriendPotteryPattern => "minecraft:friend_pottery_pattern",
GusterPotteryPattern => "minecraft:guster_pottery_pattern",
HeartPotteryPattern => "minecraft:heart_pottery_pattern",
HeartbreakPotteryPattern => "minecraft:heartbreak_pottery_pattern",
HowlPotteryPattern => "minecraft:howl_pottery_pattern",
MinerPotteryPattern => "minecraft:miner_pottery_pattern",
MournerPotteryPattern => "minecraft:mourner_pottery_pattern",
PlentyPotteryPattern => "minecraft:plenty_pottery_pattern",
PrizePotteryPattern => "minecraft:prize_pottery_pattern",
ScrapePotteryPattern => "minecraft:scrape_pottery_pattern",
SheafPotteryPattern => "minecraft:sheaf_pottery_pattern",
ShelterPotteryPattern => "minecraft:shelter_pottery_pattern",
SkullPotteryPattern => "minecraft:skull_pottery_pattern",
SnortPotteryPattern => "minecraft:snort_pottery_pattern",
DecoratedPotBase => "minecraft:decorated_pot_base",
}
}
registry! {
enum RuleBlockEntityModifier {
Clear => "minecraft:clear",
@ -6473,19 +6275,6 @@ enum NumberFormatKind {
}
}
registry! {
enum ArmorMaterial {
Leather => "minecraft:leather",
Chainmail => "minecraft:chainmail",
Iron => "minecraft:iron",
Gold => "minecraft:gold",
Diamond => "minecraft:diamond",
Turtle => "minecraft:turtle",
Netherite => "minecraft:netherite",
Armadillo => "minecraft:armadillo",
}
}
registry! {
enum DataComponentKind {
CustomData => "minecraft:custom_data",

View file

@ -9,6 +9,8 @@ def generate_registries(registries: dict):
with open(REGISTRIES_DIR, 'r') as f:
code = f.read().split('\n')
existing_registry_enum_names = set()
for registry_name, registry in registries.items():
# registry!(Block, {
# Air => "minecraft:air",
@ -18,6 +20,8 @@ def generate_registries(registries: dict):
registry_name = registry_name.split(':')[1]
registry_enum_name = registry_name_to_enum_name(registry_name)
existing_registry_enum_names.add(registry_enum_name)
registry_code = []
registry_code.append(f'enum {registry_enum_name} {{')
registry_entries = sorted(
@ -47,6 +51,24 @@ def generate_registries(registries: dict):
code.append('}')
code.append('')
# delete the unused registries
i = 0
while i < len(code):
if code[i] == 'registry! {':
# skip until we get to the enum line
while not code[i].startswith('enum '):
i += 1
enum_name = code[i].split(' ')[1]
if enum_name not in existing_registry_enum_names:
i -= 1
while code[i] != '}':
code.pop(i)
code.pop(i)
# close the registry! block
code.pop(i)
else:
i += 1
with open(REGISTRIES_DIR, 'w') as f:
f.write('\n'.join(code))