mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-18 09:25:31 +00:00
Moved selection handling code to CNodeSelection, implemented instance spawning, half-implemented instance deleting (this build is buggy/crash prone)
This commit is contained in:
@@ -15,6 +15,8 @@ public:
|
||||
bool IsLayerEnabled() const;
|
||||
bool IsSkyEnabled() const;
|
||||
CModel* SkyModel() const;
|
||||
|
||||
inline CScriptObject* Instance() const { return mpObj; }
|
||||
};
|
||||
|
||||
#endif // CAREAATTRIBUTES_H
|
||||
|
||||
@@ -2,23 +2,25 @@
|
||||
#include "Core/Resource/Script/CScriptLayer.h"
|
||||
#include "Core/Render/CRenderer.h"
|
||||
|
||||
CGameArea::CGameArea() : CResource()
|
||||
CGameArea::CGameArea()
|
||||
: CResource()
|
||||
, mWorldIndex(-1)
|
||||
, mVertexCount(0)
|
||||
, mTriangleCount(0)
|
||||
, mTerrainMerged(false)
|
||||
, mOriginalWorldMeshCount(0)
|
||||
, mUsesCompression(false)
|
||||
, mMaterialSet(nullptr)
|
||||
, mpGeneratorLayer(nullptr)
|
||||
, mpCollision(nullptr)
|
||||
{
|
||||
mVertexCount = 0;
|
||||
mTriangleCount = 0;
|
||||
mTerrainMerged = false;
|
||||
mOriginalWorldMeshCount = 0;
|
||||
mUsesCompression = false;
|
||||
mMaterialSet = nullptr;
|
||||
mpGeneratorLayer = nullptr;
|
||||
mCollision = nullptr;
|
||||
}
|
||||
|
||||
CGameArea::~CGameArea()
|
||||
{
|
||||
ClearTerrain();
|
||||
|
||||
delete mCollision;
|
||||
delete mpCollision;
|
||||
delete mpGeneratorLayer;
|
||||
|
||||
for (u32 iSCLY = 0; iSCLY < mScriptLayers.size(); iSCLY++)
|
||||
@@ -108,85 +110,109 @@ void CGameArea::ClearScriptLayers()
|
||||
mpGeneratorLayer = nullptr;
|
||||
}
|
||||
|
||||
EGame CGameArea::Version()
|
||||
u32 CGameArea::TotalInstanceCount() const
|
||||
{
|
||||
return mVersion;
|
||||
u32 Num = 0;
|
||||
|
||||
for (u32 iLyr = 0; iLyr < mScriptLayers.size(); iLyr++)
|
||||
Num += mScriptLayers[iLyr]->NumInstances();
|
||||
|
||||
return Num;
|
||||
}
|
||||
|
||||
CTransform4f CGameArea::GetTransform()
|
||||
{
|
||||
return mTransform;
|
||||
}
|
||||
|
||||
u32 CGameArea::GetTerrainModelCount()
|
||||
{
|
||||
return mTerrainModels.size();
|
||||
}
|
||||
|
||||
u32 CGameArea::GetStaticModelCount()
|
||||
{
|
||||
return mStaticTerrainModels.size();
|
||||
}
|
||||
|
||||
CModel* CGameArea::GetTerrainModel(u32 mdl)
|
||||
{
|
||||
return mTerrainModels[mdl];
|
||||
}
|
||||
|
||||
CStaticModel* CGameArea::GetStaticModel(u32 mdl)
|
||||
{
|
||||
return mStaticTerrainModels[mdl];
|
||||
}
|
||||
|
||||
CCollisionMeshGroup* CGameArea::GetCollision()
|
||||
{
|
||||
return mCollision;
|
||||
}
|
||||
|
||||
u32 CGameArea::GetScriptLayerCount()
|
||||
{
|
||||
return mScriptLayers.size();
|
||||
}
|
||||
|
||||
CScriptLayer* CGameArea::GetScriptLayer(u32 index)
|
||||
{
|
||||
return mScriptLayers[index];
|
||||
}
|
||||
|
||||
CScriptLayer* CGameArea::GetGeneratorLayer()
|
||||
{
|
||||
return mpGeneratorLayer;
|
||||
}
|
||||
|
||||
CScriptObject* CGameArea::GetInstanceByID(u32 InstanceID)
|
||||
CScriptObject* CGameArea::InstanceByID(u32 InstanceID)
|
||||
{
|
||||
auto it = mObjectMap.find(InstanceID);
|
||||
if (it != mObjectMap.end()) return it->second;
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
u32 CGameArea::GetLightLayerCount()
|
||||
|
||||
CScriptObject* CGameArea::SpawnInstance(CScriptTemplate *pTemplate,
|
||||
CScriptLayer *pLayer,
|
||||
const CVector3f& rkPosition /*= CVector3f::skZero*/,
|
||||
const CQuaternion& rkRotation /*= CQuaternion::skIdentity*/,
|
||||
const CVector3f& rkScale /*= CVector3f::skOne*/,
|
||||
u32 SuggestedID /*= -1*/,
|
||||
u32 SuggestedLayerIndex /*= -1*/ )
|
||||
{
|
||||
return mLightLayers.size();
|
||||
// Verify we can fit another instance in this area.
|
||||
u32 NumInstances = TotalInstanceCount();
|
||||
|
||||
if (NumInstances >= 0xFFFF)
|
||||
{
|
||||
Log::Error("Unable to spawn a new script instance; too many instances in area (" + TString::FromInt32(NumInstances, 0, 10) + ")");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check whether the suggested instance ID is valid
|
||||
u32 InstanceID = SuggestedID;
|
||||
|
||||
if (InstanceID != -1)
|
||||
{
|
||||
if (mObjectMap.find(InstanceID) == mObjectMap.end())
|
||||
InstanceID = -1;
|
||||
}
|
||||
|
||||
// If not valid (or if there's no suggested ID) then determine a new instance ID
|
||||
if (InstanceID == -1)
|
||||
{
|
||||
// Determine layer index
|
||||
u32 LayerIndex = -1;
|
||||
|
||||
for (u32 iLyr = 0; iLyr < mScriptLayers.size(); iLyr++)
|
||||
{
|
||||
if (mScriptLayers[iLyr] == pLayer)
|
||||
{
|
||||
LayerIndex = iLyr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (LayerIndex == -1)
|
||||
{
|
||||
Log::Error("Unable to spawn a new script instance; invalid script layer passed in");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Look for a valid instance ID
|
||||
InstanceID = (LayerIndex << 26) | (mWorldIndex << 16) | 1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
auto it = mObjectMap.find(InstanceID);
|
||||
|
||||
if (it == mObjectMap.end())
|
||||
break;
|
||||
else
|
||||
InstanceID++;
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn instance
|
||||
CScriptObject *pInstance = new CScriptObject(InstanceID, this, pLayer, pTemplate);
|
||||
pInstance->EvaluateProperties();
|
||||
pInstance->SetPosition(rkPosition);
|
||||
pInstance->SetRotation(rkRotation.ToEuler());
|
||||
pInstance->SetScale(rkScale);
|
||||
pInstance->SetName(pTemplate->Name());
|
||||
if (pTemplate->Game() < eEchoesDemo) pInstance->SetActive(true);
|
||||
pLayer->AddInstance(pInstance, SuggestedLayerIndex);
|
||||
mObjectMap[InstanceID] = pInstance;
|
||||
return pInstance;
|
||||
}
|
||||
|
||||
u32 CGameArea::GetLightCount(u32 layer)
|
||||
void CGameArea::DeleteInstance(CScriptObject *pInstance)
|
||||
{
|
||||
if (mLightLayers.empty()) return 0;
|
||||
return mLightLayers[layer].size();
|
||||
}
|
||||
pInstance->Layer()->RemoveInstance(pInstance);
|
||||
pInstance->Template()->RemoveObject(pInstance);
|
||||
|
||||
CLight* CGameArea::GetLight(u32 layer, u32 light)
|
||||
{
|
||||
return mLightLayers[layer][light];
|
||||
}
|
||||
auto it = mObjectMap.find(pInstance->InstanceID());
|
||||
if (it != mObjectMap.end()) mObjectMap.erase(it);
|
||||
|
||||
CPoiToWorld* CGameArea::GetPoiToWorldMap()
|
||||
{
|
||||
return mpPoiToWorldMap;
|
||||
}
|
||||
if (mpPoiToWorldMap && mpPoiToWorldMap->HasPoiMappings(pInstance->InstanceID()))
|
||||
mpPoiToWorldMap->RemovePoi(pInstance->InstanceID());
|
||||
|
||||
CAABox CGameArea::AABox()
|
||||
{
|
||||
return mAABox;
|
||||
pInstance->BreakAllLinks();
|
||||
delete pInstance;
|
||||
}
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
#include "Core/Resource/Model/CModel.h"
|
||||
#include "Core/Resource/Model/CStaticModel.h"
|
||||
#include <Common/types.h>
|
||||
#include <Math/CQuaternion.h>
|
||||
#include <Math/CTransform4f.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
class CScriptLayer;
|
||||
class CScriptObject;
|
||||
class CScriptTemplate;
|
||||
|
||||
class CGameArea : public CResource
|
||||
{
|
||||
@@ -23,6 +25,7 @@ class CGameArea : public CResource
|
||||
friend class CAreaCooker;
|
||||
|
||||
EGame mVersion;
|
||||
u32 mWorldIndex;
|
||||
u32 mVertexCount;
|
||||
u32 mTriangleCount;
|
||||
bool mTerrainMerged;
|
||||
@@ -50,7 +53,7 @@ class CGameArea : public CResource
|
||||
CScriptLayer *mpGeneratorLayer;
|
||||
std::unordered_map<u32, CScriptObject*> mObjectMap;
|
||||
// Collision
|
||||
CCollisionMeshGroup *mCollision;
|
||||
CCollisionMeshGroup *mpCollision;
|
||||
// Lights
|
||||
std::vector<std::vector<CLight*>> mLightLayers;
|
||||
// Object to Static Geometry Map
|
||||
@@ -64,24 +67,34 @@ public:
|
||||
void MergeTerrain();
|
||||
void ClearTerrain();
|
||||
void ClearScriptLayers();
|
||||
u32 TotalInstanceCount() const;
|
||||
CScriptObject* InstanceByID(u32 InstanceID);
|
||||
CScriptObject* SpawnInstance(CScriptTemplate *pTemplate, CScriptLayer *pLayer,
|
||||
const CVector3f& rkPosition = CVector3f::skZero,
|
||||
const CQuaternion& rkRotation = CQuaternion::skIdentity,
|
||||
const CVector3f& rkScale = CVector3f::skOne,
|
||||
u32 SuggestedID = -1, u32 SuggestedLayerIndex = -1);
|
||||
void DeleteInstance(CScriptObject *pInstance);
|
||||
|
||||
// Getters
|
||||
EGame Version();
|
||||
CTransform4f GetTransform();
|
||||
u32 GetTerrainModelCount();
|
||||
u32 GetStaticModelCount();
|
||||
CModel* GetTerrainModel(u32 mdl);
|
||||
CStaticModel* GetStaticModel(u32 mdl);
|
||||
CCollisionMeshGroup* GetCollision();
|
||||
u32 GetScriptLayerCount();
|
||||
CScriptLayer* GetScriptLayer(u32 index);
|
||||
CScriptLayer* GetGeneratorLayer();
|
||||
CScriptObject* GetInstanceByID(u32 InstanceID);
|
||||
u32 GetLightLayerCount();
|
||||
u32 GetLightCount(u32 layer);
|
||||
CLight* GetLight(u32 layer, u32 light);
|
||||
CPoiToWorld* GetPoiToWorldMap();
|
||||
CAABox AABox();
|
||||
// Inline Accessors
|
||||
inline EGame Version() const { return mVersion; }
|
||||
inline u32 WorldIndex() const { return mWorldIndex; }
|
||||
inline CTransform4f GetTransform() const { return mTransform; }
|
||||
inline u32 GetTerrainModelCount() const { return mTerrainModels.size(); }
|
||||
inline u32 GetStaticModelCount() const { return mStaticTerrainModels.size(); }
|
||||
inline CModel* GetTerrainModel(u32 iMdl) const { return mTerrainModels[iMdl]; }
|
||||
inline CStaticModel* GetStaticModel(u32 iMdl) const { return mStaticTerrainModels[iMdl]; }
|
||||
inline CCollisionMeshGroup* GetCollision() const { return mpCollision; }
|
||||
inline u32 GetScriptLayerCount() const { return mScriptLayers.size(); }
|
||||
inline CScriptLayer* GetScriptLayer(u32 Index) const { return mScriptLayers[Index]; }
|
||||
inline CScriptLayer* GetGeneratorLayer() const { return mpGeneratorLayer; }
|
||||
inline u32 GetLightLayerCount() const { return mLightLayers.size(); }
|
||||
inline u32 GetLightCount(u32 LayerIndex) const { return (LayerIndex < mLightLayers.size() ? mLightLayers[LayerIndex].size() : 0); }
|
||||
inline CLight* GetLight(u32 LayerIndex, u32 LightIndex) const { return mLightLayers[LayerIndex][LightIndex]; }
|
||||
inline CPoiToWorld* GetPoiToWorldMap() const { return mpPoiToWorldMap; }
|
||||
inline CAABox AABox() const { return mAABox; }
|
||||
|
||||
inline void SetWorldIndex(u32 NewWorldIndex) { mWorldIndex = NewWorldIndex; }
|
||||
};
|
||||
|
||||
#endif // CGAMEAREA_H
|
||||
|
||||
@@ -39,6 +39,22 @@ public:
|
||||
{
|
||||
return mMaps[Index];
|
||||
}
|
||||
|
||||
inline const SPoiMap* MapByID(u32 InstanceID) const
|
||||
{
|
||||
auto it = mPoiLookupMap.find(InstanceID);
|
||||
|
||||
if (it != mPoiLookupMap.end())
|
||||
return it->second;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool HasPoiMappings(u32 InstanceID) const
|
||||
{
|
||||
auto it = mPoiLookupMap.find(InstanceID);
|
||||
return (it != mPoiLookupMap.end());
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CPOITOWORLD_H
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
|
||||
inline CUniqueID ID() const
|
||||
{
|
||||
TString FileName = mPath.GetFileName();
|
||||
TString FileName = mPath.GetFileName(false);
|
||||
|
||||
if (!mIsPath)
|
||||
return CUniqueID::FromString(FileName);
|
||||
|
||||
@@ -16,12 +16,12 @@ CWorld::~CWorld()
|
||||
{
|
||||
}
|
||||
|
||||
void CWorld::SetAreaLayerInfo(CGameArea *pArea, u32 AreaIndex)
|
||||
void CWorld::SetAreaLayerInfo(CGameArea *pArea)
|
||||
{
|
||||
// The AreaIndex parameter is a placeholder until an improved world loader is implemented.
|
||||
// For now it's the easiest/fastest way to do this because this function is called from
|
||||
// the start window and the start window already knows the area index.
|
||||
SArea& AreaInfo = mAreas[AreaIndex];
|
||||
SArea& AreaInfo = mAreas[pArea->WorldIndex()];
|
||||
|
||||
for (u32 iLyr = 0; iLyr < pArea->GetScriptLayerCount(); iLyr++)
|
||||
{
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
CWorld();
|
||||
~CWorld();
|
||||
|
||||
void SetAreaLayerInfo(CGameArea *pArea, u32 AreaIndex);
|
||||
void SetAreaLayerInfo(CGameArea *pArea);
|
||||
|
||||
// Setters
|
||||
EGame Version();
|
||||
|
||||
@@ -595,7 +595,7 @@ void CAreaLoader::ReadCollision()
|
||||
{
|
||||
Log::FileWrite(mpMREA->GetSourceString(), "Reading collision (MP1/MP2/MP3)");
|
||||
mpSectionMgr->ToSection(mCollisionBlockNum);
|
||||
mpArea->mCollision = CCollisionLoader::LoadAreaCollision(*mpMREA);
|
||||
mpArea->mpCollision = CCollisionLoader::LoadAreaCollision(*mpMREA);
|
||||
}
|
||||
|
||||
void CAreaLoader::ReadEGMC()
|
||||
@@ -643,7 +643,7 @@ void CAreaLoader::SetUpObjects()
|
||||
|
||||
if (iConMap != mConnectionMap.end())
|
||||
{
|
||||
CScriptObject *pObj = mpArea->GetInstanceByID(InstanceID);
|
||||
CScriptObject *pObj = mpArea->InstanceByID(InstanceID);
|
||||
pObj->mInLinks = iConMap->second;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,8 +214,8 @@ CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& SCLY)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mpObj = new CScriptObject(mpArea, mpLayer, pTemp);
|
||||
mpObj->mInstanceID = SCLY.ReadLong();
|
||||
u32 InstanceID = SCLY.ReadLong();
|
||||
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemp);
|
||||
|
||||
// Load connections
|
||||
u32 NumLinks = SCLY.ReadLong();
|
||||
@@ -249,7 +249,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream &SCLY)
|
||||
SCLY.Seek(0x1, SEEK_CUR); // One unknown byte at the start of each layer
|
||||
u32 NumObjects = SCLY.ReadLong();
|
||||
|
||||
mpLayer = new CScriptLayer();
|
||||
mpLayer = new CScriptLayer(mpArea);
|
||||
mpLayer->Reserve(NumObjects);
|
||||
|
||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||
@@ -327,8 +327,8 @@ CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& SCLY)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mpObj = new CScriptObject(mpArea, mpLayer, pTemplate);
|
||||
mpObj->mInstanceID = SCLY.ReadLong();
|
||||
u32 InstanceID = SCLY.ReadLong();
|
||||
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemplate);
|
||||
|
||||
// Load connections
|
||||
u32 NumConnections = SCLY.ReadShort();
|
||||
@@ -359,7 +359,7 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
|
||||
SCLY.Seek(0x1, SEEK_CUR); // Skipping version. todo: verify this?
|
||||
u32 NumObjects = SCLY.ReadLong();
|
||||
|
||||
mpLayer = new CScriptLayer();
|
||||
mpLayer = new CScriptLayer(mpArea);
|
||||
mpLayer->Reserve(NumObjects);
|
||||
|
||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||
@@ -372,9 +372,10 @@ CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
|
||||
return mpLayer;
|
||||
}
|
||||
|
||||
CScriptLayer* CScriptLoader::LoadLayer(IInputStream &SCLY, CGameArea *pArea, EGame Version)
|
||||
// ************ STATIC ************
|
||||
CScriptLayer* CScriptLoader::LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version)
|
||||
{
|
||||
if (!SCLY.IsValid()) return nullptr;
|
||||
if (!rSCLY.IsValid()) return nullptr;
|
||||
|
||||
CScriptLoader Loader;
|
||||
Loader.mVersion = Version;
|
||||
@@ -391,7 +392,7 @@ CScriptLayer* CScriptLoader::LoadLayer(IInputStream &SCLY, CGameArea *pArea, EGa
|
||||
CTemplateLoader::LoadGameTemplates(Version);
|
||||
|
||||
if (Version <= ePrime)
|
||||
return Loader.LoadLayerMP1(SCLY);
|
||||
return Loader.LoadLayerMP1(rSCLY);
|
||||
else
|
||||
return Loader.LoadLayerMP2(SCLY);
|
||||
return Loader.LoadLayerMP2(rSCLY);
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ public:
|
||||
void SetSender(u32 NewSenderID, u32 Index = -1)
|
||||
{
|
||||
u32 OldSenderID = mSenderID;
|
||||
CScriptObject *pOldSender = mpArea->GetInstanceByID(OldSenderID);
|
||||
CScriptObject *pNewSender = mpArea->GetInstanceByID(NewSenderID);
|
||||
CScriptObject *pOldSender = mpArea->InstanceByID(OldSenderID);
|
||||
CScriptObject *pNewSender = mpArea->InstanceByID(NewSenderID);
|
||||
|
||||
mSenderID = NewSenderID;
|
||||
pOldSender->RemoveLink(eOutgoing, this);
|
||||
@@ -63,8 +63,8 @@ public:
|
||||
void SetReceiver(u32 NewReceiverID, u32 Index = -1)
|
||||
{
|
||||
u32 OldReceiverID = mSenderID;
|
||||
CScriptObject *pOldReceiver = mpArea->GetInstanceByID(OldReceiverID);
|
||||
CScriptObject *pNewReceiver = mpArea->GetInstanceByID(NewReceiverID);
|
||||
CScriptObject *pOldReceiver = mpArea->InstanceByID(OldReceiverID);
|
||||
CScriptObject *pNewReceiver = mpArea->InstanceByID(NewReceiverID);
|
||||
|
||||
mReceiverID = NewReceiverID;
|
||||
pOldReceiver->RemoveLink(eIncoming, this);
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
|
||||
u32 SenderIndex() const
|
||||
{
|
||||
CScriptObject *pSender = mpArea->GetInstanceByID(mSenderID);
|
||||
CScriptObject *pSender = mpArea->InstanceByID(mSenderID);
|
||||
|
||||
for (u32 iLink = 0; iLink < pSender->NumLinks(eOutgoing); iLink++)
|
||||
{
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
|
||||
u32 ReceiverIndex() const
|
||||
{
|
||||
CScriptObject *pReceiver = mpArea->GetInstanceByID(mReceiverID);
|
||||
CScriptObject *pReceiver = mpArea->InstanceByID(mReceiverID);
|
||||
|
||||
for (u32 iLink = 0; iLink < pReceiver->NumLinks(eIncoming); iLink++)
|
||||
{
|
||||
@@ -117,8 +117,8 @@ public:
|
||||
u32 Message() const { return mMessageID; }
|
||||
u32 SenderID() const { return mSenderID; }
|
||||
u32 ReceiverID() const { return mReceiverID; }
|
||||
CScriptObject* Sender() const { return mpArea->GetInstanceByID(mSenderID); }
|
||||
CScriptObject* Receiver() const { return mpArea->GetInstanceByID(mReceiverID); }
|
||||
CScriptObject* Sender() const { return mpArea->InstanceByID(mSenderID); }
|
||||
CScriptObject* Receiver() const { return mpArea->InstanceByID(mReceiverID); }
|
||||
|
||||
void SetState(u32 StateID) { mStateID = StateID; }
|
||||
void SetMessage(u32 MessageID) { mMessageID = MessageID; }
|
||||
|
||||
@@ -8,13 +8,15 @@
|
||||
|
||||
class CScriptLayer
|
||||
{
|
||||
CGameArea *mpArea;
|
||||
TString mLayerName;
|
||||
bool mActive;
|
||||
bool mVisible;
|
||||
std::vector<CScriptObject*> mInstances;
|
||||
public:
|
||||
CScriptLayer()
|
||||
: mLayerName("New Layer")
|
||||
CScriptLayer(CGameArea *pArea)
|
||||
: mpArea(pArea)
|
||||
, mLayerName("New Layer")
|
||||
, mActive(true)
|
||||
, mVisible(true)
|
||||
{
|
||||
@@ -27,9 +29,17 @@ public:
|
||||
}
|
||||
|
||||
// Data Manipulation
|
||||
void AddInstance(CScriptObject *pObject)
|
||||
void AddInstance(CScriptObject *pObject, u32 Index = -1)
|
||||
{
|
||||
mInstances.push_back(pObject);
|
||||
if (Index != -1 && Index < mInstances.size())
|
||||
{
|
||||
auto it = mInstances.begin();
|
||||
std::advance(it, Index);
|
||||
mInstances.insert(it, pObject);
|
||||
}
|
||||
|
||||
else
|
||||
mInstances.push_back(pObject);
|
||||
}
|
||||
|
||||
void RemoveInstance(CScriptObject *pInstance)
|
||||
@@ -67,6 +77,7 @@ public:
|
||||
}
|
||||
|
||||
// Accessors
|
||||
inline CGameArea* Area() const { return mpArea; }
|
||||
inline TString Name() const { return mLayerName; }
|
||||
inline bool IsActive() const { return mActive; }
|
||||
inline bool IsVisible() const { return mVisible; }
|
||||
@@ -88,6 +99,17 @@ public:
|
||||
inline void SetActive(bool Active) { mActive = Active; }
|
||||
inline void SetVisible(bool Visible) { mVisible = Visible; }
|
||||
|
||||
inline u32 AreaIndex() const
|
||||
{
|
||||
for (u32 iLyr = 0; iLyr < mpArea->GetScriptLayerCount(); iLyr++)
|
||||
{
|
||||
if (mpArea->GetScriptLayer(iLyr) == this)
|
||||
return iLyr;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Operators
|
||||
CScriptObject* operator[](u32 Index) { return InstanceByIndex(Index); }
|
||||
};
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
#include "CMasterTemplate.h"
|
||||
#include "Core/Resource/CAnimSet.h"
|
||||
|
||||
CScriptObject::CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate)
|
||||
CScriptObject::CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate)
|
||||
: mpTemplate(pTemplate)
|
||||
, mpArea(pArea)
|
||||
, mpLayer(pLayer)
|
||||
, mVersion(0)
|
||||
, mInstanceID(InstanceID)
|
||||
, mpDisplayModel(nullptr)
|
||||
, mpCollision(nullptr)
|
||||
, mHasInGameModel(false)
|
||||
@@ -75,16 +76,27 @@ bool CScriptObject::IsEditorProperty(IProperty *pProp)
|
||||
);
|
||||
}
|
||||
|
||||
void CScriptObject::SetLayer(CScriptLayer *pLayer)
|
||||
void CScriptObject::SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex)
|
||||
{
|
||||
if (pLayer != mpLayer)
|
||||
{
|
||||
mpLayer->RemoveInstance(this);
|
||||
mpLayer = pLayer;
|
||||
mpLayer->AddInstance(this);
|
||||
mpLayer->AddInstance(this, NewLayerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
u32 CScriptObject::LayerIndex() const
|
||||
{
|
||||
for (u32 iInst = 0; iInst < mpLayer->NumInstances(); iInst++)
|
||||
{
|
||||
if (mpLayer->InstanceByIndex(iInst) == this)
|
||||
return iInst;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CScriptObject::HasNearVisibleActivation() const
|
||||
{
|
||||
/* This function is used to check whether an inactive DKCR object should render in game mode. DKCR deactivates a lot of
|
||||
@@ -240,6 +252,26 @@ void CScriptObject::RemoveLink(ELinkType Type, CLink *pLink)
|
||||
}
|
||||
}
|
||||
|
||||
void CScriptObject::BreakAllLinks()
|
||||
{
|
||||
for (auto it = mInLinks.begin(); it != mInLinks.end(); it++)
|
||||
{
|
||||
CLink *pLink = *it;
|
||||
pLink->Sender()->RemoveLink(eOutgoing, pLink);
|
||||
delete pLink;
|
||||
}
|
||||
|
||||
for (auto it = mOutLinks.begin(); it != mOutLinks.end(); it++)
|
||||
{
|
||||
CLink *pLink = *it;
|
||||
pLink->Receiver()->RemoveLink(eIncoming, pLink);
|
||||
delete pLink;
|
||||
}
|
||||
|
||||
mInLinks.clear();
|
||||
mOutLinks.clear();
|
||||
}
|
||||
|
||||
TString CScriptObject::InstanceName() const
|
||||
{
|
||||
if (mpInstanceName)
|
||||
|
||||
@@ -50,7 +50,7 @@ class CScriptObject
|
||||
mutable bool mIsCheckingNearVisibleActivation;
|
||||
|
||||
public:
|
||||
CScriptObject(CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate);
|
||||
CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLayer, CScriptTemplate *pTemplate);
|
||||
~CScriptObject();
|
||||
|
||||
void EvaluateProperties();
|
||||
@@ -59,7 +59,8 @@ public:
|
||||
void EvaluateCollisionModel();
|
||||
void EvaluateVolume();
|
||||
bool IsEditorProperty(IProperty *pProp);
|
||||
void SetLayer(CScriptLayer *pLayer);
|
||||
void SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex = -1);
|
||||
u32 LayerIndex() const;
|
||||
bool HasNearVisibleActivation() const;
|
||||
|
||||
CScriptTemplate* Template() const;
|
||||
@@ -78,6 +79,7 @@ public:
|
||||
CLink* Link(ELinkType Type, u32 Index) const;
|
||||
void AddLink(ELinkType Type, CLink *pLink, u32 Index = -1);
|
||||
void RemoveLink(ELinkType Type, CLink *pLink);
|
||||
void BreakAllLinks();
|
||||
|
||||
CVector3f Position() const;
|
||||
CVector3f Rotation() const;
|
||||
|
||||
@@ -65,6 +65,18 @@ CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj)
|
||||
|
||||
CScriptNode *pNode = new CScriptNode(this, mpAreaRootNode, pObj);
|
||||
mNodes[eScriptNode].push_back(pNode);
|
||||
mScriptNodeMap[pObj->InstanceID()] = pNode;
|
||||
pNode->BuildLightList(mpArea);
|
||||
|
||||
// AreaAttributes check
|
||||
switch (pObj->ObjectTypeID())
|
||||
{
|
||||
case 0x4E: // MP1 AreaAttributes ID
|
||||
case 0x52454141: // MP2/MP3/DKCR AreaAttributes ID ("REAA")
|
||||
mAreaAttributesObjects.emplace_back( CAreaAttributes(pObj) );
|
||||
break;
|
||||
}
|
||||
|
||||
mNumNodes++;
|
||||
return pNode;
|
||||
}
|
||||
@@ -79,6 +91,48 @@ CLightNode* CScene::CreateLightNode(CLight *pLight)
|
||||
return pNode;
|
||||
}
|
||||
|
||||
void CScene::DeleteNode(CSceneNode *pNode)
|
||||
{
|
||||
ENodeType Type = pNode->NodeType();
|
||||
|
||||
for (auto it = mNodes[Type].begin(); it != mNodes[Type].end(); it++)
|
||||
{
|
||||
if (*it == pNode)
|
||||
{
|
||||
mNodes[Type].erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Type == eScriptNode)
|
||||
{
|
||||
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
|
||||
|
||||
auto ScriptMapIt = mScriptNodeMap.find(pScript->Object()->InstanceID());
|
||||
if (ScriptMapIt != mScriptNodeMap.end())
|
||||
mScriptNodeMap.erase(ScriptMapIt);
|
||||
|
||||
switch (pScript->Object()->ObjectTypeID())
|
||||
{
|
||||
case 0x4E:
|
||||
case 0x52454141:
|
||||
for (auto it = mAreaAttributesObjects.begin(); it != mAreaAttributesObjects.end(); it++)
|
||||
{
|
||||
if ((*it).Instance() == pScript->Object())
|
||||
{
|
||||
mAreaAttributesObjects.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pNode->Unparent();
|
||||
delete pNode;
|
||||
mNumNodes--;
|
||||
}
|
||||
|
||||
void CScene::SetActiveArea(CGameArea *pArea)
|
||||
{
|
||||
// Clear existing area
|
||||
@@ -121,20 +175,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||
{
|
||||
CScriptObject *pObj = pLayer->InstanceByIndex(iObj);
|
||||
CScriptNode *pNode = CreateScriptNode(pObj);
|
||||
pNode->BuildLightList(mpArea);
|
||||
|
||||
// Add to map
|
||||
mScriptNodeMap[pObj->InstanceID()] = pNode;
|
||||
|
||||
// AreaAttributes check
|
||||
switch (pObj->ObjectTypeID())
|
||||
{
|
||||
case 0x4E: // MP1 AreaAttributes ID
|
||||
case 0x52454141: // MP2/MP3/DKCR AreaAttributes ID ("REAA")
|
||||
mAreaAttributesObjects.emplace_back( CAreaAttributes(pObj) );
|
||||
break;
|
||||
}
|
||||
CreateScriptNode(pObj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,10 +185,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||
for (u32 iObj = 0; iObj < pGenLayer->NumInstances(); iObj++)
|
||||
{
|
||||
CScriptObject *pObj = pGenLayer->InstanceByIndex(iObj);
|
||||
CScriptNode *pNode = CreateScriptNode(pObj);
|
||||
|
||||
// Add to map
|
||||
mScriptNodeMap[pObj->InstanceID()] = pNode;
|
||||
CreateScriptNode(pObj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,16 +255,10 @@ void CScene::AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
FShowFlags ShowFlags = (ViewInfo.GameMode ? gkGameModeShowFlags : ViewInfo.ShowFlags);
|
||||
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||
|
||||
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
||||
for (CSceneIterator It(this, NodeFlags, false); It; ++It)
|
||||
{
|
||||
if (NodeFlags & it->first)
|
||||
{
|
||||
std::vector<CSceneNode*>& rNodeVec = it->second;
|
||||
|
||||
for (u32 iNode = 0; iNode < rNodeVec.size(); iNode++)
|
||||
if (ViewInfo.GameMode || rNodeVec[iNode]->IsVisible())
|
||||
rNodeVec[iNode]->AddToRenderer(pRenderer, ViewInfo);
|
||||
}
|
||||
if (ViewInfo.GameMode || It->IsVisible())
|
||||
It->AddToRenderer(pRenderer, ViewInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,16 +268,10 @@ SRayIntersection CScene::SceneRayCast(const CRay& Ray, const SViewInfo& ViewInfo
|
||||
FNodeFlags NodeFlags = NodeFlagsForShowFlags(ShowFlags);
|
||||
CRayCollisionTester Tester(Ray);
|
||||
|
||||
for (auto it = mNodes.begin(); it != mNodes.end(); it++)
|
||||
for (CSceneIterator It(this, NodeFlags, false); It; ++It)
|
||||
{
|
||||
if (NodeFlags & it->first)
|
||||
{
|
||||
std::vector<CSceneNode*>& rNodeVec = it->second;
|
||||
|
||||
for (u32 iNode = 0; iNode < rNodeVec.size(); iNode++)
|
||||
if (rNodeVec[iNode]->IsVisible())
|
||||
rNodeVec[iNode]->RayAABoxIntersectTest(Tester, ViewInfo);
|
||||
}
|
||||
if (It->IsVisible())
|
||||
It->RayAABoxIntersectTest(Tester, ViewInfo);
|
||||
}
|
||||
|
||||
return Tester.TestNodes(ViewInfo);
|
||||
|
||||
@@ -51,6 +51,7 @@ public:
|
||||
CCollisionNode* CreateCollisionNode(CCollisionMeshGroup *pMesh);
|
||||
CScriptNode* CreateScriptNode(CScriptObject *pObj);
|
||||
CLightNode* CreateLightNode(CLight *pLight);
|
||||
void DeleteNode(CSceneNode *pNode);
|
||||
void SetActiveArea(CGameArea *pArea);
|
||||
void SetActiveWorld(CWorld *pWorld);
|
||||
void PostLoad();
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
|
||||
inline operator bool() const
|
||||
{
|
||||
return DoneIterating();
|
||||
return !DoneIterating();
|
||||
}
|
||||
|
||||
inline CSceneNode* operator*() const
|
||||
|
||||
Reference in New Issue
Block a user