valence/valence_protocol/build/enchant.rs
Ryan Johnson 420f2d1b7c
Move protocol code to valence_protocol + redesigns (#153)
Closes #83 

This PR aims to move all of Valence's networking code to the new
`valence_protocol` crate. Anything not specific to valence is going in
the new crate. It also redesigns the way packets are defined and makes a
huge number of small additions and improvements. It should be much
easier to see where code is supposed to go from now on.

`valence_protocol` is a new library which enables interactions with
Minecraft's protocol. It is completely decoupled from valence and can be
used to build new clients, servers, tools, etc.

There are two additions that will help with #5 especially:
- It is now easy to define new packets or modifications of existing
packets. Not all packets need to be bidirectional.
- The `CachedEncode` type has been created. This is used to safely cache
redundant calls to `Encode::encode`.
2022-11-13 06:10:42 -08:00

219 lines
6.6 KiB
Rust

use heck::ToPascalCase;
use proc_macro2::TokenStream;
use quote::quote;
use serde::Deserialize;
use crate::ident;
#[derive(Deserialize, Debug)]
pub struct Enchantment {
#[allow(unused)]
id: u16,
name: String,
translation_key: String,
min_level: i16,
max_level: i16,
#[serde(alias = "cursed")]
is_curse: bool,
rarity_weight: i32,
#[serde(alias = "sources")]
source: EnchantmentSources,
}
#[derive(Deserialize, Debug)]
pub struct EnchantmentSources {
treasure: bool,
enchantment_table: bool,
random_selection: bool,
}
pub fn build() -> anyhow::Result<TokenStream> {
let enchants: Vec<Enchantment> =
serde_json::from_str(include_str!("../../extracted/enchants.json"))?;
let enchantmentkind_definitions = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let id = enchant.id as isize;
quote! {
#rustified_name = #id,
}
})
.collect::<TokenStream>();
let enchantmentkind_id_to_variant_lookup = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let id = &enchant.id;
quote! {
#id => Some(Self::#rustified_name),
}
})
.collect::<TokenStream>();
let enchantmentkind_names = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let name = &enchant.name;
quote! {
Self::#rustified_name => #name,
}
})
.collect::<TokenStream>();
let enchantmentkind_translations = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let translation_key = &enchant.translation_key;
quote! {
Self::#rustified_name => #translation_key,
}
})
.collect::<TokenStream>();
let enchantmentkind_min_level = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let min_level = &enchant.min_level;
quote! {
Self::#rustified_name => #min_level,
}
})
.collect::<TokenStream>();
let enchantmentkind_max_level = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let max_level = &enchant.max_level;
quote! {
Self::#rustified_name => #max_level,
}
})
.collect::<TokenStream>();
let enchantmentkind_is_curse = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let is_curse = &enchant.is_curse;
quote! {
Self::#rustified_name => #is_curse,
}
})
.collect::<TokenStream>();
let enchantmentkind_rarity_weight = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let rarity_weight = &enchant.rarity_weight;
quote! {
Self::#rustified_name => #rarity_weight,
}
})
.collect::<TokenStream>();
let enchantmentkind_sources = enchants
.iter()
.map(|enchant| {
let rustified_name = ident(enchant.name.to_pascal_case());
let treasure = &enchant.source.treasure;
let enchantment_table = &enchant.source.enchantment_table;
let random_selection = &enchant.source.random_selection;
quote! {
Self::#rustified_name => EnchantmentSources {
treasure: #treasure,
enchantment_table: #enchantment_table,
random_selection: #random_selection,
},
}
})
.collect::<TokenStream>();
Ok(quote! {
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EnchantmentSources {
pub treasure: bool,
pub enchantment_table: bool,
pub random_selection: bool,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum EnchantmentKind {
#enchantmentkind_definitions
}
impl EnchantmentKind {
/// Constructs an `EnchantmentKind` from a raw enchantment ID.
///
/// If the given ID is invalid, `None` is returned.
pub const fn from_raw(id: u16) -> Option<Self> {
match id{
#enchantmentkind_id_to_variant_lookup
_ => None
}
}
/// Returns the raw enchantment ID.
pub const fn to_raw(self) -> u16 {
self as u16
}
/// Returns the translation key.
pub const fn translation_key(self) -> &'static str {
match self{
#enchantmentkind_translations
}
}
/// Returns the enchantment name the game uses.
pub const fn name(self) -> &'static str {
match self{
#enchantmentkind_names
}
}
/// Returns the minimum enchantment level officially supported by Minecraft.
pub const fn min_level(self) -> i16 {
match self{
#enchantmentkind_min_level
}
}
/// Returns the maximum enchantment level officially supported by Minecraft.
pub const fn max_level(self) -> i16 {
match self{
#enchantmentkind_max_level
}
}
/// Returns true if the enchantment is of the curse type.
pub const fn is_curse(self) -> bool {
match self{
#enchantmentkind_is_curse
}
}
/// Returns the rarity of the enchant. Lower means more rare.
pub const fn rarity_weight(self) -> i32 {
match self{
#enchantmentkind_rarity_weight
}
}
/// Returns the different sources this enchantment has.
pub const fn sources(self) -> EnchantmentSources {
match self{
#enchantmentkind_sources
}
}
}
})
}