26 std::shared_ptr<World> world = c.
GetWorld();
27 const Blockstate* blockstate = world->GetBlock(pos);
30 if (blockstate ==
nullptr)
37 blockstate = world->GetBlock(pos);
41 if (blockstate ==
nullptr)
43 LOG_WARNING(
"Digging target block is nullptr while being close to player");
48 if (blockstate->
IsAir())
53 const GameType game_mode = local_player->GetGameMode();
57 (!local_player->GetInstabuild() && blockstate->
GetHardness() < 0.0f)
64#if PROTOCOL_VERSION < 766
67 const double range =
static_cast<double>(local_player->GetAttributePlayerBlockInteractionRangeValue());
72 int pathfind_tolerance = 4;
73 while (pathfind_tolerance > 0 && eye_pos.
SqrDist(closest_point_on_block) >= range * range)
79 eye_pos = local_player->GetPosition() +
Vector3<double>(0.0, local_player->GetEyeHeight(), 0.0);
81 pathfind_tolerance -= 1;
85 if (eye_pos.
SqrDist(closest_point_on_block) >= range * range)
91 static_cast<int>(std::floor(eye_pos.
x)),
92 static_cast<int>(std::floor(eye_pos.
y)),
93 static_cast<int>(std::floor(eye_pos.
z))
95 const bool is_on_ground = local_player->GetOnGround();
97 const Blockstate* head_blockstate = world->GetBlock(eyes_block);
98 const bool is_head_in_fluid = head_blockstate !=
nullptr && head_blockstate->
IsFluid();
102#if PROTOCOL_VERSION < 767
103 float efficiency_speed_boost = 0.0f;
105 const float efficiency_speed_boost =
static_cast<float>(local_player->GetAttributePlayerMiningEfficiencyValue());
107#if PROTOCOL_VERSION < 767
108 float submerged_speed_multiplier = 1.0f;
110 float submerged_speed_multiplier = is_head_in_fluid ?
static_cast<float>(local_player->GetAttributePlayerSubmergedMiningSpeedValue()) : 1.0f;
112 if (!local_player->GetInstabuild())
116#if PROTOCOL_VERSION < 767
118 if (is_head_in_fluid)
123 submerged_speed_multiplier = 0.2f;
129 const Slot main_hand = inventory_manager->GetHotbarSelected();
133#if PROTOCOL_VERSION < 347
143#if PROTOCOL_VERSION < 767
145 efficiency_speed_boost = (efficiency_level > 0) * 1.0f + efficiency_level * efficiency_level;
150 unsigned char haste_amplifier = 0;
151 unsigned char mining_fatigue_amplifier = 0;
152 if (!local_player->GetInstabuild())
154 for (
const auto& effect : local_player->GetEffects())
158 haste_amplifier = effect.amplifier + 1;
163 mining_fatigue_amplifier = effect.amplifier + 1;
169#if PROTOCOL_VERSION < 766
170 constexpr float speed_multiplier = 1.0f;
172 const float speed_multiplier =
static_cast<float>(local_player->GetAttributePlayerBlockBreakSpeedValue());
176 const float expected_mining_time_s =
177 local_player->GetInstabuild() ? 0.0f :
180 current_tool_material,
181 efficiency_speed_boost,
183 mining_fatigue_amplifier,
185 speed_multiplier * submerged_speed_multiplier
186 ) *
static_cast<float>(ms_per_tick / 50.0);
187 if (expected_mining_time_s > 60.0f)
189 LOG_INFO(
"Starting an expected " << expected_mining_time_s <<
" seconds long mining at " << pos <<
".A little help?");
198 std::shared_ptr<ServerboundPlayerActionPacket> msg_digging = std::make_shared<ServerboundPlayerActionPacket>();
201 msg_digging->SetDirection(
static_cast<int>(face));
202#if PROTOCOL_VERSION > 758
203 msg_digging->SetSequence(world->GetNextWorldInteractionSequenceId());
205 network_manager->Send(msg_digging);
207 std::shared_ptr<ServerboundSwingPacket> swing_packet;
208 std::chrono::steady_clock::time_point last_time_send_swing;
211 swing_packet = std::make_shared<ServerboundSwingPacket>();
212 swing_packet->SetHand(
static_cast<int>(
Hand::Main));
213 network_manager->Send(swing_packet);
214 last_time_send_swing = std::chrono::steady_clock::now();
217 auto start = std::chrono::steady_clock::now();
218 bool finished_sent = local_player->GetInstabuild();
221 auto now = std::chrono::steady_clock::now();
222 long long int elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start).count();
223 if (elapsed > 50 * ms_per_tick + expected_mining_time_s * 1000.0f)
225 LOG_WARNING(
"Something went wrong waiting block breaking confirmation (Timeout).");
228 if (elapsed >= expected_mining_time_s * 1000.0f
234 msg_finish->SetDirection(
static_cast<int>(face));
235#if PROTOCOL_VERSION > 758
236 msg_finish->SetSequence(world->GetNextWorldInteractionSequenceId());
238 network_manager->Send(msg_finish);
240 finished_sent =
true;
242 if (send_swing && !finished_sent && std::chrono::duration_cast<std::chrono::milliseconds>(now - last_time_send_swing).count() > 5.0 * ms_per_tick)
244 last_time_send_swing = now;
245 network_manager->Send(swing_packet);
247 const Blockstate* block = world->GetBlock(pos);
249 if (block ==
nullptr || block->
IsAir())