1use azalea_block::{BlockBehavior, BlockTrait};
2use azalea_core::tier::get_item_tier;
3use azalea_registry as registry;
4
5use crate::{FluidOnEyes, Physics, effects};
6
7pub fn get_mine_progress(
18 block: &dyn BlockTrait,
19 held_item: registry::Item,
20 player_inventory: &azalea_inventory::Menu,
21 fluid_on_eyes: &FluidOnEyes,
22 physics: &Physics,
23) -> f32 {
24 let block_behavior: BlockBehavior = block.behavior();
25
26 let destroy_time = block_behavior.destroy_time;
27 if destroy_time == -1. {
28 return 0.;
29 }
30 let divisor = if has_correct_tool_for_drops(block, held_item) {
31 30
32 } else {
33 100
34 };
35
36 let base_destroy_speed = destroy_speed(
37 block.as_registry_block(),
38 held_item,
39 player_inventory,
40 fluid_on_eyes,
41 physics,
42 );
43 (base_destroy_speed / destroy_time) / divisor as f32
44}
45
46fn has_correct_tool_for_drops(block: &dyn BlockTrait, tool: registry::Item) -> bool {
47 if !block.behavior().requires_correct_tool_for_drops {
48 return true;
49 }
50 let registry_block = block.as_registry_block();
51 if tool == registry::Item::Shears {
52 matches!(
53 registry_block,
54 registry::Block::Cobweb | registry::Block::RedstoneWire | registry::Block::Tripwire
55 )
56 } else if registry::tags::items::SWORDS.contains(&tool) {
57 registry_block == registry::Block::Cobweb
58 } else if registry::tags::items::PICKAXES.contains(&tool)
59 || registry::tags::items::SHOVELS.contains(&tool)
60 || registry::tags::items::HOES.contains(&tool)
61 || registry::tags::items::AXES.contains(&tool)
62 {
63 let tier = get_item_tier(tool).expect("all pickaxes and shovels should be matched");
64 let tier_level = tier.level();
65 !((tier_level < 3 && registry::tags::blocks::NEEDS_DIAMOND_TOOL.contains(®istry_block))
66 || (tier_level < 2
67 && registry::tags::blocks::NEEDS_IRON_TOOL.contains(®istry_block))
68 || (tier_level < 1
69 && registry::tags::blocks::NEEDS_STONE_TOOL.contains(®istry_block)))
70 } else {
71 false
72 }
73}
74
75fn destroy_speed(
80 block: registry::Block,
81 tool: registry::Item,
82 _player_inventory: &azalea_inventory::Menu,
83 _fluid_on_eyes: &FluidOnEyes,
84 physics: &Physics,
85) -> f32 {
86 let mut base_destroy_speed = base_destroy_speed(block, tool);
87
88 if let Some(dig_speed_amplifier) = effects::get_dig_speed_amplifier() {
99 base_destroy_speed *= 1. + (dig_speed_amplifier + 1) as f32 * 0.2;
100 }
101
102 if let Some(dig_slowdown) = effects::get_effect(registry::MobEffect::MiningFatigue) {
103 let multiplier = match dig_slowdown {
104 0 => 0.3,
105 1 => 0.09,
106 2 => 0.0027,
107 _ => 8.1E-4,
108 };
109 base_destroy_speed *= multiplier;
110 }
111
112 if !physics.on_ground {
121 base_destroy_speed /= 5.;
122 }
123
124 base_destroy_speed
125}
126
127fn base_destroy_speed(block: registry::Block, tool: registry::Item) -> f32 {
128 if tool == registry::Item::Shears {
129 if block == registry::Block::Cobweb || registry::tags::blocks::LEAVES.contains(&block) {
130 15.
131 } else if registry::tags::blocks::WOOL.contains(&block) {
132 5.
133 } else if matches!(block, registry::Block::Vine | registry::Block::GlowLichen) {
134 2.
135 } else {
136 1.
137 }
138 } else if registry::tags::items::SWORDS.contains(&tool) {
139 if block == registry::Block::Cobweb {
140 15.
141 } else if registry::tags::blocks::SWORD_EFFICIENT.contains(&block) {
142 1.5
143 } else {
144 1.
145 }
146 } else if registry::tags::items::PICKAXES.contains(&tool) {
147 if registry::tags::blocks::MINEABLE_PICKAXE.contains(&block) {
148 get_item_tier(tool).unwrap().speed()
149 } else {
150 1.
151 }
152 } else if registry::tags::items::SHOVELS.contains(&tool) {
153 if registry::tags::blocks::MINEABLE_SHOVEL.contains(&block) {
154 get_item_tier(tool).unwrap().speed()
155 } else {
156 1.
157 }
158 } else if registry::tags::items::HOES.contains(&tool) {
159 if registry::tags::blocks::MINEABLE_HOE.contains(&block) {
160 get_item_tier(tool).unwrap().speed()
161 } else {
162 1.
163 }
164 } else if registry::tags::items::AXES.contains(&tool) {
165 if registry::tags::blocks::MINEABLE_AXE.contains(&block) {
166 get_item_tier(tool).unwrap().speed()
167 } else {
168 1.
169 }
170 } else {
171 1.
172 }
173}