From cadc98ce951c43573e5b090f3a83380f0b08db89 Mon Sep 17 00:00:00 2001 From: Jhobean Date: Wed, 5 Nov 2025 18:23:12 -0500 Subject: [PATCH] Fix issue on OpenDoor Macro --- Changelog.txt | 3 + src/game/clients/CClientEvent.cpp | 97 +++++++++++++++++++++---------- 2 files changed, 70 insertions(+), 30 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 01b71f701..218adad03 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -4070,3 +4070,6 @@ When setting a property like MORE to the a spell or skill defname, trying to rea - Fixed: Changing Char flags didn't always trigger a full update packet. - Fixed: Sector indexing issue. - Changed: Made both Windows and Linux load scripts in a folder in alphabetical order. + +05-11-2025, , canerksk / Jhobean +- Fixed: On some situation OPENDOOR macro do not open the correct door (issue #1510). diff --git a/src/game/clients/CClientEvent.cpp b/src/game/clients/CClientEvent.cpp index c323aca24..9dc330aba 100644 --- a/src/game/clients/CClientEvent.cpp +++ b/src/game/clients/CClientEvent.cpp @@ -3094,36 +3094,73 @@ void CClient::Event_ExtCmd( EXTCMD_TYPE type, tchar *pszName ) return; } - case EXTCMD_DOOR_AUTO: // open door macro - { - CPointMap pt = m_pChar->GetTopPoint(); - char iCharZ = pt.m_z; - - pt.Move(m_pChar->m_dirFace); - auto Area = CWorldSearchHolder::GetInstance(pt, bDoorAutoDist); - for (;;) - { - CItem *pItem = Area->GetItem(); - if ( !pItem ) - return; - - switch ( pItem->GetType() ) - { - case IT_DOOR: - case IT_DOOR_LOCKED: - case IT_PORTCULIS: - case IT_PORT_LOCKED: - if ( abs(iCharZ - pItem->GetTopPoint().m_z) < 20 ) - { - m_pChar->SysMessageDefault(DEFMSG_MACRO_OPENDOOR); - m_pChar->Use_Obj(pItem, true); - return; - } - } - } - return; - } - + case EXTCMD_DOOR_AUTO: + { + CPointMap charPt = m_pChar->GetTopPoint(); + int charZ = charPt.m_z; + int16 x = charPt.m_x; + int16 y = charPt.m_y; + switch (m_pChar->m_dirFace) + { + case DIR_N:--y; break; + case DIR_NE:++x; --y; break; + case DIR_E: ++x; break; + case DIR_SE:++x; ++y; break; + case DIR_S:++y; break; + case DIR_SW:--x; ++y; break; + case DIR_W:--x; break; + case DIR_NW:--x; --y; break; + default:break; + } + CPointMap ptTarget(x, y, charPt.m_z, charPt.m_map); + auto Area = CWorldSearchHolder::GetInstance(ptTarget, bDoorAutoDist); + CItem* pBestCandidate = nullptr; + int iBestDist = bDoorAutoDist + UO_MAP_VIEW_SIGHT; + for (;;) + { + CItem* pItem = Area->GetItem(); + if (!pItem) + break; + switch (pItem->GetType()) + { + case IT_DOOR: + case IT_DOOR_LOCKED: + case IT_PORTCULIS: + case IT_PORT_LOCKED: + { + const CPointMap itPt = pItem->GetTopPoint(); + int itemTopZ = itPt.m_z; + bool z_overlap = ((itemTopZ + pItem->GetHeight()) > charZ) && ((charZ + 16) > itemTopZ); + bool z_close = (std::abs(charZ - itemTopZ) < 20); + if (!z_overlap || !z_close) + break; + //if (!m_pChar->CanSee(pItem) + //break; + if (itPt.m_x == x && itPt.m_y == y) + { + m_pChar->SysMessageDefault(DEFMSG_MACRO_OPENDOOR); + m_pChar->Use_Obj(pItem, true); + return; + } + int iDist = charPt.GetDist(itPt); + if (iDist < iBestDist) + { + iBestDist = iDist; + pBestCandidate = pItem; + } + break; + } + default: + break; + } + } + if (pBestCandidate) + { + m_pChar->SysMessageDefault(DEFMSG_MACRO_OPENDOOR); + m_pChar->Use_Obj(pBestCandidate, true); + } + return; + } case EXTCMD_INVOKE_VIRTUE: { if ( !IsTrigUsed(TRIGGER_USERVIRTUEINVOKE) )