Alexander Medvedev 2026-01-15 16:51:37 +01:00
parent 578bab259a
commit 2faf24bb42
4 changed files with 53 additions and 49 deletions

View File

@ -168,17 +168,9 @@ impl ToTokens for UniformLootNumberProvider {
} }
impl UniformLootNumberProvider { impl UniformLootNumberProvider {
pub fn get_min(&self) -> f32 {
self.min
}
pub fn get(&self, random: &mut impl RandomImpl) -> f32 { pub fn get(&self, random: &mut impl RandomImpl) -> f32 {
random.next_f32() * (self.max - self.min) + self.min random.next_f32() * (self.max - self.min) + self.min
} }
pub fn get_max(&self) -> f32 {
self.max
}
} }
#[derive(Deserialize, PartialEq, Clone, Copy, Debug)] #[derive(Deserialize, PartialEq, Clone, Copy, Debug)]
@ -204,15 +196,6 @@ impl ToTokens for LootNumberProviderTypes {
} }
impl LootNumberProviderTypes { impl LootNumberProviderTypes {
pub fn get_min(&self) -> f32 {
match self {
LootNumberProviderTypes::Object(int_provider) => match int_provider {
LootNumberProviderTypesProvider::Uniform(uniform) => uniform.get_min(),
},
LootNumberProviderTypes::Constant(i) => *i,
}
}
pub fn get(&self, random: &mut impl RandomImpl) -> f32 { pub fn get(&self, random: &mut impl RandomImpl) -> f32 {
match self { match self {
LootNumberProviderTypes::Object(int_provider) => match int_provider { LootNumberProviderTypes::Object(int_provider) => match int_provider {
@ -221,13 +204,4 @@ impl LootNumberProviderTypes {
LootNumberProviderTypes::Constant(i) => *i, LootNumberProviderTypes::Constant(i) => *i,
} }
} }
pub fn get_max(&self) -> f32 {
match self {
LootNumberProviderTypes::Object(int_provider) => match int_provider {
LootNumberProviderTypesProvider::Uniform(uniform) => uniform.get_max(),
},
LootNumberProviderTypes::Constant(i) => *i,
}
}
} }

View File

@ -882,11 +882,10 @@ impl Player {
// return; // return;
// } // }
if self.packet_sequence.load(Ordering::Relaxed) > -1 { let seq = self.packet_sequence.swap(-1, Ordering::Relaxed);
if seq != -1 {
self.client self.client
.enqueue_packet(&CAcknowledgeBlockChange::new( .send_packet_now(&CAcknowledgeBlockChange::new(seq.into()))
self.packet_sequence.swap(-1, Ordering::Relaxed).into(),
))
.await; .await;
} }
{ {

View File

@ -2036,6 +2036,11 @@ impl JavaClient {
let _replaced_id = world let _replaced_id = world
.set_block_state(&final_block_pos, new_state, BlockFlags::NOTIFY_ALL) .set_block_state(&final_block_pos, new_state, BlockFlags::NOTIFY_ALL)
.await; .await;
self.send_packet_now(&CBlockUpdate::new(
final_block_pos,
VarInt(i32::from(new_state)),
))
.await;
server server
.block_registry .block_registry

View File

@ -4,7 +4,7 @@ use pumpkin_util::{
LootCondition, LootFunctionNumberProvider, LootFunctionTypes, LootPoolEntry, LootCondition, LootFunctionNumberProvider, LootFunctionTypes, LootPoolEntry,
LootPoolEntryTypes, LootTable, LootPoolEntryTypes, LootTable,
}, },
random::{RandomGenerator, xoroshiro128::Xoroshiro}, random::{RandomGenerator, RandomImpl, get_seed, xoroshiro128::Xoroshiro},
}; };
use pumpkin_world::item::ItemStack; use pumpkin_world::item::ItemStack;
use rand::Rng; use rand::Rng;
@ -23,32 +23,56 @@ pub trait LootTableExt {
impl LootTableExt for LootTable { impl LootTableExt for LootTable {
fn get_loot(&self, params: LootContextParameters) -> Vec<ItemStack> { fn get_loot(&self, params: LootContextParameters) -> Vec<ItemStack> {
let mut stacks = Vec::new(); let mut stacks = Vec::new();
let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(get_seed()));
if let Some(pools) = self.pools { if let Some(pools) = self.pools {
for pool in pools { for pool in pools {
if let Some(conditions) = pool.conditions if let Some(conditions) = pool.conditions
&& !conditions.iter().all(|cond| cond.is_fulfilled(&params)) && !conditions.iter().all(|cond| cond.is_fulfilled(&params))
{ {
return stacks; continue;
} }
// TODO let rolls = pool.rolls.get(&mut random).round() as i32;
let rolls = pool
.rolls for _ in 0..rolls {
.get(&mut RandomGenerator::Xoroshiro(Xoroshiro::from_seed(123))) let mut total_weight = 0;
.round() let mut valid_entries = Vec::new();
+ pool.bonus_rolls.floor(); // TODO: multiply by luck
for _ in 0..(rolls as i32) {
for entry in pool.entries { for entry in pool.entries {
if let Some(loot) = entry.get_loot(&params) { if entry
stacks.extend(loot); .conditions
.as_ref()
.is_none_or(|c| c.iter().all(|cond| cond.is_fulfilled(&params)))
{
let w = 1; // TODO: weight
total_weight += w;
valid_entries.push((entry, w));
}
}
if total_weight == 0 || valid_entries.is_empty() {
continue;
}
let mut r = random.next_bounded_i32(total_weight);
for (entry, weight) in valid_entries {
r -= weight;
if r < 0 {
if let Some(loot) = entry.get_loot(&params) {
for stack in loot {
if stack.item_count > 0 {
stacks.push(stack);
}
}
}
break;
} }
} }
} }
} }
} }
stacks stacks
} }
} }
@ -145,12 +169,14 @@ impl LootPoolEntryTypesExt for LootPoolEntryTypes {
Self::LootTable => todo!(), Self::LootTable => todo!(),
Self::Dynamic => todo!(), Self::Dynamic => todo!(),
Self::Tag => todo!(), Self::Tag => todo!(),
Self::Alternatives(alternative_entry) => alternative_entry Self::Alternatives(alternative_entry) => {
.children for entry in alternative_entry.children {
.iter() if let Some(loot) = entry.get_loot(params) {
.filter_map(|entry| entry.get_loot(params)) return loot;
.flatten() }
.collect(), }
Vec::new()
}
Self::Sequence => todo!(), Self::Sequence => todo!(),
Self::Group => todo!(), Self::Group => todo!(),
} }
@ -209,7 +235,7 @@ impl LootFunctionNumberProviderExt for LootFunctionNumberProvider {
fn generate(&self) -> f32 { fn generate(&self) -> f32 {
match self { match self {
Self::Constant { value } => *value, Self::Constant { value } => *value,
Self::Uniform { min, max } => rand::rng().random_range(*min..=*max), Self::Uniform { min, max } => rand::random::<f32>() * (max - min) + min,
Self::Binomial { n, p } => (0..n.floor() as u32).fold(0.0, |c, _| { Self::Binomial { n, p } => (0..n.floor() as u32).fold(0.0, |c, _| {
if rand::rng().random_bool(f64::from(*p)) { if rand::rng().random_bool(f64::from(*p)) {
c + 1.0 c + 1.0