From 967815d27e975f4e3d07c03a9e999382df7ad2c0 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Mon, 15 Feb 2021 05:27:37 +0100 Subject: [PATCH] Fix player's clipModel->axis when loading savegame, fixes #328 idClipModel::axis is an idMat3 rotation matrix. Usually it's an identity matrix, but if the player is pushed around by an idPush entity it's modified and apparently can (wrongly) remain modified, possibly when saving while idPush is active. This seems to happen sometimes on the crashing elevator in game/delta1. The fix/workaround is to reset it to mat3_identity when loading a savegame. --- d3xp/physics/Physics_Player.cpp | 14 ++++++++++++++ game/physics/Physics_Player.cpp | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/d3xp/physics/Physics_Player.cpp b/d3xp/physics/Physics_Player.cpp index af1a764..1c80ceb 100644 --- a/d3xp/physics/Physics_Player.cpp +++ b/d3xp/physics/Physics_Player.cpp @@ -1626,6 +1626,20 @@ void idPhysics_Player::Restore( idRestoreGame *savefile ) { savefile->ReadInt( (int &)waterLevel ); savefile->ReadInt( waterType ); + + /* DG: It can apparently happen that the player saves while the clipModel's axis are + * modified by idPush::TryRotatePushEntity() -> idPhysics_Player::Rotate() -> idClipModel::Link() + * Normally idPush seems to reset them to the identity matrix in the next frame, + * but apparently not when coming from a savegame. + * Usually clipModel->axis is the identity matrix, and if it isn't there's clipping bugs + * like CheckGround() reporting that it's steep even though the player is only trying to + * walk up normal stairs. + * Resetting the axis to mat3_identity when restoring a savegame works around that issue + * and makes sure players can go on playing if their savegame was "corrupted" by saving + * while idPush was active. See https://github.com/dhewm/dhewm3/issues/328 for more details */ + if ( clipModel != nullptr ) { + clipModel->SetPosition( clipModel->GetOrigin(), mat3_identity ); + } } /* diff --git a/game/physics/Physics_Player.cpp b/game/physics/Physics_Player.cpp index af1a764..1c80ceb 100644 --- a/game/physics/Physics_Player.cpp +++ b/game/physics/Physics_Player.cpp @@ -1626,6 +1626,20 @@ void idPhysics_Player::Restore( idRestoreGame *savefile ) { savefile->ReadInt( (int &)waterLevel ); savefile->ReadInt( waterType ); + + /* DG: It can apparently happen that the player saves while the clipModel's axis are + * modified by idPush::TryRotatePushEntity() -> idPhysics_Player::Rotate() -> idClipModel::Link() + * Normally idPush seems to reset them to the identity matrix in the next frame, + * but apparently not when coming from a savegame. + * Usually clipModel->axis is the identity matrix, and if it isn't there's clipping bugs + * like CheckGround() reporting that it's steep even though the player is only trying to + * walk up normal stairs. + * Resetting the axis to mat3_identity when restoring a savegame works around that issue + * and makes sure players can go on playing if their savegame was "corrupted" by saving + * while idPush was active. See https://github.com/dhewm/dhewm3/issues/328 for more details */ + if ( clipModel != nullptr ) { + clipModel->SetPosition( clipModel->GetOrigin(), mat3_identity ); + } } /*