2019-05-15 16:52:37 +02:00
|
|
|
#include "common.h"
|
2020-04-17 15:31:11 +02:00
|
|
|
|
2019-07-06 12:27:21 +02:00
|
|
|
#include "World.h"
|
|
|
|
#include "Vehicle.h"
|
|
|
|
#include "PlayerPed.h"
|
|
|
|
#include "Pools.h"
|
2019-05-15 16:52:37 +02:00
|
|
|
#include "References.h"
|
|
|
|
|
2020-04-17 07:54:14 +02:00
|
|
|
CReference CReferences::aRefs[NUMREFERENCES];
|
|
|
|
CReference *CReferences::pEmptyList;
|
2019-05-15 16:52:37 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
CReferences::Init(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
pEmptyList = &aRefs[0];
|
|
|
|
for(i = 0; i < NUMREFERENCES; i++){
|
|
|
|
aRefs[i].pentity = nil;
|
|
|
|
aRefs[i].next = &aRefs[i+1];
|
|
|
|
}
|
|
|
|
aRefs[NUMREFERENCES-1].next = nil;
|
|
|
|
}
|
|
|
|
|
2020-12-29 12:55:26 +01:00
|
|
|
void
|
|
|
|
CEntity::RegisterReference(CEntity **pent)
|
|
|
|
{
|
|
|
|
if(IsBuilding())
|
|
|
|
return;
|
|
|
|
CReference *ref;
|
|
|
|
// check if already registered
|
|
|
|
for(ref = m_pFirstReference; ref; ref = ref->next)
|
|
|
|
if(ref->pentity == pent)
|
|
|
|
return;
|
|
|
|
// have to allocate new reference
|
|
|
|
ref = CReferences::pEmptyList;
|
|
|
|
if(ref){
|
|
|
|
CReferences::pEmptyList = ref->next;
|
|
|
|
|
|
|
|
ref->pentity = pent;
|
|
|
|
ref->next = m_pFirstReference;
|
|
|
|
m_pFirstReference = ref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clean up the reference from *pent -> 'this'
|
|
|
|
void
|
|
|
|
CEntity::CleanUpOldReference(CEntity **pent)
|
|
|
|
{
|
|
|
|
CReference* ref, ** lastnextp;
|
|
|
|
lastnextp = &m_pFirstReference;
|
|
|
|
for (ref = m_pFirstReference; ref; ref = ref->next) {
|
|
|
|
if (ref->pentity == pent) {
|
|
|
|
*lastnextp = ref->next;
|
|
|
|
ref->next = CReferences::pEmptyList;
|
|
|
|
CReferences::pEmptyList = ref;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
lastnextp = &ref->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clear all references to this entity
|
|
|
|
void
|
|
|
|
CEntity::ResolveReferences(void)
|
|
|
|
{
|
|
|
|
CReference *ref;
|
|
|
|
// clear pointers to this entity
|
|
|
|
for(ref = m_pFirstReference; ref; ref = ref->next)
|
|
|
|
if(*ref->pentity == this)
|
|
|
|
*ref->pentity = nil;
|
|
|
|
// free list
|
|
|
|
if(m_pFirstReference){
|
|
|
|
for(ref = m_pFirstReference; ref->next; ref = ref->next)
|
|
|
|
;
|
|
|
|
ref->next = CReferences::pEmptyList;
|
|
|
|
CReferences::pEmptyList = m_pFirstReference;
|
|
|
|
m_pFirstReference = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Free all references that no longer point to this entity
|
|
|
|
void
|
|
|
|
CEntity::PruneReferences(void)
|
|
|
|
{
|
|
|
|
CReference *ref, *next, **lastnextp;
|
|
|
|
lastnextp = &m_pFirstReference;
|
|
|
|
for(ref = m_pFirstReference; ref; ref = next){
|
|
|
|
next = ref->next;
|
|
|
|
if(*ref->pentity == this)
|
|
|
|
lastnextp = &ref->next;
|
|
|
|
else{
|
|
|
|
*lastnextp = ref->next;
|
|
|
|
ref->next = CReferences::pEmptyList;
|
|
|
|
CReferences::pEmptyList = ref;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-06 12:27:21 +02:00
|
|
|
void
|
|
|
|
CReferences::RemoveReferencesToPlayer(void)
|
|
|
|
{
|
|
|
|
if(FindPlayerVehicle())
|
|
|
|
FindPlayerVehicle()->ResolveReferences();
|
2020-04-18 22:50:37 +02:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
if (FindPlayerPed()) {
|
|
|
|
CPlayerPed* pPlayerPed = FindPlayerPed();
|
|
|
|
FindPlayerPed()->ResolveReferences();
|
|
|
|
CWorld::Players[CWorld::PlayerInFocus].m_pPed = pPlayerPed;
|
|
|
|
pPlayerPed->RegisterReference((CEntity**)&CWorld::Players[CWorld::PlayerInFocus].m_pPed);
|
|
|
|
}
|
|
|
|
#else
|
2019-07-06 12:27:21 +02:00
|
|
|
if(FindPlayerPed())
|
|
|
|
FindPlayerPed()->ResolveReferences();
|
2020-04-18 22:50:37 +02:00
|
|
|
#endif
|
2019-07-06 12:27:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
CReferences::PruneAllReferencesInWorld(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
CEntity *e;
|
|
|
|
|
|
|
|
i = CPools::GetPedPool()->GetSize();
|
|
|
|
while(--i >= 0){
|
|
|
|
e = CPools::GetPedPool()->GetSlot(i);
|
|
|
|
if(e)
|
|
|
|
e->PruneReferences();
|
|
|
|
}
|
|
|
|
|
|
|
|
i = CPools::GetVehiclePool()->GetSize();
|
|
|
|
while(--i >= 0){
|
|
|
|
e = CPools::GetVehiclePool()->GetSlot(i);
|
|
|
|
if(e)
|
|
|
|
e->PruneReferences();
|
|
|
|
}
|
|
|
|
|
|
|
|
i = CPools::GetObjectPool()->GetSize();
|
|
|
|
while(--i >= 0){
|
|
|
|
e = CPools::GetObjectPool()->GetSlot(i);
|
|
|
|
if(e)
|
|
|
|
e->PruneReferences();
|
|
|
|
}
|
|
|
|
}
|