Set up DKCR waypoints to draw using the color of their attached spline path

This commit is contained in:
parax0
2016-02-27 02:16:29 -07:00
parent 17bb4567df
commit ecab7be63f
10 changed files with 216 additions and 11 deletions

View File

@@ -6,6 +6,7 @@
#include "CPointOfInterestExtra.h"
#include "CDoorExtra.h"
#include "CRadiusSphereExtra.h"
#include "CSplinePathExtra.h"
CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode)
{
@@ -50,6 +51,12 @@ CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode)
case 0x52414444: // "RADD" RadialDamage (MP2/MP3/DKCR)
pExtra = new CRadiusSphereExtra(pObj, pNode->Scene(), pNode);
break;
case 0x53505041: // SplinePath (DKCR)
case 0x5043544C: // PathControl (DKCR)
case 0x434C5043: // ClingPathControl (DKCR)
pExtra = new CSplinePathExtra(pObj, pNode->Scene(), pNode);
break;
}
}

View File

@@ -27,6 +27,8 @@ public:
}
virtual ~CScriptExtra() {}
inline CScriptObject* Instance() const { return mpInstance; }
inline EGame Game() const { return mGame; }
// Default implementations for CSceneNode
virtual ENodeType NodeType() { return eScriptExtraNode; }

View File

@@ -0,0 +1,84 @@
#include "CSplinePathExtra.h"
#include "CWaypointExtra.h"
#include "Core/Scene/CScene.h"
CSplinePathExtra::CSplinePathExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent)
: CScriptExtra(pInstance, pScene, pParent)
{
mpPathColor = TPropCast<TColorProperty>(pInstance->Properties()->PropertyByID(0x00DD86E2));
}
void CSplinePathExtra::PropertyModified(IProperty *pProperty)
{
if (pProperty == mpPathColor)
{
for (auto it = mWaypoints.begin(); it != mWaypoints.end(); it++)
(*it)->CheckColor();
}
}
void CSplinePathExtra::PostLoad()
{
AddWaypoints();
}
void CSplinePathExtra::FindAttachedWaypoints(std::set<CWaypointExtra*>& rChecked, CWaypointExtra *pWaypoint)
{
if (rChecked.find(pWaypoint) != rChecked.end())
return;
rChecked.insert(pWaypoint);
pWaypoint->AddToSplinePath(this);
mWaypoints.push_back(pWaypoint);
std::list<CWaypointExtra*> Attached;
pWaypoint->GetLinkedWaypoints(Attached);
for (auto it = Attached.begin(); it != Attached.end(); it++)
FindAttachedWaypoints(rChecked, *it);
}
void CSplinePathExtra::AddWaypoints()
{
if (mGame != eReturns)
return;
std::set<CWaypointExtra*> CheckedWaypoints;
for (u32 iLink = 0; iLink < mpInstance->NumOutLinks(); iLink++)
{
const SLink& rkLink = mpInstance->OutLink(iLink);
if ( (rkLink.State == 0x49533030 && rkLink.Message == 0x41544348) || // InternalState00/Attach
(rkLink.State == 0x4D4F5450 && rkLink.Message == 0x41544348) ) // MotionPath/Attach
{
CScriptNode *pNode = mpScene->ScriptNodeByID(rkLink.ObjectID);
if (pNode && pNode->Object()->ObjectTypeID() == 0x57415950) // Waypoint
{
CWaypointExtra *pWaypoint = static_cast<CWaypointExtra*>(pNode->Extra());
FindAttachedWaypoints(CheckedWaypoints, pWaypoint);
}
}
}
}
void CSplinePathExtra::RemoveWaypoint(CWaypointExtra *pWaypoint)
{
for (auto it = mWaypoints.begin(); it != mWaypoints.end(); it++)
{
if (*it == pWaypoint)
{
mWaypoints.erase(it);
break;
}
}
}
void CSplinePathExtra::ClearWaypoints()
{
for (auto it = mWaypoints.begin(); it != mWaypoints.end(); it++)
(*it)->RemoveFromSplinePath(this);
mWaypoints.clear();
}

View File

@@ -0,0 +1,31 @@
#ifndef CSPLINEPATHEXTRA_H
#define CSPLINEPATHEXTRA_H
#include "CScriptExtra.h"
#include <Common/CColor.h>
#include <list>
#include <set>
class CWaypointExtra;
class CSplinePathExtra : public CScriptExtra
{
// Recolor waypoint paths to match the editor color parameter
TColorProperty *mpPathColor;
std::list<CWaypointExtra*> mWaypoints;
public:
explicit CSplinePathExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0);
~CSplinePathExtra() { ClearWaypoints(); }
inline CColor PathColor() const { return (mpPathColor ? mpPathColor->Get() : CColor::skBlack); }
void PostLoad();
void PropertyModified(IProperty *pProperty);
void FindAttachedWaypoints(std::set<CWaypointExtra*>& rChecked, CWaypointExtra *pWaypoint);
void AddWaypoints();
void RemoveWaypoint(CWaypointExtra *pWaypoint);
void ClearWaypoints();
};
#endif // CSPLINEPATHEXTRA_H

