Camera shakers and controller action scripting

This commit is contained in:
Jack Andersen 2017-03-17 19:12:27 -10:00
parent 3639cbf8e2
commit 6c9462e099
17 changed files with 399 additions and 35 deletions

View File

@ -13,9 +13,9 @@ struct ControllerAction : IScriptObject
{
DECL_YAML
String<-1> name;
Value<bool> unknown1;
Value<atUint32> unknown2;
Value<bool> unknown3;
Value<bool> active;
Value<atUint32> command;
Value<bool> deactivateOnClose;
};
}
}

View File

@ -98,7 +98,7 @@ void ViewManager::TestGameView::draw(boo::IGraphicsCommandQueue* gfxQ)
if (m_vm.m_modelTest.IsLoaded())
{
#if 1
#if 0
CModelFlags flags;
flags.m_extendedShader = EExtendedShader::Flat;
@ -177,7 +177,7 @@ void ViewManager::TestGameView::draw(boo::IGraphicsCommandQueue* gfxQ)
m_vm.m_moviePlayer->DrawFrame();
}
//m_vm.m_projManager.mainDraw();
m_vm.m_projManager.mainDraw();
++m_frame;
}
@ -405,7 +405,7 @@ bool ViewManager::proc()
if (m_rootSpaceView && m_editorFrames <= 30)
m_rootSpaceView->setMultiplyColor(zeus::CColor::lerp({1,1,1,0}, {1,1,1,1}, m_editorFrames / 30.0));
//m_projManager.mainUpdate();
m_projManager.mainUpdate();
if (g_Renderer)
g_Renderer->BeginScene();

View File

@ -349,6 +349,38 @@ CSfxHandle CSfxManager::SfxStart(u16 id, float vol, float pan, bool useAcoustics
return wrapper;
}
CSfxHandle CSfxManager::AddEmitter(u16 id, const zeus::CVector3f& pos, const zeus::CVector3f& dir, float vol,
bool useAcoustics, bool looped, s16 prio, s32 areaId)
{
CAudioSys::C3DEmitterParmData parmData;
parmData.x0_pos = pos;
parmData.xc_dir = dir;
parmData.x18_maxDist = 150.f;
parmData.x1c_distComp = 0.1f;
parmData.x20_flags = 1;
parmData.x24_sfxId = id;
parmData.x26_maxVol = std::max(vol, 0.165f);
parmData.x28_ = 0;
parmData.x29_ = 0x7f;
return AddEmitter(parmData, useAcoustics, prio, looped, areaId);
}
CSfxHandle CSfxManager::AddEmitter(const CAudioSys::C3DEmitterParmData& parmData,
bool useAcoustics, s16 prio, bool looped, s32 areaId)
{
if (m_muted || parmData.x24_sfxId == 0xffff)
return {};
CAudioSys::C3DEmitterParmData data = parmData;
if (looped)
data.x20_flags |= 0x6;
m_doUpdate = true;
CSfxHandle wrapper = std::make_shared<CSfxEmitterWrapper>(looped, prio, data, useAcoustics, areaId);
CSfxChannel& chanObj = m_channels[int(m_currentChannel)];
chanObj.x48_handles.insert(wrapper);
return wrapper;
}
void CSfxManager::StopAndRemoveAllEmitters()
{
for (int i=0 ; i<4 ; ++i)

View File

@ -200,6 +200,10 @@ public:
static u16 TranslateSFXID(u16);
static void SfxStop(const CSfxHandle& handle);
static CSfxHandle SfxStart(u16 id, float vol, float pan, bool useAcoustics, s16 prio, bool looped, s32 areaId);
static CSfxHandle AddEmitter(u16 id, const zeus::CVector3f& pos, const zeus::CVector3f& dir, float vol,
bool useAcoustics, bool looped, s16 prio, s32 areaId);
static CSfxHandle AddEmitter(const CAudioSys::C3DEmitterParmData& parmData,
bool useAcoustics, s16 prio, bool looped, s32 areaId);
static void StopAndRemoveAllEmitters();
static void DisableAuxCallback();
static void EnableAuxCallback();

View File

@ -363,6 +363,7 @@ public:
bool ShouldQuitGame() const { return xf94_25_quitGame; }
void SetInSaveUI(bool b) { xf94_28_inSaveUI = b; }
void SetInMapScreen(bool b) { xf94_27_inMapScreen = b; }
bool GetInMapScreen() const { return xf94_27_inMapScreen; }
const std::shared_ptr<CPlayerState>& GetPlayerState() const {return x8b8_playerState;}
CRandom16* GetActiveRandom() {return x900_activeRandom;}
@ -400,6 +401,7 @@ public:
bool GetIsGeneratingObject() const { return xf94_26_generatingObject; }
void SetIsGeneratingObject(bool gen) { xf94_26_generatingObject = gen; }
u32 GetParticleFlags() const { return xf34_particleFlags; }
const CFinalInput& GetFinalInput() const { return xb54_finalInput; }
};
}

