Implement CScriptActorKeyframe

This commit is contained in:
Phillip Stephens 2018-05-14 14:44:09 -07:00
parent e7c3942754
commit 0c49c8ea9e
13 changed files with 148 additions and 34 deletions

View File

@ -252,6 +252,7 @@ public:
u32 GetPassedSoundPOICount() const { return x218_passedSoundCount; }
s32 GetCharacterIndex() const { return x204_charIdx; }
u16 GetDefaultAnimation() const { return x208_defaultAnim; }
};
}

View File

@ -2006,7 +2006,7 @@ CFrontEndUI::CFrontEndUI()
m->ResetGameState();
g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id));
g_GameState->CurrentWorldState().SetAreaId(0);
g_GameState->CurrentWorldState().SetAreaId(7);
g_GameState->GameOptions().ResetToDefaults();
g_GameState->WriteBackupBuf();

View File

@ -7,6 +7,7 @@
#include "CParticleElectric.hpp"
#include "Graphics/CModel.hpp"
#include "Graphics/Shaders/CElementGenShaders.hpp"
#include "Character/CActorLights.hpp"
#include "CWarp.hpp"
#define MAX_GLOBAL_PARTICLES 2560
@ -885,7 +886,7 @@ u32 CElementGen::GetSystemCount()
return (ret + (x25c_activeParticleCount != 0));
}
void CElementGen::Render()
void CElementGen::Render(const CActorLights* actorLights)
{
CGenDescription* desc = x1c_genDesc.GetObj();
@ -903,7 +904,7 @@ void CElementGen::Render()
{
SParticleModel& pmdl = desc->x5c_x48_PMDL;
if (pmdl.m_found || desc->x45_24_x31_26_PMUS)
RenderModels();
RenderModels(actorLights);
if (x26c_31_LINE)
RenderLines();
@ -914,7 +915,7 @@ void CElementGen::Render()
CParticleGlobals::g_currentParticleSystem = prevSystem;
}
void CElementGen::RenderModels()
void CElementGen::RenderModels(const CActorLights* actorLights)
{
CGenDescription* desc = x1c_genDesc.GetObj();
@ -1134,6 +1135,8 @@ void CElementGen::RenderModels()
else
{
CModel* model = desc->x5c_x48_PMDL.m_token.GetObj();
if (actorLights)
actorLights->ActivateLights(model->GetInstance());
if (g_subtractBlend)
{
model->Draw({5, 0, 1, zeus::CColor(1.f, 0.5f)});

View File

@ -23,6 +23,7 @@ class IGenDescription;
class CGenDescription;
class CParticleSwoosh;
class CParticleElectric;
class CActorLights;
class CElementGen : public CParticleGen
{
@ -203,13 +204,13 @@ public:
void SetCEXTValue(int i, float v) { x9c_cextValues[i] = v; }
bool InternalUpdate(double);
void RenderModels();
void RenderModels(const CActorLights* actLights);
void RenderLines();
void RenderParticles();
void RenderParticlesIndirectTexture();
bool Update(double);
void Render();
void Render(const CActorLights* = nullptr);
void SetOrientation(const zeus::CTransform&);
void SetTranslation(const zeus::CVector3f&);
void SetGlobalOrientation(const zeus::CTransform&);

View File

@ -625,7 +625,7 @@ bool CParticleElectric::Update(double dt)
return ret;
}
void CParticleElectric::Render()
void CParticleElectric::Render(const CActorLights*)
{
if (x3e8_electricManagers.size())
{

View File

@ -107,7 +107,7 @@ public:
CParticleElectric(const TToken<CElectricDescription>& desc);
bool Update(double);
void Render();
void Render(const CActorLights* = nullptr);
void SetOrientation(const zeus::CTransform&);
void SetTranslation(const zeus::CVector3f&);
void SetGlobalOrientation(const zeus::CTransform&);

View File

@ -12,6 +12,7 @@
namespace urde
{
class CWarp;
class CActorLights;
struct CParticle
{
@ -33,7 +34,7 @@ public:
virtual ~CParticleGen() = default;
virtual bool Update(double)=0;
virtual void Render()=0;
virtual void Render(const CActorLights* = nullptr)=0;
virtual void SetOrientation(const zeus::CTransform&)=0;
virtual void SetTranslation(const zeus::CVector3f&)=0;
virtual void SetGlobalOrientation(const zeus::CTransform&)=0;

View File

@ -978,7 +978,7 @@ void CParticleSwoosh::Render2SidedNoSplineNoGaps()
CGraphics::DrawArray(drawStart, m_cachedVerts.size() - drawStart);
}
void CParticleSwoosh::Render()
void CParticleSwoosh::Render(const CActorLights*)
{
if (x1b4_LENG < 2 || x1ac_particleCount <= 1)
return;

View File

@ -134,7 +134,7 @@ public:
CSwooshDescription* GetDesc() { return x1c_desc.GetObj(); }
bool Update(double);
void Render();
void Render(const CActorLights* = nullptr);
void SetOrientation(const zeus::CTransform&);
void SetTranslation(const zeus::CVector3f&);
void SetGlobalOrientation(const zeus::CTransform&);

View File

@ -1,19 +1,26 @@
#include "CScriptActorKeyframe.hpp"
#include "CStateManager.hpp"
#include "World/CScriptActor.hpp"
#include "World/CScriptPlatform.hpp"
#include "World/CAi.hpp"
#include "TCastTo.hpp"
namespace urde
{
CScriptActorKeyframe::CScriptActorKeyframe(TUniqueId uid, std::string_view name, const CEntityInfo& info, s32 animId,
bool b1, float f1, bool b2, u32 w2, bool active, float totalPlayback)
bool looping, float lifetime, bool b2, u32 w2, bool active, float totalPlayback)
: CEntity(uid, info, active, name)
, x34_animationId(animId)
, x38_(f1)
, x3c_(totalPlayback)
, x40_(f1)
, x38_initialLifetime(lifetime)
, x3c_playbackRate(totalPlayback)
, x40_lifetime(lifetime)
{
x44_24_ = b1;
x44_25_ = b2;
x44_24_looping = looping;
x44_25_disableUpdate = b2;
x44_26_ = w2;
x44_27_ = w2;
x44_28_ = false;
x44_29_ = false;
}
void CScriptActorKeyframe::Accept(IVisitor& visitor)
@ -21,14 +28,113 @@ void CScriptActorKeyframe::Accept(IVisitor& visitor)
visitor.Visit(this);
}
void CScriptActorKeyframe::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) {}
void CScriptActorKeyframe::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
if (msg == EScriptObjectMessage::Action)
{
if (GetActive())
{
if (!x44_25_disableUpdate)
{
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Play)
continue;
auto search = mgr.GetIdListForScript(conn.x8_objId);
for (auto it = search.first; it != search.second; ++it)
UpdateEntity(it->second, mgr);
}
}
x44_28_ = true;
SendScriptMsgs(EScriptObjectState::Play, mgr, EScriptObjectMessage::None);
}
}
else if (msg == EScriptObjectMessage::InitializedInArea)
{
if (x34_animationId == -1)
x34_animationId = 0;
}
CEntity::AcceptScriptMsg(msg, uid, mgr);
}
void CScriptActorKeyframe::Think(float dt, CStateManager& mgr)
{
if (x44_25_)
if (!x44_25_disableUpdate || !x44_24_looping || !x44_27_ || !x44_28_ || x40_lifetime <= 0.f)
{
CEntity::Think(dt, mgr);
return;
}
x40_lifetime -= dt;
if (x40_lifetime <= 0.f)
{
CEntity::Think(dt, mgr);
return;
}
x44_28_ = false;
for (const SConnection& conn : x20_conns)
{
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg!= EScriptObjectMessage::Play)
continue;
CEntity* ent = mgr.ObjectById(mgr.GetIdForScript(conn.x8_objId));
if (TCastToPtr<CScriptActor> act = ent)
{
if (act->HasModelData() && act->GetModelData()->HasAnimData())
{
CAnimData* animData = act->ModelData()->AnimationData();
if (animData->IsAdditiveAnimation(x34_animationId))
animData->DelAdditiveAnimation(x34_animationId);
if (animData->GetDefaultAnimation() == x34_animationId)
animData->EnableLooping(false);
}
}
else if (TCastToPtr<CAi> ai = ent)
{
CAnimData* animData = act->ModelData()->AnimationData();
if (animData->IsAdditiveAnimation(x34_animationId))
animData->DelAdditiveAnimation(x34_animationId);
/* TODO: Finish */
}
}
CEntity::Think(dt, mgr);
}
void CScriptActorKeyframe::UpdateEntity(TUniqueId, CStateManager&) {}
void CScriptActorKeyframe::UpdateEntity(TUniqueId uid, CStateManager& mgr)
{
CEntity* ent = mgr.ObjectById(uid);
CActor* act = nullptr;
if (TCastToPtr<CScriptActor> tmp = ent)
act = tmp;
else if (TCastToPtr<CScriptPlatform> tmp = ent)
act = tmp;
if (act)
{
if (!act->GetActive())
mgr.SendScriptMsg(act, GetUniqueId(), EScriptObjectMessage::Activate);
act->SetDrawFlags({0, 0, 3, zeus::CColor::skWhite});
if (act->HasModelData() && act->GetModelData()->HasAnimData())
{
CAnimData* animData = act->ModelData()->AnimationData();
if (animData->IsAdditiveAnimation(x34_animationId))
{
animData->AddAdditiveAnimation(x34_animationId, 1.f, x44_24_looping, x44_26_);
}
else
{
animData->SetAnimation(CAnimPlaybackParms(x34_animationId, -1, 1.f, true), false);
act->ModelData()->EnableLooping(x44_24_looping);
animData->MultiplyPlaybackRate(x3c_playbackRate);
}
}
}
/* TODO: Finish */
}
}

View File

@ -9,14 +9,14 @@ class CScriptActorKeyframe : public CEntity
{
private:
s32 x34_animationId;
float x38_;
float x3c_;
float x40_;
float x38_initialLifetime;
float x3c_playbackRate;
float x40_lifetime;
union {
struct
{
bool x44_24_ : 1;
bool x44_25_ : 1;
bool x44_24_looping : 1;
bool x44_25_disableUpdate : 1;
bool x44_26_ : 1;
bool x44_27_ : 1;
bool x44_28_ : 1;

View File

@ -275,12 +275,14 @@ void CScriptEffect::AddToRenderer(const zeus::CFrustum& frustum, const CStateMan
void CScriptEffect::Render(const CStateManager& mgr) const
{
// if (x138_actorLights)
// x138_actorLights->ActivateLights();
/* The following code is kept for reference, this is now performed in CElementGen
if (x138_actorLights)
x138_actorLights->ActivateLights();
*/
if (x104_particleSystem && x104_particleSystem->GetParticleCountAll() > 0)
{
g_NumParticlesRendered += x104_particleSystem->GetParticleCountAll();
x104_particleSystem->Render();
x104_particleSystem->Render(GetActorLights());
}
if (xf4_electric && xf4_electric->GetParticleCount() > 0)

View File

@ -1181,17 +1181,17 @@ CEntity* ScriptLoader::LoadActorKeyframe(CStateManager& mgr, CInputStream& in, i
return nullptr;
std::string name = mgr.HashInstanceName(in);
s32 w1 = in.readInt32Big();
bool b1 = in.readBool();
float f1 = in.readFloatBig();
s32 animId = in.readInt32Big();
bool looping = in.readBool();
float lifetime = in.readFloatBig();
bool active = in.readBool();
u32 w2 = in.readUint32Big();
float f2 = in.readFloatBig();
float totalPlayback = in.readFloatBig();
if (w1 == -1)
if (animId == -1)
return nullptr;
return new CScriptActorKeyframe(mgr.AllocateUniqueId(), name, info, w1, b1, f1, false, w2, active, f2);
return new CScriptActorKeyframe(mgr.AllocateUniqueId(), name, info, animId, looping, lifetime, false, w2, active, totalPlayback);
}
CEntity* ScriptLoader::LoadWater(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)