feat: Entities drop exp now
This commit is contained in:
parent
d33484d057
commit
501fd0ced5
File diff suppressed because one or more lines are too long
@ -15,6 +15,7 @@ pub struct EntityType {
|
|||||||
/// Numeric registry ID for this entity type.
|
/// Numeric registry ID for this entity type.
|
||||||
pub id: u16,
|
pub id: u16,
|
||||||
pub attributes: Option<Vec<BTreeMap<String, f64>>>,
|
pub attributes: Option<Vec<BTreeMap<String, f64>>>,
|
||||||
|
pub experience_reward: Option<u32>,
|
||||||
/// Static hurt sound event name when it is safely derivable from extracted entity data.
|
/// Static hurt sound event name when it is safely derivable from extracted entity data.
|
||||||
pub hurt_sound: Option<String>,
|
pub hurt_sound: Option<String>,
|
||||||
/// Whether this entity can be attacked by players or other entities.
|
/// Whether this entity can be attacked by players or other entities.
|
||||||
@ -180,10 +181,13 @@ impl ToTokens for NamedEntityType<'_> {
|
|||||||
quote! { None }
|
quote! { None }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let experience_reward = entity.experience_reward.unwrap_or(0);
|
||||||
|
|
||||||
tokens.extend(quote! {
|
tokens.extend(quote! {
|
||||||
EntityType {
|
EntityType {
|
||||||
id: #id,
|
id: #id,
|
||||||
attributes: #attributes_field,
|
attributes: #attributes_field,
|
||||||
|
experience_reward: #experience_reward,
|
||||||
hurt_sound: #hurt_sound,
|
hurt_sound: #hurt_sound,
|
||||||
attackable: #attackable,
|
attackable: #attackable,
|
||||||
mob: #mob,
|
mob: #mob,
|
||||||
@ -247,6 +251,7 @@ pub fn build() -> TokenStream {
|
|||||||
pub struct EntityType {
|
pub struct EntityType {
|
||||||
pub id: u16,
|
pub id: u16,
|
||||||
pub attributes: &'static [(Attributes, f64)],
|
pub attributes: &'static [(Attributes, f64)],
|
||||||
|
pub experience_reward: u32,
|
||||||
pub hurt_sound: Option<Sound>,
|
pub hurt_sound: Option<Sound>,
|
||||||
pub attackable: Option<bool>,
|
pub attackable: Option<bool>,
|
||||||
pub mob: bool,
|
pub mob: bool,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,7 @@ use std::sync::atomic::{
|
|||||||
use std::{collections::HashMap, sync::atomic::AtomicI32};
|
use std::{collections::HashMap, sync::atomic::AtomicI32};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
|
|
||||||
|
use super::experience_orb::ExperienceOrbEntity;
|
||||||
use super::{Entity, NBTStorage};
|
use super::{Entity, NBTStorage};
|
||||||
use super::{EntityBase, NBTStorageInit};
|
use super::{EntityBase, NBTStorageInit};
|
||||||
use crate::block::OnLandedUponArgs;
|
use crate::block::OnLandedUponArgs;
|
||||||
@ -1301,6 +1302,16 @@ impl LivingEntity {
|
|||||||
|
|
||||||
// Drop loot
|
// Drop loot
|
||||||
self.drop_loot(params).await;
|
self.drop_loot(params).await;
|
||||||
|
|
||||||
|
// Award experience
|
||||||
|
if params.killed_by_player.unwrap_or(false)
|
||||||
|
&& world.level_info.load().game_rules.mob_drops
|
||||||
|
{
|
||||||
|
let amount = dyn_self.get_experience_reward(cause);
|
||||||
|
if amount > 0 {
|
||||||
|
ExperienceOrbEntity::spawn(&world, self.entity.pos.load(), amount).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
self.entity.pose.store(EntityPose::Dying);
|
self.entity.pose.store(EntityPose::Dying);
|
||||||
|
|
||||||
let block_pos = self.entity.block_pos.load();
|
let block_pos = self.entity.block_pos.load();
|
||||||
|
|||||||
@ -335,6 +335,10 @@ pub trait Mob: EntityBase + Send + Sync {
|
|||||||
fn is_sitting(&self) -> bool {
|
fn is_sitting(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_base_experience_reward(&self) -> u32 {
|
||||||
|
self.get_entity().entity_type.experience_reward
|
||||||
|
}
|
||||||
}
|
}
|
||||||
impl<T: Mob + Send + 'static> EntityBase for T {
|
impl<T: Mob + Send + 'static> EntityBase for T {
|
||||||
fn tick<'a>(
|
fn tick<'a>(
|
||||||
@ -511,6 +515,23 @@ impl<T: Mob + Send + 'static> EntityBase for T {
|
|||||||
fn get_y_velocity_drag(&self) -> Option<f64> {
|
fn get_y_velocity_drag(&self) -> Option<f64> {
|
||||||
self.get_mob_y_velocity_drag()
|
self.get_mob_y_velocity_drag()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_experience_reward(&self, _killer: Option<&dyn EntityBase>) -> u32 {
|
||||||
|
if self
|
||||||
|
.get_entity()
|
||||||
|
.age
|
||||||
|
.load(std::sync::atomic::Ordering::Relaxed)
|
||||||
|
< 0
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// TODO: apply enchantment processing like in vanilla
|
||||||
|
Mob::get_base_experience_reward(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_base_experience_reward(&self) -> u32 {
|
||||||
|
Mob::get_base_experience_reward(self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[expect(dead_code)]
|
#[expect(dead_code)]
|
||||||
|
|||||||
@ -363,6 +363,14 @@ pub trait EntityBase: Send + Sync + NBTStorage + std::any::Any {
|
|||||||
|
|
||||||
/// Returns itself as the nbt storage for saving and loading data.
|
/// Returns itself as the nbt storage for saving and loading data.
|
||||||
fn as_nbt_storage(&self) -> &dyn NBTStorage;
|
fn as_nbt_storage(&self) -> &dyn NBTStorage;
|
||||||
|
|
||||||
|
fn get_experience_reward(&self, _killer: Option<&dyn EntityBase>) -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_base_experience_reward(&self) -> u32 {
|
||||||
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||||
|
|||||||
@ -3842,6 +3842,12 @@ impl EntityBase for Player {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_experience_reward(&self, _killer: Option<&dyn EntityBase>) -> u32 {
|
||||||
|
// vanilla: min(level * 7, 100)
|
||||||
|
let level = self.experience_level.load(Ordering::Relaxed);
|
||||||
|
(level * 7).min(100) as u32
|
||||||
|
}
|
||||||
|
|
||||||
fn tick_in_void<'a>(&'a self, dyn_self: &'a dyn EntityBase) -> EntityBaseFuture<'a, ()> {
|
fn tick_in_void<'a>(&'a self, dyn_self: &'a dyn EntityBase) -> EntityBaseFuture<'a, ()> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
self.living_entity.tick_in_void(dyn_self).await;
|
self.living_entity.tick_in_void(dyn_self).await;
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use pumpkin_util::{
|
|||||||
};
|
};
|
||||||
use rand::RngExt;
|
use rand::RngExt;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Copy, Clone)]
|
||||||
pub struct LootContextParameters {
|
pub struct LootContextParameters {
|
||||||
pub explosion_radius: Option<f32>,
|
pub explosion_radius: Option<f32>,
|
||||||
pub block_state: Option<&'static BlockState>,
|
pub block_state: Option<&'static BlockState>,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user