Skip to content

Commit

Permalink
Implement experience and experiene/xp commands (#521)
Browse files Browse the repository at this point in the history
* Initial experience support

For some reason I am getting link errors

* Implement experience math

* Fix packet and format/clippy

* Fix translate strings

* Fix experience handling

* Clippy & Format

* Fix experience calculations

* Fix how we store experience.

Math WIP

* Redo all experience calculations

This should be 100% vanilla parity.
  • Loading branch information
drakeerv authored Feb 1, 2025
1 parent a1f08eb commit 9706561
Show file tree
Hide file tree
Showing 8 changed files with 515 additions and 5 deletions.
23 changes: 23 additions & 0 deletions pumpkin-protocol/src/client/play/c_set_experience.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use pumpkin_data::packet::clientbound::PLAY_SET_EXPERIENCE;
use pumpkin_macros::client_packet;
use serde::Serialize;

use crate::VarInt;

#[derive(Serialize)]
#[client_packet(PLAY_SET_EXPERIENCE)]
pub struct CSetExperience {
progress: f32,
level: VarInt,
total_experience: VarInt,
}

impl CSetExperience {
pub fn new(progress: f32, level: VarInt, total_experience: VarInt) -> Self {
Self {
progress,
level,
total_experience,
}
}
}
2 changes: 2 additions & 0 deletions pumpkin-protocol/src/client/play/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ mod c_set_border_warning_distance;
mod c_set_container_content;
mod c_set_container_property;
mod c_set_container_slot;
mod c_set_experience;
mod c_set_health;
mod c_set_held_item;
mod c_set_time;
Expand Down Expand Up @@ -123,6 +124,7 @@ pub use c_set_border_warning_distance::*;
pub use c_set_container_content::*;
pub use c_set_container_property::*;
pub use c_set_container_slot::*;
pub use c_set_experience::*;
pub use c_set_health::*;
pub use c_set_held_item::*;
pub use c_set_time::*;
Expand Down
39 changes: 39 additions & 0 deletions pumpkin-util/src/math/experience.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/// Get the number of points in a level
pub fn points_in_level(level: i32) -> i32 {
match level {
0..=15 => 2 * level + 7,
16..=30 => 5 * level - 38,
_ => 9 * level - 158,
}
}

/// Calculate the total number of points to reach a level
pub fn points_to_level(level: i32) -> i32 {
match level {
0..=15 => (level * level + 6 * level) / 2,
16..=30 => ((2.5 * f64::from(level * level)) - (40.5 * f64::from(level)) + 360.0) as i32,
_ => ((4.5 * f64::from(level * level)) - (162.5 * f64::from(level)) + 2220.0) as i32,
}
}

/// Calculate level and points from total points
pub fn total_to_level_and_points(total_points: i32) -> (i32, i32) {
let level = match total_points {
0..=352 => ((total_points as f64 + 9.0).sqrt() - 3.0) as i32,
353..=1507 => (81.0 + (total_points as f64 - 7839.0) / 40.0).sqrt() as i32,
_ => (325.0 + (total_points as f64 - 54215.0) / 72.0).sqrt() as i32,
};

let level_start = points_to_level(level);
let points_into_level = total_points - level_start;

(level, points_into_level)
}

/// Calculate progress (0.0 to 1.0) from points within a level
pub fn progress_in_level(points: i32, level: i32) -> f32 {
let max_points = points_in_level(level);
#[allow(clippy::cast_precision_loss)]
let progress = (points as f32) / (max_points as f32);
progress.clamp(0.0, 1.0)
}
1 change: 1 addition & 0 deletions pumpkin-util/src/math/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use num_traits::PrimInt;

pub mod boundingbox;
pub mod experience;
pub mod position;
pub mod vector2;
pub mod vector3;
Expand Down
Loading

0 comments on commit 9706561

Please sign in to comment.