Fixed bug that could produce multiple script instances with equivalent instance IDs

This commit is contained in:
Aruki 2017-05-14 21:30:32 -06:00
parent 77cda50153
commit 43a3558383
6 changed files with 16 additions and 14 deletions

View File

@ -149,9 +149,9 @@ CScriptObject* CGameArea::InstanceByID(u32 InstanceID)
else return nullptr; else return nullptr;
} }
u32 CGameArea::FindUnusedInstanceID(CScriptLayer *pLayer) const u32 CGameArea::FindUnusedInstanceID() const
{ {
u32 InstanceID = (pLayer->AreaIndex() << 26) | (mWorldIndex << 16) | 1; u32 InstanceID = (mWorldIndex << 16) | 1;
while (true) while (true)
{ {
@ -205,7 +205,7 @@ CScriptObject* CGameArea::SpawnInstance(CScriptTemplate *pTemplate,
} }
// Look for a valid instance ID // Look for a valid instance ID
InstanceID = FindUnusedInstanceID(pLayer); InstanceID = FindUnusedInstanceID();
} }
// Spawn instance // Spawn instance

View File

@ -72,7 +72,7 @@ public:
void ClearScriptLayers(); void ClearScriptLayers();
u32 TotalInstanceCount() const; u32 TotalInstanceCount() const;
CScriptObject* InstanceByID(u32 InstanceID); CScriptObject* InstanceByID(u32 InstanceID);
u32 FindUnusedInstanceID(CScriptLayer *pLayer) const; u32 FindUnusedInstanceID() const;
CScriptObject* SpawnInstance(CScriptTemplate *pTemplate, CScriptLayer *pLayer, CScriptObject* SpawnInstance(CScriptTemplate *pTemplate, CScriptLayer *pLayer,
const CVector3f& rkPosition = CVector3f::skZero, const CVector3f& rkPosition = CVector3f::skZero,
const CQuaternion& rkRotation = CQuaternion::skIdentity, const CQuaternion& rkRotation = CQuaternion::skIdentity,

View File

@ -215,7 +215,8 @@ void CScriptCooker::WriteInstanceMP1(CScriptObject *pInstance)
mpSCLY->WriteLong(0); mpSCLY->WriteLong(0);
u32 InstanceStart = mpSCLY->Tell(); u32 InstanceStart = mpSCLY->Tell();
mpSCLY->WriteLong(pInstance->InstanceID()); u32 InstanceID = (pInstance->Layer()->AreaIndex() << 26) | pInstance->InstanceID();
mpSCLY->WriteLong(InstanceID);
mpSCLY->WriteLong(pInstance->NumLinks(eOutgoing)); mpSCLY->WriteLong(pInstance->NumLinks(eOutgoing));
for (u32 iLink = 0; iLink < pInstance->NumLinks(eOutgoing); iLink++) for (u32 iLink = 0; iLink < pInstance->NumLinks(eOutgoing); iLink++)
@ -265,7 +266,8 @@ void CScriptCooker::WriteInstanceMP2(CScriptObject *pInstance)
mpSCLY->WriteShort(0); mpSCLY->WriteShort(0);
u32 InstanceStart = mpSCLY->Tell(); u32 InstanceStart = mpSCLY->Tell();
mpSCLY->WriteLong(pInstance->InstanceID()); u32 InstanceID = (pInstance->Layer()->AreaIndex() << 26) | pInstance->InstanceID();
mpSCLY->WriteLong(InstanceID);
mpSCLY->WriteShort((u16) pInstance->NumLinks(eOutgoing)); mpSCLY->WriteShort((u16) pInstance->NumLinks(eOutgoing));
for (u32 iLink = 0; iLink < pInstance->NumLinks(eOutgoing); iLink++) for (u32 iLink = 0; iLink < pInstance->NumLinks(eOutgoing); iLink++)

View File

@ -8,7 +8,7 @@ CPoiToWorld* CPoiToWorldLoader::LoadEGMC(IInputStream& rEGMC, CResourceEntry *pE
for (u32 iMap = 0; iMap < NumMappings; iMap++) for (u32 iMap = 0; iMap < NumMappings; iMap++)
{ {
u32 MeshID = rEGMC.ReadLong(); u32 MeshID = rEGMC.ReadLong();
u32 InstanceID = rEGMC.ReadLong(); u32 InstanceID = rEGMC.ReadLong() & 0x03FFFFFF;
pOut->AddPoiMeshMap(InstanceID, MeshID); pOut->AddPoiMeshMap(InstanceID, MeshID);
} }

View File

@ -259,8 +259,8 @@ CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& rSCLY)
return nullptr; return nullptr;
} }
u32 InstanceID = rSCLY.ReadLong(); u32 InstanceID = rSCLY.ReadLong() & 0x03FFFFFF;
if (InstanceID == -1) InstanceID = mpArea->FindUnusedInstanceID(mpLayer); if (InstanceID == -1) InstanceID = mpArea->FindUnusedInstanceID();
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemp); mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemp);
// Load connections // Load connections
@ -271,7 +271,7 @@ CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& rSCLY)
{ {
u32 State = rSCLY.ReadLong(); u32 State = rSCLY.ReadLong();
u32 Message = rSCLY.ReadLong(); u32 Message = rSCLY.ReadLong();
u32 ReceiverID = rSCLY.ReadLong(); u32 ReceiverID = rSCLY.ReadLong() & 0x03FFFFFF;
CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID); CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID);
mpObj->mOutLinks.push_back(pLink); mpObj->mOutLinks.push_back(pLink);
@ -373,8 +373,8 @@ CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& rSCLY)
return nullptr; return nullptr;
} }
u32 InstanceID = rSCLY.ReadLong(); u32 InstanceID = rSCLY.ReadLong() & 0x03FFFFFF;
if (InstanceID == -1) InstanceID = mpArea->FindUnusedInstanceID(mpLayer); if (InstanceID == -1) InstanceID = mpArea->FindUnusedInstanceID();
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemplate); mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemplate);
// Load connections // Load connections
@ -385,7 +385,7 @@ CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& rSCLY)
{ {
u32 State = rSCLY.ReadLong(); u32 State = rSCLY.ReadLong();
u32 Message = rSCLY.ReadLong(); u32 Message = rSCLY.ReadLong();
u32 ReceiverID = rSCLY.ReadLong(); u32 ReceiverID = rSCLY.ReadLong() & 0x03FFFFFF;
CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID); CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID);
mpObj->mOutLinks.push_back(pLink); mpObj->mOutLinks.push_back(pLink);

View File

@ -6,7 +6,7 @@
<property ID="0x01" name="Position" type="vector3f"/> <property ID="0x01" name="Position" type="vector3f"/>
<property ID="0x02" name="Rotation" type="vector3f"/> <property ID="0x02" name="Rotation" type="vector3f"/>
<property ID="0x03" name="Unknown 1" type="bool"/> <property ID="0x03" name="Unknown 1" type="bool"/>
<property ID="0x04" name="Unknown 2" type="float"/> <property ID="0x04" name="Shot Duration" type="float"/>
<property ID="0x05" name="Unknown 3" type="bool"/> <property ID="0x05" name="Unknown 3" type="bool"/>
<property ID="0x06" name="Unknown 4" type="bool"/> <property ID="0x06" name="Unknown 4" type="bool"/>
<property ID="0x07" name="Unknown 5" type="bool"/> <property ID="0x07" name="Unknown 5" type="bool"/>