Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement experience and experiene/xp commands #521

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
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 @@ -122,6 +123,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