From ed0bf820f7d3fbe7cdea3a23f0a7863882920ccd Mon Sep 17 00:00:00 2001 From: kedor <99351777+aure31@users.noreply.github.com> Date: Wed, 24 Jun 2026 18:20:12 +0200 Subject: [PATCH] feat: Add the display position calculation of the advancements (#2256) * generate the placement of the advancements to be display rightfully for the client * fix typos with appropriate naming --- pumpkin-codegen/src/advancement.rs | 437 +++++++++++++++++++- pumpkin-data/src/generated/advancement.rs | 474 +++++++++++----------- 2 files changed, 673 insertions(+), 238 deletions(-) diff --git a/pumpkin-codegen/src/advancement.rs b/pumpkin-codegen/src/advancement.rs index 8e40eb392..8daddfb18 100644 --- a/pumpkin-codegen/src/advancement.rs +++ b/pumpkin-codegen/src/advancement.rs @@ -220,8 +220,433 @@ impl ToTokens for AdvancementNode { }) } } +/// Represents a node in the advancement tree used to calculate positions using the Reingold-Tilford algorithm. +/// +/// This structure is used internally by the positioning algorithm to compute the layout of advancements +/// as they are displayed by the client, mirroring the behavior of the original Minecraft server. +/// Each node stores positioning information, parent-child relationships, and temporary data used during +/// the tree traversal algorithms. +struct TreeNodePosition { + node: usize, + parent: Option, + previous_sibling: Option, + child_index: usize, + children: Vec, + ancestor: usize, + thread: Option, + x: i32, + y: f32, + mod_field: f32, + change: f32, + shift: f32, +} -///the structure that represent a advancement +impl TreeNodePosition { + /// Calculates and sets the x and y positions for all advancement nodes in the tree using the Reingold-Tilford algorithm. + /// + /// This method implements the three-pass Reingold-Tilford algorithm to compute an optimal hierarchical layout + /// for advancement nodes within the advancement tree. The algorithm ensures that the tree is drawn with + /// minimal width while maintaining a clear parent-child hierarchy. + /// + /// # Arguments + /// + /// * `tree` - A mutable reference to the `AdvancementTree` containing all the advancement nodes. + /// The method updates the x and y positions of each node's display information. + /// * `root_index` - The index of the root node in the tree from which to start the positioning algorithm. + /// The root must have a display component, otherwise the function will panic. + /// + /// # Panics + /// + /// Panics if the root node at `root_index` does not have a display component, as the algorithm cannot + /// position children of invisible nodes. + /// + /// # Algorithm Overview + /// + /// The positioning is done in three phases: + /// 1. **First walk**: Assigns preliminary x-coordinates based on subtree placement rules + /// 2. **Second walk**: Converts preliminary coordinates to final coordinates and calculates the minimum y value + /// 3. **Third walk**: Adjusts all y-coordinates if necessary to ensure they are non-negative + pub fn run(tree: &mut AdvancementTree, root_index: usize) { + let root_node = if let Some(node) = tree.nodes_vector.get(root_index) { + node + } else { + eprintln!("AdvancementNode index out of bounds"); + return; + }; + if !root_node.has_display() { + panic!("Can't position children of an invisible root!"); + } + let mut nodes: Vec = Vec::with_capacity(32); + let root_idx = nodes.len(); + nodes.push(TreeNodePosition { + node: root_index, + parent: None, + previous_sibling: None, + child_index: 1, + children: Vec::new(), + ancestor: root_idx, + thread: None, + x: 0, + y: -1.0, + mod_field: 0.0, + change: 0.0, + shift: 0.0, + }); + + let mut previous_idx = None; + for child in root_node.children.clone() { + previous_idx = Self::add_child(&mut nodes, tree, root_idx, child, previous_idx); + } + + Self::first_walk(&mut nodes, root_idx); + + let root_y = nodes[root_idx].y; + let min = Self::second_walk(&mut nodes, root_idx, 0.0, 0, root_y); + + if min < 0.0 { + Self::third_walk(&mut nodes, root_idx, -min); + } + + Self::finalize_position(tree, &nodes, root_idx); + } + + fn add_child( + nodes: &mut Vec, + tree: &mut AdvancementTree, + parent_idx: usize, + adv_node_idx: usize, + mut previous_idx: Option, + ) -> Option { + let adv_node = tree.nodes_vector.get(adv_node_idx).unwrap(); + if adv_node.has_display() { + let child_idx = nodes.len(); + let next_child_index = nodes[parent_idx].children.len() + 1; + let depth = nodes[parent_idx].x + 1; + + nodes.push(TreeNodePosition { + node: adv_node_idx, + parent: Some(parent_idx), + previous_sibling: previous_idx, + child_index: next_child_index, + children: Vec::new(), + ancestor: child_idx, + thread: None, + x: depth, + y: -1.0, + mod_field: 0.0, + change: 0.0, + shift: 0.0, + }); + + nodes[parent_idx].children.push(child_idx); + + let mut child_prev = None; + for child in adv_node.children.clone() { + child_prev = Self::add_child(nodes, tree, child_idx, child, child_prev); + } + + Some(child_idx) + } else { + for grandchild in &adv_node.children.clone() { + previous_idx = Self::add_child(nodes, tree, parent_idx, *grandchild, previous_idx); + } + previous_idx + } + } + + /// First walk of the tree positioning algorithm. + /// + /// This function assigns preliminary y-coordinates to nodes based on subtree placement rules. + /// It performs a post-order traversal (children before parent) to recursively calculate positions. + /// + /// For leaf nodes, the y-coordinate is set based on the previous sibling's position. + /// For nodes with children, y-coordinates are calculated as the midpoint between the + /// first and last child after applying the apportion algorithm to resolve overlaps. + /// + /// # Arguments + /// + /// * `nodes` - A mutable reference to the vector of `TreeNodePosition` representing the tree structure. + /// * `idx` - The index of the current node being processed in the `nodes` vector. + /// + /// # Algorithm Details + /// + /// - Recursively processes all children first (post-order traversal) + /// - Uses `apportion()` to detect and resolve overlaps between subtrees + /// - Executes shifts to propagate positioning adjustments down the tree + /// - Calculates the node's y-coordinate as either the midpoint of children or positioned + /// relative to the previous sibling + /// + /// # Note + /// + /// This is the first of three passes needed to compute final positions. It sets preliminary + /// coordinates that will be refined in subsequent passes. + fn first_walk(nodes: &mut Vec, idx: usize) { + let num_children = nodes[idx].children.len(); + + if num_children == 0 { + if let Some(prev_sib) = nodes[idx].previous_sibling { + nodes[idx].y = nodes[prev_sib].y + 1.0; + } else { + nodes[idx].y = 0.0; + } + } else { + let mut default_ancestor = None; + for i in 0..num_children { + let child_idx = nodes[idx].children[i]; + Self::first_walk(nodes, child_idx); + let arg_ancestor = default_ancestor.unwrap_or(child_idx); + default_ancestor = Some(Self::apportion(nodes, child_idx, arg_ancestor)); + } + + Self::execute_shifts(nodes, idx); + + let first_child_idx = nodes[idx].children[0]; + let last_child_idx = nodes[idx].children[num_children - 1]; + let midpoint = (nodes[first_child_idx].y + nodes[last_child_idx].y) / 2.0; + + if let Some(prev_sib) = nodes[idx].previous_sibling { + nodes[idx].y = nodes[prev_sib].y + 1.0; + nodes[idx].mod_field = nodes[idx].y - midpoint; + } else { + nodes[idx].y = midpoint; + } + } + } + + /// Second walk of the tree positioning algorithm. + /// + /// This function converts preliminary coordinates to final coordinates and calculates + /// the minimum y value encountered during the traversal. It performs a pre-order traversal + /// (parent before children) to accumulate modifications from parent nodes to children. + /// + /// # Arguments + /// + /// * `nodes` - A mutable reference to the vector of `TreeNodePosition` representing the tree structure. + /// * `idx` - The index of the current node being processed in the `nodes` vector. + /// * `mod_sum` - The accumulated modification offset from all ancestor nodes. This value is + /// added to convert preliminary coordinates to final coordinates. + /// * `depth` - The depth level of the current node in the tree (0 for root, increments for children). + /// * `mut min` - The minimum y-coordinate encountered so far in the traversal. + /// + /// # Returns + /// + /// The minimum y-coordinate value found in the current node and all its descendants. + /// + /// # Algorithm Details + /// + /// - Applies accumulated modifications to convert preliminary y-coordinates to final coordinates + /// - Sets the x-coordinate (depth) for positioning nodes horizontally + /// - Tracks the minimum y value to detect if adjustment is needed + /// - Recursively processes all children, accumulating their modifier offsets + /// + /// # Note + /// + /// This is the second of three passes. The returned minimum value is used to ensure + /// all y-coordinates are non-negative in the third walk. + fn second_walk( + nodes: &mut Vec, + idx: usize, + mod_sum: f32, + depth: i32, + mut min: f32, + ) -> f32 { + nodes[idx].y += mod_sum; + nodes[idx].x = depth; + + if nodes[idx].y < min { + min = nodes[idx].y; + } + + let num_children = nodes[idx].children.len(); + let current_mod = nodes[idx].mod_field; + + for i in 0..num_children { + let child_idx = nodes[idx].children[i]; + min = Self::second_walk(nodes, child_idx, mod_sum + current_mod, depth + 1, min); + } + + min + } + + /// Third walk of the tree positioning algorithm. + /// + /// This function adjusts all y-coordinates of the tree by adding a uniform offset, ensuring + /// all coordinates are non-negative. It traverses the tree recursively, applying the same + /// offset to each node and its descendants. + /// + /// # Arguments + /// + /// * `nodes` - A mutable reference to the vector of `TreeNodePosition` representing the tree structure. + /// * `idx` - The index of the current node being processed in the `nodes` vector. + /// * `offset` - The y-coordinate offset to apply. This is typically the negation of the minimum + /// y value found in the second walk. + /// + /// # Algorithm Details + /// + /// - Adds the offset to the current node's y-coordinate + /// - Recursively applies the same offset to all children + /// - Uses a simple post-order traversal to ensure uniform adjustment across the entire tree + /// + /// # Note + /// + /// This is the third of three passes. It only executes if the minimum y value found in + /// the second walk was negative, ensuring all final positions are non-negative. + fn third_walk(nodes: &mut Vec, idx: usize, offset: f32) { + nodes[idx].y += offset; + + let num_children = nodes[idx].children.len(); + for i in 0..num_children { + let child_idx = nodes[idx].children[i]; + Self::third_walk(nodes, child_idx, offset); + } + } + + fn execute_shifts(nodes: &mut [TreeNodePosition], idx: usize) { + let mut shift = 0.0; + let mut change = 0.0; + + for &child_idx in nodes[idx].children.iter().rev() { + nodes[child_idx].y += shift; + nodes[child_idx].mod_field += shift; + change += nodes[child_idx].change; + shift += nodes[child_idx].shift + change; + } + } + + #[inline] + fn previous_or_thread(nodes: &[TreeNodePosition], idx: usize) -> Option { + nodes[idx] + .thread + .or_else(|| nodes[idx].children.first().copied()) + } + + #[inline] + fn next_or_thread(nodes: &[TreeNodePosition], idx: usize) -> Option { + nodes[idx] + .thread + .or_else(|| nodes[idx].children.last().copied()) + } + + fn apportion(nodes: &mut [TreeNodePosition], idx: usize, mut default_ancestor: usize) -> usize { + let prev_sib = match nodes[idx].previous_sibling { + Some(p) => p, + None => return default_ancestor, + }; + let parent_idx = nodes[idx].parent.expect("Tree invariant broken: no parent"); + let mut inner_left = prev_sib; + let mut inner_right = idx; + let mut outer_left = nodes[parent_idx].children[0]; + let mut outer_right = idx; + + let mut shift_inner_right = nodes[inner_right].mod_field; + let mut shift_outer_right = nodes[outer_right].mod_field; + let mut shift_inner_left = nodes[inner_left].mod_field; + let mut shift_outer_left = nodes[outer_left].mod_field; + while let (Some(next_inner_left), Some(next_inner_right)) = ( + Self::next_or_thread(nodes, inner_left), + Self::previous_or_thread(nodes, inner_right), + ) { + inner_left = next_inner_left; + inner_right = next_inner_right; + outer_left = Self::previous_or_thread(nodes, outer_left).expect("Tree invariant broken"); + outer_right = Self::next_or_thread(nodes, outer_right).expect("Tree invariant broken"); + + nodes[outer_right].ancestor = idx; + + let shift = (nodes[inner_left].y + shift_inner_left) - (nodes[inner_right].y + shift_inner_right) + 1.0; + if shift > 0.0 { + let ancestor_idx = Self::get_ancestor(nodes, inner_left, idx, default_ancestor); + Self::move_subtree(nodes, ancestor_idx, idx, shift); + shift_inner_right += shift; + shift_outer_right += shift; + } + + shift_inner_left += nodes[inner_left].mod_field; + shift_inner_right += nodes[inner_right].mod_field; + shift_outer_left += nodes[outer_left].mod_field; + shift_outer_right += nodes[outer_right].mod_field; + } + + if Self::next_or_thread(nodes, inner_left).is_some() + && Self::next_or_thread(nodes, outer_right).is_none() + { + nodes[outer_right].thread = Self::next_or_thread(nodes, inner_left); + nodes[outer_right].mod_field += shift_inner_left - shift_outer_right; + } else { + if Self::previous_or_thread(nodes, inner_right).is_some() + && Self::previous_or_thread(nodes, outer_left).is_none() + { + nodes[outer_left].thread = Self::previous_or_thread(nodes, inner_right); + nodes[outer_left].mod_field += shift_inner_right - shift_outer_left; + } + default_ancestor = idx; + } + default_ancestor + } + + fn move_subtree(nodes: &mut [TreeNodePosition], left: usize, right: usize, shift: f32) { + let subtrees = (nodes[right].child_index as f32) - (nodes[left].child_index as f32); + if subtrees != 0.0 { + nodes[right].change -= shift / subtrees; + nodes[left].change += shift / subtrees; + } + nodes[right].shift += shift; + nodes[right].y += shift; + nodes[right].mod_field += shift; + } + + fn get_ancestor( + nodes: &[TreeNodePosition], + vil: usize, + idx: usize, + default_ancestor: usize, + ) -> usize { + let ancestor = nodes[vil].ancestor; + let parent_idx = nodes[idx].parent.unwrap(); + + if nodes[parent_idx].children.contains(&ancestor) { + ancestor + } else { + default_ancestor + } + } + + /// Final walk of the tree positioning algorithm. + /// + /// This function applies the computed positions to the actual advancement nodes in the tree, + /// finalizing their display locations. It traverses the tree recursively and updates each node's + /// position coordinates in the tree structure. + /// + /// # Arguments + /// + /// * `tree` - A mutable reference to the `AdvancementTree`. This tree is updated with the + /// computed x and y positions from the `TreeNodePosition` nodes. + /// * `nodes` - A reference to the vector of `TreeNodePosition` containing the computed positions + /// for each node in the tree. + /// * `idx` - The index of the current node being processed in the `nodes` vector. + /// + /// # Algorithm Details + /// + /// - Retrieves the computed x and y positions from the `TreeNodePosition` at the given index + /// - Sets these positions on the corresponding advancement node in the tree + /// - Recursively processes all children, updating their positions as well + /// - Uses a post-order traversal to ensure all nodes are properly positioned + /// + /// # Note + /// + /// This is the fourth and final pass. It should only be called after all three positioning walks + /// (first, second, and third) have been completed successfully. This function transfers the + /// computed positions from the internal `TreeNodePosition` structures back to the actual + /// `AdvancementNode` display information. + fn finalize_position(tree: &mut AdvancementTree, nodes: &[TreeNodePosition], idx: usize) { + tree.nodes_vector[nodes[idx].node].set_location(nodes[idx].x as f32, nodes[idx].y); + for &child_idx in &nodes[idx].children { + Self::finalize_position(tree, nodes, child_idx); + } + } +} + +/// The structure that represents an advancement #[derive(Deserialize, Default, Clone)] pub struct AdvancementStruct { pub parent: Option, @@ -374,6 +799,11 @@ fn identifier_to_tokens(identifier: &Identifier) -> TokenStream { } } +/// Entry point for the code generation of advancements. +/// +/// Parses the `advancements.json` asset, builds the advancement tree, +/// calculates positions using the Reingold-Tilford algorithm, and generates +/// the final Rust source code. pub(crate) fn build() -> TokenStream { let advancements_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../assets/advancements.json"); @@ -396,6 +826,11 @@ pub(crate) fn build() -> TokenStream { .map(|(key, value)| AdvancementHolder(Identifier::parse(&key).unwrap(), value)) .collect(), ); + for index in tree.roots.clone() { + if tree.nodes_vector.get(index).unwrap().has_display() { + TreeNodePosition::run(&mut tree, index); + } + } let advancement_tree = quote! { pub static ADVANCEMENT_TREE : LazyLock = #tree; }; diff --git a/pumpkin-data/src/generated/advancement.rs b/pumpkin-data/src/generated/advancement.rs index 928c2c6c5..398476de5 100644 --- a/pumpkin-data/src/generated/advancement.rs +++ b/pumpkin-data/src/generated/advancement.rs @@ -48,7 +48,7 @@ impl Advancement { false, false, 0f32, - 0f32, + 13.25f32, )), reward: &AdvancementReward { experience: 0i32, @@ -69,7 +69,7 @@ impl Advancement { true, false, true, - 0f32, + 1f32, 0f32, )), reward: &AdvancementReward { @@ -101,8 +101,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -123,8 +123,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 4f32, )), reward: &AdvancementReward { experience: 0i32, @@ -145,8 +145,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 5.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -167,8 +167,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -189,8 +189,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 7f32, )), reward: &AdvancementReward { experience: 0i32, @@ -230,8 +230,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 8f32, )), reward: &AdvancementReward { experience: 0i32, @@ -252,8 +252,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 1f32, + 9f32, )), reward: &AdvancementReward { experience: 0i32, @@ -277,8 +277,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 1f32, )), reward: &AdvancementReward { experience: 0i32, @@ -300,7 +300,7 @@ impl Advancement { false, false, 0f32, - 0f32, + 1.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -322,7 +322,7 @@ impl Advancement { false, false, 0f32, - 0f32, + 7f32, )), reward: &AdvancementReward { experience: 0i32, @@ -343,7 +343,7 @@ impl Advancement { true, false, true, - 0f32, + 1f32, 0f32, )), reward: &AdvancementReward { @@ -365,8 +365,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 1f32, )), reward: &AdvancementReward { experience: 0i32, @@ -387,8 +387,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -409,8 +409,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 4.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -456,7 +456,7 @@ impl Advancement { true, false, true, - 0f32, + 2f32, 0f32, )), reward: &AdvancementReward { @@ -481,8 +481,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 3f32, )), reward: &AdvancementReward { experience: 50i32, @@ -514,7 +514,7 @@ impl Advancement { false, false, 0f32, - 0f32, + 4.25f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1498,7 +1498,7 @@ impl Advancement { false, false, 0f32, - 0f32, + 1.75f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1522,8 +1522,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 2f32, )), reward: &AdvancementReward { experience: 500i32, @@ -1600,8 +1600,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 10f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1622,8 +1622,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 11f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1647,7 +1647,7 @@ impl Advancement { true, false, true, - 0f32, + 2f32, 0f32, )), reward: &AdvancementReward { @@ -1669,8 +1669,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 12f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1691,8 +1691,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 13f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1713,8 +1713,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 14f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1742,8 +1742,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 2f32, + 9f32, )), reward: &AdvancementReward { experience: 100i32, @@ -1764,8 +1764,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 15f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1786,8 +1786,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 16f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1850,8 +1850,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 13.5f32, )), reward: &AdvancementReward { experience: 100i32, @@ -1914,8 +1914,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 14.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1936,8 +1936,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 18.75f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1958,8 +1958,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 21.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -1980,8 +1980,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 25.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2005,8 +2005,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 19.5f32, )), reward: &AdvancementReward { experience: 50i32, @@ -2030,8 +2030,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2052,8 +2052,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 26.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2074,8 +2074,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 15.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2099,8 +2099,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 15f32, )), reward: &AdvancementReward { experience: 50i32, @@ -2121,8 +2121,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 16.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2146,8 +2146,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 4f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2168,8 +2168,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 6f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2190,8 +2190,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 17.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2212,8 +2212,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 18.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2237,8 +2237,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 7f32, )), reward: &AdvancementReward { experience: 150i32, @@ -2268,8 +2268,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 24.5f32, )), reward: &AdvancementReward { experience: 65i32, @@ -2293,8 +2293,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 20.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2318,8 +2318,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 17.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2343,8 +2343,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 21.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2365,8 +2365,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 25.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2387,8 +2387,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 1.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2409,7 +2409,7 @@ impl Advancement { true, false, true, - 0f32, + 2f32, 0f32, )), reward: &AdvancementReward { @@ -2431,8 +2431,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 1f32, + 7f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2453,8 +2453,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 8f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2478,8 +2478,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 4f32, )), reward: &AdvancementReward { experience: 50i32, @@ -2512,8 +2512,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 9f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2537,8 +2537,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2563,8 +2563,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 10f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2585,8 +2585,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 1f32, + 11f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2607,8 +2607,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 12f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2629,8 +2629,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 13f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2662,8 +2662,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2687,8 +2687,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 6f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2709,8 +2709,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 14f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2734,8 +2734,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 9f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2761,7 +2761,7 @@ impl Advancement { true, false, true, - 0f32, + 3f32, 0f32, )), reward: &AdvancementReward { @@ -2783,7 +2783,7 @@ impl Advancement { true, false, true, - 0f32, + 1f32, 0f32, )), reward: &AdvancementReward { @@ -2805,8 +2805,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 1f32, )), reward: &AdvancementReward { experience: 100i32, @@ -2827,8 +2827,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2849,8 +2849,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 3.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2871,8 +2871,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2893,8 +2893,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2920,8 +2920,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2942,8 +2942,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 4f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2964,8 +2964,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 6f32, )), reward: &AdvancementReward { experience: 0i32, @@ -2986,8 +2986,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 7f32, )), reward: &AdvancementReward { experience: 50i32, @@ -3008,8 +3008,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 8.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -3030,8 +3030,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 8f32, )), reward: &AdvancementReward { experience: 0i32, @@ -3055,8 +3055,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -3080,8 +3080,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 7f32, )), reward: &AdvancementReward { experience: 100i32, @@ -19695,8 +19695,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 1f32, + 1.75f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19717,8 +19717,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 1.75f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19739,8 +19739,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 2f32, + 26.5f32, )), reward: &AdvancementReward { experience: 85i32, @@ -19764,8 +19764,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 22.5f32, )), reward: &AdvancementReward { experience: 40i32, @@ -19789,8 +19789,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 16f32, )), reward: &AdvancementReward { experience: 50i32, @@ -19814,8 +19814,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 23.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19839,8 +19839,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 20.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19864,8 +19864,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 4f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19886,8 +19886,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 1f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19908,8 +19908,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19930,8 +19930,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19955,8 +19955,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -19977,8 +19977,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 2.5f32, )), reward: &AdvancementReward { experience: 50i32, @@ -20002,8 +20002,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 2f32, + 7f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20027,8 +20027,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 9f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20049,8 +20049,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 12.5f32, )), reward: &AdvancementReward { experience: 100i32, @@ -20115,8 +20115,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 8f32, )), reward: &AdvancementReward { experience: 100i32, @@ -20167,8 +20167,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 2f32, + 11f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20192,8 +20192,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20217,8 +20217,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 9f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20239,8 +20239,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 13.5f32, )), reward: &AdvancementReward { experience: 100i32, @@ -20264,8 +20264,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 3f32, + 11f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20289,8 +20289,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 4f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20314,8 +20314,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 6f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20336,8 +20336,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20358,8 +20358,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 5f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20380,8 +20380,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 9f32, )), reward: &AdvancementReward { experience: 500i32, @@ -20411,8 +20411,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 2f32, + 5f32, )), reward: &AdvancementReward { experience: 100i32, @@ -20433,8 +20433,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 3f32, + 1.75f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20455,8 +20455,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 3.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20477,8 +20477,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 4f32, )), reward: &AdvancementReward { experience: 100i32, @@ -20499,8 +20499,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 0.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20521,8 +20521,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20543,8 +20543,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 5f32, + 0.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20565,8 +20565,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 4f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20592,7 +20592,7 @@ impl Advancement { true, false, true, - 0f32, + 6f32, 0f32, )), reward: &AdvancementReward { @@ -20619,8 +20619,8 @@ impl Advancement { true, true, true, - 0f32, - 0f32, + 5f32, + 4f32, )), reward: &AdvancementReward { experience: 1000i32, @@ -20641,8 +20641,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 5f32, + 3f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20663,8 +20663,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 6f32, + 1f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20685,8 +20685,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 5f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20707,8 +20707,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 6f32, + 2f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20732,8 +20732,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 7f32, + 1.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20757,8 +20757,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 7f32, + 2.5f32, )), reward: &AdvancementReward { experience: 0i32, @@ -20782,8 +20782,8 @@ impl Advancement { true, false, true, - 0f32, - 0f32, + 8f32, + 1.5f32, )), reward: &AdvancementReward { experience: 0i32,