Initial CCinematicCamera implementations

This commit is contained in:
Jack Andersen 2017-11-22 16:15:09 -10:00
parent ef4a07e963
commit 41edf5a226
10 changed files with 207 additions and 113 deletions

View File

@ -2021,7 +2021,7 @@ void CStateManager::MoveDoors(float dt)
continue;
if (TCastToPtr<CAi> ai = physActor)
{
bool doThink = !xf94_29_;
bool doThink = !xf94_29_cinematicPause;
if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId)
{
const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways());
@ -2107,7 +2107,7 @@ void CStateManager::ThinkEffectsAndActors(float dt)
for (CEntity* ent : GetAllObjectList())
if (TCastToPtr<CAi> ai = ent)
{
bool doThink = !xf94_29_;
bool doThink = !xf94_29_cinematicPause;
if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId)
{
const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways());

View File

@ -220,7 +220,7 @@ private:
bool xf94_26_generatingObject : 1;
bool xf94_27_inMapScreen : 1;
bool xf94_28_inSaveUI : 1;
bool xf94_29_ : 1;
bool xf94_29_cinematicPause : 1;
bool xf94_30_fullThreat : 1;
};
u32 xf94_ = 0;
@ -442,6 +442,7 @@ public:
void SetThermalColdScale2(float s) { xf28_thermColdScale2 = s; }
float IntegrateVisorFog(float f) const;
u32 GetUpdateFrameIndex() const { return x8d8_updateFrameIdx; }
void SetCinematicPause(bool p) { xf94_29_cinematicPause = p; }
void QueueMessage(u32 frameCount, CAssetId msg, float f1)
{
xf84_ = frameCount;

View File

@ -1,16 +1,19 @@
#include "CCinematicCamera.hpp"
#include "CStateManager.hpp"
#include "Camera/CCameraManager.hpp"
#include "World/CPlayer.hpp"
#include "World/CScriptActor.hpp"
#include "TCastTo.hpp"
namespace urde
{
CCinematicCamera::CCinematicCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, float shotDuration, float fovy, float znear,
float zfar, float aspect, u32 w1)
: CGameCamera(uid, active, name, info, xf, fovy, znear, zfar, aspect, kInvalidUniqueId, w1 & 0x20, 0), x21c_w1(w1)
const zeus::CTransform& xf, bool active, float shotDuration,
float fovy, float znear, float zfar, float aspect, u32 flags)
: CGameCamera(uid, active, name, info, xf, fovy, znear, zfar, aspect, kInvalidUniqueId, flags & 0x20, 0),
x1e8_duration(shotDuration), x1f0_origFovy(fovy), x1fc_(zeus::CQuaternion(xf.basis)), x21c_flags(flags)
{
x220_24_ = false;
}
void CCinematicCamera::Accept(IVisitor& visitor)
@ -18,33 +21,75 @@ void CCinematicCamera::Accept(IVisitor& visitor)
visitor.Visit(this);
}
void CCinematicCamera::ProcessInput(const CFinalInput&, CStateManager& mgr) {}
void CCinematicCamera::ProcessInput(const CFinalInput&, CStateManager& mgr)
{
// Empty
}
void CCinematicCamera::Reset(const zeus::CTransform&, CStateManager& mgr) {}
void CCinematicCamera::Reset(const zeus::CTransform&, CStateManager& mgr)
{
// Empty
}
void CCinematicCamera::WasDeactivated(CStateManager& mgr)
{
mgr.GetCameraManager()->RemoveCinemaCamera(GetUniqueId(), mgr);
mgr.GetPlayer().GetMorphBall()->LoadMorphBallModel(mgr);
if (x21c_flags & 0x100)
mgr.SetCinematicPause(false);
x188_.clear();
x198_.clear();
x1a8_.clear();
x1b8_.clear();
x1c8_.clear();
x1d8_.clear();
}
void CCinematicCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
CGameCamera::AcceptScriptMsg(msg, uid, mgr);
if (msg == EScriptObjectMessage::Activate)
switch (msg)
{
case EScriptObjectMessage::InitializedInArea:
if (x21c_flags & 0x4 || x21c_flags & 0x2)
{
for (const SConnection& conn : x20_conns)
{
TUniqueId id = mgr.GetIdForScript(conn.x8_objId);
if (TCastToPtr<CScriptActor> act = mgr.ObjectById(id))
{
if (act->GetX2E3_24())
{
x20c_lookAtId = id;
if (conn.x4_msg != EScriptObjectMessage::Deactivate &&
conn.x4_msg != EScriptObjectMessage::Reset)
break;
}
}
}
}
break;
case EScriptObjectMessage::Activate:
CalculateWaypoints(mgr);
if (x21c_w1 & 1)
{
}
}
else if (msg == EScriptObjectMessage::Deactivate)
{
if ((x21c_flags & 1) == 0 && x220_24_ && x1b8_.empty())
break;
x1ec_ = 0.f;
Think(0.f, mgr);
mgr.GetCameraManager()->AddCinemaCamera(GetUniqueId(), mgr);
x1f4_ = 0;
if (x1a8_.size() > 0)
SendArrivedMsg(x1a8_[x1f4_], mgr);
x1f8_ = 0;
if (x1c8_.size() > 0)
SendArrivedMsg(x1c8_[x1f8_], mgr);
if (x21c_flags & 0x100)
mgr.SetCinematicPause(true);
break;
case EScriptObjectMessage::Deactivate:
WasDeactivated(mgr);
}
else if (msg == EScriptObjectMessage::InitializedInArea)
{
break;
default:
break;
}
}

