-
-
Notifications
You must be signed in to change notification settings - Fork 184
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Experience Orb and drop it when breaking Blocks
- Loading branch information
Showing
13 changed files
with
225 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use serde::Deserialize; | ||
|
||
#[derive(Deserialize, Clone)] | ||
#[serde(tag = "type")] | ||
pub enum NormalInvProvider { | ||
#[serde(rename = "minecraft:uniform")] | ||
Uniform(UniformIntProvider), | ||
// TODO: Add more... | ||
} | ||
|
||
#[derive(Deserialize, Clone)] | ||
#[serde(untagged)] | ||
pub enum InvProvider { | ||
Object(NormalInvProvider), | ||
Constant(i32), | ||
} | ||
|
||
impl InvProvider { | ||
pub fn get_min(&self) -> i32 { | ||
match self { | ||
InvProvider::Object(inv_provider) => match inv_provider { | ||
NormalInvProvider::Uniform(uniform) => uniform.get_min(), | ||
}, | ||
InvProvider::Constant(i) => *i, | ||
} | ||
} | ||
|
||
pub fn get(&self) -> i32 { | ||
match self { | ||
InvProvider::Object(inv_provider) => match inv_provider { | ||
NormalInvProvider::Uniform(uniform) => uniform.get(), | ||
}, | ||
InvProvider::Constant(i) => *i, | ||
} | ||
} | ||
|
||
pub fn get_max(&self) -> i32 { | ||
match self { | ||
InvProvider::Object(inv_provider) => match inv_provider { | ||
NormalInvProvider::Uniform(uniform) => uniform.get_max(), | ||
}, | ||
InvProvider::Constant(i) => *i, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Deserialize, Clone)] | ||
pub struct UniformIntProvider { | ||
min_inclusive: i32, | ||
max_inclusive: i32, | ||
} | ||
|
||
impl UniformIntProvider { | ||
pub fn get_min(&self) -> i32 { | ||
self.min_inclusive | ||
} | ||
pub fn get(&self) -> i32 { | ||
rand::random_range(self.min_inclusive..self.max_inclusive) | ||
} | ||
pub fn get_max(&self) -> i32 { | ||
self.max_inclusive | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
use std::sync::{Arc, atomic::AtomicU32}; | ||
|
||
use async_trait::async_trait; | ||
use pumpkin_data::{damage::DamageType, entity::EntityType}; | ||
use pumpkin_util::math::vector3::Vector3; | ||
|
||
use crate::{server::Server, world::World}; | ||
|
||
use super::{Entity, EntityBase, living::LivingEntity, player::Player}; | ||
|
||
pub struct ExperienceOrbEntity { | ||
entity: Entity, | ||
amount: u32, | ||
orb_age: AtomicU32, | ||
} | ||
|
||
impl ExperienceOrbEntity { | ||
pub fn new(entity: Entity, amount: u32) -> Self { | ||
entity.yaw.store(rand::random::<f32>() * 360.0); | ||
Self { | ||
entity, | ||
amount, | ||
orb_age: AtomicU32::new(0), | ||
} | ||
} | ||
|
||
pub async fn spawn(world: &Arc<World>, server: &Server, position: Vector3<f64>, amount: u32) { | ||
let mut amount = amount; | ||
while amount > 0 { | ||
let i = Self::round_to_orb_size(amount); | ||
amount -= i; | ||
let entity = server.add_entity(position, EntityType::EXPERIENCE_ORB, world); | ||
let orb = Arc::new(Self::new(entity, i)); | ||
world.spawn_entity(orb).await; | ||
} | ||
} | ||
|
||
fn round_to_orb_size(value: u32) -> u32 { | ||
if value >= 2477 { | ||
2477 | ||
} else if value >= 1237 { | ||
1237 | ||
} else if value >= 617 { | ||
617 | ||
} else if value >= 307 { | ||
307 | ||
} else if value >= 149 { | ||
149 | ||
} else if value >= 73 { | ||
73 | ||
} else if value >= 37 { | ||
37 | ||
} else if value >= 17 { | ||
17 | ||
} else if value >= 7 { | ||
7 | ||
} else if value >= 3 { | ||
3 | ||
} else { | ||
1 | ||
} | ||
} | ||
} | ||
|
||
#[async_trait] | ||
impl EntityBase for ExperienceOrbEntity { | ||
async fn tick(&self, _: &Server) { | ||
let age = self | ||
.orb_age | ||
.fetch_add(1, std::sync::atomic::Ordering::Relaxed); | ||
if age >= 6000 { | ||
self.entity.remove().await; | ||
} | ||
} | ||
|
||
fn get_entity(&self) -> &Entity { | ||
&self.entity | ||
} | ||
|
||
async fn on_player_collision(&self, player: Arc<Player>) { | ||
let mut delay = player.experience_pick_up_delay.lock().await; | ||
if *delay == 0 { | ||
*delay = 2; | ||
player.living_entity.pickup(&self.entity, 1).await; | ||
player.add_experience_points(self.amount as i32).await; | ||
// TODO: pickingCount for merging | ||
self.entity.remove().await; | ||
} | ||
} | ||
|
||
async fn damage(&self, _amount: f32, _damage_type: DamageType) -> bool { | ||
false | ||
} | ||
|
||
fn get_living_entity(&self) -> Option<&LivingEntity> { | ||
None | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.