mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-12 22:56:13 +00:00
Mass refactoring part 1/2: establishing multiple subprojects, moving source files to their new location, adding resources/templates to version control
This commit is contained in:
259
src/Core/ScriptExtra/CDamageableTriggerExtra.cpp
Normal file
259
src/Core/ScriptExtra/CDamageableTriggerExtra.cpp
Normal file
@@ -0,0 +1,259 @@
|
||||
#include "CDamageableTriggerExtra.h"
|
||||
#include <Core/CDrawUtil.h>
|
||||
#include <Core/CRenderer.h>
|
||||
|
||||
CDamageableTriggerExtra::CDamageableTriggerExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent)
|
||||
: CScriptExtra(pInstance, pScene, pParent)
|
||||
, mpRenderSideProp(nullptr)
|
||||
, mpMat(nullptr)
|
||||
{
|
||||
for (u32 iTex = 0; iTex < 3; iTex++)
|
||||
mpTextures[iTex] = nullptr;
|
||||
|
||||
SetInheritance(true, false, false);
|
||||
CreateMaterial();
|
||||
|
||||
CPropertyStruct *pBaseStruct = pInstance->Properties();
|
||||
|
||||
// Fetch render side
|
||||
mpRenderSideProp = (CEnumProperty*) pBaseStruct->PropertyByIndex(0x5);
|
||||
|
||||
if (mpRenderSideProp && mpRenderSideProp->Type() != eEnumProperty)
|
||||
mpRenderSideProp = nullptr;
|
||||
|
||||
if (mpRenderSideProp) PropertyModified(mpRenderSideProp);
|
||||
|
||||
// Fetch scale
|
||||
mpSizeProp = (CVector3Property*) pBaseStruct->PropertyByIndex(0x2);
|
||||
|
||||
if (mpSizeProp && mpSizeProp->Type() != eVector3Property)
|
||||
mpSizeProp = nullptr;
|
||||
|
||||
if (mpSizeProp) PropertyModified (mpSizeProp);
|
||||
|
||||
// Fetch textures
|
||||
for (u32 iTex = 0; iTex < 3; iTex++)
|
||||
{
|
||||
mpTextureProps[iTex] = (CFileProperty*) pBaseStruct->PropertyByIndex(0x6 + iTex);
|
||||
|
||||
if (mpTextureProps[iTex])
|
||||
{
|
||||
if (mpTextureProps[iTex]->Type() == eFileProperty)
|
||||
PropertyModified(mpTextureProps[iTex]);
|
||||
else
|
||||
mpTextureProps[iTex] = nullptr;
|
||||
}
|
||||
|
||||
else
|
||||
mpTextures[iTex] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
CDamageableTriggerExtra::~CDamageableTriggerExtra()
|
||||
{
|
||||
delete mpMat;
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::CreateMaterial()
|
||||
{
|
||||
if (mpMat) delete mpMat;
|
||||
mpMat = new CMaterial(mGame, ePosition | eNormal | eTex0);
|
||||
|
||||
// Most values/TEV setup were found from the executable + from graphics debuggers
|
||||
// Animation parameters are estimates from eyeballing the values ingame
|
||||
mpMat->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
mpMat->SetLightingEnabled(true);
|
||||
mpMat->SetOptions(CMaterial::eTransparent);
|
||||
mpMat->SetKonst(CColor((float) 1.f, 1.f, 1.f, 0.2f), 0);
|
||||
mpMat->SetNumPasses(3);
|
||||
|
||||
CMaterialPass *pPassA = mpMat->Pass(0);
|
||||
pPassA->SetKColorSel(eKonst0_RGB);
|
||||
pPassA->SetTexCoordSource(4);
|
||||
pPassA->SetTexture(mpTextures[0]);
|
||||
pPassA->SetColorInputs(eZeroRGB, eTextureRGB, eKonstRGB, eZeroRGB);
|
||||
pPassA->SetAnimMode(eUVScroll);
|
||||
pPassA->SetAnimParam(3, -0.48f);
|
||||
|
||||
CMaterialPass *pPassB = mpMat->Pass(1);
|
||||
pPassB->SetTexCoordSource(4);
|
||||
pPassB->SetTexture(mpTextures[1]);
|
||||
pPassB->SetColorInputs(eZeroRGB, eTextureRGB, ePrevRGB, eZeroRGB);
|
||||
pPassB->SetAnimMode(eUVScroll);
|
||||
pPassB->SetAnimParam(2, 0.25f);
|
||||
pPassB->SetAnimParam(3, -0.3f);
|
||||
|
||||
CMaterialPass *pPassC = mpMat->Pass(2);
|
||||
pPassC->SetTexCoordSource(4);
|
||||
pPassC->SetTexture(mpTextures[2]);
|
||||
pPassC->SetRasSel(eRasColor0A0);
|
||||
pPassC->SetKAlphaSel(eKonst0_A);
|
||||
pPassC->SetColorInputs(eZeroRGB, eTextureRGB, eOneRGB, ePrevRGB);
|
||||
pPassC->SetAlphaInputs(eZeroAlpha, eZeroAlpha, eZeroAlpha, eKonstAlpha);
|
||||
pPassC->SetAnimMode(eUVScroll);
|
||||
pPassC->SetAnimParam(3, -0.16f);
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::UpdatePlaneTransform()
|
||||
{
|
||||
CVector3f Extent = mPlaneSize / 2.f;
|
||||
|
||||
switch (mRenderSide)
|
||||
{
|
||||
case eNorth:
|
||||
case eSouth:
|
||||
{
|
||||
float Scalar = (mRenderSide == eNorth ? 1.f : -1.f);
|
||||
|
||||
mPosition = CVector3f(0.f, Extent.y * Scalar, 0.f);
|
||||
mRotation = CQuaternion::FromEuler(CVector3f(90.f * Scalar, 0.f, 0.f));
|
||||
mScale = CVector3f(Extent.x, Extent.z, 0.f);
|
||||
mCoordScale = mPlaneSize.xz();
|
||||
break;
|
||||
}
|
||||
|
||||
case eWest:
|
||||
case eEast:
|
||||
{
|
||||
float Scalar = (mRenderSide == eWest ? 1.f : -1.f);
|
||||
|
||||
mPosition = CVector3f(-Extent.x * Scalar, 0.f, 0.f);
|
||||
mRotation = CQuaternion::FromEuler(CVector3f(0.f, 90.f * Scalar, 0.f));
|
||||
mScale = CVector3f(Extent.z, Extent.y, 0.f);
|
||||
mCoordScale = -mPlaneSize.yz();
|
||||
break;
|
||||
}
|
||||
|
||||
case eUp:
|
||||
case eDown:
|
||||
{
|
||||
float Scalar = (mRenderSide == eUp ? 1.f : -1.f);
|
||||
float RotAngle = (mRenderSide == eUp ? 180.f : 0.f);
|
||||
|
||||
mPosition = CVector3f(0.f, 0.f, Extent.z * Scalar);
|
||||
mRotation = CQuaternion::FromEuler(CVector3f(0.f, RotAngle, 0.f));
|
||||
mScale = CVector3f(Extent.x, Extent.y, 0.f);
|
||||
mCoordScale = -mPlaneSize.xy();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mRenderSide == eNoRender)
|
||||
mLocalAABox = CAABox::skZero;
|
||||
else
|
||||
mLocalAABox = CAABox(CVector3f(-1.f, -1.f, 0.f), CVector3f(1.f, 1.f, 0.f));
|
||||
|
||||
MarkTransformChanged();
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::PropertyModified(CPropertyBase *pProperty)
|
||||
{
|
||||
if (pProperty == mpRenderSideProp)
|
||||
{
|
||||
mRenderSide = (ERenderSide) mpRenderSideProp->Get();
|
||||
UpdatePlaneTransform();
|
||||
}
|
||||
|
||||
else if (pProperty == mpSizeProp)
|
||||
{
|
||||
mPlaneSize = mpSizeProp->Get();
|
||||
UpdatePlaneTransform();
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
for (u32 iTex = 0; iTex < 3; iTex++)
|
||||
{
|
||||
if (pProperty == mpTextureProps[iTex])
|
||||
{
|
||||
mpTextures[iTex] = mpTextureProps[iTex]->Get();
|
||||
|
||||
if (mpTextures[iTex] && mpTextures[iTex]->Type() != eTexture)
|
||||
mpTextures[iTex] = nullptr;
|
||||
|
||||
mpMat->Pass(iTex)->SetTexture(mpTextures[iTex]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CDamageableTriggerExtra::ShouldDrawNormalAssets()
|
||||
{
|
||||
return (mRenderSide == eNoRender);
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
{
|
||||
if (ViewInfo.GameMode && !mpInstance->IsActive())
|
||||
return;
|
||||
|
||||
if (mRenderSide != eNoRender)
|
||||
{
|
||||
if (ViewInfo.ViewFrustum.BoxInFrustum(AABox()))
|
||||
pRenderer->AddTransparentMesh(this, -1, AABox(), eDrawMesh);
|
||||
if (mpParent->IsSelected() && !ViewInfo.GameMode)
|
||||
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
|
||||
}
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::Draw(ERenderOptions Options, int /*ComponentIndex*/, const SViewInfo& ViewInfo)
|
||||
{
|
||||
LoadModelMatrix();
|
||||
CGraphics::sPixelBlock.TintColor = mpParent->TintColor(ViewInfo).ToVector4f();
|
||||
mpMat->SetCurrent(Options);
|
||||
|
||||
// Note: The plane the game renders this onto is 5x4.5, which is why we divide the tex coords by this value
|
||||
CVector2f TexUL(0.f, mCoordScale.y / 4.5f);
|
||||
CVector2f TexUR(mCoordScale.x / 5.f, mCoordScale.y / 4.5f);
|
||||
CVector2f TexBR(mCoordScale.x / 5.f, 0.f);
|
||||
CVector2f TexBL(0.f, 0.f);
|
||||
CDrawUtil::DrawSquare(TexUL, TexUR, TexBR, TexBL);
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::DrawSelection()
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
LoadModelMatrix();
|
||||
CDrawUtil::UseColorShader(WireframeColor());
|
||||
CDrawUtil::DrawSquare();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
|
||||
void CDamageableTriggerExtra::RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo)
|
||||
{
|
||||
if (mRenderSide == eNoRender) return;
|
||||
if (ViewInfo.GameMode && !mpInstance->IsActive()) return;
|
||||
|
||||
const CRay& Ray = Tester.Ray();
|
||||
|
||||
if (ViewInfo.pRenderer->RenderOptions() & eEnableBackfaceCull)
|
||||
{
|
||||
// We're guaranteed to be axis-aligned, so we can take advantage of that
|
||||
// to perform a very simple backface check.
|
||||
switch (mRenderSide)
|
||||
{
|
||||
case eNorth: if (Ray.Origin().y > AbsolutePosition().y) return; break;
|
||||
case eSouth: if (Ray.Origin().y < AbsolutePosition().y) return; break;
|
||||
case eWest: if (Ray.Origin().x < AbsolutePosition().x) return; break;
|
||||
case eEast: if (Ray.Origin().x > AbsolutePosition().x) return; break;
|
||||
case eUp: if (Ray.Origin().z > AbsolutePosition().z) return; break;
|
||||
case eDown: if (Ray.Origin().z < AbsolutePosition().z) return; break;
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<bool,float> Result = AABox().IntersectsRay(Ray);
|
||||
|
||||
if (Result.first)
|
||||
Tester.AddNode(this, -1, Result.second);
|
||||
}
|
||||
|
||||
SRayIntersection CDamageableTriggerExtra::RayNodeIntersectTest(const CRay& Ray, u32 /*ComponentIndex*/, const SViewInfo& /*ViewInfo*/)
|
||||
{
|
||||
// The bounding box and all other tests already passed in RayAABoxIntersectTest, so we
|
||||
// already know that we have a positive. We just need the distance again.
|
||||
std::pair<bool,float> Result = AABox().IntersectsRay(Ray);
|
||||
return SRayIntersection(true, Result.second, mpParent, -1);
|
||||
}
|
||||
45
src/Core/ScriptExtra/CDamageableTriggerExtra.h
Normal file
45
src/Core/ScriptExtra/CDamageableTriggerExtra.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef CDAMAGEABLETRIGGEREXTRA_H
|
||||
#define CDAMAGEABLETRIGGEREXTRA_H
|
||||
|
||||
#include "CScriptExtra.h"
|
||||
|
||||
class CDamageableTriggerExtra : public CScriptExtra
|
||||
{
|
||||
// Render fluid planes for doors in MP1
|
||||
enum ERenderSide
|
||||
{
|
||||
eNoRender = 0,
|
||||
eNorth = 1,
|
||||
eSouth = 2,
|
||||
eWest = 3,
|
||||
eEast = 4,
|
||||
eUp = 5,
|
||||
eDown = 6
|
||||
};
|
||||
|
||||
CVector3Property *mpSizeProp;
|
||||
CEnumProperty *mpRenderSideProp;
|
||||
CFileProperty *mpTextureProps[3];
|
||||
|
||||
CVector3f mPlaneSize;
|
||||
ERenderSide mRenderSide;
|
||||
TResPtr<CTexture> mpTextures[3];
|
||||
|
||||
CMaterial *mpMat;
|
||||
CVector2f mCoordScale;
|
||||
|
||||
public:
|
||||
explicit CDamageableTriggerExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||
~CDamageableTriggerExtra();
|
||||
void CreateMaterial();
|
||||
void UpdatePlaneTransform();
|
||||
void PropertyModified(CPropertyBase *pProperty);
|
||||
bool ShouldDrawNormalAssets();
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
void Draw(ERenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
void DrawSelection();
|
||||
void RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo);
|
||||
SRayIntersection RayNodeIntersectTest(const CRay& Ray, u32 ComponentIndex, const SViewInfo& ViewInfo);
|
||||
};
|
||||
|
||||
#endif // CDAMAGEABLETRIGGEREXTRA_H
|
||||
121
src/Core/ScriptExtra/CDoorExtra.cpp
Normal file
121
src/Core/ScriptExtra/CDoorExtra.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "CDoorExtra.h"
|
||||
#include <Core/CRenderer.h>
|
||||
|
||||
CDoorExtra::CDoorExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent)
|
||||
: CScriptExtra(pInstance, pScene, pParent)
|
||||
, mpShieldModelProp(nullptr)
|
||||
, mpShieldColorProp(nullptr)
|
||||
, mpShieldModel(nullptr)
|
||||
{
|
||||
CPropertyStruct *pBaseStruct = pInstance->Properties();
|
||||
|
||||
mpShieldModelProp = (CFileProperty*) pBaseStruct->PropertyByID(0xB20CC271);
|
||||
if (mpShieldModelProp && (mpShieldModelProp->Type() != eFileProperty))
|
||||
mpShieldModelProp = nullptr;
|
||||
|
||||
mpShieldColorProp = (CColorProperty*) pBaseStruct->PropertyByID(0x47B4E863);
|
||||
if (mpShieldColorProp && (mpShieldColorProp->Type() != eColorProperty))
|
||||
mpShieldColorProp = nullptr;
|
||||
|
||||
if (mpShieldModelProp)
|
||||
PropertyModified(mpShieldModelProp);
|
||||
}
|
||||
|
||||
void CDoorExtra::PropertyModified(CPropertyBase *pProperty)
|
||||
{
|
||||
if (pProperty == mpShieldModelProp)
|
||||
{
|
||||
mpShieldModel = mpShieldModelProp->Get();
|
||||
|
||||
if (mpShieldModel)
|
||||
mLocalAABox = mpShieldModel->AABox();
|
||||
|
||||
else
|
||||
mLocalAABox = CAABox::skInfinite;
|
||||
|
||||
MarkTransformChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void CDoorExtra::AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo)
|
||||
{
|
||||
if (!mpShieldModel) return;
|
||||
if (ViewInfo.GameMode && !mpInstance->IsActive()) return;
|
||||
|
||||
if (mpParent->IsVisible() && ViewInfo.ViewFrustum.BoxInFrustum(AABox()))
|
||||
{
|
||||
if (mpShieldModel->HasTransparency(0))
|
||||
AddSurfacesToRenderer(pRenderer, mpShieldModel, 0, ViewInfo);
|
||||
else
|
||||
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawMesh);
|
||||
|
||||
if (mpParent->IsSelected())
|
||||
pRenderer->AddOpaqueMesh(this, -1, AABox(), eDrawSelection);
|
||||
}
|
||||
}
|
||||
|
||||
void CDoorExtra::Draw(ERenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo)
|
||||
{
|
||||
LoadModelMatrix();
|
||||
mpParent->LoadLights(ViewInfo);
|
||||
|
||||
CGraphics::SetupAmbientColor();
|
||||
CGraphics::UpdateVertexBlock();
|
||||
|
||||
CColor Tint = mpParent->TintColor(ViewInfo);
|
||||
|
||||
if (mpShieldColorProp)
|
||||
Tint *= mpShieldColorProp->Get();
|
||||
|
||||
CGraphics::sPixelBlock.TintColor = Tint.ToVector4f();
|
||||
CGraphics::sPixelBlock.TevColor = CColor::skWhite.ToVector4f();
|
||||
CGraphics::UpdatePixelBlock();
|
||||
|
||||
if (ComponentIndex < 0)
|
||||
mpShieldModel->Draw(Options, 0);
|
||||
else
|
||||
mpShieldModel->DrawSurface(Options, ComponentIndex, 0);
|
||||
}
|
||||
|
||||
void CDoorExtra::DrawSelection()
|
||||
{
|
||||
LoadModelMatrix();
|
||||
glBlendFunc(GL_ONE, GL_ZERO);
|
||||
mpShieldModel->DrawWireframe(eNoRenderOptions, mpParent->WireframeColor());
|
||||
}
|
||||
|
||||
void CDoorExtra::RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo)
|
||||
{
|
||||
if (!mpShieldModel) return;
|
||||
if (ViewInfo.GameMode && !mpInstance->IsActive()) return;
|
||||
|
||||
const CRay& Ray = Tester.Ray();
|
||||
std::pair<bool,float> BoxResult = AABox().IntersectsRay(Ray);
|
||||
|
||||
if (BoxResult.first)
|
||||
Tester.AddNodeModel(this, mpShieldModel);
|
||||
}
|
||||
|
||||
SRayIntersection CDoorExtra::RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo)
|
||||
{
|
||||
ERenderOptions Options = ViewInfo.pRenderer->RenderOptions();
|
||||
|
||||
SRayIntersection out;
|
||||
out.pNode = mpParent;
|
||||
out.ComponentIndex = AssetID;
|
||||
|
||||
CRay TransformedRay = Ray.Transformed(Transform().Inverse());
|
||||
std::pair<bool,float> Result = mpShieldModel->GetSurface(AssetID)->IntersectsRay(TransformedRay, ((Options & eEnableBackfaceCull) == 0));
|
||||
|
||||
if (Result.first)
|
||||
{
|
||||
out.Hit = true;
|
||||
CVector3f HitPoint = TransformedRay.PointOnRay(Result.second);
|
||||
CVector3f WorldHitPoint = Transform() * HitPoint;
|
||||
out.Distance = Ray.Origin().Distance(WorldHitPoint);
|
||||
}
|
||||
|
||||
else out.Hit = false;
|
||||
|
||||
return out;
|
||||
}
|
||||
23
src/Core/ScriptExtra/CDoorExtra.h
Normal file
23
src/Core/ScriptExtra/CDoorExtra.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef CDOOREXTRA_H
|
||||
#define CDOOREXTRA_H
|
||||
|
||||
#include "CScriptExtra.h"
|
||||
|
||||
class CDoorExtra : public CScriptExtra
|
||||
{
|
||||
// Render colored door shield in MP2/3
|
||||
CFileProperty *mpShieldModelProp;
|
||||
CColorProperty *mpShieldColorProp;
|
||||
TResPtr<CModel> mpShieldModel;
|
||||
|
||||
public:
|
||||
explicit CDoorExtra(CScriptObject *pInstance, CSceneManager *pScene, CSceneNode *pParent = 0);
|
||||
void PropertyModified(CPropertyBase *pProperty);
|
||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||
void Draw(ERenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
void DrawSelection();
|
||||
void RayAABoxIntersectTest(CRayCollisionTester& Tester, const SViewInfo& ViewInfo);
|
||||
SRayIntersection RayNodeIntersectTest(const CRay &Ray, u32 AssetID, const SViewInfo& ViewInfo);
|
||||
};
|
||||
|
||||
#endif // CDOOREXTRA_H
|
||||
55
src/Core/ScriptExtra/CPointOfInterestExtra.cpp
Normal file
55
src/Core/ScriptExtra/CPointOfInterestExtra.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#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 = mpScanProperty->Get();
|
||||
}
|
||||
|
||||
void CPointOfInterestExtra::ModifyTintColor(CColor& Color)
|
||||
{
|
||||
if (mpScanData)
|
||||
{
|
||||
if (mpScanData->IsImportant()) Color *= skImportantColor;
|
||||
else Color *= skRegularColor;
|
||||
}
|
||||
}
|
||||
23
src/Core/ScriptExtra/CPointOfInterestExtra.h
Normal file
23
src/Core/ScriptExtra/CPointOfInterestExtra.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#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;
|
||||
TResPtr<CScan> mpScanData;
|
||||
|
||||
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
|
||||
49
src/Core/ScriptExtra/CScriptExtra.cpp
Normal file
49
src/Core/ScriptExtra/CScriptExtra.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "CScriptExtra.h"
|
||||
|
||||
#include "CWaypointExtra.h"
|
||||
#include "CDamageableTriggerExtra.h"
|
||||
#include "CSpacePirateExtra.h"
|
||||
#include "CPointOfInterestExtra.h"
|
||||
#include "CDoorExtra.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 0x1A: // DamageableTrigger (MP1)
|
||||
pExtra = new CDamageableTriggerExtra(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;
|
||||
|
||||
case 0x444F4F52: // "DOOR" Door (MP2/MP3)
|
||||
pExtra = new CDoorExtra(pObj, pNode->Scene(), pNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pExtra;
|
||||
}
|
||||
54
src/Core/ScriptExtra/CScriptExtra.h
Normal file
54
src/Core/ScriptExtra/CScriptExtra.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#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 CColor WireframeColor() const { return mpParent->WireframeColor(); }
|
||||
|
||||
// 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
|
||||
49
src/Core/ScriptExtra/CSpacePirateExtra.cpp
Normal file
49
src/Core/ScriptExtra/CSpacePirateExtra.cpp
Normal file
@@ -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;
|
||||
}
|
||||
20
src/Core/ScriptExtra/CSpacePirateExtra.h
Normal file
20
src/Core/ScriptExtra/CSpacePirateExtra.h
Normal file
@@ -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
|
||||
106
src/Core/ScriptExtra/CWaypointExtra.cpp
Normal file
106
src/Core/ScriptExtra/CWaypointExtra.cpp
Normal file
@@ -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 && (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
|
||||
// won't work properly 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, eDrawMesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CWaypointExtra::Draw(ERenderOptions /*Options*/, int ComponentIndex, 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[ComponentIndex].pWaypoint->AABox().Center(), mColor);
|
||||
}
|
||||
30
src/Core/ScriptExtra/CWaypointExtra.h
Normal file
30
src/Core/ScriptExtra/CWaypointExtra.h
Normal file
@@ -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 Draw(ERenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||
};
|
||||
|
||||
#endif // CWAYPOINTEXTRA_H
|
||||
Reference in New Issue
Block a user