mirror of
https://github.com/minetest/minetest.git
synced 2024-11-20 06:33:45 +01:00
LocalPlayer: Restore 2u height sneak jump (#15015)
Fix 1: Do not consider LocalPlayer's CAO in the collision data. Fix 2: work around the "aabbox3d::intersectsWithBox" edge-case.
This commit is contained in:
parent
21ed680b10
commit
8109563a02
@ -360,7 +360,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
||||
|
||||
collisionMoveResult result = collisionMoveSimple(env, m_client,
|
||||
pos_max_d, m_collisionbox, player_stepheight, dtime,
|
||||
&position, &m_speed, accel_f);
|
||||
&position, &m_speed, accel_f, m_cao);
|
||||
|
||||
bool could_sneak = control.sneak && !free_move && !in_liquid &&
|
||||
!is_climbing && physics_override.sneak;
|
||||
@ -444,7 +444,7 @@ void LocalPlayer::move(f32 dtime, Environment *env, f32 pos_max_d,
|
||||
v3f check_pos = position;
|
||||
check_pos.Y += y_diff * dtime * 22.0f + BS * 0.01f;
|
||||
if (y_diff < BS * 0.6f || (physics_override.sneak_glitch
|
||||
&& !collision_check_intersection(env, m_client, m_collisionbox, check_pos))) {
|
||||
&& !collision_check_intersection(env, m_client, m_collisionbox, check_pos, m_cao))) {
|
||||
// Smoothen the movement (based on 'position.Y = bmax.Y')
|
||||
position.Y = std::min(check_pos.Y, bmax.Y);
|
||||
m_speed.Y = 0.0f;
|
||||
@ -990,7 +990,7 @@ void LocalPlayer::old_move(f32 dtime, Environment *env, f32 pos_max_d,
|
||||
|
||||
collisionMoveResult result = collisionMoveSimple(env, m_client,
|
||||
pos_max_d, m_collisionbox, player_stepheight, dtime,
|
||||
&position, &m_speed, accel_f);
|
||||
&position, &m_speed, accel_f, m_cao);
|
||||
|
||||
// Position was slightly changed; update standing node pos
|
||||
if (touching_ground)
|
||||
@ -1254,7 +1254,7 @@ void LocalPlayer::handleAutojump(f32 dtime, Environment *env,
|
||||
|
||||
// try at peak of jump, zero step height
|
||||
collisionMoveResult jump_result = collisionMoveSimple(env, m_client, pos_max_d,
|
||||
m_collisionbox, 0.0f, dtime, &jump_pos, &jump_speed, v3f(0.0f));
|
||||
m_collisionbox, 0.0f, dtime, &jump_pos, &jump_speed, v3f(0.0f), m_cao);
|
||||
|
||||
// see if we can get a little bit farther horizontally if we had
|
||||
// jumped
|
||||
|
@ -273,7 +273,7 @@ static void add_object_boxes(Environment *env,
|
||||
const v3f pos_f, const v3f speed_f, ActiveObject *self,
|
||||
std::vector<NearbyCollisionInfo> &cinfo)
|
||||
{
|
||||
auto process_object = [&] (ActiveObject *object) {
|
||||
auto process_object = [&cinfo] (ActiveObject *object) {
|
||||
if (object && object->collideWithObjects()) {
|
||||
aabb3f box;
|
||||
if (object->getCollisionBox(&box))
|
||||
@ -292,7 +292,7 @@ static void add_object_boxes(Environment *env,
|
||||
c_env->getActiveObjects(pos_f, distance, clientobjects);
|
||||
|
||||
for (auto &clientobject : clientobjects) {
|
||||
// Do collide with everything but itself and the parent CAO
|
||||
// Do collide with everything but itself and children
|
||||
if (!self || (self != clientobject.obj &&
|
||||
self != clientobject.obj->getParent())) {
|
||||
process_object(clientobject.obj);
|
||||
@ -301,12 +301,12 @@ static void add_object_boxes(Environment *env,
|
||||
|
||||
// add collision with local player
|
||||
LocalPlayer *lplayer = c_env->getLocalPlayer();
|
||||
if (lplayer->getParent() == nullptr) {
|
||||
auto *obj = (ClientActiveObject*) lplayer->getCAO();
|
||||
if (!self || (self != obj && self != obj->getParent())) {
|
||||
aabb3f lplayer_collisionbox = lplayer->getCollisionbox();
|
||||
v3f lplayer_pos = lplayer->getPosition();
|
||||
lplayer_collisionbox.MinEdge += lplayer_pos;
|
||||
lplayer_collisionbox.MaxEdge += lplayer_pos;
|
||||
auto *obj = (ActiveObject*) lplayer->getCAO();
|
||||
cinfo.emplace_back(obj, 0, lplayer_collisionbox);
|
||||
}
|
||||
}
|
||||
@ -315,7 +315,7 @@ static void add_object_boxes(Environment *env,
|
||||
{
|
||||
ServerEnvironment *s_env = dynamic_cast<ServerEnvironment*>(env);
|
||||
if (s_env) {
|
||||
// search for objects which are not us, or we are not its parent.
|
||||
// search for objects which are not us and not our children.
|
||||
// we directly process the object in this callback to avoid useless
|
||||
// looping afterwards.
|
||||
auto include_obj_cb = [self, &process_object] (ServerActiveObject *obj) {
|
||||
@ -623,8 +623,10 @@ bool collision_check_intersection(Environment *env, IGameDef *gamedef,
|
||||
Collision detection
|
||||
*/
|
||||
aabb3f checkbox = box_0;
|
||||
checkbox.MinEdge += pos_f;
|
||||
checkbox.MaxEdge += pos_f;
|
||||
// aabbox3d::intersectsWithBox(box) returns true when the faces are touching perfectly.
|
||||
// However, we do not want want a true-ish return value in that case. Add some tolerance.
|
||||
checkbox.MinEdge += pos_f + (0.1f * BS);
|
||||
checkbox.MaxEdge += pos_f - (0.1f * BS);
|
||||
|
||||
/*
|
||||
Go through every node and object box
|
||||
|
@ -65,7 +65,8 @@ struct collisionMoveResult
|
||||
std::vector<CollisionInfo> collisions;
|
||||
};
|
||||
|
||||
// Moves using a single iteration; speed should not exceed pos_max_d/dtime
|
||||
/// @brief Moves using a single iteration; speed should not exceed pos_max_d/dtime
|
||||
/// @param self (optional) ActiveObject to ignore in the collision detection.
|
||||
collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
|
||||
f32 pos_max_d, const aabb3f &box_0,
|
||||
f32 stepheight, f32 dtime,
|
||||
@ -73,7 +74,11 @@ collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
|
||||
v3f accel_f, ActiveObject *self=NULL,
|
||||
bool collide_with_objects=true);
|
||||
|
||||
// check if box is in collision on actual position
|
||||
/// @brief A simpler version of "collisionMoveSimple" that only checks whether
|
||||
/// a collision occurs at the given position.
|
||||
/// @param self (optional) ActiveObject to ignore in the collision detection.
|
||||
/// @returns `true` when `box_0` truly intersects with a node or object.
|
||||
/// Touching faces are not counted as intersection.
|
||||
bool collision_check_intersection(Environment *env, IGameDef *gamedef,
|
||||
const aabb3f &box_0, const v3f &pos_f, ActiveObject *self = nullptr,
|
||||
bool collide_with_objects = true);
|
||||
|
Loading…
Reference in New Issue
Block a user