Skip to content

Commit 23a4957

Browse files
authored
Revert "Revert "Fix stack overflow when attaching elements in maps"" (#1690)
This reverts commit b08d5b7.
1 parent 5b4f590 commit 23a4957

File tree

8 files changed

+54
-32
lines changed

8 files changed

+54
-32
lines changed

Client/mods/deathmatch/logic/CClientEntity.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,27 @@ bool CClientEntity::IsEntityAttached(CClientEntity* pEntity)
10701070
return ListContains(m_AttachedEntities, pEntity);
10711071
}
10721072

1073+
bool CClientEntity::IsAttachedToElement(CClientEntity* pEntity, bool bRecursive)
1074+
{
1075+
if (bRecursive)
1076+
{
1077+
std::set<CClientEntity*> history;
1078+
1079+
for (CClientEntity* pCurrent = this; pCurrent; pCurrent = pCurrent->GetAttachedTo())
1080+
{
1081+
if (pCurrent == pEntity)
1082+
return true;
1083+
1084+
if (!std::get<bool>(history.insert(pCurrent)))
1085+
break; // This should not be possible, but you never know
1086+
}
1087+
1088+
return false;
1089+
}
1090+
1091+
return m_pAttachedToEntity == pEntity;
1092+
}
1093+
10731094
void CClientEntity::ReattachEntities()
10741095
{
10751096
// Jax: this should be called on streamIn/creation

Client/mods/deathmatch/logic/CClientEntity.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ class CClientEntity : public CClientEntityBase
233233
virtual void GetAttachedOffsets(CVector& vecPosition, CVector& vecRotation);
234234
virtual void SetAttachedOffsets(CVector& vecPosition, CVector& vecRotation);
235235
bool IsEntityAttached(CClientEntity* pEntity);
236+
bool IsAttachedToElement(CClientEntity* pEntity, bool bRecursive = true);
236237
uint GetAttachedEntityCount() { return m_AttachedEntities.size(); }
237238
CClientEntity* GetAttachedEntity(uint uiIndex) { return m_AttachedEntities[uiIndex]; }
238239
void ReattachEntities();

Client/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,19 +1317,8 @@ bool CStaticFunctionDefinitions::AttachElements(CClientEntity& Entity, CClientEn
13171317
{
13181318
RUN_CHILDREN(AttachElements(**iter, AttachedToEntity, vecPosition, vecRotation))
13191319

1320-
// Check the elements we are attaching are not already connected
1321-
std::set<CClientEntity*> history;
1322-
for (CClientEntity* pCurrent = &AttachedToEntity; pCurrent; pCurrent = pCurrent->GetAttachedTo())
1323-
{
1324-
if (pCurrent == &Entity)
1325-
return false;
1326-
if (MapContains(history, pCurrent))
1327-
break; // This should not be possible, but you never know
1328-
MapInsert(history, pCurrent);
1329-
}
1330-
13311320
// Can these elements be attached?
1332-
if (Entity.IsAttachToable() && AttachedToEntity.IsAttachable() && Entity.GetDimension() == AttachedToEntity.GetDimension())
1321+
if (Entity.IsAttachToable() && AttachedToEntity.IsAttachable() && !AttachedToEntity.IsAttachedToElement(&Entity) && Entity.GetDimension() == AttachedToEntity.GetDimension())
13331322
{
13341323
ConvertDegreesToRadians(vecRotation);
13351324

Server/mods/deathmatch/logic/CElement.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,27 @@ bool CElement::IsElementAttached(CElement* pElement)
11261126
return false;
11271127
}
11281128

1129+
bool CElement::IsAttachedToElement(CElement* pElement, bool bRecursive)
1130+
{
1131+
if (bRecursive)
1132+
{
1133+
std::set<CElement*> history;
1134+
1135+
for (CElement* pCurrent = this; pCurrent; pCurrent = pCurrent->GetAttachedToElement())
1136+
{
1137+
if (pCurrent == pElement)
1138+
return true;
1139+
1140+
if (!std::get<bool>(history.insert(pCurrent)))
1141+
break; // This should not be possible, but you never know
1142+
}
1143+
1144+
return false;
1145+
}
1146+
1147+
return m_pAttachedTo == pElement;
1148+
}
1149+
11291150
bool CElement::IsAttachable()
11301151
{
11311152
switch (GetType())

Server/mods/deathmatch/logic/CElement.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ class CElement
195195
std::list<CElement*>::const_iterator AttachedElementsEnd() { return m_AttachedElements.end(); }
196196
const char* GetAttachToID() { return m_strAttachToID; }
197197
bool IsElementAttached(CElement* pElement);
198+
bool IsAttachedToElement(CElement* pElement, bool bRecursive = true);
198199
virtual bool IsAttachable();
199200
virtual bool IsAttachToable();
200201
void GetAttachedPosition(CVector& vecPosition);

Server/mods/deathmatch/logic/CMapManager.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -954,7 +954,7 @@ void CMapManager::LinkupElements()
954954
{
955955
CElement* pElement = g_pGame->GetMapManager()->GetRootElement()->FindChild(szAttachToID, 0, true);
956956

957-
if (pElement)
957+
if (pElement && !pElement->IsAttachedToElement(vehicle))
958958
vehicle->AttachTo(pElement);
959959
}
960960
}
@@ -968,7 +968,7 @@ void CMapManager::LinkupElements()
968968
if (szAttachToID[0])
969969
{
970970
CElement* pElement = g_pGame->GetMapManager()->GetRootElement()->FindChild(szAttachToID, 0, true);
971-
if (pElement)
971+
if (pElement && !pElement->IsAttachedToElement(pPlayer))
972972
pPlayer->AttachTo(pElement);
973973
}
974974
}
@@ -982,7 +982,7 @@ void CMapManager::LinkupElements()
982982
if (szAttachToID[0])
983983
{
984984
CElement* pElement = g_pGame->GetMapManager()->GetRootElement()->FindChild(szAttachToID, 0, true);
985-
if (pElement)
985+
if (pElement && !pElement->IsAttachedToElement(pObject))
986986
pObject->AttachTo(pElement);
987987
}
988988
}
@@ -996,7 +996,7 @@ void CMapManager::LinkupElements()
996996
if (szAttachToID[0])
997997
{
998998
CElement* pElement = g_pGame->GetMapManager()->GetRootElement()->FindChild(szAttachToID, 0, true);
999-
if (pElement)
999+
if (pElement && !pElement->IsAttachedToElement(pBlip))
10001000
pBlip->AttachTo(pElement);
10011001
}
10021002
}