View File

@ -8,16 +8,32 @@ namespace urde
class CCinematicCamera : public CGameCamera
{
u32 x21c_w1;
std::vector<zeus::CVector3f> x188_;
std::vector<zeus::CQuaternion> x198_;
std::vector<TUniqueId> x1a8_;
std::vector<zeus::CVector3f> x1b8_;
std::vector<TUniqueId> x1c8_;
std::vector<float> x1d8_;
float x1e8_duration;
float x1ec_ = 0.f;
float x1f0_origFovy;
u32 x1f4_ = 0;
u32 x1f8_ = 0;
zeus::CQuaternion x1fc_;
TUniqueId x20c_lookAtId = kInvalidUniqueId;
zeus::CVector3f x210_;
u32 x21c_flags;
bool x220_24_;
public:
CCinematicCamera(TUniqueId, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, bool, float, float, float, float, float, u32 w1);
CCinematicCamera(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, float shotDuration,
float fovy, float znear, float zfar, float aspect, u32 flags);
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr);
void ProcessInput(const CFinalInput&, CStateManager& mgr);
void Reset(const zeus::CTransform&, CStateManager& mgr);
u32 GetW1() const { return x21c_w1; }
u32 GetFlags() const { return x21c_flags; }
void WasDeactivated(CStateManager& mgr);
void CalculateWaypoints(CStateManager& mgr);
void SendArrivedMsg(TUniqueId reciever, CStateManager& mgr);

View File