View File

@ -46,18 +46,34 @@ zeus::CTransform CCameraManager::GetCurrentCameraTransform(const CStateManager&
void CCameraManager::RemoveCameraShaker(int id)
{
for (auto it = x18_shakers.begin(); it != x18_shakers.end(); ++it)
if (it->x20_shakerId == id)
for (auto it = x14_shakers.begin(); it != x14_shakers.end(); ++it)
if (it->xbc_shakerId == id)
{
x18_shakers.erase(it);
x14_shakers.erase(it);
break;
}
}
int CCameraManager::AddCameraShaker(const CCameraShakeData& data)
int CCameraManager::AddCameraShaker(const CCameraShakeData& data, bool sfx)
{
x18_shakers.emplace_back(data);
x18_shakers.back().x20_shakerId = ++x2c_lastShakeId;
x14_shakers.emplace_back(data);
x14_shakers.back().xbc_shakerId = ++x2c_lastShakeId;
if (!xa0_24_)
{
xa0_24_ = true;
x90_ = 0.5f;
}
if (sfx && data.x0_duration > 0.f)
{
float vol =zeus::clamp(100.f, std::max(data.GetSomething(), data.GetSomething2()) * 9.f + 100.f, 127.f);
CSfxHandle sfxHandle;
if (data.xc0_flags & 0x1)
sfxHandle = CSfxManager::AddEmitter(1133, data.xc4_sfxPos, zeus::CVector3f::skZero,
vol / 127.f, false, false, 0x7f, kInvalidAreaId);
else
sfxHandle = CSfxManager::SfxStart(1133, vol / 127.f, 0.f, false, 0x7f, false, kInvalidAreaId);
sfxHandle->SetTimeRemaining(data.x0_duration);
}
return x2c_lastShakeId;
}

View File

@ -23,7 +23,7 @@ class CCameraManager
static float sThirdPersonFOV;
TUniqueId x0_curCameraId;
std::vector<TUniqueId> x4_cineCameras;
std::list<CCameraShakeData> x18_shakers;
std::list<CCameraShakeData> x14_shakers;
u32 x2c_lastShakeId = 0;
zeus::CVector3f x30_shakeOffset;
CGameArea::CAreaFog x3c_fog;
@ -32,7 +32,10 @@ class CCameraManager
CFirstPersonCamera* x7c_fpCamera = nullptr;
CBallCamera* x80_ballCamera = nullptr;
s16 x84_rumbleId = -1;
float x94_;
float x90_ = 0.f;
float x94_ = 1.f;
float x98_ = 0.f;
float x9c_ = 1.f;
union
{
@ -77,7 +80,7 @@ public:
zeus::CVector3f GetGlobalCameraTranslation(const CStateManager& stateMgr) const;
zeus::CTransform GetCurrentCameraTransform(const CStateManager& stateMgr) const;
void RemoveCameraShaker(int id);
int AddCameraShaker(const CCameraShakeData& data);
int AddCameraShaker(const CCameraShakeData& data, bool sfx);
void AddCinemaCamera(TUniqueId, CStateManager& stateMgr);
void SetInsideFluid(bool, TUniqueId);
void Update(float dt, CStateManager& stateMgr);

View File

@ -1,13 +1,59 @@
#include "CCameraShakeData.hpp"
#include "CRandom16.hpp"
#include "World/ScriptLoader.hpp"
namespace urde
{
CCameraShakeData::CCameraShakeData(float xA, float xB, float yA, float yB,
float zA, float zB, float duration, bool shakeY)
: x0_pointA(xA, yA, zA), xc_pointB(xB, yB, zB), x18_duration(duration), x40_shakeY(shakeY) {}
SCameraShakePoint SCameraShakePoint::LoadCameraShakePoint(CInputStream& in)
{
u32 flags = ScriptLoader::LoadParameterFlags(in);
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
float f4 = in.readFloatBig();
return {flags, f1, f2, f3, f4};
}
CCameraShakerComponent CCameraShakerComponent::LoadNewCameraShakerComponent(CInputStream& in)
{
u32 flags = ScriptLoader::LoadParameterFlags(in);
SCameraShakePoint sp1 = SCameraShakePoint::LoadCameraShakePoint(in);
SCameraShakePoint sp2 = SCameraShakePoint::LoadCameraShakePoint(in);
return {flags, sp1, sp2};
}
CCameraShakeData::CCameraShakeData(float f1, float f2, u32 w1, const zeus::CVector3f& v1,
const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2,
const CCameraShakerComponent& shaker3)
: x0_duration(f1), x8_shaker1(shaker1), x44_shaker2(shaker2), x80_shaker3(shaker3), xc0_flags(w1), xc4_sfxPos(v1), xd0_f2(f2)
{}
float CCameraShakeData::GetSomething() const
{
float ret = 0.f;
if (x8_shaker1.x4_w1)
ret = x8_shaker1.x8_sp1.GetSomething();
if (x44_shaker2.x4_w1)
ret = std::max(ret, x44_shaker2.x8_sp1.GetSomething());
if (x80_shaker3.x4_w1)
ret = std::max(ret, x80_shaker3.x8_sp1.GetSomething());
return ret;
}
float CCameraShakeData::GetSomething2() const
{
float ret = 0.f;
if (x8_shaker1.x4_w1)
ret = x8_shaker1.x20_sp2.GetSomething();
if (x44_shaker2.x4_w1)
ret = std::max(ret, x44_shaker2.x20_sp2.GetSomething());
if (x80_shaker3.x4_w1)
ret = std::max(ret, x80_shaker3.x20_sp2.GetSomething());
return ret;
}
#if 0
zeus::CVector3f CCameraShakeData::GeneratePoint(float dt, CRandom16& r)
{
x3c_cycleTimeLeft -= dt;
@ -33,5 +79,30 @@ zeus::CVector3f CCameraShakeData::GeneratePoint(float dt, CRandom16& r)
x1c_curTime += dt;
return x24_position * zeus::CVector3f::lerp(x0_pointA, xc_pointB, interp);
}
#endif
CCameraShakeData CCameraShakeData::LoadCameraShakeData(CInputStream& in)
{
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
float f4 = in.readFloatBig();
float f5 = in.readFloatBig();
float f6 = in.readFloatBig();
float duration = in.readFloatBig();
SCameraShakePoint sp1(0, 0.f, 0.f, duration, 2.f * f1);
SCameraShakePoint sp2(0, 0.f, 0.f, duration, 2.f * f3);
SCameraShakePoint sp3(0, 0.f, 0.f, duration, 2.f * f5);
SCameraShakePoint sp4(0, 0.f, 0.f, 0.5f * duration, 3.f);
SCameraShakePoint sp5(0, 0.f, 0.f, 0.5f * duration, 0.f);
SCameraShakePoint sp6(0, 0.f, 0.f, 0.5f * duration, 3.f);
CCameraShakerComponent shaker1(1, sp1, sp4);
CCameraShakerComponent shaker2;
CCameraShakerComponent shaker3(1, sp3, sp6);
return {duration, 100.f, 0, zeus::CVector3f::skZero, shaker1, shaker2, shaker3};
}
}

View File

@ -8,22 +8,58 @@ namespace urde
{
class CRandom16;
struct SCameraShakePoint
{
friend class CCameraShakeData;
u32 x0_w1 = 0;
float x4_ = 0.f;
float x8_f4 = 0.f;
float xc_f1 = 0.f;
float x10_f2 = 0.f;
float x14_f3 = 0.f;
SCameraShakePoint() = default;
SCameraShakePoint(u32 w1, float f1, float f2, float f3, float f4)
: x0_w1(w1), x8_f4(f4), xc_f1(f1), x10_f2(f2), x14_f3(f3) {}
float GetSomething() const { return x0_w1 ? x8_f4 : x4_; }
static SCameraShakePoint LoadCameraShakePoint(CInputStream& in);
};
class CCameraShakerComponent
{
friend class CCameraShakeData;
u32 x4_w1 = 0;
SCameraShakePoint x8_sp1, x20_sp2;
float x38_ = 0.f;
public:
CCameraShakerComponent() = default;
CCameraShakerComponent(u32 w1, const SCameraShakePoint& sp1, const SCameraShakePoint& sp2)
: x4_w1(w1), x8_sp1(sp1), x20_sp2(sp2) {}
static CCameraShakerComponent LoadNewCameraShakerComponent(CInputStream& in);
};
class CCameraShakeData
{
friend class CCameraManager;
zeus::CVector3f x0_pointA;
zeus::CVector3f xc_pointB;
float x18_duration;
float x1c_curTime = 0.f;
u32 x20_shakerId = 0;
zeus::CVector3f x24_position;
zeus::CVector3f x30_velocity;
float x3c_cycleTimeLeft;
bool x40_shakeY;
float x0_duration;
float x4_ = 0.f;
CCameraShakerComponent x8_shaker1;
CCameraShakerComponent x44_shaker2;
CCameraShakerComponent x80_shaker3;
u32 xbc_shakerId = 0;
u32 xc0_flags; // 0x1: positional sfx
zeus::CVector3f xc4_sfxPos;
float xd0_f2;
public:
CCameraShakeData(float xA, float xB, float yA, float yB,
float zA, float zB, float duration, bool shakeY);
zeus::CVector3f GeneratePoint(float dt, CRandom16& r);
CCameraShakeData(float duration, float f2, u32 w1, const zeus::CVector3f& v1,
const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2,
const CCameraShakerComponent& shaker3);
//zeus::CVector3f GeneratePoint(float dt, CRandom16& r);
float GetSomething() const;
float GetSomething2() const;
void SetShakerId(u32 id) { xbc_shakerId = id; }
u32 GetShakerId() const { return xbc_shakerId; }
static CCameraShakeData LoadCameraShakeData(CInputStream& in);
};
}

View File

@ -52,7 +52,7 @@ public:
ResId GetIceSkinRulesId() const {return xac_cskrOverlay;}
const CParticleResData& GetParticleResData() const {return x44_partRes;}
u32 GetAnimationIndex(u32 idx) const { return xb0_animIdxs[idx]; }
u32 GetAnimationIndex(u32 idx) const { return xb0_animIdxs.at(idx); }
const CPASDatabase& GetPASDatabase() const { return x30_pasDatabase; }
};

View File

@ -37,7 +37,9 @@ CENTITY_TYPES = (
('CScriptAiJumpPoint', 'World/CScriptAiJumpPoint.hpp'),
('CScriptCameraHint', 'World/CScriptCameraHint.hpp'),
('CScriptCameraPitchVolume', 'World/CScriptCameraPitchVolume.hpp'),
('CScriptCameraShaker', 'World/CScriptCameraShaker.hpp'),
('CScriptCameraWaypoint', 'World/CScriptCameraWaypoint.hpp'),
('CScriptControllerAction', 'World/CScriptControllerAction.hpp'),
('CScriptCoverPoint', 'World/CScriptCoverPoint.hpp'),
('CScriptDebugCameraWaypoint', 'World/CScriptDebugCameraWaypoint.hpp'),
('CScriptDistanceFog', 'World/CScriptDistanceFog.hpp'),

View File

@ -7,6 +7,7 @@ set(WORLD_SOURCES
CPlayerEnergyDrain.hpp CPlayerEnergyDrain.cpp
CEnergyDrainSource.hpp CEnergyDrainSource.cpp
CPlayerCameraBob.hpp CPlayerCameraBob.cpp
CScriptCameraShaker.hpp CScriptCameraShaker.cpp
CMorphBall.hpp CMorphBall.cpp
CMorphBallShadow.hpp CMorphBallShadow.cpp
CActor.hpp CActor.cpp
@ -89,6 +90,7 @@ set(WORLD_SOURCES
CScriptShadowProjector.hpp CScriptShadowProjector.cpp
CScriptStreamedMusic.hpp CScriptStreamedMusic.cpp
CScriptRoomAcoustics.hpp CScriptRoomAcoustics.cpp
CScriptControllerAction.hpp CScriptControllerAction.cpp
CGrappleParameters.hpp
CActorParameters.hpp
CLightParameters.hpp

View File

@ -0,0 +1,48 @@
#include "CScriptCameraShaker.hpp"
#include "TCastTo.hpp"
#include "CStateManager.hpp"
#include "CWorld.hpp"
namespace urde
{
CScriptCameraShaker::CScriptCameraShaker(TUniqueId uid, const std::string& name, const CEntityInfo& info,
bool active, const CCameraShakeData& shakeData)
: CEntity(uid, info, active, name), x34_shakeData(shakeData)
{}
void CScriptCameraShaker::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptCameraShaker::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr)
{
switch (msg)
{
case EScriptObjectMessage::Action:
{
TAreaId aid = GetAreaIdAlways();
if (GetActive() && aid != kInvalidAreaId)
{
const CGameArea* area = stateMgr.GetWorld()->GetAreaAlways(aid);
CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded;
if (area->IsPostConstructed())
occState = area->GetPostConstructed()->x10dc_occlusionState;
if (occState == CGameArea::EOcclusionState::Occluded)
x34_shakeData.SetShakerId(stateMgr.GetCameraManager()->AddCameraShaker(x34_shakeData, false));
}
break;
}
case EScriptObjectMessage::Deactivate:
{
if (GetActive())
stateMgr.GetCameraManager()->RemoveCameraShaker(x34_shakeData.GetShakerId());
break;
}
default: break;
}
CEntity::AcceptScriptMsg(msg, objId, stateMgr);
}
}

View File

@ -0,0 +1,22 @@
#ifndef __URDE_CSCRIPTCAMERASHAKER_HPP__
#define __URDE_CSCRIPTCAMERASHAKER_HPP__
#include "CEntity.hpp"
#include "Camera/CCameraShakeData.hpp"
namespace urde
{
class CScriptCameraShaker : public CEntity
{
CCameraShakeData x34_shakeData;
public:
CScriptCameraShaker(TUniqueId uid, const std::string& name, const CEntityInfo& info,
bool active, const CCameraShakeData& shakeData);
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr);
};
}
#endif // __URDE_CSCRIPTCAMERASHAKER_HPP__

View File

@ -0,0 +1,54 @@
#include "CScriptControllerAction.hpp"
#include "TCastTo.hpp"
#include "CStateManager.hpp"
#include "Input/ControlMapper.hpp"
namespace urde
{
CScriptControllerAction::CScriptControllerAction(TUniqueId uid, const std::string& name,
const CEntityInfo& info, bool active,
ControlMapper::ECommands command, bool b1, u32 w1, bool b2)
: CEntity(uid, info, active, name), x34_command(command), x38_mapScreenSubaction(w1)
{
x3c_24_mapScreenResponse = b1;
x3c_25_deactivateOnClose = b2;
}
void CScriptControllerAction::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptControllerAction::Think(float dt, CStateManager& stateMgr)
{
bool old26 = x3c_26_pressed;
if (x3c_24_mapScreenResponse)
{
if (x38_mapScreenSubaction == 0)
x3c_26_pressed = stateMgr.GetInMapScreen();
}
else
{
x3c_26_pressed = ControlMapper::GetDigitalInput(x34_command, stateMgr.GetFinalInput());
}
if (GetActive() && x3c_26_pressed != old26)
{
if (x3c_26_pressed)
{
SendScriptMsgs(EScriptObjectState::Open, stateMgr, EScriptObjectMessage::None);
}
else
{
SendScriptMsgs(EScriptObjectState::Closed, stateMgr, EScriptObjectMessage::None);
if (x3c_25_deactivateOnClose)
{
SetActive(false);
SendScriptMsgs(EScriptObjectState::Inactive, stateMgr, EScriptObjectMessage::None);
}
}
}
}
}

View File

@ -0,0 +1,33 @@
#ifndef __URDE_CSCRIPTCONTROLLERACTION_HPP__
#define __URDE_CSCRIPTCONTROLLERACTION_HPP__
#include "CEntity.hpp"
#include "Input/ControlMapper.hpp"
namespace urde
{
class CScriptControllerAction : public CEntity
{
ControlMapper::ECommands x34_command;
u32 x38_mapScreenSubaction;
union
{
struct
{
bool x3c_24_mapScreenResponse : 1;
bool x3c_25_deactivateOnClose : 1;
bool x3c_26_pressed : 1;
};
u8 _dummy = 0;
};
public:
CScriptControllerAction(TUniqueId uid, const std::string& name, const CEntityInfo& info,
bool active, ControlMapper::ECommands command, bool b1, u32 w1, bool b2);
void Accept(IVisitor& visitor);
void Think(float, CStateManager&);
};
}
#endif // __URDE_CSCRIPTCONTROLLERACTION_HPP__

View File

@ -53,6 +53,7 @@
#include "CWallCrawlerSwarm.hpp"
#include "CScriptAiJumpPoint.hpp"
#include "CScriptColorModulate.hpp"
#include "CScriptCameraShaker.hpp"
#include "CRepulsor.hpp"
#include "CScriptCameraPitchVolume.hpp"
#include "CScriptCameraHintTrigger.hpp"
@ -67,6 +68,7 @@
#include "CScriptStreamedMusic.hpp"
#include "CScriptMidi.hpp"
#include "CScriptRoomAcoustics.hpp"
#include "CScriptControllerAction.hpp"
#include "CPatternedInfo.hpp"
#include "CSimplePool.hpp"
#include "Collision/CCollidableOBBTreeGroup.hpp"
@ -423,7 +425,7 @@ CEntity* ScriptLoader::LoadActor(CStateManager& mgr, CInputStream& in, int propC
CModelData data;
if (animType == SBIG('ANCS'))
data = CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, true, aParms.GetInitialAnimation());
data = CAnimRes(aParms.GetACSFile(), aParms.GetCharacter(), head.x40_scale, aParms.GetInitialAnimation(), true);
else
data = CStaticRes(staticId, head.x40_scale);
@ -1154,7 +1156,14 @@ CEntity* ScriptLoader::LoadDebris(CStateManager& mgr, CInputStream& in, int prop
CEntity* ScriptLoader::LoadCameraShaker(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{
return nullptr;
if (!EnsurePropertyCount(propCount, 9, "CameraShaker"))
return nullptr;
std::string name = mgr.HashInstanceName(in);
CCameraShakeData shakeData = CCameraShakeData::LoadCameraShakeData(in);
bool active = in.readBool();
return new CScriptCameraShaker(mgr.AllocateUniqueId(), name, info, active, shakeData);
}
CEntity* ScriptLoader::LoadActorKeyframe(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
@ -1835,7 +1844,22 @@ CEntity* ScriptLoader::LoadJellyZap(CStateManager& mgr, CInputStream& in, int pr
CEntity* ScriptLoader::LoadControllerAction(CStateManager& mgr, CInputStream& in, int propCount,
const CEntityInfo& info)
{
return nullptr;
if (!EnsurePropertyCount(propCount, 4, "ControllerAction") || propCount > 6)
return nullptr;
std::string name = mgr.HashInstanceName(in);
bool active = in.readBool();
ControlMapper::ECommands w1 = ControlMapper::ECommands(in.readUint32Big());
bool b1 = false;
u32 w2 = 0;
if (propCount == 6)
{
b1 = in.readBool();
w2 = in.readUint32Big();
}
bool b2 = in.readBool();
return new CScriptControllerAction(mgr.AllocateUniqueId(), name, info, active, w1, b1, w2, b2);
}
CEntity* ScriptLoader::LoadSwitch(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
@ -2291,7 +2315,22 @@ CEntity* ScriptLoader::LoadPhazonHealingNodule(CStateManager& mgr, CInputStream&
CEntity* ScriptLoader::LoadNewCameraShaker(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{
return nullptr;
if (!EnsurePropertyCount(propCount, 8, "NewCameraShaker"))
return nullptr;
std::string name = mgr.HashInstanceName(in);
zeus::CVector3f v1 = zeus::CVector3f::ReadBig(in);
bool active = in.readBool();
u32 flags = LoadParameterFlags(in);
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
CCameraShakerComponent shaker1 = CCameraShakerComponent::LoadNewCameraShakerComponent(in);
CCameraShakerComponent shaker2 = CCameraShakerComponent::LoadNewCameraShakerComponent(in);
CCameraShakerComponent shaker3 = CCameraShakerComponent::LoadNewCameraShakerComponent(in);
CCameraShakeData shakeData(f1, f2, flags, v1, shaker1, shaker2, shaker3);
return new CScriptCameraShaker(mgr.AllocateUniqueId(), name, info, active, shakeData);
}
CEntity* ScriptLoader::LoadShadowProjector(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)