Revert "feat: implementing the base generation of advancement (#2236)"
This reverts commit decfc460b2.
This commit is contained in:
parent
636331ead3
commit
dd524b6ef9
File diff suppressed because one or more lines are too long
@ -1,534 +0,0 @@
|
|||||||
use heck::ToShoutySnakeCase;
|
|
||||||
use proc_macro2::TokenStream;
|
|
||||||
use pumpkin_util::identifier::Identifier;
|
|
||||||
use pumpkin_util::resource_location::ResourceLocation;
|
|
||||||
use pumpkin_util::text::TextComponent;
|
|
||||||
use pumpkin_util::text::TextContent::Translate;
|
|
||||||
use quote::{ToTokens, format_ident, quote};
|
|
||||||
use serde::{Deserialize, Deserializer, Serialize, de::Error as _};
|
|
||||||
use std::cmp::PartialEq;
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::{collections::BTreeMap, fs};
|
|
||||||
|
|
||||||
// helper default used by serde for fields that should be `true` when omitted.
|
|
||||||
const fn default_true() -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
///the structure that contains the display information of a advancement
|
|
||||||
#[derive(Deserialize, Clone)]
|
|
||||||
pub struct AdvancementDisplay {
|
|
||||||
pub title: TextComponent,
|
|
||||||
pub description: TextComponent,
|
|
||||||
#[serde(rename = "icon", deserialize_with = "deserialize_icon_id")]
|
|
||||||
pub item_icon: ResourceLocation,
|
|
||||||
#[serde(default, rename = "frame")]
|
|
||||||
pub frame_type: FrameTypeStruct,
|
|
||||||
#[serde(default, rename = "background")]
|
|
||||||
pub background_texture: Option<ResourceLocation>,
|
|
||||||
#[serde(default = "default_true")]
|
|
||||||
pub show_toast: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
pub hidden: bool,
|
|
||||||
#[serde(default = "default_true")]
|
|
||||||
pub announce_to_chat: bool,
|
|
||||||
#[serde(skip)]
|
|
||||||
pub x: f32,
|
|
||||||
#[serde(skip)]
|
|
||||||
pub y: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_translate(text: &TextComponent) -> TokenStream {
|
|
||||||
let Translate {
|
|
||||||
translate,
|
|
||||||
bedrock_translate: _,
|
|
||||||
with: _,
|
|
||||||
} = text.0.content.as_ref()
|
|
||||||
else {
|
|
||||||
panic!("expected a translatable text component for advancement display")
|
|
||||||
};
|
|
||||||
quote! { #translate }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn token_option<D>(option: &Option<D>) -> TokenStream
|
|
||||||
where
|
|
||||||
D: ToTokens,
|
|
||||||
{
|
|
||||||
match option {
|
|
||||||
Some(x) => quote! { Some(#x) },
|
|
||||||
None => quote! { None },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToTokens for AdvancementDisplay {
|
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
||||||
let item_icon = format_ident!(
|
|
||||||
"{}",
|
|
||||||
self.item_icon
|
|
||||||
.strip_prefix("minecraft:")
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
panic!(
|
|
||||||
"expected a vanilla Minecraft item icon, got `{}`",
|
|
||||||
self.item_icon
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.to_uppercase()
|
|
||||||
);
|
|
||||||
let frame_type = &self.frame_type;
|
|
||||||
let announce_to_chat = &self.announce_to_chat;
|
|
||||||
let show_toast = &self.show_toast;
|
|
||||||
let hidden = &self.hidden;
|
|
||||||
let background_texture = token_option(&self.background_texture);
|
|
||||||
let title = as_translate(&self.title);
|
|
||||||
let description = as_translate(&self.description);
|
|
||||||
let x = self.x;
|
|
||||||
let y = self.y;
|
|
||||||
tokens.extend(quote! {
|
|
||||||
AdvancementDisplay::new(#title,
|
|
||||||
#description,
|
|
||||||
ItemStack::new(1,&Item::#item_icon),
|
|
||||||
#frame_type,
|
|
||||||
#background_texture,
|
|
||||||
#show_toast,
|
|
||||||
#hidden,
|
|
||||||
#announce_to_chat,
|
|
||||||
#x,
|
|
||||||
#y,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///store which type of frame should be use when display
|
|
||||||
#[derive(Clone, Copy, Deserialize, Serialize, Default)]
|
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
pub enum FrameTypeStruct {
|
|
||||||
#[default]
|
|
||||||
Task = 0,
|
|
||||||
Challenge = 1,
|
|
||||||
Goal = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToTokens for FrameTypeStruct {
|
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
||||||
let t = match self {
|
|
||||||
FrameTypeStruct::Task => quote! { FrameType::Task },
|
|
||||||
FrameTypeStruct::Challenge => quote! { FrameType::Challenge },
|
|
||||||
FrameTypeStruct::Goal => quote! { FrameType::Goal },
|
|
||||||
};
|
|
||||||
tokens.extend(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///what it gives you when you complete a advancment
|
|
||||||
#[derive(Deserialize, Default, Clone)]
|
|
||||||
pub struct AdvancementRewards {
|
|
||||||
#[serde(default)]
|
|
||||||
experience: i32,
|
|
||||||
//loot: Vec<ResourceLocation> TODO,
|
|
||||||
#[serde(default)]
|
|
||||||
recipes: Vec<ResourceLocation>,
|
|
||||||
//functions: Option<Function> TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToTokens for AdvancementRewards {
|
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
||||||
let experience = self.experience;
|
|
||||||
let recipes = self.recipes.iter().map(|_recipe| {
|
|
||||||
quote! {
|
|
||||||
//TODO implement recipe reward
|
|
||||||
//Recipe::from_id(#recipe)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tokens.extend(quote! {
|
|
||||||
AdvancementReward {
|
|
||||||
experience: #experience,
|
|
||||||
recipes: &[#(#recipes),*],
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// represent a node in the advancement tree
|
|
||||||
pub struct AdvancementNode {
|
|
||||||
pub children: Vec<usize>,
|
|
||||||
pub parent: Option<usize>,
|
|
||||||
pub value: AdvancementHolder,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AdvancementNode {
|
|
||||||
#[inline]
|
|
||||||
pub fn add_child(&mut self, child: usize) {
|
|
||||||
self.children.push(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(value: AdvancementHolder, parent: Option<usize>) -> Self {
|
|
||||||
Self {
|
|
||||||
value,
|
|
||||||
parent,
|
|
||||||
children: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[must_use]
|
|
||||||
pub const fn has_display(&self) -> bool {
|
|
||||||
self.value.1.display.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub const fn set_location(&mut self, x: f32, y: f32) {
|
|
||||||
if let Some(val) = self.value.1.display.as_mut() {
|
|
||||||
val.x = x;
|
|
||||||
val.y = y;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq<Self> for AdvancementNode {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.value == other.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for AdvancementNode {}
|
|
||||||
|
|
||||||
impl Display for AdvancementNode {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", self.value.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Hash for AdvancementNode {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.value.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToTokens for AdvancementNode {
|
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
||||||
let parent = token_option(&self.parent);
|
|
||||||
let children = &self.children;
|
|
||||||
let value = &self.value;
|
|
||||||
tokens.extend(quote! {
|
|
||||||
AdvancementNode{
|
|
||||||
parent:#parent,
|
|
||||||
children: vec![#(#children),*],
|
|
||||||
value: #value,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///the structure that represent a advancement
|
|
||||||
#[derive(Deserialize, Default, Clone)]
|
|
||||||
pub struct AdvancementStruct {
|
|
||||||
pub parent: Option<Identifier>,
|
|
||||||
#[serde(default)]
|
|
||||||
pub display: Option<AdvancementDisplay>,
|
|
||||||
//pub criteria : Vec<Criterion>,
|
|
||||||
#[serde(default)]
|
|
||||||
pub rewards: AdvancementRewards,
|
|
||||||
#[serde(default, rename = "sends_telemetry_event")]
|
|
||||||
pub sends_telemetry: bool,
|
|
||||||
pub requirements: Vec<Vec<String>>,
|
|
||||||
}
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct AdvancementHolder(Identifier, AdvancementStruct);
|
|
||||||
|
|
||||||
impl PartialEq for AdvancementHolder {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.0.eq(&other.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Eq for AdvancementHolder {}
|
|
||||||
|
|
||||||
impl Hash for AdvancementHolder {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.0.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToTokens for AdvancementHolder {
|
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
||||||
let name = format_ident!("{}", self.0.path().to_shouty_snake_case());
|
|
||||||
tokens.extend(quote! {
|
|
||||||
Advancement::#name
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///the item use for the icon of the display
|
|
||||||
/// (doesn't support custom items has the vanilla advancement does not use custom items)
|
|
||||||
#[derive(Deserialize)]
|
|
||||||
struct DisplayIcon {
|
|
||||||
id: ResourceLocation,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_icon_id<'de, D>(deserializer: D) -> Result<ResourceLocation, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let icon = DisplayIcon::deserialize(deserializer)?;
|
|
||||||
Ok(icon.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// represent the structure that is used to store the different node and linking her id to it's corresponding node.
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct AdvancementTree {
|
|
||||||
pub nodes: BTreeMap<Identifier, usize>,
|
|
||||||
pub nodes_vector: Vec<AdvancementNode>,
|
|
||||||
pub roots: Vec<usize>,
|
|
||||||
pub tasks: Vec<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AdvancementTree {
|
|
||||||
///Iterate over all advancements until every advancement that can be inserted has been inserted.
|
|
||||||
///
|
|
||||||
///see [`AdvancementTree::try_insert`]
|
|
||||||
pub fn add_all(&mut self, advancements: Vec<AdvancementHolder>) {
|
|
||||||
let mut advancements_to_add: Vec<AdvancementHolder> = advancements;
|
|
||||||
|
|
||||||
while !advancements_to_add.is_empty() {
|
|
||||||
let len_before = advancements_to_add.len();
|
|
||||||
|
|
||||||
advancements_to_add = advancements_to_add
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|advancement| self.try_insert(advancement))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if advancements_to_add.len() == len_before && !advancements_to_add.is_empty() {
|
|
||||||
eprintln!(
|
|
||||||
"Couldn't load advancements: {:?}",
|
|
||||||
advancements_to_add.iter().map(|a| &a.0).collect::<Vec<_>>()
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///try to insert the advancement in the tree if it has a parent and his has not yet been register fail
|
|
||||||
/// and return the owned AdvancementHolder
|
|
||||||
pub fn try_insert(&mut self, advancement: AdvancementHolder) -> Option<AdvancementHolder> {
|
|
||||||
let parent_id = &advancement.1.parent;
|
|
||||||
let parent_idx: Option<usize> = match parent_id {
|
|
||||||
Some(id) => match self.nodes.get(id) {
|
|
||||||
Some(node) => Some(*node),
|
|
||||||
None => return Some(advancement),
|
|
||||||
},
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
let id = advancement.0.clone();
|
|
||||||
let node = AdvancementNode::new(advancement, parent_idx);
|
|
||||||
let node_idx = self.nodes_vector.len();
|
|
||||||
self.nodes.insert(id, node_idx);
|
|
||||||
if let Some(parent) = parent_idx {
|
|
||||||
let parent_node = self.nodes_vector.get_mut(parent).unwrap();
|
|
||||||
parent_node.add_child(node_idx);
|
|
||||||
self.tasks.push(node_idx);
|
|
||||||
} else {
|
|
||||||
self.roots.push(node_idx);
|
|
||||||
}
|
|
||||||
self.nodes_vector.push(node);
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToTokens for AdvancementTree {
|
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
|
||||||
let nodes = self.nodes.iter().map(|(k, v)| {
|
|
||||||
quote! {
|
|
||||||
nodes.insert(#k, #v);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let nodes_vector = &self.nodes_vector;
|
|
||||||
let roots = &self.roots;
|
|
||||||
let tasks = &self.tasks;
|
|
||||||
tokens.extend(quote! {
|
|
||||||
LazyLock::new(|| {
|
|
||||||
let mut nodes = BTreeMap::new();
|
|
||||||
#(#nodes)*
|
|
||||||
let nodes_vector = vec![#(#nodes_vector),*];
|
|
||||||
let roots = vec![#(#roots),*];
|
|
||||||
let tasks = vec![#(#tasks),*];
|
|
||||||
AdvancementTree {
|
|
||||||
nodes,
|
|
||||||
nodes_vector,
|
|
||||||
roots,
|
|
||||||
tasks,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///Convert a identifier to its token form
|
|
||||||
fn identifier_to_tokens(identifier: &Identifier) -> TokenStream {
|
|
||||||
let namespace = identifier.namespace();
|
|
||||||
let path = identifier.path();
|
|
||||||
quote! {
|
|
||||||
Identifier::from_static(#namespace, #path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn build() -> TokenStream {
|
|
||||||
let advancements_path =
|
|
||||||
std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../assets/advancements.json");
|
|
||||||
let advancements_json = fs::read_to_string(&advancements_path)
|
|
||||||
.unwrap_or_else(|err| panic!("Failed to read {}: {err}", advancements_path.display()));
|
|
||||||
let advancements: BTreeMap<String, AdvancementStruct> =
|
|
||||||
serde_json::from_str(&advancements_json)
|
|
||||||
.unwrap_or_else(|err| panic!("Failed to parse {}: {err}", advancements_path.display()));
|
|
||||||
|
|
||||||
let mut variants = TokenStream::new();
|
|
||||||
let mut name_to_type = TokenStream::new();
|
|
||||||
let mut minecraft_name_to_type = TokenStream::new();
|
|
||||||
let mut minecraft_namespaces = TokenStream::new();
|
|
||||||
let capacity = advancements.len();
|
|
||||||
//construct the tree
|
|
||||||
let mut tree = AdvancementTree::default();
|
|
||||||
tree.add_all(
|
|
||||||
advancements
|
|
||||||
.into_iter()
|
|
||||||
.map(|(key, value)| AdvancementHolder(Identifier::parse(&key).unwrap(), value))
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
let advancement_tree = quote! {
|
|
||||||
pub static ADVANCEMENT_TREE : LazyLock<AdvancementTree> = #tree;
|
|
||||||
};
|
|
||||||
let advancements_holder: Vec<AdvancementHolder> = tree
|
|
||||||
.nodes_vector
|
|
||||||
.into_iter()
|
|
||||||
.map(|node| node.value)
|
|
||||||
.collect();
|
|
||||||
for AdvancementHolder(identifier, advancement) in advancements_holder {
|
|
||||||
let raw_name = identifier.path();
|
|
||||||
let format_name = format_ident!("{}", raw_name.to_shouty_snake_case());
|
|
||||||
|
|
||||||
let parent = if let Some(identifier) = &advancement.parent {
|
|
||||||
let parent = identifier_to_tokens(identifier);
|
|
||||||
quote! {Some(#parent)}
|
|
||||||
} else {
|
|
||||||
quote! { None }
|
|
||||||
};
|
|
||||||
let send_telemetry = advancement.sends_telemetry;
|
|
||||||
let display = match &advancement.display {
|
|
||||||
Some(display) => quote! { Some(&#display) },
|
|
||||||
None => quote! { None },
|
|
||||||
};
|
|
||||||
let reward = advancement.rewards;
|
|
||||||
let requirements = advancement.requirements.iter().map(|inner_req| {
|
|
||||||
quote! { &[#(#inner_req),*]}
|
|
||||||
});
|
|
||||||
variants.extend([quote! {
|
|
||||||
pub const #format_name: &Self = &Self {
|
|
||||||
id: Identifier::vanilla_static(#raw_name),
|
|
||||||
parent : #parent,
|
|
||||||
send_telemetry : #send_telemetry,
|
|
||||||
display : #display,
|
|
||||||
reward : &#reward,
|
|
||||||
requirements: AdvancementRequirement{
|
|
||||||
requirements : &[#(#requirements),*]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}]);
|
|
||||||
let minecraft_name = identifier.to_string();
|
|
||||||
name_to_type.extend(quote! { #raw_name => Some(Self::#format_name), });
|
|
||||||
minecraft_name_to_type.extend(quote! { #minecraft_name => Some(Self::#format_name), });
|
|
||||||
minecraft_namespaces.extend(quote! { #identifier,})
|
|
||||||
}
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
use pumpkin_util::text::TextComponent;
|
|
||||||
use crate::item_stack::ItemStack;
|
|
||||||
use crate::item::Item;
|
|
||||||
use crate::advancement_data::*;
|
|
||||||
use std::sync::LazyLock;
|
|
||||||
use pumpkin_util::identifier::Identifier;
|
|
||||||
use pumpkin_util::text::{color::NamedColor,
|
|
||||||
style::Style,
|
|
||||||
hover::HoverEvent,
|
|
||||||
color::Color};
|
|
||||||
use std::hash::{Hash,Hasher};
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
pub struct Advancement {
|
|
||||||
pub id : Identifier,
|
|
||||||
pub parent : Option<Identifier>,
|
|
||||||
pub send_telemetry : bool,
|
|
||||||
pub display : Option<&'static AdvancementDisplay>,
|
|
||||||
pub reward : &'static AdvancementReward,
|
|
||||||
pub requirements: AdvancementRequirement,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Advancement {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", self.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hash for Advancement {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.id.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq<Self> for Advancement {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
other.id == self.id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for Advancement {}
|
|
||||||
|
|
||||||
impl Advancement {
|
|
||||||
#variants
|
|
||||||
|
|
||||||
pub fn option_name(&self) -> Option<TextComponent> {
|
|
||||||
match self.display {
|
|
||||||
Some(display) => {
|
|
||||||
let mut over = display.get_title();
|
|
||||||
let color = Color::Named(display.frame_type.get_color());
|
|
||||||
*over.0.style = Style::default().color(color);
|
|
||||||
over = over.add_text("\n").add_child(display.get_description());
|
|
||||||
let mut text = display.get_title();
|
|
||||||
text.0.style.hover_event = Some(HoverEvent::show_text(over));
|
|
||||||
Some(text.wrap_in_square_brackets().color(color))
|
|
||||||
}
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn name(&self) -> TextComponent {
|
|
||||||
self.option_name().unwrap_or(TextComponent::text(self.id.to_string()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_name(name: &str) -> Option<&'static Self> {
|
|
||||||
match name {
|
|
||||||
#name_to_type
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn from_minecraft_name(name: &str) -> Option<&'static Self> {
|
|
||||||
match name {
|
|
||||||
#minecraft_name_to_type
|
|
||||||
_ => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn get_list() -> [Identifier;#capacity] {
|
|
||||||
[#minecraft_namespaces]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn is_root(&self) -> bool{
|
|
||||||
self.parent.is_none()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
#advancement_tree
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -9,7 +9,6 @@ use std::{
|
|||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod advancement;
|
|
||||||
mod attributes;
|
mod attributes;
|
||||||
mod biome;
|
mod biome;
|
||||||
mod bitsets;
|
mod bitsets;
|
||||||
@ -76,7 +75,6 @@ pub fn main() {
|
|||||||
wit::main();
|
wit::main();
|
||||||
|
|
||||||
let mut build_functions: Vec<(BuilderFn, &str)> = vec![
|
let mut build_functions: Vec<(BuilderFn, &str)> = vec![
|
||||||
(advancement::build, "advancement.rs"),
|
|
||||||
(packet::build, "packet.rs"),
|
(packet::build, "packet.rs"),
|
||||||
(screen::build, "screen.rs"),
|
(screen::build, "screen.rs"),
|
||||||
(particle::build, "particle.rs"),
|
(particle::build, "particle.rs"),
|
||||||
|
|||||||
@ -18,10 +18,9 @@ pub fn map_type(ty: &Type) -> WitType {
|
|||||||
"u16" | "i16" => WitType::S32,
|
"u16" | "i16" => WitType::S32,
|
||||||
"Option" => {
|
"Option" => {
|
||||||
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments
|
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments
|
||||||
&& let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first()
|
&& let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first() {
|
||||||
{
|
return WitType::option(map_type(inner_ty));
|
||||||
return WitType::option(map_type(inner_ty));
|
}
|
||||||
}
|
|
||||||
WitType::String
|
WitType::String
|
||||||
}
|
}
|
||||||
"Box" => {
|
"Box" => {
|
||||||
@ -33,16 +32,15 @@ pub fn map_type(ty: &Type) -> WitType {
|
|||||||
}
|
}
|
||||||
"Vec" => {
|
"Vec" => {
|
||||||
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments
|
if let syn::PathArguments::AngleBracketed(args) = &last_segment.arguments
|
||||||
&& let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first()
|
&& let Some(syn::GenericArgument::Type(inner_ty)) = args.args.first() {
|
||||||
{
|
// Check if the inner type is u8
|
||||||
// Check if the inner type is u8
|
if let Type::Path(tp) = inner_ty
|
||||||
if let Type::Path(tp) = inner_ty
|
&& tp.path.segments.last().unwrap().ident == "u8"
|
||||||
&& tp.path.segments.last().unwrap().ident == "u8"
|
{
|
||||||
{
|
return WitType::list(WitType::U8);
|
||||||
return WitType::list(WitType::U8);
|
}
|
||||||
|
return WitType::list(map_type(inner_ty));
|
||||||
}
|
}
|
||||||
return WitType::list(map_type(inner_ty));
|
|
||||||
}
|
|
||||||
WitType::String
|
WitType::String
|
||||||
}
|
}
|
||||||
"Vector3" | "BlockPos" => {
|
"Vector3" | "BlockPos" => {
|
||||||
|
|||||||
@ -41,7 +41,6 @@ default = [
|
|||||||
"potion",
|
"potion",
|
||||||
"recipe_remainder",
|
"recipe_remainder",
|
||||||
"chunk_gen_settings",
|
"chunk_gen_settings",
|
||||||
"advancement",
|
|
||||||
"carver",
|
"carver",
|
||||||
"villager",
|
"villager",
|
||||||
"placed_feature",
|
"placed_feature",
|
||||||
@ -49,7 +48,6 @@ default = [
|
|||||||
"slot_ranges"
|
"slot_ranges"
|
||||||
]
|
]
|
||||||
|
|
||||||
advancement = []
|
|
||||||
item = []
|
item = []
|
||||||
packet = []
|
packet = []
|
||||||
jukebox_song = []
|
jukebox_song = []
|
||||||
|
|||||||
@ -1,197 +0,0 @@
|
|||||||
use crate::item_stack::ItemStack;
|
|
||||||
use crate::potion_brewing::ItemRecipe;
|
|
||||||
use crate::{ADVANCEMENT_TREE, Advancement};
|
|
||||||
use pumpkin_util::identifier::Identifier;
|
|
||||||
use pumpkin_util::resource_location::ResourceLocation;
|
|
||||||
use pumpkin_util::text::TextComponent;
|
|
||||||
use pumpkin_util::text::color::{Color, NamedColor};
|
|
||||||
use serde::ser::SerializeStruct;
|
|
||||||
use serde::{Deserialize, Serialize, Serializer};
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::fmt::Display;
|
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct AdvancementDisplay {
|
|
||||||
pub title: &'static str,
|
|
||||||
pub description: &'static str,
|
|
||||||
pub item_icon: ItemStack,
|
|
||||||
pub frame_type: FrameType,
|
|
||||||
pub background_texture: Option<&'static str>,
|
|
||||||
pub show_toast: bool,
|
|
||||||
pub hidden: bool,
|
|
||||||
pub announce_to_chat: bool,
|
|
||||||
pub x: f32,
|
|
||||||
pub y: f32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AdvancementDisplay {
|
|
||||||
pub fn get_title(&self) -> TextComponent {
|
|
||||||
TextComponent::translate(self.title, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_description(&self) -> TextComponent {
|
|
||||||
TextComponent::translate(self.description, [])
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_background(&self) -> bool {
|
|
||||||
self.background_texture.is_some()
|
|
||||||
}
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub const fn new(
|
|
||||||
title: &'static str,
|
|
||||||
description: &'static str,
|
|
||||||
item_icon: ItemStack,
|
|
||||||
frame_type: FrameType,
|
|
||||||
background_texture: Option<&'static str>,
|
|
||||||
show_toast: bool,
|
|
||||||
hidden: bool,
|
|
||||||
announce_to_chat: bool,
|
|
||||||
x: f32,
|
|
||||||
y: f32,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
frame_type,
|
|
||||||
item_icon,
|
|
||||||
background_texture,
|
|
||||||
show_toast,
|
|
||||||
hidden,
|
|
||||||
announce_to_chat,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Deserialize, Serialize, Default, Debug)]
|
|
||||||
#[repr(i32)]
|
|
||||||
#[serde(rename_all = "lowercase")]
|
|
||||||
pub enum FrameType {
|
|
||||||
#[default]
|
|
||||||
Task = 0,
|
|
||||||
Challenge = 1,
|
|
||||||
Goal = 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FrameType {
|
|
||||||
pub fn get_color(&self) -> NamedColor {
|
|
||||||
match self {
|
|
||||||
FrameType::Task => NamedColor::Green,
|
|
||||||
FrameType::Challenge => NamedColor::DarkPurple,
|
|
||||||
FrameType::Goal => NamedColor::Green,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_name(&self) -> &'static str {
|
|
||||||
match self {
|
|
||||||
FrameType::Task => "task",
|
|
||||||
FrameType::Challenge => "challenge",
|
|
||||||
FrameType::Goal => "goal",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AdvancementReward {
|
|
||||||
pub experience: i32,
|
|
||||||
pub recipes: &'static [ItemRecipe],
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AdvancementNode {
|
|
||||||
pub children: Vec<usize>,
|
|
||||||
pub parent: Option<usize>,
|
|
||||||
pub value: &'static Advancement,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AdvancementNode {
|
|
||||||
pub fn add_child(&mut self, child: usize) {
|
|
||||||
self.children.push(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(value: &'static Advancement, parent: Option<usize>) -> Self {
|
|
||||||
Self {
|
|
||||||
value,
|
|
||||||
parent,
|
|
||||||
children: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
#[must_use]
|
|
||||||
pub const fn has_display(&self) -> bool {
|
|
||||||
self.value.display.is_some()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn root(&self) -> &AdvancementNode {
|
|
||||||
let mut advancement_node = self;
|
|
||||||
while let Some(parent) = &advancement_node.parent {
|
|
||||||
advancement_node = &ADVANCEMENT_TREE.nodes_vector[*parent];
|
|
||||||
}
|
|
||||||
advancement_node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq<Self> for AdvancementNode {
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
|
||||||
self.value == other.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for AdvancementNode {}
|
|
||||||
|
|
||||||
impl Display for AdvancementNode {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}", self.value.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Hash for AdvancementNode {
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
|
||||||
self.value.hash(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct AdvancementTree {
|
|
||||||
pub nodes: BTreeMap<Identifier, usize>,
|
|
||||||
pub nodes_vector: Vec<AdvancementNode>,
|
|
||||||
pub roots: Vec<usize>,
|
|
||||||
pub tasks: Vec<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AdvancementTree {
|
|
||||||
pub fn get_node_from_id(&self, id: &Identifier) -> Option<&AdvancementNode> {
|
|
||||||
if let Some(idx) = self.nodes.get(id) {
|
|
||||||
self.nodes_vector.get(*idx)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_node_from_idx(&self, idx: usize) -> Option<&AdvancementNode> {
|
|
||||||
self.nodes_vector.get(idx)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_idx(&self, id: &Identifier) -> Option<usize> {
|
|
||||||
self.nodes.get(id).copied()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct AdvancementProgress {
|
|
||||||
pub id: Identifier,
|
|
||||||
pub progress: Vec<Criteria>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct Criteria {
|
|
||||||
pub criterion_id: Identifier,
|
|
||||||
pub achieve_date: Option<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AdvancementRequirement {
|
|
||||||
pub requirements: &'static [&'static [&'static str]],
|
|
||||||
}
|
|
||||||
pub trait Criterion {}
|
|
||||||
File diff suppressed because one or more lines are too long
@ -97,7 +97,7 @@ static ITEM_STACK_ID_GEN: ItemStackIdGenerator = ItemStackIdGenerator::new();
|
|||||||
|
|
||||||
impl ItemStack {
|
impl ItemStack {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn new(item_count: u8, item: &'static Item) -> Self {
|
pub fn new(item_count: u8, item: &'static Item) -> Self {
|
||||||
Self {
|
Self {
|
||||||
item_count,
|
item_count,
|
||||||
item,
|
item,
|
||||||
|
|||||||
@ -58,17 +58,6 @@ pub mod sound {
|
|||||||
pub use crate::sound_enum::*;
|
pub use crate::sound_enum::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "advancement")]
|
|
||||||
#[rustfmt::skip]
|
|
||||||
#[path = "generated/advancement.rs"]
|
|
||||||
pub mod advancement;
|
|
||||||
|
|
||||||
#[cfg(feature = "advancement")]
|
|
||||||
pub mod advancement_data;
|
|
||||||
|
|
||||||
#[cfg(feature = "advancement")]
|
|
||||||
pub use advancement::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "recipes")]
|
#[cfg(feature = "recipes")]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
#[path = "generated/recipes.rs"]
|
#[path = "generated/recipes.rs"]
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
|
use std::{borrow::Cow, fmt::Display};
|
||||||
|
|
||||||
use pumpkin_codecs::{DataResult, FlatTryFrom, comap_flat_map_codec_impl};
|
use pumpkin_codecs::{DataResult, FlatTryFrom, comap_flat_map_codec_impl};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{borrow::Cow, fmt::Display};
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub const VANILLA_NAMESPACE: &str = "minecraft";
|
pub const VANILLA_NAMESPACE: &str = "minecraft";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user