Server/mods/deathmatch/logic/CResourceMapItem.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ void CResourceMapItem::LinkupElements()
207207
{
208208
CElement* const pElement = pRootElement->FindChild(szAttachToID, 0, true);
209209

210-
if (pElement)
210+
if (pElement && !pElement->IsAttachedToElement(vehicle))
211211
vehicle->AttachTo(pElement);
212212
}
213213
}
@@ -221,7 +221,7 @@ void CResourceMapItem::LinkupElements()
221221
{
222222
CElement* const pElement = pRootElement->FindChild(szAttachToID, 0, true);
223223

224-
if (pElement)
224+
if (pElement && !pElement->IsAttachedToElement(pPlayer))
225225
pPlayer->AttachTo(pElement);
226226
}
227227
}
@@ -235,7 +235,7 @@ void CResourceMapItem::LinkupElements()
235235
{
236236
CElement* const pElement = pRootElement->FindChild(szAttachToID, 0, true);
237237

238-
if (pElement)
238+
if (pElement && !pElement->IsAttachedToElement(pObject))
239239
pObject->AttachTo(pElement);
240240
}
241241
}
@@ -249,7 +249,7 @@ void CResourceMapItem::LinkupElements()
249249
{
250250
CElement* const pElement = pRootElement->FindChild(szAttachToID, 0, true);
251251

252-
if (pElement)
252+
if (pElement && !pElement->IsAttachedToElement(pBlip))
253253
pBlip->AttachTo(pElement);
254254
}
255255
}

Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,18 +1453,7 @@ bool CStaticFunctionDefinitions::AttachElements(CElement* pElement, CElement* pA
14531453
assert(pElement);
14541454
assert(pAttachedToElement);
14551455

1456-
// Check the elements we are attaching are not already connected
1457-
std::set<CElement*> history;
1458-
for (CElement* pCurrent = pAttachedToElement; pCurrent; pCurrent = pCurrent->GetAttachedToElement())
1459-
{
1460-
if (pCurrent == pElement)
1461-
return false;
1462-
if (MapContains(history, pCurrent))
1463-
break; // This should not be possible, but you never know
1464-
MapInsert(history, pCurrent);
1465-
}
1466-
1467-
if (pElement->IsAttachToable() && pAttachedToElement->IsAttachable() && pElement->GetDimension() == pAttachedToElement->GetDimension())
1456+
if (pElement->IsAttachToable() && pAttachedToElement->IsAttachable() && !pAttachedToElement->IsAttachedToElement(pElement) && pElement->GetDimension() == pAttachedToElement->GetDimension())
14681457
{
14691458
pElement->SetAttachedOffsets(vecPosition, vecRotation);
14701459
ConvertDegreesToRadians(vecRotation);

0 commit comments

Comments
 (0)