113 LOG_WARNING(
"Received a PlayerPosition packet without a player");
117 std::scoped_lock<std::shared_mutex> lock(
player->entity_mutex);
118#if PROTOCOL_VERSION < 768
119 if (packet.GetRelativeArguments() & 0x01)
121 player->position.x =
player->position.x + packet.GetX();
125 player->position.x = packet.GetX();
128 if (packet.GetRelativeArguments() & 0x02)
130 player->position.y =
player->position.y + packet.GetY();
134 player->position.y = packet.GetY();
137 if (packet.GetRelativeArguments() & 0x04)
139 player->position.z =
player->position.z + packet.GetZ();
143 player->position.z = packet.GetZ();
146 player->yaw = packet.GetRelativeArguments() & 0x08 ?
player->yaw + packet.GetYRot() : packet.GetYRot();
147 player->pitch = packet.GetRelativeArguments() & 0x10 ?
player->pitch + packet.GetXRot() : packet.GetXRot();
153 for (
int i = 0; i < 3; ++i)
155 player->position[i] = packet.GetRelatives() & (1 << i) ?
player->position[i] + packet.GetChange().GetPosition()[i] : packet.GetChange().GetPosition()[i];
157 const float new_yaw = packet.GetRelatives() & (1 << 3) ?
player->yaw + packet.GetChange().GetYRot() : packet.GetChange().GetYRot();
158 const float new_pitch = packet.GetRelatives() & (1 << 4) ?
player->pitch + packet.GetChange().GetXRot() : packet.GetChange().GetXRot();
160 if (packet.GetRelatives() & (1 << 8))
162 const float delta_yaw =
player->yaw - new_yaw;
163 const float delta_pitch =
player->pitch - new_pitch;
167 speed.
y *
static_cast<double>(std::cos(delta_pitch * 0.017453292f )) + speed.
z *
static_cast<double>(std::sin(delta_pitch * 0.017453292f )),
168 speed.
z *
static_cast<double>(std::cos(delta_pitch * 0.017453292f )) - speed.
y *
static_cast<double>(std::sin(delta_pitch * 0.017453292f ))
172 speed.
x *
static_cast<double>(std::cos(delta_yaw * 0.017453292f )) + speed.
z *
static_cast<double>(std::sin(delta_yaw * 0.017453292f )),
174 speed.
z *
static_cast<double>(std::cos(delta_yaw * 0.017453292f )) - speed.
x *
static_cast<double>(std::sin(delta_yaw * 0.017453292f ))
178 player->pitch = new_pitch;
179 for (
int i = 0; i < 3; ++i)
181 player->speed[i] = packet.GetRelatives() & (1 << (5 + i)) ? speed[i] + packet.GetChange().GetDeltaMovement()[i] : packet.GetChange().GetDeltaMovement()[i];
183 for (
int i = 0; i < 3; ++i)
185 player->previous_position[i] = packet.GetRelatives() & (1 << i) ?
player->previous_position[i] + packet.GetChange().GetPosition()[i] : packet.GetChange().GetPosition()[i];
187 player->previous_yaw = packet.GetRelatives() & (1 << 3) ?
player->yaw + packet.GetChange().GetYRot() : packet.GetChange().GetYRot();
188 player->previous_pitch = packet.GetRelatives() & (1 << 4) ?
player->pitch + packet.GetChange().GetXRot() : packet.GetChange().GetXRot();
243 auto end = std::chrono::steady_clock::now();
245 end += std::chrono::microseconds(
static_cast<long long int>(1000.0 *
ms_per_tick));
254 std::scoped_lock<std::shared_mutex> lock(
player->entity_mutex);
259 std::shared_ptr<ServerboundMovePlayerPacketPosRot> updated_position_packet = std::make_shared<ServerboundMovePlayerPacketPosRot>();
260 updated_position_packet->SetX(
player->position.x);
261 updated_position_packet->SetY(
player->position.y);
262 updated_position_packet->SetZ(
player->position.z);
263 updated_position_packet->SetYRot(
player->yaw);
264 updated_position_packet->SetXRot(
player->pitch);
265 updated_position_packet->SetOnGround(
false);
266#if PROTOCOL_VERSION > 767
267 updated_position_packet->SetHorizontalCollision(
false);
270 std::shared_ptr<ServerboundAcceptTeleportationPacket> accept_tp_packet = std::make_shared<ServerboundAcceptTeleportationPacket>();
274#if PROTOCOL_VERSION < 768
285#if PROTOCOL_VERSION > 767
286 std::shared_ptr<ServerboundClientTickEndPacket> tick_end_packet = std::make_shared<ServerboundClientTickEndPacket>();
304 static_cast<int>(std::floor(
player->position.x)),
305 static_cast<int>(std::floor(
player->position.y)),
306 static_cast<int>(std::floor(
player->position.z))
311 player->on_ground =
false;
322 player->sprint_double_tap_trigger_time = std::max(0,
player->sprint_double_tap_trigger_time - 1);
335 player->speed.y -= 0.03999999910593033;
345 player->fly_jump_trigger_time = std::max(0,
player->fly_jump_trigger_time - 1);
355 player->jump_delay = std::max(0,
player->jump_delay - 1);
357#if PROTOCOL_VERSION < 770
358 if (std::abs(
player->speed.x) < 0.003)
362 if (std::abs(
player->speed.z) < 0.003)
373 if (std::abs(
player->speed.y) < 0.003)
378#if PROTOCOL_VERSION > 769
379 player->inputs.forward_axis *= 0.98f;
380 player->inputs.left_axis *= 0.98f;
385#if PROTOCOL_VERSION < 770
386 player->inputs.forward_axis *= 0.98f;
387 player->inputs.left_axis *= 0.98f;
393 const double m_sin_pitch =
player->front_vector.y;
394 bool condition = m_sin_pitch <= 0.0 ||
player->inputs.jump;
398 static_cast<int>(std::floor(
player->position.x)),
399 static_cast<int>(std::floor(
player->position.y + 1.0 - 0.1)),
400 static_cast<int>(std::floor(
player->position.z))
402 condition = above_block !=
nullptr && above_block->
IsFluid();
406 player->speed.y += (m_sin_pitch -
player->speed.y) * (m_sin_pitch < -0.2 ? 0.085 : 0.06);
410 const double speed_y =
player->speed.y;
414 player->speed.y = 0.6 * speed_y;
434 player->position.x = std::clamp(
player->position.x, -2.9999999E7, 2.9999999E7);
435 player->position.z = std::clamp(
player->position.z, -2.9999999E7, 2.9999999E7);
437#if PROTOCOL_VERSION > 404
445 else if (
player->GetSleepingPosIdImpl())
453 else if (
player->GetDataLivingEntityFlagsImpl() & 0x04)
468 player->SetDataPoseImpl(current_pose);
497#if PROTOCOL_VERSION > 404
498 const int attached_id =
reinterpret_cast<const FireworkRocketEntity*
>(e.second.get())->GetDataAttachedToTarget().value_or(0);
500 const int attached_id =
reinterpret_cast<const FireworkRocketEntity*
>(e.second.get())->GetDataAttachedToTarget();
502 if (attached_id ==
player->entity_id)
549 player->under_water =
false;
558 const double eye_height =
player->position.
y +
player->GetEyeHeightImpl();
562 double fluid_relative_height = 0.0;
565 for (
int x =
static_cast<int>(std::floor(min_aabb.
x)); x <= static_cast<int>(std::floor(max_aabb.
x)); ++x)
568 for (
int y =
static_cast<int>(std::floor(min_aabb.
y)); y <= static_cast<int>(std::floor(max_aabb.
y)); ++y)
571 for (
int z =
static_cast<int>(std::floor(min_aabb.
z)); z <= static_cast<int>(std::floor(max_aabb.
z)); ++z)
575 if (block ==
nullptr || !block->
IsFluid() ||
581 double fluid_height = 0.0;
583 ((block_above->IsLava() && block->
IsLava()) || (block_above->IsWater() && block->
IsWater())))
592 if (fluid_height + y < min_aabb.
y)
600 if (fluid_height + y >= eye_height)
602 player->under_water =
true;
610 fluid_relative_height = std::max(fluid_height - min_aabb.
y, fluid_relative_height);
618 if (fluid_relative_height < 0.4)
620 current_push *= fluid_relative_height;
622 push += current_push;
632 push /=
static_cast<double>(num_push);
640 push *=
world->IsInFastLavaDimension() ? 0.007 : 0.0023333333333333335;
642 const double push_norm = std::sqrt(push.
SqrNorm());
643 if (std::abs(
player->speed.x) < 0.003 && std::abs(
player->speed.z) < 0.003 && push_norm < 0.0045000000000000005)
647 push *= 0.0045000000000000005;
711 const bool was_sneaking =
player->previous_sneak;
712 const bool had_enough_impulse_to_start_sprinting =
player->previous_forward >= (
player->under_water ? 1e-5f : 0.8f);
713 const bool has_enough_impulse_to_start_sprinting =
player->inputs.forward_axis >= (
player->under_water ? 1e-5f : 0.8f);
715#if PROTOCOL_VERSION > 404
718 const bool is_moving_slowly =
player->crouching;
723 player->sprint_double_tap_trigger_time = 0;
726 bool has_blindness =
false;
727 for (
const auto& effect :
player->effects)
731 has_blindness =
true;
736 const bool can_start_sprinting = !(
738 !has_enough_impulse_to_start_sprinting ||
742 (is_moving_slowly && !
player->under_water)
745 if ((
player->on_ground ||
player->under_water) && !was_sneaking && !had_enough_impulse_to_start_sprinting && can_start_sprinting)
747 if (
player->sprint_double_tap_trigger_time > 0 ||
player->inputs.sprint)
757 if ((!
player->in_water ||
player->under_water) && can_start_sprinting &&
player->inputs.sprint)
765 const bool stop_sprint_condition =
player->inputs.forward_axis <= 1e-5 || (
player->food <= 6 && !
player->may_fly);
768 if ((!
player->on_ground && !
player->inputs.sneak && stop_sprint_condition) || !
player->in_water)
773 else if (stop_sprint_condition ||
774 player->horizontal_collision ||
969#if PROTOCOL_VERSION > 767
972#if PROTOCOL_VERSION < 771
973 const bool shift_key_down =
player->inputs.sneak;
974 if (shift_key_down !=
player->previous_shift_key_down)
976 std::shared_ptr<ServerboundPlayerCommandPacket> player_command_packet = std::make_shared<ServerboundPlayerCommandPacket>();
977 player_command_packet->SetAction(
static_cast<int>(shift_key_down ? PlayerCommandAction::PressShiftKey : PlayerCommandAction::ReleaseShiftKey));
978 player_command_packet->SetId_(
player->entity_id);
980 player->previous_shift_key_down = shift_key_down;
984 if (
player->last_sent_inputs.sneak !=
player->inputs.sneak ||
986 player->last_sent_inputs.sprint !=
player->inputs.sprint ||
987 player->last_sent_inputs.forward_axis !=
player->inputs.forward_axis ||
988 player->last_sent_inputs.left_axis !=
player->inputs.left_axis)
990 std::shared_ptr<ServerboundPlayerInputPacket> player_input_packet = std::make_shared<ServerboundPlayerInputPacket>();
991 player_input_packet->SetForward(
player->inputs.forward_axis > 0.0f);
992 player_input_packet->SetBackward(
player->inputs.forward_axis < 0.0f);
993 player_input_packet->SetLeft(
player->inputs.left_axis > 0.0f);
994 player_input_packet->SetRight(
player->inputs.left_axis < 0.0f);
995 player_input_packet->SetJump(
player->inputs.jump);
996 player_input_packet->SetShift(
player->inputs.sneak);
997 player_input_packet->SetSprint(
player->inputs.sprint);
1004 if (sprinting !=
player->previous_sprinting)
1006 std::shared_ptr<ServerboundPlayerCommandPacket> player_command_packet = std::make_shared<ServerboundPlayerCommandPacket>();
1008 player_command_packet->SetId_(
player->entity_id);
1010 player->previous_sprinting = sprinting;
1013#if PROTOCOL_VERSION < 768
1015 const bool shift_key_down =
player->inputs.sneak;
1016 if (shift_key_down !=
player->previous_shift_key_down)
1018 std::shared_ptr<ServerboundPlayerCommandPacket> player_command_packet = std::make_shared<ServerboundPlayerCommandPacket>();
1019 player_command_packet->SetAction(
static_cast<int>(shift_key_down ? PlayerCommandAction::PressShiftKey : PlayerCommandAction::ReleaseShiftKey));
1020 player_command_packet->SetId_(
player->entity_id);
1022 player->previous_shift_key_down = shift_key_down;
1028 if (has_moved && has_rotated)
1030 std::shared_ptr<ServerboundMovePlayerPacketPosRot> move_player_packet = std::make_shared<ServerboundMovePlayerPacketPosRot>();
1031 move_player_packet->SetX(
player->position.x);
1032 move_player_packet->SetY(
player->position.y);
1033 move_player_packet->SetZ(
player->position.z);
1034 move_player_packet->SetXRot(
player->pitch);
1035 move_player_packet->SetYRot(
player->yaw);
1036 move_player_packet->SetOnGround(
player->on_ground);
1037#if PROTOCOL_VERSION > 767
1038 move_player_packet->SetHorizontalCollision(
player->horizontal_collision);
1044 std::shared_ptr<ServerboundMovePlayerPacketPos> move_player_packet = std::make_shared<ServerboundMovePlayerPacketPos>();
1045 move_player_packet->SetX(
player->position.x);
1046 move_player_packet->SetY(
player->position.y);
1047 move_player_packet->SetZ(
player->position.z);
1048 move_player_packet->SetOnGround(
player->on_ground);
1049#if PROTOCOL_VERSION > 767
1050 move_player_packet->SetHorizontalCollision(
player->horizontal_collision);
1054 else if (has_rotated)
1056 std::shared_ptr<ServerboundMovePlayerPacketRot> move_player_packet = std::make_shared<ServerboundMovePlayerPacketRot>();
1057 move_player_packet->SetXRot(
player->pitch);
1058 move_player_packet->SetYRot(
player->yaw);
1059 move_player_packet->SetOnGround(
player->on_ground);
1060#if PROTOCOL_VERSION > 767
1061 move_player_packet->SetHorizontalCollision(
player->horizontal_collision);
1065 else if (
player->on_ground !=
player->previous_on_ground
1066#
if PROTOCOL_VERSION > 767
1067 ||
player->horizontal_collision !=
player->previous_horizontal_collision
1071#if PROTOCOL_VERSION > 754
1072 std::shared_ptr<ServerboundMovePlayerPacketStatusOnly> move_player_packet = std::make_shared<ServerboundMovePlayerPacketStatusOnly>();
1074 std::shared_ptr<ServerboundMovePlayerPacket> move_player_packet = std::make_shared<ServerboundMovePlayerPacket>();
1076 move_player_packet->SetOnGround(
player->on_ground);
1077#if PROTOCOL_VERSION > 767
1078 move_player_packet->SetHorizontalCollision(
player->horizontal_collision);
1094#if PROTOCOL_VERSION > 767
1095 player->previous_horizontal_collision =
player->horizontal_collision;
1114 const std::vector<AABB> colliders =
world->GetColliders(aabb, movement);
1116 if (colliders.size() == 0)
1123 AABB moved_aabb = aabb;
1128 if (std::abs(collided_movement.
x) > std::abs(collided_movement.
z))
1140 return collided_movement;
1147 const int this_axis = axis % 3;
1148 const int axis_1 = (axis + 1) % 3;
1149 const int axis_2 = (axis + 2) % 3;
1151 for (
const AABB& collider : colliders)
1153 if (std::abs(movement[this_axis]) < 1.0e-7)
1155 movement[this_axis] = 0.0;
1160 if (max_aabb[axis_1] - 1e-7 > min_collider[axis_1] && min_aabb[axis_1] + 1e-7 < max_collider[axis_1] &&
1161 max_aabb[axis_2] - 1e-7 > min_collider[axis_2] && min_aabb[axis_2] + 1e-7 < max_collider[axis_2])
1163 if (movement[this_axis] > 0.0 && max_aabb[this_axis] - 1e-7 <= min_collider[this_axis])
1165 movement[this_axis] = std::min(min_collider[this_axis] - max_aabb[this_axis], movement[this_axis]);
1167 else if (movement[this_axis] < 0.0 && min_aabb[this_axis] + 1e-7 >= max_collider[this_axis])
1169 movement[this_axis] = std::max(max_collider[this_axis] - min_aabb[this_axis], movement[this_axis]);
1174 translation[this_axis] = movement[this_axis];
1205 const bool going_down =
player->speed.y <= 0.0;
1206 bool has_slow_falling =
false;
1207#if PROTOCOL_VERSION > 340
1208 for (
const auto& effect :
player->effects)
1212 has_slow_falling =
true;
1218#if PROTOCOL_VERSION < 766
1219 const double drag = (going_down && has_slow_falling) ? 0.01 : 0.08;
1221 const double drag = (going_down && has_slow_falling) ? std::min(0.01,
player->GetAttributeGravityValueImpl()) :
player->GetAttributeGravityValueImpl();
1227 const double init_y =
player->position.y;
1229 float inputs_strength = 0.02f;
1231#if PROTOCOL_VERSION < 767
1235 float depth_strider_mult =
static_cast<float>(
player->GetAttributeWaterMovementEfficiencyValueImpl());
1239 depth_strider_mult *= 0.5f;
1241 if (depth_strider_mult > 0.0)
1243 water_slow_down += (0.54600006f - water_slow_down) * depth_strider_mult;
1244 inputs_strength += (
static_cast<float>(
player->GetAttributeMovementSpeedValueImpl()) - inputs_strength) * depth_strider_mult;
1247#if PROTOCOL_VERSION > 340
1248 for (
const auto& effect :
player->effects)
1252 water_slow_down = 0.96f;
1260 if (
player->horizontal_collision &&
player->on_climbable)
1264 player->speed.x *= water_slow_down;
1265 player->speed.y *= 0.800000011920929;
1266 player->speed.z *= water_slow_down;
1271 std::abs(
player->speed.y - 0.005) >= 0.003 &&
1272 std::abs(
player->speed.y - drag / 16.0) < 0.003)
1274 player->speed.y = -0.003;
1278 player->speed.y -= drag / 16.0;
1283 if (
player->horizontal_collision &&
1286 player->speed.y = 0.30000001192092896;
1292 const double init_y =
player->position.y;
1296 player->speed.y -= drag / 4.0;
1298 if (
player->horizontal_collision &&
1301 player->speed.y = 0.30000001192092896;
1309 const double cos_pitch_from_length = std::sqrt(
player->front_vector.x *
player->front_vector.x +
player->front_vector.z *
player->front_vector.z);
1310 const double cos_pitch = std::cos(
static_cast<double>(
player->pitch * 0.017453292f ));
1311 const double cos_pitch_sqr = cos_pitch * cos_pitch;
1314 player->speed.y += drag * (-1.0 + 0.75 * cos_pitch_sqr);
1316 if (
player->speed.y < 0.0 && cos_pitch_from_length > 0.0)
1318 const double delta_speed = -
player->speed.y * 0.1 * cos_pitch_sqr;
1319 player->speed.x +=
player->front_vector.x * delta_speed / cos_pitch_from_length;
1320 player->speed.y += delta_speed;
1321 player->speed.z +=
player->front_vector.z * delta_speed / cos_pitch_from_length;
1323 if (
player->pitch < 0.0 && cos_pitch_from_length > 0.0)
1326 const double delta_speed = horizontal_speed *
player->front_vector.y * 0.04;
1327 player->speed.x -=
player->front_vector.x * delta_speed / cos_pitch_from_length;
1328 player->speed.y += delta_speed * 3.2;
1329 player->speed.z -=
player->front_vector.z * delta_speed / cos_pitch_from_length;
1331 if (cos_pitch_from_length > 0.0)
1333 player->speed.x += (
player->front_vector.x / cos_pitch_from_length * horizontal_speed -
player->speed.x) * 0.1;
1334 player->speed.z += (
player->front_vector.z / cos_pitch_from_length * horizontal_speed -
player->speed.z) * 0.1;
1343 const float friction = below_block ==
nullptr ? 0.6f : below_block->
GetFriction();
1344 const float inertia =
player->on_ground ? friction * 0.91f : 0.91f;
1347 (
static_cast<float>(
player->GetAttributeMovementSpeedValueImpl()) * (0.21600002f / (friction * friction * friction))) :
1348#if PROTOCOL_VERSION < 762
1354 if (
player->on_climbable)
1356 player->speed.x = std::clamp(
player->speed.x, -0.15000000596046448, 0.15000000596046448);
1357 player->speed.y = std::max(
player->speed.y, -0.15000000596046448);
1361 static_cast<int>(std::floor(
player->position.x)),
1362 static_cast<int>(std::floor(
player->position.y)),
1363 static_cast<int>(std::floor(
player->position.z))
1369 player->speed.z = std::clamp(
player->speed.z, -0.15000000596046448, 0.15000000596046448);
1373 if ((
player->horizontal_collision ||
player->inputs.jump) &&
1380 unsigned char levitation = 0;
1381 for (
const auto& effect :
player->effects)
1385 levitation = effect.amplifier + 1;
1391 player->speed.y += (0.05 * levitation -
player->speed.y) * 0.2;
1397 player->speed.x *= inertia;
1398 player->speed.y *= 0.9800000190734863;
1399 player->speed.z *= inertia;
1414 if (
player->stuck_speed_multiplier.SqrNorm() > 1e-7)
1416 movement *=
player->stuck_speed_multiplier;
1417 player->stuck_speed_multiplier *= 0.0;
1421#if PROTOCOL_VERSION < 766
1422 constexpr double max_up_step = 0.6;
1424 const double max_up_step =
player->GetAttributeStepHeightValueImpl();
1426 const AABB player_aabb =
player->GetColliderImpl();
1428 && movement.
y <= 0.0
1433 const double step = 0.05;
1435 while (movement.
x != 0.0 &&
world->IsFree((player_aabb +
Vector3<double>(movement.
x, -max_up_step, 0.0)).Inflate(-1e-7),
false))
1437 movement.
x = (movement.
x < step && movement.
x >= -step) ? 0.0 : (movement.
x > 0.0 ? (movement.
x - step) : (movement.
x + step));
1440 while (movement.
z != 0.0 &&
world->IsFree((player_aabb +
Vector3<double>(0.0, -max_up_step, movement.
z)).Inflate(-1e-7),
false))
1442 movement.
z = (movement.
z < step && movement.
z >= -step) ? 0.0 : (movement.
z > 0.0 ? (movement.
z - step) : (movement.
z + step));
1445 while (movement.
x != 0.0 && movement.
z != 0.0 &&
world->IsFree((player_aabb +
Vector3<double>(movement.
x, -max_up_step, movement.
z)).Inflate(-1e-7),
false))
1447 movement.
x = (movement.
x < step && movement.
x >= -step) ? 0.0 : (movement.
x > 0.0 ? (movement.
x - step) : (movement.
x + step));
1448 movement.
z = (movement.
z < step && movement.
z >= -step) ? 0.0 : (movement.
z > 0.0 ? (movement.
z - step) : (movement.
z + step));
1454 if (movement.
SqrNorm() != 0.0)
1462 if ((
player->on_ground || (movement.
y != movement_before_collisions.
y && movement_before_collisions.
y < 0.0)) &&
1463 (movement.
x != movement_before_collisions.
x || movement.
z != movement_before_collisions.
z))
1467 movement_before_collisions.
x,
1469 movement_before_collisions.
z
1472 if (movement_step_up_only.
y < max_up_step)
1475 if (check.
x * check.
x + check.
z * check.
z > movement_with_step_up.
x * movement_with_step_up.
x + movement_with_step_up.
z * movement_with_step_up.
z)
1477 movement_with_step_up = check;
1480 if (movement_with_step_up.
x * movement_with_step_up.
x + movement_with_step_up.
z * movement_with_step_up.
z > movement.
x * movement.
x + movement.
z * movement.
z)
1482 movement = movement_with_step_up +
CollideBoundingBox(player_aabb + movement_with_step_up,
Vector3<double>(0.0, -movement_with_step_up.
y + movement_before_collisions.
y, 0.0));
1487 if (movement.
SqrNorm() > 1.0e-7)
1489 player->position += movement;
1491 const bool collision_x = movement_before_collisions.
x != movement.
x;
1492 const bool collision_y = movement_before_collisions.
y != movement.
y;
1493 const bool collision_z = movement_before_collisions.
z != movement.
z;
1494 player->horizontal_collision = collision_x || collision_z;
1497 player->on_ground = movement_before_collisions.
y < 0.0 && collision_y;
1501 const double half_width = 0.5 *
player->GetWidthImpl();
1502 const AABB feet_slice_aabb(
1505 player->position.y - 0.5e-6,
1508 std::optional<Position> supporting_block_pos =
world->GetSupportingBlockPos(feet_slice_aabb);
1509 if (supporting_block_pos.has_value() ||
player->on_ground_without_supporting_block)
1511 player->supporting_block_pos = supporting_block_pos;
1517 player->on_ground_without_supporting_block = !
player->supporting_block_pos.has_value();
1521 player->on_ground_without_supporting_block =
false;
1522 player->supporting_block_pos = std::optional<Position>();
1527#if PROTOCOL_VERSION < 776
1538 if (
player->inputs.sneak)
1545 static_cast<int>(std::floor(
player->position.x)),
1546 static_cast<int>(std::floor(
player->position.y - 0.2)),
1547 static_cast<int>(std::floor(
player->position.z))
1549 double new_speed = 0.0;
1550 if (block_below !=
nullptr)
1554 new_speed = -
player->speed.y;
1556 else if (block_below->
IsBed())
1558 new_speed =
player->speed.y * -0.66f;
1561 player->speed.y = new_speed;
1565 if (collision_x || collision_y || collision_z)
1568 double restitution =
player->inputs.sneak ? 0.0 :
player->GetAttributeBouncinessValueImpl();
1579 bool has_slow_falling =
false;
1580 for (
const auto& effect :
player->effects)
1584 has_slow_falling =
true;
1588 const double effective_gravity = has_slow_falling ? std::min(0.01,
player->GetAttributeGravityValueImpl()) :
player->GetAttributeGravityValueImpl();
1589 if (
player->speed.y < 0.0)
1591 if (-
player->speed.y < effective_gravity ||
player->inputs.sneak)
1598 static_cast<int>(std::floor(
player->position.x)),
1599 static_cast<int>(std::floor(
player->position.y - 0.2)),
1600 static_cast<int>(std::floor(
player->position.z))
1602 if (block_below !=
nullptr)
1606 restitution = std::max(restitution, 1.0);
1608 else if (block_below->
IsBed())
1610 restitution = std::max(restitution, 0.75);
1616 double effective_drag = 1.0;
1617 double gravity_compensation = 0.0;
1618 if (restitution > 0.0)
1620 const double portion_with_movement = movement.
y / movement_before_collisions.
y;
1621 gravity_compensation = portion_with_movement * effective_gravity;
1622 effective_drag = 1.0 + portion_with_movement * (std::clamp(1.0f - (1.0f - 0.98f) *
static_cast<float>(
player->GetAttributeAirDragModifierValueImpl()), 0.0f, 1.0f) - 1.0);
1624 player->speed.y = (gravity_compensation -
player->speed.y) * effective_drag * restitution;
1631#if PROTOCOL_VERSION > 578 && PROTOCOL_VERSION < 767
1632 short soul_speed_lvl = 0;
1637 constexpr short soul_speed_lvl = 0;
1639 float block_speed_factor = 1.0f;
1641 static_cast<int>(std::floor(
player->position.x)),
1642 static_cast<int>(std::floor(
player->position.y)),
1643 static_cast<int>(std::floor(
player->position.z))
1645 if (feet_block !=
nullptr && (feet_block->
IsHoney() || (feet_block->
IsSoulSand() && soul_speed_lvl == 0)))
1647 block_speed_factor = 0.4f;
1649 if (block_speed_factor == 1.0f)
1652 if (below_block !=
nullptr && (below_block->
IsHoney() || (below_block->
IsSoulSand() && soul_speed_lvl == 0)))
1654 block_speed_factor = 0.4f;
1658#if PROTOCOL_VERSION > 766
1659 block_speed_factor = block_speed_factor +
static_cast<float>(
player->GetAttributeMovementEfficiencyValueImpl()) * (1.0f - block_speed_factor);
1662 player->speed.x *= block_speed_factor;
1663 player->speed.z *= block_speed_factor;
1684 for (
int y =
static_cast<int>(std::floor(min_aabb.
y)); y <= static_cast<int>(std::floor(max_aabb.
y)); ++y)
1687 for (
int z =
static_cast<int>(std::floor(min_aabb.
z)); z <= static_cast<int>(std::floor(max_aabb.
z)); ++z)
1690 for (
int x =
static_cast<int>(std::floor(min_aabb.
x)); x <= static_cast<int>(std::floor(max_aabb.
x)); ++x)
1694 if (block ==
nullptr)
1705 if (above_block ==
nullptr || above_block->
IsAir())
1717 if (!
player->on_ground &&
1718 player->position.y <= y + 0.9375 - 1.0e-7 &&
1719 player->speed.y < -0.08 && (
1720 std::abs(x + 0.5 -
player->position.x) + 1.0e-7 > 0.4375 +
player->GetWidthImpl() / 2.0 ||
1721 std::abs(z + 0.5 -
player->position.z) + 1.0e-7 > 0.4375 +
player->GetWidthImpl() / 2.0)
1724 if (
player->speed.y < -0.13)
1726 const double factor = -0.05 /
player->speed.y;
1727 player->speed.x *= factor;
1729 player->speed.z *= factor;
1744 static_cast<int>(std::floor(
player->position.x)),
1745 static_cast<int>(std::floor(
player->position.y)),
1746 static_cast<int>(std::floor(
player->position.z))
1748 if (feet_block !=
nullptr && feet_block->
IsPowderSnow())