View File

@@ -8,15 +8,69 @@ CWaypointExtra::CWaypointExtra(CScriptObject *pInstance, CScene *pScene, CSceneN
, mColor(CColor::skBlack)
, mLinksBuilt(false)
{
// Fetch color from parent node's model
CScriptNode *pScript = static_cast<CScriptNode*>(pParent);
CModel *pModel = pScript->ActiveModel();
CheckColor();
}
if (pModel && (pModel->GetMatSetCount() > 0) && (pModel->GetMatCount() > 0))
CWaypointExtra::~CWaypointExtra()
{
for (auto it = mPaths.begin(); it != mPaths.end(); it++)
(*it)->RemoveWaypoint(this);
}
void CWaypointExtra::CheckColor()
{
// Fetch color from attached SplinePath
if (!mPaths.empty())
{
CMaterial *pMat = pModel->GetMaterialByIndex(0, 0);
mColor = pMat->Konst(0);
mColor.a = 0;
CSplinePathExtra *pPath = mPaths.front();
mColor = pPath->PathColor();
}
// Fetch color from parent node's model (MP1/2/3)
else if (mGame < eReturns)
{
CScriptNode *pScript = static_cast<CScriptNode*>(mpParent);
CModel *pModel = pScript->ActiveModel();
if (pModel && (pModel->GetMatSetCount() > 0) && (pModel->GetMatCount() > 0))
{
CMaterial *pMat = pModel->GetMaterialByIndex(0, 0);
mColor = pMat->Konst(0);
}
}
// Use preset color (DKCR)
else
{
mColor = CColor::skCyan;
}
mColor.a = 0;
}
void CWaypointExtra::AddToSplinePath(CSplinePathExtra *pPath)
{
for (auto it = mPaths.begin(); it != mPaths.end(); it++)
{
if (*it == pPath)
return;
}
mPaths.push_back(pPath);
if (mPaths.size() == 1)
CheckColor();
}
void CWaypointExtra::RemoveFromSplinePath(CSplinePathExtra *pPath)
{
for (auto it = mPaths.begin(); it != mPaths.end(); it++)
{
if (*it == pPath)
{
mPaths.erase(it);
CheckColor();
break;
}
}
}
@@ -71,6 +125,18 @@ bool CWaypointExtra::IsPathLink(const SLink& rkLink)
return false;
}
void CWaypointExtra::GetLinkedWaypoints(std::list<CWaypointExtra*>& rOut)
{
if (!mLinksBuilt) BuildLinks();
for (u32 iLink = 0; iLink < mLinks.size(); iLink++)
{
const SWaypointLink& rkLink = mLinks[iLink];
CWaypointExtra *pExtra = static_cast<CWaypointExtra*>(rkLink.pWaypoint->Extra());
rOut.push_back(pExtra);
}
}
void CWaypointExtra::LinksModified()
{
BuildLinks();
@@ -104,3 +170,8 @@ void CWaypointExtra::Draw(FRenderOptions /*Options*/, int ComponentIndex, const
CGraphics::UpdateMVPBlock();
CDrawUtil::DrawLine(mpParent->AABox().Center(), mLinks[ComponentIndex].pWaypoint->AABox().Center(), mColor);
}
CColor CWaypointExtra::TevColor()
{
return (mGame < eReturns ? CColor::skWhite : mColor);
}

View File

@@ -2,6 +2,7 @@
#define CWAYPOINTEXTRA_H
#include "CScriptExtra.h"
#include "CSplinePathExtra.h"
#include <Common/CColor.h>
class CWaypointExtra : public CScriptExtra
@@ -9,6 +10,7 @@ class CWaypointExtra : public CScriptExtra
// Draw waypoint paths formed by script connections
CColor mColor;
bool mLinksBuilt;
std::list<CSplinePathExtra*> mPaths;
struct SWaypointLink
{
@@ -19,12 +21,18 @@ class CWaypointExtra : public CScriptExtra
public:
explicit CWaypointExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0);
~CWaypointExtra();
void CheckColor();
void AddToSplinePath(CSplinePathExtra *pPath);
void RemoveFromSplinePath(CSplinePathExtra *pPath);
void BuildLinks();
bool IsPathLink(const SLink& rkLink);
void GetLinkedWaypoints(std::list<CWaypointExtra*>& rOut);
void LinksModified();
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
CColor TevColor();
};
#endif // CWAYPOINTEXTRA_H