Skip to content

Commit 8d718a6

Browse files
committed
replace hard-coded block break speed checks
1 parent 4bf8247 commit 8d718a6

File tree

7 files changed

+76
-97
lines changed

7 files changed

+76
-97
lines changed

azalea-client/src/plugins/mining.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ pub fn handle_mining_queued(
342342
if block_is_solid
343343
&& get_mine_progress(
344344
block.as_ref(),
345-
held_item.kind(),
345+
held_item,
346346
fluid_on_eyes,
347347
physics,
348348
attributes,
@@ -657,7 +657,7 @@ pub fn continue_mining_block(
657657
let block = Box::<dyn BlockTrait>::from(target_block_state);
658658
**mine_progress += get_mine_progress(
659659
block.as_ref(),
660-
current_mining_item.kind(),
660+
current_mining_item,
661661
fluid_on_eyes,
662662
physics,
663663
attributes,

azalea-entity/src/attributes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub struct Attributes {
2121
pub attack_speed: AttributeInstance,
2222
pub water_movement_efficiency: AttributeInstance,
2323
pub mining_efficiency: AttributeInstance,
24+
pub block_break_speed: AttributeInstance,
2425

2526
pub block_interaction_range: AttributeInstance,
2627
pub entity_interaction_range: AttributeInstance,
@@ -41,6 +42,7 @@ impl Attributes {
4142
Attribute::BlockInteractionRange => &mut self.block_interaction_range,
4243
Attribute::EntityInteractionRange => &mut self.entity_interaction_range,
4344
Attribute::StepHeight => &mut self.step_height,
45+
Attribute::BlockBreakSpeed => &mut self.block_break_speed,
4446
_ => return None,
4547
};
4648
Some(value)

azalea-entity/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ impl Attributes {
398398
block_interaction_range: AttributeInstance::new(4.5),
399399
entity_interaction_range: AttributeInstance::new(3.0),
400400
step_height: AttributeInstance::new(0.6),
401+
block_break_speed: AttributeInstance::new(1.0),
401402
}
402403
}
403404
}

azalea-entity/src/mining.rs

Lines changed: 35 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use azalea_block::{BlockBehavior, BlockTrait};
2-
use azalea_core::tier::get_item_tier;
3-
use azalea_registry::{
4-
builtin::{BlockKind, ItemKind, MobEffect},
5-
tags,
6-
};
2+
use azalea_inventory::{ItemStack, components::Tool};
3+
use azalea_registry::builtin::{BlockKind, MobEffect};
74

85
use crate::{ActiveEffects, Attributes, FluidOnEyes, Physics};
96

@@ -19,7 +16,7 @@ use crate::{ActiveEffects, Attributes, FluidOnEyes, Physics};
1916
/// to your mining speed.
2017
pub fn get_mine_progress(
2118
block: &dyn BlockTrait,
22-
held_item: ItemKind,
19+
held_item: &ItemStack,
2320
fluid_on_eyes: &FluidOnEyes,
2421
physics: &Physics,
2522
attributes: &Attributes,
@@ -45,34 +42,26 @@ pub fn get_mine_progress(
4542
attributes,
4643
active_effects,
4744
);
48-
(base_destroy_speed / destroy_time) / divisor as f32
45+
(base_destroy_speed / destroy_time) / (divisor as f32)
4946
}
5047

51-
fn has_correct_tool_for_drops(block: &dyn BlockTrait, tool: ItemKind) -> bool {
48+
fn has_correct_tool_for_drops(block: &dyn BlockTrait, item: &ItemStack) -> bool {
5249
if !block.behavior().requires_correct_tool_for_drops {
5350
return true;
5451
}
52+
let Some(tool) = item.get_component::<Tool>() else {
53+
return false;
54+
};
5555
let registry_block = block.as_registry_block();
56-
if tool == ItemKind::Shears {
57-
matches!(
58-
registry_block,
59-
BlockKind::Cobweb | BlockKind::RedstoneWire | BlockKind::Tripwire
60-
)
61-
} else if tags::items::SWORDS.contains(&tool) {
62-
registry_block == BlockKind::Cobweb
63-
} else if tags::items::PICKAXES.contains(&tool)
64-
|| tags::items::SHOVELS.contains(&tool)
65-
|| tags::items::HOES.contains(&tool)
66-
|| tags::items::AXES.contains(&tool)
67-
{
68-
let tier = get_item_tier(tool).expect("all pickaxes and shovels should be matched");
69-
let tier_level = tier.level();
70-
!((tier_level < 3 && tags::blocks::NEEDS_DIAMOND_TOOL.contains(&registry_block))
71-
|| (tier_level < 2 && tags::blocks::NEEDS_IRON_TOOL.contains(&registry_block))
72-
|| (tier_level < 1 && tags::blocks::NEEDS_STONE_TOOL.contains(&registry_block)))
73-
} else {
74-
false
56+
for rule in &tool.rules {
57+
if let Some(correct) = rule.correct_for_drops
58+
&& rule.blocks.contains(registry_block)
59+
{
60+
return correct;
61+
}
7562
}
63+
64+
false
7665
}
7766

7867
/// Returns the destroy speed of the given block with the given tool, taking
@@ -82,21 +71,21 @@ fn has_correct_tool_for_drops(block: &dyn BlockTrait, tool: ItemKind) -> bool {
8271
/// `ItemKind::Air`.
8372
fn destroy_speed(
8473
block: BlockKind,
85-
tool: ItemKind,
74+
tool: &ItemStack,
8675
_fluid_on_eyes: &FluidOnEyes,
8776
physics: &Physics,
8877
attributes: &Attributes,
8978
active_effects: &ActiveEffects,
9079
) -> f32 {
91-
let mut base_destroy_speed = base_destroy_speed(block, tool);
80+
let mut speed = base_destroy_speed(block, tool);
9281

93-
if base_destroy_speed > 1. {
82+
if speed > 1. {
9483
// efficiency enchantment
95-
base_destroy_speed += attributes.mining_efficiency.calculate() as f32;
84+
speed += attributes.mining_efficiency.calculate() as f32;
9685
}
9786

9887
if let Some(dig_speed_amplifier) = active_effects.get_dig_speed_amplifier() {
99-
base_destroy_speed *= 1. + (dig_speed_amplifier + 1) as f32 * 0.2;
88+
speed *= 1. + (dig_speed_amplifier + 1) as f32 * 0.2;
10089
}
10190

10291
if let Some(dig_slowdown) = active_effects.get_level(MobEffect::MiningFatigue) {
@@ -106,9 +95,11 @@ fn destroy_speed(
10695
2 => 0.0027,
10796
_ => 8.1E-4,
10897
};
109-
base_destroy_speed *= multiplier;
98+
speed *= multiplier;
11099
}
111100

101+
speed *= attributes.block_break_speed.calculate() as f32;
102+
112103
// TODO
113104
// if **fluid_on_eyes == FluidKind::Water
114105
// && enchantments::get_enchant_level(registry::Enchantment::AquaAffinity,
@@ -118,56 +109,21 @@ fn destroy_speed(
118109
// }
119110

120111
if !physics.on_ground {
121-
base_destroy_speed /= 5.;
112+
speed /= 5.;
122113
}
123114

124-
base_destroy_speed
115+
speed
125116
}
126117

127-
fn base_destroy_speed(block: BlockKind, tool: ItemKind) -> f32 {
128-
if tool == ItemKind::Shears {
129-
if block == BlockKind::Cobweb || tags::blocks::LEAVES.contains(&block) {
130-
15.
131-
} else if tags::blocks::WOOL.contains(&block) {
132-
5.
133-
} else if matches!(block, BlockKind::Vine | BlockKind::GlowLichen) {
134-
2.
135-
} else {
136-
1.
137-
}
138-
} else if tags::items::SWORDS.contains(&tool) {
139-
if block == BlockKind::Cobweb {
140-
15.
141-
} else if tags::blocks::SWORD_EFFICIENT.contains(&block) {
142-
1.5
143-
} else {
144-
1.
118+
fn base_destroy_speed(block: BlockKind, item: &ItemStack) -> f32 {
119+
let tool = item.get_component::<Tool>();
120+
let Some(tool) = tool else { return 1. };
121+
for rule in &tool.rules {
122+
if let Some(speed) = rule.speed
123+
&& rule.blocks.contains(block)
124+
{
125+
return speed;
145126
}
146-
} else if tags::items::PICKAXES.contains(&tool) {
147-
if tags::blocks::MINEABLE_PICKAXE.contains(&block) {
148-
get_item_tier(tool).unwrap().speed()
149-
} else {
150-
1.
151-
}
152-
} else if tags::items::SHOVELS.contains(&tool) {
153-
if tags::blocks::MINEABLE_SHOVEL.contains(&block) {
154-
get_item_tier(tool).unwrap().speed()
155-
} else {
156-
1.
157-
}
158-
} else if tags::items::HOES.contains(&tool) {
159-
if tags::blocks::MINEABLE_HOE.contains(&block) {
160-
get_item_tier(tool).unwrap().speed()
161-
} else {
162-
1.
163-
}
164-
} else if tags::items::AXES.contains(&tool) {
165-
if tags::blocks::MINEABLE_AXE.contains(&block) {
166-
get_item_tier(tool).unwrap().speed()
167-
} else {
168-
1.
169-
}
170-
} else {
171-
1.
172127
}
128+
tool.default_mining_speed
173129
}

azalea-registry/azalea-registry-macros/src/lib.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,28 +140,35 @@ pub fn registry(input: TokenStream) -> TokenStream {
140140
});
141141

142142
// Display that uses registry ids
143-
let mut display_items = quote! {};
143+
let mut to_str_items = quote! {};
144144
let mut from_str_items = quote! {};
145145
for item in &input.items {
146146
let name = &item.name;
147147
let id = &item.id;
148-
display_items.extend(quote! {
149-
Self::#name => write!(f, concat!("minecraft:", #id)),
148+
to_str_items.extend(quote! {
149+
Self::#name => concat!("minecraft:", #id),
150150
});
151151
from_str_items.extend(quote! {
152152
#id => Ok(Self::#name),
153153
});
154154
}
155155
generated.extend(quote! {
156-
/// Convert the value to a stringified identifier, formatted like
157-
/// `"minecraft:air"`.
158-
impl std::fmt::Display for #name {
159-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
156+
impl #name {
157+
/// Convert the value to a stringified identifier, formatted like
158+
/// `"minecraft:air"`.
159+
pub fn to_str(&self) -> &'static str {
160160
match self {
161-
#display_items
161+
#to_str_items
162162
}
163163
}
164164
}
165+
impl std::fmt::Display for #name {
166+
/// Convert the value to a stringified identifier, formatted like
167+
/// `"minecraft:air"`.
168+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169+
write!(f, "{}", self.to_str())
170+
}
171+
}
165172
impl<'a> TryFrom<&'a crate::Identifier> for #name {
166173
type Error = ();
167174
fn try_from(ident: &'a crate::Identifier) -> Result<Self, Self::Error> {
@@ -172,6 +179,11 @@ pub fn registry(input: TokenStream) -> TokenStream {
172179
}
173180
}
174181
}
182+
impl<'a> From<#name> for crate::Identifier {
183+
fn from(value: #name) -> Self {
184+
Self::new(value.to_str())
185+
}
186+
}
175187
/// Parse the value from a stringified identifier, formatted like
176188
/// either `"air"` or `"minecraft:air"`.
177189
impl std::str::FromStr for #name {

azalea-registry/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,14 @@ impl<D: Registry, Identifier: AzBuf> Default for HolderSet<D, Identifier> {
204204
}
205205
}
206206
}
207+
impl<D: Registry, Identifier: AzBuf + From<D> + PartialEq> HolderSet<D, Identifier> {
208+
pub fn contains(&self, value: D) -> bool {
209+
match self {
210+
HolderSet::Direct { contents } => contents.contains(&value),
211+
HolderSet::Named { key: _, contents } => contents.contains(&Identifier::from(value)),
212+
}
213+
}
214+
}
207215

208216
/// A reference to either a registry or a custom value (usually something with
209217
/// an `Identifier`).

azalea/src/auto_tool.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use azalea_block::{BlockState, BlockTrait, fluid_state::FluidKind};
22
use azalea_core::position::BlockPos;
33
use azalea_entity::{ActiveEffects, Attributes, FluidOnEyes, Physics, inventory::Inventory};
44
use azalea_inventory::{ItemStack, Menu, components};
5-
use azalea_registry::builtin::{BlockKind, EntityKind, ItemKind};
5+
use azalea_registry::builtin::{BlockKind, EntityKind};
66

77
use crate::Client;
88

@@ -92,13 +92,13 @@ pub fn accurate_best_tool_in_hotbar_for_block(
9292
}
9393

9494
// find the first slot that has an item without durability
95-
for (i, item_slot) in hotbar_slots.iter().enumerate() {
95+
for (i, item_stack_data) in hotbar_slots.iter().enumerate() {
9696
let this_item_speed;
97-
match item_slot {
97+
match item_stack_data {
9898
ItemStack::Empty => {
9999
this_item_speed = Some(azalea_entity::mining::get_mine_progress(
100100
block.as_ref(),
101-
ItemKind::Air,
101+
&ItemStack::Empty,
102102
fluid_on_eyes,
103103
physics,
104104
attributes,
@@ -111,7 +111,7 @@ pub fn accurate_best_tool_in_hotbar_for_block(
111111
if !item_stack.component_patch.has::<components::Damage>() {
112112
this_item_speed = Some(azalea_entity::mining::get_mine_progress(
113113
block.as_ref(),
114-
item_stack.kind,
114+
item_stack_data,
115115
fluid_on_eyes,
116116
physics,
117117
attributes,
@@ -131,11 +131,11 @@ pub fn accurate_best_tool_in_hotbar_for_block(
131131
}
132132

133133
// now check every item
134-
for (i, item_slot) in hotbar_slots.iter().enumerate() {
135-
if let ItemStack::Present(item_slot) = item_slot {
134+
for (i, item_stack) in hotbar_slots.iter().enumerate() {
135+
if item_stack.is_present() {
136136
let this_item_speed = azalea_entity::mining::get_mine_progress(
137137
block.as_ref(),
138-
item_slot.kind,
138+
item_stack,
139139
fluid_on_eyes,
140140
physics,
141141
attributes,

0 commit comments

Comments
 (0)