@ -41,7 +41,7 @@ CIOWin::EMessageReturn CMFGame::OnMessage(const CArchitectureMessage& msg, CArch
const CEntity* cam = x14_stateManager->GetCameraManager()->GetCurrentCamera(*x14_stateManager);
TCastToConstPtr<CCinematicCamera> cineCam = cam;
if ((x20_cineSkipTime >= 1.f && x14_stateManager->SpecialSkipCinematic()) || !cineCam ||
(cineCam->GetW1() & 0x10 && x28_skippedCineCam != cineCam->GetUniqueId()))
(cineCam->GetFlags() & 0x10 && x28_skippedCineCam != cineCam->GetUniqueId()))
{
static_cast<CMain&>(*g_Main).SetScreenFading(false);
x1c_flowState = EGameFlowState::InGame;

View File

@ -1332,7 +1332,7 @@ void CPlayer::Render(const CStateManager& mgr) const
bool doRender = x2f4_cameraState != EPlayerCameraState::Spawned;
if (!doRender)
if (TCastToConstPtr<CCinematicCamera> cam = mgr.GetCameraManager()->GetCurrentCamera(mgr))
doRender = (x2f8_morphBallState == EPlayerMorphBallState::Morphed && cam->GetW1() & 0x40);
doRender = (x2f8_morphBallState == EPlayerMorphBallState::Morphed && cam->GetFlags() & 0x40);
if (x2f4_cameraState != EPlayerCameraState::FirstPerson && doRender)
{
bool doTransitionRender = false;
@ -1911,7 +1911,7 @@ bool CPlayer::ShouldSampleFailsafe(CStateManager& mgr) const
TCastToPtr<CCinematicCamera> cineCam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
if (!mgr.GetPlayerState()->IsPlayerAlive())
return false;
return x2f4_cameraState != EPlayerCameraState::Spawned || !cineCam || (cineCam->GetW1() & 0x80) == 0;
return x2f4_cameraState != EPlayerCameraState::Spawned || !cineCam || (cineCam->GetFlags() & 0x80) == 0;
}
void CPlayer::CalculateLeaveMorphBallDirection(const CFinalInput& input)
@ -6301,7 +6301,7 @@ void CPlayer::SetCameraState(EPlayerCameraState camState, CStateManager& stateMg
{
bool ballLight = false;
if (TCastToPtr<CCinematicCamera> cineCam = camMgr->GetCurrentCamera(stateMgr))
ballLight = x2f8_morphBallState == EPlayerMorphBallState::Morphed && cineCam->GetW1() & 0x40;
ballLight = x2f8_morphBallState == EPlayerMorphBallState::Morphed && cineCam->GetFlags() & 0x40;
x768_morphball->SetBallLightActive(stateMgr, ballLight);
break;
}

View File

@ -30,6 +30,7 @@ CScriptActor::CScriptActor(TUniqueId uid, std::string_view name, const CEntityIn
, x2e2_29_((x2e2_24_ && x2e2_25_dead && x2d8_ != 0))
, x2e2_30_transposeRotate(b4)
, x2e2_31_(b5)
, x2e3_24_(false)
{
if (x64_modelData && (x64_modelData->HasAnimData() || x64_modelData->HasNormalModel()) && castsShadow)
CreateShadow(true);

View File

@ -44,7 +44,8 @@ public:
void Touch(CActor&, CStateManager&);
const CDamageVulnerability* GetDamageVulnerability() const { return &x268_damageVulnerability; }
CHealthInfo* HealthInfo(CStateManager&) { return &x260_currentHealth; }
bool GetX2E3_24() const { return x2e3_24_; }
};
};
}
#endif // __URDE_CSCRIPTACTOR_HPP__

View File

@ -1,14 +1,10 @@
#include "CScriptTrigger.hpp"
#include "Character/CModelData.hpp"
#include "CActorParameters.hpp"
#include "Collision/CMaterialList.hpp"
#include "CStateManager.hpp"
#include "TCastTo.hpp"
#include "World/CPlayer.hpp"
#include "Weapon/CGameProjectile.hpp"
#include "Weapon/CWeapon.hpp"
#include "Particle/CGenDescription.hpp"
#include "CPlayerState.hpp"
#include "Camera/CGameCamera.hpp"
namespace urde
{
@ -47,9 +43,9 @@ void CScriptTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CS
x148_25_camSubmerged = false;
}
if (x148_28_)
if (x148_28_playerDamage)
{
x148_28_ = false;
x148_28_playerDamage = false;
if (x148_29_didPhazonDamage)
{
mgr.Player()->DecrementPhazon();
@ -76,32 +72,36 @@ CScriptTrigger::CObjectTracker* CScriptTrigger::FindObject(TUniqueId id)
void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr)
{
#if 0
bool inhabitantExited = false;
bool player = false;
for (auto it = xe8_inhabitants.begin(); it != xe8_inhabitants.end();)
bool sendInside = false;
bool sendExited = false;
std::list<CObjectTracker>::iterator nextIt;
for (auto it = xe8_inhabitants.begin(); it != xe8_inhabitants.end(); it = nextIt)
{
TCastToPtr<CActor> act(mgr.ObjectById((*it).GetObjectId()));
if (act->GetUniqueId() == mgr.Player()->GetUniqueId())
nextIt = it;
++nextIt;
if (TCastToPtr<CActor> act = mgr.ObjectById(it->GetObjectId()))
{
TCastToPtr<CPlayer> pl(act);
if (bool(x12c_flags & ETriggerFlags::DetectPlayer))
bool playerValid = true;
if (it->GetObjectId() == mgr.GetPlayer().GetUniqueId())
{
player = true;
using EPlayerMorphBallState = CPlayer::EPlayerMorphBallState;
EPlayerMorphBallState mState = pl->GetMorphballTransitionState();
if ((mState == EPlayerMorphBallState::Morphed &&
bool(x12c_flags & ETriggerFlags::DetectMorphedPlayer)) ||
(mState == EPlayerMorphBallState::Unmorphed &&
bool(x12c_flags & ETriggerFlags::DetectUnmorphedPlayer)))
if ((x12c_flags & ETriggerFlags::DetectPlayer) == ETriggerFlags::None &&
((mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed &&
(x12c_flags & ETriggerFlags::DetectUnmorphedPlayer) != ETriggerFlags::None) ||
(mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed &&
(x12c_flags & ETriggerFlags::DetectMorphedPlayer) != ETriggerFlags::None)))
{
it = xe8_inhabitants.erase(it);
if (x148_28_)
playerValid = false;
}
if (!playerValid)
{
x148_28_ = false;
xe8_inhabitants.erase(it);
sendExited = true;
if (x148_28_playerDamage)
{
x148_28_playerDamage = false;
if (x148_29_didPhazonDamage)
{
mgr.Player()->DecrementPhazon();
mgr.GetPlayer().DecrementPhazon();
x148_29_didPhazonDamage = false;
}
@ -114,97 +114,127 @@ void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr)
}
}
const auto& touchBounds = GetTouchBounds();
const auto& actTouchBounds = act->GetTouchBounds();
if (touchBounds && actTouchBounds)
auto touchBounds = GetTouchBounds();
auto actTouchBounds = act->GetTouchBounds();
if (touchBounds && actTouchBounds && touchBounds->intersects(*actTouchBounds))
{
if (actTouchBounds->intersects(*touchBounds))
{
inhabitantExited = true;
sendInside = true;
InhabitantIdle(*act, mgr);
if (act->HealthInfo() && x100_damageInfo.GetDamage() > 0.f)
if (act->HealthInfo(mgr) && x100_damageInfo.GetDamage() > 0.f)
mgr.ApplyDamage(GetUniqueId(), act->GetUniqueId(), GetUniqueId(), x100_damageInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}));
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}),
zeus::CVector3f::skZero);
TCastToPtr<CPhysicsActor> physAct{act};
if (physAct)
if (x128_forceMagnitude > 0.f)
{
if (TCastToPtr<CPhysicsActor> pact = act.GetPtr())
{
float forceMult = 1.f;
if (bool(x12c_flags & ETriggerFlags::UseBooleanIntersection))
if ((x12c_flags & ETriggerFlags::UseBooleanIntersection) != ETriggerFlags::None)
forceMult =
touchBounds->booleanIntersection(*actTouchBounds).volume() / actTouchBounds->volume();
zeus::CVector3f force = forceMult * x11c_forceField;
if (bool(x12c_flags & ETriggerFlags::UseCollisionImpulses))
if ((x12c_flags & ETriggerFlags::UseCollisionImpulses) != ETriggerFlags::None)
{
physAct->ApplyImpulseWR(force, zeus::CAxisAngle::sIdentity);
physAct->UseCollisionImpulses();
pact->ApplyImpulseWR(force, zeus::CAxisAngle::sIdentity);
pact->UseCollisionImpulses();
}
else
physAct->ApplyForceWR(force, zeus::CAxisAngle::sIdentity);
pact->ApplyForceWR(force, zeus::CAxisAngle::sIdentity);
}
}
}
else
{
it = xe8_inhabitants.erase(it);
if (mgr.Player()->GetUniqueId() == (*it).GetObjectId())
xe8_inhabitants.erase(it);
sendExited = true;
if (mgr.GetPlayer().GetUniqueId() == it->GetObjectId() && x148_28_playerDamage)
{
if (x148_28_)
{
x148_28_ = false;
x148_28_playerDamage = false;
if (x148_29_didPhazonDamage)
{
mgr.Player()->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
}
}
if (mgr.GetLastTriggerId() == GetUniqueId())
mgr.SetLastTriggerId(kInvalidUniqueId);
}
InhabitantExited(*act, mgr);
continue;
}
}
else
{
it = xe8_inhabitants.erase(it);
if (mgr.Player()->GetUniqueId() == (*it).GetObjectId())
xe8_inhabitants.erase(it);
if (mgr.GetPlayer().GetUniqueId() == it->GetObjectId() && x148_28_playerDamage)
{
if (x148_28_)
{
x148_28_ = false;
x148_28_playerDamage = false;
if (x148_29_didPhazonDamage)
{
mgr.Player()->DecrementPhazon();
x148_29_didPhazonDamage = false;
}
}
}
if (mgr.GetLastTriggerId() == GetUniqueId())
mgr.SetLastTriggerId(kInvalidUniqueId);
}
}
if (bool(x12c_flags & ETriggerFlags::DetectPlayerIfInside) && x148_24_playerInside && !inhabitantExited)
{
SendScriptMsgs(EScriptObjectState::Inside, mgr, EScriptObjectMessage::None);
return;
}
if (!player)
if ((x12c_flags & ETriggerFlags::DetectPlayerIfInside) != ETriggerFlags::None || x148_24_playerInside)
{
SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::None);
CGameCamera* cam = mgr.GetCameraManager()->GetCurrentCamera(mgr);
bool camInTrigger = GetTriggerBoundsWR().pointInside(cam->GetTranslation());
if (x148_25_camSubmerged)
{
if (!camInTrigger)
{
x148_25_camSubmerged = false;
if ((x12c_flags & ETriggerFlags::DetectPlayerIfInside) != ETriggerFlags::None)
{
sendExited = true;
InhabitantExited(*cam, mgr);
}
}
else
{
if ((x12c_flags & ETriggerFlags::DetectPlayerIfInside) != ETriggerFlags::None)
{
InhabitantIdle(*cam, mgr);
sendInside = true;
}
}
}
else
{
if (camInTrigger)
{
x148_25_camSubmerged = true;
if ((x12c_flags & ETriggerFlags::DetectPlayerIfInside) != ETriggerFlags::None)
{
InhabitantAdded(*cam, mgr);
SendScriptMsgs(EScriptObjectState::Entered, mgr, EScriptObjectMessage::Activate);
}
}
}
}
if (sendInside)
{
SendScriptMsgs(EScriptObjectState::Inside, mgr, EScriptObjectMessage::Activate);
}
if (sendExited)
{
SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::Activate);
if (x148_27_deactivateOnExited)
{
mgr.SendScriptMsg(GetUniqueId(), mgr.GetEditorIdForUniqueId(GetUniqueId()),
EScriptObjectMessage::Deactivate, EScriptObjectState::Exited);
}
}
#endif
}
std::list<CScriptTrigger::CObjectTracker>& CScriptTrigger::GetInhabitants() { return xe8_inhabitants; }
@ -266,9 +296,9 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr)
if (pl)
{
if (!x148_28_)
if (!x148_28_playerDamage)
{
x148_28_ = true;
x148_28_playerDamage = true;
if (x148_29_didPhazonDamage)
{
mgr.Player()->DecrementPhazon();

View File

@ -61,7 +61,7 @@ protected:
bool x148_25_camSubmerged : 1;
bool x148_26_deactivateOnEntered : 1;
bool x148_27_deactivateOnExited : 1;
bool x148_28_ : 1;
bool x148_28_playerDamage : 1;
bool x148_29_didPhazonDamage : 1;
};
u8 dummy = 0;