From 2faf24bb42886fdbcf71d242f45004593c0d1a39 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Thu, 15 Jan 2026 16:51:37 +0100 Subject: [PATCH] fix: https://github.com/Pumpkin-MC/Pumpkin/issues/1286 --- pumpkin-util/src/loot_table.rs | 26 -------------- pumpkin/src/entity/player.rs | 7 ++-- pumpkin/src/net/java/play.rs | 5 +++ pumpkin/src/world/loot.rs | 64 ++++++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/pumpkin-util/src/loot_table.rs b/pumpkin-util/src/loot_table.rs index 54a56c877..84913edcb 100644 --- a/pumpkin-util/src/loot_table.rs +++ b/pumpkin-util/src/loot_table.rs @@ -168,17 +168,9 @@ impl ToTokens for UniformLootNumberProvider { } impl UniformLootNumberProvider { - pub fn get_min(&self) -> f32 { - self.min - } - pub fn get(&self, random: &mut impl RandomImpl) -> f32 { random.next_f32() * (self.max - self.min) + self.min } - - pub fn get_max(&self) -> f32 { - self.max - } } #[derive(Deserialize, PartialEq, Clone, Copy, Debug)] @@ -204,15 +196,6 @@ impl ToTokens for 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 { match self { LootNumberProviderTypes::Object(int_provider) => match int_provider { @@ -221,13 +204,4 @@ impl LootNumberProviderTypes { 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, - } - } } diff --git a/pumpkin/src/entity/player.rs b/pumpkin/src/entity/player.rs index 37610d809..fad5615c7 100644 --- a/pumpkin/src/entity/player.rs +++ b/pumpkin/src/entity/player.rs @@ -882,11 +882,10 @@ impl Player { // return; // } - if self.packet_sequence.load(Ordering::Relaxed) > -1 { + let seq = self.packet_sequence.swap(-1, Ordering::Relaxed); + if seq != -1 { self.client - .enqueue_packet(&CAcknowledgeBlockChange::new( - self.packet_sequence.swap(-1, Ordering::Relaxed).into(), - )) + .send_packet_now(&CAcknowledgeBlockChange::new(seq.into())) .await; } { diff --git a/pumpkin/src/net/java/play.rs b/pumpkin/src/net/java/play.rs index 2773eb57f..a70c98fd7 100644 --- a/pumpkin/src/net/java/play.rs +++ b/pumpkin/src/net/java/play.rs @@ -2036,6 +2036,11 @@ impl JavaClient { let _replaced_id = world .set_block_state(&final_block_pos, new_state, BlockFlags::NOTIFY_ALL) .await; + self.send_packet_now(&CBlockUpdate::new( + final_block_pos, + VarInt(i32::from(new_state)), + )) + .await; server .block_registry diff --git a/pumpkin/src/world/loot.rs b/pumpkin/src/world/loot.rs index e13b62363..5cfc0b8c3 100644 --- a/pumpkin/src/world/loot.rs +++ b/pumpkin/src/world/loot.rs @@ -4,7 +4,7 @@ use pumpkin_util::{ LootCondition, LootFunctionNumberProvider, LootFunctionTypes, LootPoolEntry, LootPoolEntryTypes, LootTable, }, - random::{RandomGenerator, xoroshiro128::Xoroshiro}, + random::{RandomGenerator, RandomImpl, get_seed, xoroshiro128::Xoroshiro}, }; use pumpkin_world::item::ItemStack; use rand::Rng; @@ -23,32 +23,56 @@ pub trait LootTableExt { impl LootTableExt for LootTable { fn get_loot(&self, params: LootContextParameters) -> Vec { let mut stacks = Vec::new(); + let mut random = RandomGenerator::Xoroshiro(Xoroshiro::from_seed(get_seed())); if let Some(pools) = self.pools { for pool in pools { if let Some(conditions) = pool.conditions && !conditions.iter().all(|cond| cond.is_fulfilled(¶ms)) { - return stacks; + continue; } - // TODO - let rolls = pool - .rolls - .get(&mut RandomGenerator::Xoroshiro(Xoroshiro::from_seed(123))) - .round() - + pool.bonus_rolls.floor(); // TODO: multiply by luck + let rolls = pool.rolls.get(&mut random).round() as i32; + + for _ in 0..rolls { + let mut total_weight = 0; + let mut valid_entries = Vec::new(); - for _ in 0..(rolls as i32) { for entry in pool.entries { - if let Some(loot) = entry.get_loot(¶ms) { - stacks.extend(loot); + if entry + .conditions + .as_ref() + .is_none_or(|c| c.iter().all(|cond| cond.is_fulfilled(¶ms))) + { + 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(¶ms) { + for stack in loot { + if stack.item_count > 0 { + stacks.push(stack); + } + } + } + break; } } } } } - stacks } } @@ -145,12 +169,14 @@ impl LootPoolEntryTypesExt for LootPoolEntryTypes { Self::LootTable => todo!(), Self::Dynamic => todo!(), Self::Tag => todo!(), - Self::Alternatives(alternative_entry) => alternative_entry - .children - .iter() - .filter_map(|entry| entry.get_loot(params)) - .flatten() - .collect(), + Self::Alternatives(alternative_entry) => { + for entry in alternative_entry.children { + if let Some(loot) = entry.get_loot(params) { + return loot; + } + } + Vec::new() + } Self::Sequence => todo!(), Self::Group => todo!(), } @@ -209,7 +235,7 @@ impl LootFunctionNumberProviderExt for LootFunctionNumberProvider { fn generate(&self) -> f32 { match self { Self::Constant { value } => *value, - Self::Uniform { min, max } => rand::rng().random_range(*min..=*max), + Self::Uniform { min, max } => rand::random::() * (max - min) + min, Self::Binomial { n, p } => (0..n.floor() as u32).fold(0.0, |c, _| { if rand::rng().random_bool(f64::from(*p)) { c + 1.0