diff --git a/src/d/actor/d_a_obj_Lv5Key.cpp b/src/d/actor/d_a_obj_Lv5Key.cpp index 9c3b5c0e4c..2a5369d834 100644 --- a/src/d/actor/d_a_obj_Lv5Key.cpp +++ b/src/d/actor/d_a_obj_Lv5Key.cpp @@ -7,6 +7,9 @@ #include "d/actor/d_a_obj_Lv5Key.h" #include "d/d_com_inf_game.h" +#if TARGET_PC +#include "d/d_map.h" +#endif static int useHeapInit(fopAc_ac_c*); @@ -113,6 +116,40 @@ void daObjLv5Key_c::Action() { } void daObjLv5Key_c::Wait(int param_0) { +#if TARGET_PC + if (randomizer_IsActive()) { + // Prevent softlock that occurs when opening a locked door from behind. + // This patch compares z and x pos depending on yRot and turns the lock to face the player. + Vec player_pos = dMapInfo_n::getMapPlayerPos(); + + const s32 collisionRotY = shape_angle.y; + + float* playerAxisPos = NULL; + float* lockPos = NULL; + + if (collisionRotY & 0x4000) { + playerAxisPos = &player_pos.x; + lockPos = ¤t.pos.x; + } else { + playerAxisPos = &player_pos.z; + lockPos = ¤t.pos.z; + } + + bool swapSides = false; + if (collisionRotY & 0x8000 && *playerAxisPos > *lockPos + 17.f) { + *lockPos += 34.f; + swapSides = true; + } else if (!(collisionRotY & 0x8000) && *playerAxisPos < *lockPos - 17.f) { + *lockPos -= 34.f; + swapSides = true; + } + + if (swapSides) { + shape_angle.y ^= 0x8000; + current.angle.y ^= 0x8000; + } + } +#endif switch (mMode) { case -1: break;