From bfab6604cc28be3a817d8afc6161e9f964cdbe4e Mon Sep 17 00:00:00 2001 From: DracoScript Date: Tue, 21 Jun 2022 23:02:03 -0300 Subject: [PATCH] Avoiding dinamically reading event list while processing Using the current method of checking changes on events won't work properly if an event is added at the same time as another is removed, because the list size stays the same and an event may be skipped. Probably my solution was not the most optimized, but it's how I made it work. To be more specific about the issue I faced, I had 5 events to be processed and the 3rd one removed itself and added another one, keeping the list with 5 elements but skipping the 4th element on the original list as it became the 3rd and the index jumped to the 4th without knowing the 3rd was replaced by an unprocessed event. --- src/graysvr/CCharAct.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/graysvr/CCharAct.cpp b/src/graysvr/CCharAct.cpp index 300ba77a9..7de83a24f 100644 --- a/src/graysvr/CCharAct.cpp +++ b/src/graysvr/CCharAct.cpp @@ -3369,11 +3369,16 @@ TRIGRET_TYPE CChar::OnTrigger(LPCTSTR pszTrigName, CTextConsole *pSrc, CScriptTr if ( IsTrigUsed(pszTrigName) ) { EXC_SET("events"); - size_t origEvents = m_OEvents.GetCount(); - size_t curEvents = origEvents; - for ( size_t i = 0; i < curEvents; ++i ) + CResourceRefArray events; + for ( size_t i = 0; i < m_OEvents.GetCount(); ++i ) // EVENTS (could be modifyed ingame!) { - CResourceLink *pLink = m_OEvents[i]; + events.Add(m_OEvents[i]); + } + for ( size_t i = 0; i < events.GetCount(); ++i ) + { + CResourceLink* pLink = events[i]; + if ( !m_OEvents.ContainsResourceID(pLink->GetResourceID()) ) + continue; if ( !pLink || !pLink->HasTrigger(iAction) ) continue; CResourceLock s; @@ -3382,13 +3387,6 @@ TRIGRET_TYPE CChar::OnTrigger(LPCTSTR pszTrigName, CTextConsole *pSrc, CScriptTr iRet = CScriptObj::OnTriggerScript(s, pszTrigName, pSrc, pArgs); if ( (iRet != TRIGRET_RET_FALSE) && (iRet != TRIGRET_RET_DEFAULT) ) goto stopandret; //return iRet; - - curEvents = m_OEvents.GetCount(); - if ( curEvents < origEvents ) // the event has been deleted, modify the counter for other trigs to work - { - --i; - origEvents = curEvents; - } } // TEVENTS