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

Binary file not shown.

View File

@ -185,7 +185,8 @@ HEADERS += \
Resource/Factory/CPoiToWorldLoader.h \ Resource/Factory/CPoiToWorldLoader.h \
Resource/Cooker/CPoiToWorldCooker.h \ Resource/Cooker/CPoiToWorldCooker.h \
Resource/Factory/CSectionMgrIn.h \ Resource/Factory/CSectionMgrIn.h \
Resource/Cooker/CScriptCooker.h Resource/Cooker/CScriptCooker.h \
ScriptExtra/CSplinePathExtra.h
# Source Files # Source Files
SOURCES += \ SOURCES += \
@ -271,4 +272,5 @@ SOURCES += \
Resource/CPoiToWorld.cpp \ Resource/CPoiToWorld.cpp \
Resource/Factory/CPoiToWorldLoader.cpp \ Resource/Factory/CPoiToWorldLoader.cpp \
Resource/Cooker/CPoiToWorldCooker.cpp \ Resource/Cooker/CPoiToWorldCooker.cpp \
Resource/Cooker/CScriptCooker.cpp Resource/Cooker/CScriptCooker.cpp \
ScriptExtra/CSplinePathExtra.cpp

View File

@ -141,7 +141,7 @@ void CMaterialCooker::WriteMaterialPrime(IOutputStream& Out)
else else
Flags = 0x4002; Flags = 0x4002;
Flags |= (HasKonst ? 0x8 : 0x0) | mpMat->Options() | (TexFlags << 16); Flags |= (HasKonst ? 0x8 : 0x0) | (mpMat->Options() & ~0x8) | (TexFlags << 16);
Out.WriteLong(Flags); Out.WriteLong(Flags);

View File

@ -6,6 +6,7 @@
#include "CPointOfInterestExtra.h" #include "CPointOfInterestExtra.h"
#include "CDoorExtra.h" #include "CDoorExtra.h"
#include "CRadiusSphereExtra.h" #include "CRadiusSphereExtra.h"
#include "CSplinePathExtra.h"
CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode) CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode)
{ {
@ -50,6 +51,12 @@ CScriptExtra* CScriptExtra::CreateExtra(CScriptNode *pNode)
case 0x52414444: // "RADD" RadialDamage (MP2/MP3/DKCR) case 0x52414444: // "RADD" RadialDamage (MP2/MP3/DKCR)
pExtra = new CRadiusSphereExtra(pObj, pNode->Scene(), pNode); pExtra = new CRadiusSphereExtra(pObj, pNode->Scene(), pNode);
break; 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() {} virtual ~CScriptExtra() {}
inline CScriptObject* Instance() const { return mpInstance; }
inline EGame Game() const { return mGame; }
// Default implementations for CSceneNode // Default implementations for CSceneNode
virtual ENodeType NodeType() { return eScriptExtraNode; } 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) , mColor(CColor::skBlack)
, mLinksBuilt(false) , mLinksBuilt(false)
{ {
// Fetch color from parent node's model CheckColor();
CScriptNode *pScript = static_cast<CScriptNode*>(pParent); }
CModel *pModel = pScript->ActiveModel();
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); CSplinePathExtra *pPath = mPaths.front();
mColor = pMat->Konst(0); mColor = pPath->PathColor();
mColor.a = 0; }
// 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; 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() void CWaypointExtra::LinksModified()
{ {
BuildLinks(); BuildLinks();
@ -104,3 +170,8 @@ void CWaypointExtra::Draw(FRenderOptions /*Options*/, int ComponentIndex, const
CGraphics::UpdateMVPBlock(); CGraphics::UpdateMVPBlock();
CDrawUtil::DrawLine(mpParent->AABox().Center(), mLinks[ComponentIndex].pWaypoint->AABox().Center(), mColor); 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 #define CWAYPOINTEXTRA_H
#include "CScriptExtra.h" #include "CScriptExtra.h"
#include "CSplinePathExtra.h"
#include <Common/CColor.h> #include <Common/CColor.h>
class CWaypointExtra : public CScriptExtra class CWaypointExtra : public CScriptExtra
@ -9,6 +10,7 @@ class CWaypointExtra : public CScriptExtra
// Draw waypoint paths formed by script connections // Draw waypoint paths formed by script connections
CColor mColor; CColor mColor;
bool mLinksBuilt; bool mLinksBuilt;
std::list<CSplinePathExtra*> mPaths;
struct SWaypointLink struct SWaypointLink
{ {
@ -19,12 +21,18 @@ class CWaypointExtra : public CScriptExtra
public: public:
explicit CWaypointExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0); explicit CWaypointExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0);
~CWaypointExtra();
void CheckColor();
void AddToSplinePath(CSplinePathExtra *pPath);
void RemoveFromSplinePath(CSplinePathExtra *pPath);
void BuildLinks(); void BuildLinks();
bool IsPathLink(const SLink& rkLink); bool IsPathLink(const SLink& rkLink);
void GetLinkedWaypoints(std::list<CWaypointExtra*>& rOut);
void LinksModified(); void LinksModified();
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo); void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo); void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
CColor TevColor();
}; };
#endif // CWAYPOINTEXTRA_H #endif // CWAYPOINTEXTRA_H

View File

@ -15,7 +15,7 @@
<property name="Active" ID="0x255A4580:0x41435456"/> <property name="Active" ID="0x255A4580:0x41435456"/>
</properties> </properties>
<assets> <assets>
<model source="file">script/common/Waypoint.cmdl</model> <model source="file">script/dkcr/Waypoint.cmdl</model>
</assets> </assets>
<rotation_type>enabled</rotation_type> <rotation_type>enabled</rotation_type>
<scale_type>enabled</scale_type> <scale_type>enabled</scale_type>