Added Script Extras system with classes for three objects (Waypoint, PointOfInterest, SpacePirate)
This commit is contained in:
parent
07e689071a
commit
c549cdcf42
|
@ -152,7 +152,11 @@ SOURCES += \
|
||||||
UI/WAnimParamsEditor.cpp \
|
UI/WAnimParamsEditor.cpp \
|
||||||
Resource/CCollisionMeshGroup.cpp \
|
Resource/CCollisionMeshGroup.cpp \
|
||||||
Core/CFrustumPlanes.cpp \
|
Core/CFrustumPlanes.cpp \
|
||||||
Core/CLightParameters.cpp
|
Core/CLightParameters.cpp \
|
||||||
|
Scene/script/CPointOfInterestExtra.cpp \
|
||||||
|
Scene/script/CScriptExtra.cpp \
|
||||||
|
Scene/script/CSpacePirateExtra.cpp \
|
||||||
|
Scene/script/CWaypointExtra.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Common/AnimUtil.h \
|
Common/AnimUtil.h \
|
||||||
|
@ -320,7 +324,11 @@ HEADERS += \
|
||||||
Resource/CCollisionMeshGroup.h \
|
Resource/CCollisionMeshGroup.h \
|
||||||
Core/CFrustumPlanes.h \
|
Core/CFrustumPlanes.h \
|
||||||
Core/CLightParameters.h \
|
Core/CLightParameters.h \
|
||||||
Core/SViewInfo.h
|
Core/SViewInfo.h \
|
||||||
|
Scene/script/CScriptExtra.h \
|
||||||
|
Scene/script/CPointOfInterestExtra.h \
|
||||||
|
Scene/script/CSpacePirateExtra.h \
|
||||||
|
Scene/script/CWaypointExtra.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
UI/CStartWindow.ui \
|
UI/CStartWindow.ui \
|
||||||
|
|
|
@ -25,6 +25,11 @@ CMasterTemplate* CScriptTemplate::MasterTemplate()
|
||||||
return mpMaster;
|
return mpMaster;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGame CScriptTemplate::Game()
|
||||||
|
{
|
||||||
|
return mpMaster->GetGame();
|
||||||
|
}
|
||||||
|
|
||||||
TString CScriptTemplate::TemplateName(s32 propCount) const
|
TString CScriptTemplate::TemplateName(s32 propCount) const
|
||||||
{
|
{
|
||||||
// Return original name if there is only one property set
|
// Return original name if there is only one property set
|
||||||
|
|
|
@ -93,6 +93,7 @@ public:
|
||||||
~CScriptTemplate();
|
~CScriptTemplate();
|
||||||
|
|
||||||
CMasterTemplate* MasterTemplate();
|
CMasterTemplate* MasterTemplate();
|
||||||
|
EGame Game();
|
||||||
TString TemplateName(s32 propCount = -1) const;
|
TString TemplateName(s32 propCount = -1) const;
|
||||||
TString PropertySetNameByCount(s32 propCount) const;
|
TString PropertySetNameByCount(s32 propCount) const;
|
||||||
TString PropertySetNameByIndex(u32 index) const;
|
TString PropertySetNameByIndex(u32 index) const;
|
||||||
|
|
|
@ -15,9 +15,6 @@ public:
|
||||||
return eRootNode;
|
return eRootNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AddToRenderer(CRenderer *, const SViewInfo&) {}
|
|
||||||
inline void Draw(ERenderOptions, const SViewInfo&) {}
|
|
||||||
inline void DrawAsset(ERenderOptions, u32, const SViewInfo&) {}
|
|
||||||
inline void RayAABoxIntersectTest(CRayCollisionTester &) {}
|
inline void RayAABoxIntersectTest(CRayCollisionTester &) {}
|
||||||
|
|
||||||
inline SRayIntersection RayNodeIntersectTest(const CRay &, u32, const SViewInfo&) {
|
inline SRayIntersection RayNodeIntersectTest(const CRay &, u32, const SViewInfo&) {
|
||||||
|
|
|
@ -71,6 +71,11 @@ bool CSceneNode::IsVisible() const
|
||||||
return mVisible;
|
return mVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CColor CSceneNode::TintColor(const SViewInfo& ViewInfo) const
|
||||||
|
{
|
||||||
|
return (IsSelected() && !ViewInfo.GameMode ? skSelectionTint : CColor::skWhite);
|
||||||
|
}
|
||||||
|
|
||||||
CColor CSceneNode::WireframeColor() const
|
CColor CSceneNode::WireframeColor() const
|
||||||
{
|
{
|
||||||
return CColor::skWhite;
|
return CColor::skWhite;
|
||||||
|
@ -307,12 +312,6 @@ CSceneManager* CSceneNode::Scene()
|
||||||
return mpScene;
|
return mpScene;
|
||||||
}
|
}
|
||||||
|
|
||||||
CColor CSceneNode::TintColor(const SViewInfo& ViewInfo) const
|
|
||||||
{
|
|
||||||
// convenience; this is/will be a fairly common operation
|
|
||||||
return (IsSelected() && !ViewInfo.GameMode ? skSelectionTint : CColor::skWhite);
|
|
||||||
}
|
|
||||||
|
|
||||||
CVector3f CSceneNode::LocalPosition() const
|
CVector3f CSceneNode::LocalPosition() const
|
||||||
{
|
{
|
||||||
return mPosition;
|
return mPosition;
|
||||||
|
|
|
@ -54,10 +54,12 @@ public:
|
||||||
virtual ~CSceneNode();
|
virtual ~CSceneNode();
|
||||||
virtual ENodeType NodeType() = 0;
|
virtual ENodeType NodeType() = 0;
|
||||||
virtual TString PrefixedName() const;
|
virtual TString PrefixedName() const;
|
||||||
|
virtual void AddToRenderer(CRenderer* /*pRenderer*/, const SViewInfo& /*ViewInfo*/) {}
|
||||||
virtual void DrawSelection();
|
virtual void DrawSelection();
|
||||||
virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester);
|
virtual void RayAABoxIntersectTest(CRayCollisionTester& Tester);
|
||||||
virtual SRayIntersection RayNodeIntersectTest(const CRay& Ray, u32 AssetID, const SViewInfo& ViewInfo) = 0;
|
virtual SRayIntersection RayNodeIntersectTest(const CRay& Ray, u32 AssetID, const SViewInfo& ViewInfo) = 0;
|
||||||
virtual bool IsVisible() const;
|
virtual bool IsVisible() const;
|
||||||
|
virtual CColor TintColor(const SViewInfo& ViewInfo) const;
|
||||||
virtual CColor WireframeColor() const;
|
virtual CColor WireframeColor() const;
|
||||||
|
|
||||||
void Unparent();
|
void Unparent();
|
||||||
|
@ -82,7 +84,6 @@ public:
|
||||||
TString Name() const;
|
TString Name() const;
|
||||||
CSceneNode* Parent() const;
|
CSceneNode* Parent() const;
|
||||||
CSceneManager* Scene();
|
CSceneManager* Scene();
|
||||||
CColor TintColor(const SViewInfo& ViewInfo) const;
|
|
||||||
CVector3f LocalPosition() const;
|
CVector3f LocalPosition() const;
|
||||||
CVector3f AbsolutePosition() const;
|
CVector3f AbsolutePosition() const;
|
||||||
CQuaternion LocalRotation() const;
|
CQuaternion LocalRotation() const;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "CScriptNode.h"
|
#include "CScriptNode.h"
|
||||||
#include <gtx/quaternion.hpp>
|
#include "script/CScriptExtra.h"
|
||||||
|
|
||||||
#include <Common/AnimUtil.h>
|
#include <Common/AnimUtil.h>
|
||||||
#include <Common/Math.h>
|
#include <Common/Math.h>
|
||||||
#include <Core/CDrawUtil.h>
|
#include <Core/CDrawUtil.h>
|
||||||
|
@ -89,6 +90,8 @@ CScriptNode::CScriptNode(CSceneManager *pScene, CSceneNode *pParent, CScriptObje
|
||||||
mLocalAABox = mpActiveModel->AABox();
|
mLocalAABox = mpActiveModel->AABox();
|
||||||
else
|
else
|
||||||
mLocalAABox = CAABox::skOne;
|
mLocalAABox = CAABox::skOne;
|
||||||
|
|
||||||
|
mpExtra = CScriptExtra::CreateExtra(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ENodeType CScriptNode::NodeType()
|
ENodeType CScriptNode::NodeType()
|
||||||
|
@ -105,6 +108,9 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||||
{
|
{
|
||||||
if (!mpInstance) return;
|
if (!mpInstance) return;
|
||||||
|
|
||||||
|
// Add script extra to renderer first
|
||||||
|
if (mpExtra) mpExtra->AddToRenderer(pRenderer, ViewInfo);
|
||||||
|
|
||||||
// If we're in game mode, then override other visibility settings.
|
// If we're in game mode, then override other visibility settings.
|
||||||
if (ViewInfo.GameMode)
|
if (ViewInfo.GameMode)
|
||||||
{
|
{
|
||||||
|
@ -112,6 +118,11 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether the script extra wants us to render before we render.
|
||||||
|
bool ShouldDraw = (!mpExtra || mpExtra->ShouldDrawNormalAssets());
|
||||||
|
|
||||||
|
if (ShouldDraw)
|
||||||
|
{
|
||||||
// Otherwise, we proceed as normal
|
// Otherwise, we proceed as normal
|
||||||
ERenderOptions options = pRenderer->RenderOptions();
|
ERenderOptions options = pRenderer->RenderOptions();
|
||||||
|
|
||||||
|
@ -152,14 +163,16 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (IsSelected() && !ViewInfo.GameMode)
|
if (IsSelected() && !ViewInfo.GameMode)
|
||||||
{
|
{
|
||||||
// Script nodes always draw their selections regardless of frustum planes
|
// Script nodes always draw their selections regardless of frustum planes
|
||||||
// in order to ensure that script connection lines don't get improperly culled.
|
// in order to ensure that script connection lines don't get improperly culled.
|
||||||
|
if (ShouldDraw)
|
||||||
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawSelection);
|
pRenderer->AddOpaqueMesh(this, 0, AABox(), eDrawSelection);
|
||||||
|
|
||||||
if (mHasVolumePreview)
|
if (mHasVolumePreview && (!mpExtra || mpExtra->ShouldDrawVolume()))
|
||||||
mpVolumePreviewNode->AddToRenderer(pRenderer, ViewInfo);
|
mpVolumePreviewNode->AddToRenderer(pRenderer, ViewInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,6 +186,10 @@ void CScriptNode::Draw(ERenderOptions Options, const SViewInfo& ViewInfo)
|
||||||
{
|
{
|
||||||
LoadModelMatrix();
|
LoadModelMatrix();
|
||||||
LoadLights(ViewInfo);
|
LoadLights(ViewInfo);
|
||||||
|
|
||||||
|
if (mpExtra) CGraphics::sPixelBlock.TevColor = mpExtra->TevColor().ToVector4f();
|
||||||
|
else CGraphics::sPixelBlock.TevColor = CColor::skWhite.ToVector4f();
|
||||||
|
|
||||||
CGraphics::sPixelBlock.TintColor = TintColor(ViewInfo).ToVector4f();
|
CGraphics::sPixelBlock.TintColor = TintColor(ViewInfo).ToVector4f();
|
||||||
mpActiveModel->Draw(Options, 0);
|
mpActiveModel->Draw(Options, 0);
|
||||||
}
|
}
|
||||||
|
@ -208,10 +225,14 @@ void CScriptNode::DrawAsset(ERenderOptions Options, u32 Asset, const SViewInfo&
|
||||||
else
|
else
|
||||||
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor.ToVector4f();
|
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor.ToVector4f();
|
||||||
|
|
||||||
CGraphics::sPixelBlock.TintColor = TintColor(ViewInfo).ToVector4f();
|
|
||||||
LoadModelMatrix();
|
LoadModelMatrix();
|
||||||
LoadLights(ViewInfo);
|
LoadLights(ViewInfo);
|
||||||
|
|
||||||
|
if (mpExtra) CGraphics::sPixelBlock.TevColor = mpExtra->TevColor().ToVector4f();
|
||||||
|
else CGraphics::sPixelBlock.TevColor = CColor::skWhite.ToVector4f();
|
||||||
|
|
||||||
|
CGraphics::sPixelBlock.TintColor = TintColor(ViewInfo).ToVector4f();
|
||||||
|
|
||||||
mpActiveModel->DrawSurface(Options, Asset, 0);
|
mpActiveModel->DrawSurface(Options, Asset, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,9 +255,10 @@ void CScriptNode::DrawSelection()
|
||||||
|
|
||||||
for (u32 iIn = 0; iIn < mpInstance->NumInLinks(); iIn++)
|
for (u32 iIn = 0; iIn < mpInstance->NumInLinks(); iIn++)
|
||||||
{
|
{
|
||||||
|
// Don't draw in links if the other object is selected.
|
||||||
const SLink& con = mpInstance->InLink(iIn);
|
const SLink& con = mpInstance->InLink(iIn);
|
||||||
CScriptNode *pLinkNode = mpScene->ScriptNodeByID(con.ObjectID);
|
CScriptNode *pLinkNode = mpScene->ScriptNodeByID(con.ObjectID);
|
||||||
if (pLinkNode) CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::skTransparentRed);
|
if (pLinkNode && !pLinkNode->IsSelected()) CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::skTransparentRed);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 iOut = 0; iOut < mpInstance->NumOutLinks(); iOut++)
|
for (u32 iOut = 0; iOut < mpInstance->NumOutLinks(); iOut++)
|
||||||
|
@ -253,6 +275,16 @@ void CScriptNode::RayAABoxIntersectTest(CRayCollisionTester &Tester)
|
||||||
if (!mpInstance)
|
if (!mpInstance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Let script extra do ray check first
|
||||||
|
if (mpExtra)
|
||||||
|
{
|
||||||
|
mpExtra->RayAABoxIntersectTest(Tester);
|
||||||
|
|
||||||
|
// If the extra doesn't want us rendering, then don't do the ray test either
|
||||||
|
if (!mpExtra->ShouldDrawNormalAssets()) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, proceed with the ray test as normal...
|
||||||
const CRay& Ray = Tester.Ray();
|
const CRay& Ray = Tester.Ray();
|
||||||
|
|
||||||
if (mpActiveModel || !mpBillboard)
|
if (mpActiveModel || !mpBillboard)
|
||||||
|
@ -390,6 +422,13 @@ bool CScriptNode::IsVisible() const
|
||||||
return (mVisible && mpInstance->Layer()->IsVisible() && mpInstance->Template()->IsVisible());
|
return (mVisible && mpInstance->Layer()->IsVisible() && mpInstance->Template()->IsVisible());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CColor CScriptNode::TintColor(const SViewInfo &ViewInfo) const
|
||||||
|
{
|
||||||
|
CColor BaseColor = CSceneNode::TintColor(ViewInfo);
|
||||||
|
if (mpExtra) mpExtra->ModifyTintColor(BaseColor);
|
||||||
|
return BaseColor;
|
||||||
|
}
|
||||||
|
|
||||||
CColor CScriptNode::WireframeColor() const
|
CColor CScriptNode::WireframeColor() const
|
||||||
{
|
{
|
||||||
return CColor((u8) 12, 135, 194, 255);
|
return CColor((u8) 12, 135, 194, 255);
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
class CScriptNode : public CSceneNode
|
class CScriptNode : public CSceneNode
|
||||||
{
|
{
|
||||||
CScriptObject *mpInstance;
|
CScriptObject *mpInstance;
|
||||||
|
class CScriptExtra *mpExtra;
|
||||||
|
|
||||||
CModel *mpActiveModel;
|
CModel *mpActiveModel;
|
||||||
CTexture *mpBillboard;
|
CTexture *mpBillboard;
|
||||||
CToken mModelToken;
|
CToken mModelToken;
|
||||||
|
@ -33,6 +35,7 @@ public:
|
||||||
void RayAABoxIntersectTest(CRayCollisionTester &Tester);
|
void RayAABoxIntersectTest(CRayCollisionTester &Tester);
|
||||||
SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo);
|
SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo);
|
||||||
bool IsVisible() const;
|
bool IsVisible() const;
|
||||||
|
CColor TintColor(const SViewInfo &ViewInfo) const;
|
||||||
CColor WireframeColor() const;
|
CColor WireframeColor() const;
|
||||||
|
|
||||||
CScriptObject* Object();
|
CScriptObject* Object();
|
||||||
|
|
|
@ -8,6 +8,7 @@ enum ENodeType
|
||||||
eStaticNode,
|
eStaticNode,
|
||||||
eCollisionNode,
|
eCollisionNode,
|
||||||
eScriptNode,
|
eScriptNode,
|
||||||
|
eScriptExtraNode,
|
||||||
eLightNode
|
eLightNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "CPointOfInterestExtra.h"
|
||||||
|
|
||||||
|
const CColor CPointOfInterestExtra::skRegularColor((u32) 0xFF7000FF);
|
||||||
|
const CColor CPointOfInterestExtra::skImportantColor((u32) 0xFF0000FF);
|
||||||
|
|
||||||
|
CPointOfInterestExtra::CPointOfInterestExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent)
|
||||||
|
: CScriptExtra(pInstance, pScene, pParent)
|
||||||
|
, mpScanProperty(nullptr)
|
||||||
|
, mpScanData(nullptr)
|
||||||
|
{
|
||||||
|
// Fetch scan data property
|
||||||
|
CPropertyStruct *pBaseProp = pInstance->Properties();
|
||||||
|
|
||||||
|
switch (mGame)
|
||||||
|
{
|
||||||
|
case ePrimeDemo:
|
||||||
|
case ePrime:
|
||||||
|
mpScanProperty = (CFileProperty*) pBaseProp->PropertyByIDString("0x04:0x00");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case eEchoesDemo:
|
||||||
|
case eEchoes:
|
||||||
|
case eCorruptionProto:
|
||||||
|
case eCorruption:
|
||||||
|
mpScanProperty = (CFileProperty*) pBaseProp->PropertyByIDString("0xBDBEC295:0xB94E9BE7");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mpScanProperty = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mpScanProperty)
|
||||||
|
{
|
||||||
|
if (mpScanProperty->Type() == eFileProperty)
|
||||||
|
PropertyModified(mpScanProperty);
|
||||||
|
else
|
||||||
|
mpScanProperty = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPointOfInterestExtra::PropertyModified(CPropertyBase* pProperty)
|
||||||
|
{
|
||||||
|
if (mpScanProperty == pProperty)
|
||||||
|
{
|
||||||
|
mpScanData = (CScan*) mpScanProperty->Get();
|
||||||
|
|
||||||
|
if (mpScanData && mpScanData->Type() == eScan)
|
||||||
|
mScanToken = CToken(mpScanData);
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mpScanData = nullptr;
|
||||||
|
mScanToken.Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPointOfInterestExtra::ModifyTintColor(CColor& Color)
|
||||||
|
{
|
||||||
|
if (mpScanData)
|
||||||
|
{
|
||||||
|
if (mpScanData->IsImportant()) Color *= skImportantColor;
|
||||||
|
else Color *= skRegularColor;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef CPOINTOFINTERESTEXTRA_H
|
||||||
|
#define CPOINTOFINTERESTEXTRA_H
|
||||||
|
|
||||||
|
#include "CScriptExtra.h"
|
||||||
|
#include <Common/CColor.h>
|
||||||
|
#include <Resource/CScan.h>
|
||||||
|
|
||||||
|
class CPointOfInterestExtra : public CScriptExtra
|
||||||
|
{
|
||||||
|
// Tint POI billboard orange/red depending on scan importance
|
||||||
|
CFileProperty *mpScanProperty;
|
||||||
|
CScan *mpScanData;
|
||||||
|
CToken mScanToken;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CPointOfInterestExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||||
|
void PropertyModified(CPropertyBase* pProperty);
|
||||||
|
void ModifyTintColor(CColor& Color);
|
||||||
|
|
||||||
|
static const CColor skRegularColor;
|
||||||
|
static const CColor skImportantColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CPOINTOFINTERESTEXTRA_H
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "CScriptExtra.h"
|
||||||
|
|
||||||
|
#include "CWaypointExtra.h"
|
||||||
|
#include "CSpacePirateExtra.h"
|
||||||
|
#include "CPointOfInterestExtra.h"
|
||||||
|
|
||||||
|
CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode)
|
||||||
|
{
|
||||||
|
CScriptExtra *pExtra = nullptr;
|
||||||
|
CScriptObject *pObj = pNode->Object();
|
||||||
|
|
||||||
|
if (pObj)
|
||||||
|
{
|
||||||
|
switch (pObj->ObjectTypeID())
|
||||||
|
{
|
||||||
|
case 0x02: // Waypoint (MP1)
|
||||||
|
case 0x0D: // CameraWaypoint (MP1)
|
||||||
|
case 0x2C: // SpiderBallWaypoint (MP1)
|
||||||
|
case 0x32: // DebugCameraWaypoint(MP1)
|
||||||
|
case 0x41495750: // "AIWP" AIWaypoint (MP2/MP3/DKCR)
|
||||||
|
case 0x42414C57: // "BALW" SpiderBallWaypoint (MP2/MP3)
|
||||||
|
case 0x43414D57: // "CAMW" CameraWaypoint (MP2)
|
||||||
|
case 0x57415950: // "WAYP" Waypoint (MP2/MP3/DKCR)
|
||||||
|
pExtra = new CWaypointExtra(pObj, pNode->Scene(), pNode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x24: // SpacePirate (MP1)
|
||||||
|
pExtra = new CSpacePirateExtra(pObj, pNode->Scene(), pNode);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x42: // PointOfInterest (MP1)
|
||||||
|
case 0x504F494E: // "POIN" PointOfInterest (MP2/MP3)
|
||||||
|
pExtra = new CPointOfInterestExtra(pObj, pNode->Scene(), pNode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pExtra;
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef CSCRIPTEXTRA_H
|
||||||
|
#define CSCRIPTEXTRA_H
|
||||||
|
|
||||||
|
#include "../CSceneNode.h"
|
||||||
|
#include "../CScriptNode.h"
|
||||||
|
|
||||||
|
/* CScriptExtra is a class that allows for additional coded behavior on any given
|
||||||
|
* script object type. Subclass IScriptExtra, add the new class to CScriptExtra.cpp,
|
||||||
|
* and reimplement whatever functions are needed to create the desired behavior. Note
|
||||||
|
* that in addition to the functions here you can also reimplement IRenderable functions
|
||||||
|
* (to render additional geometry) and CSceneNode functions (primarily for raycast
|
||||||
|
* intersections).
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CScriptExtra : public CSceneNode
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
CScriptObject *mpInstance;
|
||||||
|
EGame mGame;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CScriptExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0)
|
||||||
|
: CSceneNode(pScene, pParent),
|
||||||
|
mpInstance(pInstance),
|
||||||
|
mGame(pInstance->Template()->Game())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~CScriptExtra() {}
|
||||||
|
|
||||||
|
// Default implementations for CSceneNode
|
||||||
|
virtual ENodeType NodeType() { return eScriptExtraNode; }
|
||||||
|
virtual SRayIntersection RayNodeIntersectTest(const CRay& /*Ray*/, u32 /*AssetID*/, const SViewInfo& /*ViewInfo*/)
|
||||||
|
{
|
||||||
|
SRayIntersection out;
|
||||||
|
out.Hit = false;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Virtual CScriptExtra functions
|
||||||
|
virtual void InstanceTransformed() {}
|
||||||
|
virtual void PropertyModified(CPropertyBase* /*pProperty*/) {}
|
||||||
|
virtual void LinksModified() {}
|
||||||
|
virtual bool ShouldDrawNormalAssets() { return true; }
|
||||||
|
virtual bool ShouldDrawVolume() { return true; }
|
||||||
|
virtual CColor TevColor() { return CColor::skWhite; }
|
||||||
|
virtual void ModifyTintColor(CColor& /*Color*/) {}
|
||||||
|
|
||||||
|
// Create Script Extra
|
||||||
|
static CScriptExtra* CreateExtra(CScriptNode *pNode);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSCRIPTEXTRA_H
|
|
@ -0,0 +1,49 @@
|
||||||
|
#include "CSpacePirateExtra.h"
|
||||||
|
|
||||||
|
CSpacePirateExtra::CSpacePirateExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent)
|
||||||
|
: CScriptExtra(pInstance, pScene ,pParent)
|
||||||
|
, mpPowerVuln(nullptr)
|
||||||
|
, mpWaveVuln(nullptr)
|
||||||
|
, mpIceVuln(nullptr)
|
||||||
|
, mpPlasmaVuln(nullptr)
|
||||||
|
{
|
||||||
|
CPropertyStruct *pBaseStruct = pInstance->Properties();
|
||||||
|
CPropertyStruct *pVulns = (CPropertyStruct*) pBaseStruct->PropertyByIDString("0x04:0x10");
|
||||||
|
|
||||||
|
if (pVulns && pVulns->Type() == eStructProperty)
|
||||||
|
{
|
||||||
|
mpPowerVuln = (CLongProperty*) pVulns->PropertyByID(0x0);
|
||||||
|
if (mpPowerVuln && mpPowerVuln->Type() != eLongProperty && mpPowerVuln->Type() != eEnumProperty)
|
||||||
|
mpPowerVuln = nullptr;
|
||||||
|
|
||||||
|
mpWaveVuln = (CLongProperty*) pVulns->PropertyByID(0x2);
|
||||||
|
if (mpWaveVuln && mpWaveVuln->Type() != eLongProperty && mpWaveVuln->Type() != eEnumProperty)
|
||||||
|
mpWaveVuln = nullptr;
|
||||||
|
|
||||||
|
mpIceVuln = (CLongProperty*) pVulns->PropertyByID(0x1);
|
||||||
|
if (mpIceVuln && mpIceVuln->Type() != eLongProperty && mpIceVuln->Type() != eEnumProperty)
|
||||||
|
mpIceVuln = nullptr;
|
||||||
|
|
||||||
|
mpPlasmaVuln = (CLongProperty*) pVulns->PropertyByID(0x3);
|
||||||
|
if (mpPlasmaVuln && mpPlasmaVuln->Type() != eLongProperty && mpPlasmaVuln->Type() != eEnumProperty)
|
||||||
|
mpPlasmaVuln = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CColor CSpacePirateExtra::TevColor()
|
||||||
|
{
|
||||||
|
// Priority: Plasma -> Ice -> Power -> Wave
|
||||||
|
if (mpPlasmaVuln && mpPlasmaVuln->Get() == 1)
|
||||||
|
return CColor::skRed;
|
||||||
|
|
||||||
|
if (mpIceVuln && mpIceVuln->Get() == 1)
|
||||||
|
return CColor::skWhite;
|
||||||
|
|
||||||
|
if (mpPowerVuln && mpPowerVuln->Get() == 1)
|
||||||
|
return CColor::skYellow;
|
||||||
|
|
||||||
|
if (mpWaveVuln && mpWaveVuln->Get() == 1)
|
||||||
|
return CColor::skPurple;
|
||||||
|
|
||||||
|
return CColor::skWhite;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef CSPACEPIRATEEXTRA_H
|
||||||
|
#define CSPACEPIRATEEXTRA_H
|
||||||
|
|
||||||
|
#include "CScriptExtra.h"
|
||||||
|
#include <Resource/script/CProperty.h>
|
||||||
|
|
||||||
|
class CSpacePirateExtra : public CScriptExtra
|
||||||
|
{
|
||||||
|
// Render beam troopers with the correct color
|
||||||
|
CLongProperty *mpPowerVuln;
|
||||||
|
CLongProperty *mpWaveVuln;
|
||||||
|
CLongProperty *mpIceVuln;
|
||||||
|
CLongProperty *mpPlasmaVuln;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CSpacePirateExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||||
|
CColor TevColor();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSPACEPIRATEEXTRA_H
|
|
@ -0,0 +1,106 @@
|
||||||
|
#include "CWaypointExtra.h"
|
||||||
|
#include <Core/CDrawUtil.h>
|
||||||
|
#include <Core/CRenderer.h>
|
||||||
|
#include <Core/CSceneManager.h>
|
||||||
|
|
||||||
|
CWaypointExtra::CWaypointExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent)
|
||||||
|
: CScriptExtra(pInstance, pScene, pParent)
|
||||||
|
, mColor(CColor::skBlack)
|
||||||
|
, mLinksBuilt(false)
|
||||||
|
{
|
||||||
|
// Fetch color from parent node's model
|
||||||
|
CScriptNode *pScript = static_cast<CScriptNode*>(pParent);
|
||||||
|
CModel *pModel = pScript->ActiveModel();
|
||||||
|
|
||||||
|
if ((pModel->GetMatSetCount() > 0) && (pModel->GetMatCount() > 0))
|
||||||
|
{
|
||||||
|
CMaterial *pMat = pModel->GetMaterialByIndex(0, 0);
|
||||||
|
mColor = pMat->Konst(0);
|
||||||
|
mColor.a = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWaypointExtra::BuildLinks()
|
||||||
|
{
|
||||||
|
mLinks.clear();
|
||||||
|
|
||||||
|
for (u32 iLink = 0; iLink < mpInstance->NumOutLinks(); iLink++)
|
||||||
|
{
|
||||||
|
const SLink& rkLink = mpInstance->OutLink(iLink);
|
||||||
|
|
||||||
|
if (IsPathLink(rkLink))
|
||||||
|
{
|
||||||
|
CScriptNode *pNode = mpScene->ScriptNodeByID(rkLink.ObjectID);
|
||||||
|
|
||||||
|
SWaypointLink Link;
|
||||||
|
Link.pWaypoint = pNode;
|
||||||
|
Link.LineAABB.ExpandBounds(AbsolutePosition());
|
||||||
|
Link.LineAABB.ExpandBounds(pNode->AbsolutePosition());
|
||||||
|
mLinks.push_back(Link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mLinksBuilt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWaypointExtra::IsPathLink(const SLink& rkLink)
|
||||||
|
{
|
||||||
|
bool Valid = false;
|
||||||
|
|
||||||
|
if (rkLink.State < 0xFF)
|
||||||
|
{
|
||||||
|
if (rkLink.State == 0x1 && rkLink.Message == 0x8) Valid = true; // Arrived / Next (MP1)
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CFourCC State(rkLink.State);
|
||||||
|
CFourCC Message(rkLink.Message);
|
||||||
|
if (State == "ARRV" && Message == "NEXT") Valid = true; // Arrived / Next (MP2)
|
||||||
|
if (State == "NEXT" && Message == "ATCH") Valid = true; // Next / Attach (MP3/DKCR)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Valid)
|
||||||
|
{
|
||||||
|
CScriptNode *pNode = mpScene->ScriptNodeByID(rkLink.ObjectID);
|
||||||
|
|
||||||
|
if (pNode)
|
||||||
|
return pNode->Object()->ObjectTypeID() == mpInstance->ObjectTypeID();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWaypointExtra::LinksModified()
|
||||||
|
{
|
||||||
|
BuildLinks();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWaypointExtra::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||||
|
{
|
||||||
|
// This call is necessary because if we try to build links in the constructor, it'll
|
||||||
|
// fail because we haven't finished loading the scene yet.
|
||||||
|
if (!mLinksBuilt) BuildLinks();
|
||||||
|
|
||||||
|
if (!ViewInfo.GameMode && mpParent->IsVisible() && !mpParent->IsSelected())
|
||||||
|
{
|
||||||
|
for (u32 iLink = 0; iLink < mLinks.size(); iLink++)
|
||||||
|
{
|
||||||
|
CScriptNode *pNode = mLinks[iLink].pWaypoint;
|
||||||
|
|
||||||
|
if (pNode->IsVisible() && !pNode->IsSelected() && ViewInfo.ViewFrustum.BoxInFrustum(mLinks[iLink].LineAABB))
|
||||||
|
pRenderer->AddOpaqueMesh(this, iLink, mLinks[iLink].LineAABB, eDrawAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWaypointExtra::DrawAsset(ERenderOptions /*Options*/, u32 AssetID, const SViewInfo& /*ViewInfo*/)
|
||||||
|
{
|
||||||
|
glBlendFunc(GL_ONE, GL_ZERO);
|
||||||
|
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||||
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
|
CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
|
||||||
|
CGraphics::UpdateMVPBlock();
|
||||||
|
CDrawUtil::DrawLine(mpParent->AABox().Center(), mLinks[AssetID].pWaypoint->AABox().Center(), mColor);
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef CWAYPOINTEXTRA_H
|
||||||
|
#define CWAYPOINTEXTRA_H
|
||||||
|
|
||||||
|
#include "CScriptExtra.h"
|
||||||
|
#include <Common/CColor.h>
|
||||||
|
|
||||||
|
class CWaypointExtra : public CScriptExtra
|
||||||
|
{
|
||||||
|
// Draw waypoint paths formed by script connections
|
||||||
|
CColor mColor;
|
||||||
|
bool mLinksBuilt;
|
||||||
|
|
||||||
|
struct SWaypointLink
|
||||||
|
{
|
||||||
|
CScriptNode *pWaypoint;
|
||||||
|
CAABox LineAABB;
|
||||||
|
};
|
||||||
|
std::vector<SWaypointLink> mLinks;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CWaypointExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||||
|
void BuildLinks();
|
||||||
|
bool IsPathLink(const SLink& rkLink);
|
||||||
|
|
||||||
|
void LinksModified();
|
||||||
|
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||||
|
void DrawAsset(ERenderOptions Options, u32 AssetID, const SViewInfo& ViewInfo);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CWAYPOINTEXTRA_H
|
Loading…
Reference in New Issue