Work on CScriptCameraHint and CCameraManager

This commit is contained in:
Jack Andersen 2017-10-05 21:29:56 -10:00
parent c46010256c
commit 0f68e2ba3f
18 changed files with 762 additions and 118 deletions

View File

@ -27,10 +27,10 @@ struct CTweakGame final : ITweakGame
Value<float> x44_rippleIntentityPoison; Value<float> x44_rippleIntentityPoison;
Value<float> x48_rippleIntensityLava; Value<float> x48_rippleIntensityLava;
Value<float> x4c_fluidEnvBumpScale; Value<float> x4c_fluidEnvBumpScale;
Value<float> x50_unknown14; Value<float> x50_waterFogDistanceBase;
Value<float> x54_unknown15; Value<float> x54_waterFogDistanceRange;
Value<float> x58_unknown16; Value<float> x58_gravityWaterFogDistanceBase;
Value<float> x5c_unknown17; Value<float> x5c_gravityWaterFogDistanceRange;
Value<float> x60_hardmodeDamageMult; Value<float> x60_hardmodeDamageMult;
Value<float> x64_hardmodeWeaponMult; Value<float> x64_hardmodeWeaponMult;

View File

@ -40,4 +40,34 @@ void CBallCamera::TeleportCamera(const zeus::CVector3f& pos, CStateManager& mgr)
} }
void CBallCamera::TeleportCamera(const zeus::CTransform& xf, CStateManager& mgr)
{
}
void CBallCamera::ResetToTweaks(CStateManager& mgr)
{
}
void CBallCamera::UpdateLookAtPosition(float offset, CStateManager& mgr)
{
}
zeus::CTransform CBallCamera::UpdateLookDirection(const zeus::CVector3f& dir, CStateManager& mgr)
{
return {};
}
void CBallCamera::ApplyCameraHint(CStateManager& mgr)
{
}
void CBallCamera::ResetPosition()
{
}
} }

View File

@ -20,22 +20,45 @@ public:
}; };
enum class EBallCameraBehaviour enum class EBallCameraBehaviour
{ {
Zero,
One,
Two,
Three,
Four,
Five,
Six,
Seven,
Eight
}; };
private: private:
zeus::CVector3f x1d8_;
TUniqueId x3dc_tooCloseActorId = kInvalidUniqueId; TUniqueId x3dc_tooCloseActorId = kInvalidUniqueId;
float x3e0_ = 10000.f; float x3e0_ = 10000.f;
EBallCameraState x400_state;
float x470_;
float x474_;
public: public:
CBallCamera(TUniqueId, TUniqueId, const zeus::CTransform& xf, float, float, float, float); CBallCamera(TUniqueId, TUniqueId, const zeus::CTransform& xf, float, float, float, float);
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);
void ProcessInput(const CFinalInput&, CStateManager& mgr); void ProcessInput(const CFinalInput&, CStateManager& mgr);
void Reset(const zeus::CTransform&, CStateManager& mgr); void Reset(const zeus::CTransform&, CStateManager& mgr);
EBallCameraState GetState() const { return x400_state; }
void SetState(EBallCameraState state, CStateManager& mgr); void SetState(EBallCameraState state, CStateManager& mgr);
bool TransitionFromMorphBallState(CStateManager& mgr); bool TransitionFromMorphBallState(CStateManager& mgr);
TUniqueId GetTooCloseActorId() const { return x3dc_tooCloseActorId; } TUniqueId GetTooCloseActorId() const { return x3dc_tooCloseActorId; }
float GetX3E0() const { return x3e0_; } float GetX3E0() const { return x3e0_; }
void TeleportCamera(const zeus::CVector3f& pos, CStateManager& mgr); void TeleportCamera(const zeus::CVector3f& pos, CStateManager& mgr);
void TeleportCamera(const zeus::CTransform& xf, CStateManager& mgr);
const zeus::CVector3f& GetX1D8() const { return x1d8_; }
void ResetToTweaks(CStateManager& mgr);
void UpdateLookAtPosition(float offset, CStateManager& mgr);
zeus::CTransform UpdateLookDirection(const zeus::CVector3f& dir, CStateManager& mgr);
void SetX470(float f) { x470_ = f; }
void SetX474(float f) { x474_ = f; }
void ApplyCameraHint(CStateManager& mgr);
void ResetPosition();
}; };
} }

View File

@ -10,6 +10,8 @@
#include "CBallCamera.hpp" #include "CBallCamera.hpp"
#include "CInterpolationCamera.hpp" #include "CInterpolationCamera.hpp"
#include "World/CScriptCameraHint.hpp" #include "World/CScriptCameraHint.hpp"
#include "CPathCamera.hpp"
#include "World/CScriptSpindleCamera.hpp"
namespace urde namespace urde
{ {
@ -58,10 +60,10 @@ int CCameraManager::AddCameraShaker(const CCameraShakeData& data, bool sfx)
{ {
x14_shakers.emplace_back(data); x14_shakers.emplace_back(data);
x14_shakers.back().xbc_shakerId = ++x2c_lastShakeId; x14_shakers.back().xbc_shakerId = ++x2c_lastShakeId;
if (!xa0_24_) if (!xa0_24_pendingRumble)
{ {
xa0_24_ = true; xa0_24_pendingRumble = true;
x90_ = 0.5f; x90_rumbleCooldown = 0.5f;
} }
if (sfx && data.x0_duration > 0.f) if (sfx && data.x0_duration > 0.f)
{ {
@ -97,65 +99,6 @@ void CCameraManager::Update(float dt, CStateManager& stateMgr)
UpdateListener(stateMgr); UpdateListener(stateMgr);
UpdateRumble(dt, stateMgr); UpdateRumble(dt, stateMgr);
UpdateFog(dt, stateMgr); UpdateFog(dt, stateMgr);
#if 0
const CGameCamera* camera = GetCurrentCamera(stateMgr);
zeus::CVector3f heading = camera->GetTransform().basis * zeus::CVector3f{0.f, 1.f, 0.f};
CSfxManager::UpdateListener(camera->GetTransform().origin, zeus::CVector3f::skZero, heading, {0.f, 0.f, 1.f}, 0x7f);
x30_shakeOffset = zeus::CVector3f::skZero;
for (auto it = x18_shakers.begin(); it != x18_shakers.end();)
{
if (it->x1c_curTime >= it->x18_duration)
{
it = x18_shakers.erase(it);
continue;
}
x30_shakeOffset += it->GeneratePoint(dt, *stateMgr.GetActiveRandom());
++it;
}
if (x18_shakers.size())
{
if (!xa0_25_rumbling || xa0_24_)
{
stateMgr.GetRumbleManager().Rumble(ERumbleFxId::Seven, stateMgr, ERumblePriority::Two);
xa0_25_rumbling = true;
}
}
else
{
xa0_25_rumbling = false;
if (x84_rumbleId != -1)
{
stateMgr.GetRumbleManager().StopRumble(x84_rumbleId);
x84_rumbleId = -1;
}
}
if (x74_fluidCounter)
{
const CScriptWater* water = TCastToConstPtr<CScriptWater>(stateMgr.GetObjectById(x78_fluidId));
if (water)
{
// TODO: Finish
zeus::CColor tmpColor; // Get from water
zeus::CVector2f tmpVector; // Get from camera
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, tmpColor, tmpVector);
stateMgr.GetCameraFilterPass(4).SetFilter(EFilterType::Multiply,
CCameraFilterPass::EFilterShape::Fullscreen, 0.f, tmpColor, -1);
}
xa0_26_inWater = true;
}
else
{
xa0_26_inWater = false;
x3c_fog.DisableFog();
stateMgr.GetCameraFilterPass(4).DisableFilter(dt);
}
x3c_fog.Update(dt);
#endif
} }
CGameCamera* CCameraManager::GetCurrentCamera(CStateManager& stateMgr) const CGameCamera* CCameraManager::GetCurrentCamera(CStateManager& stateMgr) const
@ -210,9 +153,359 @@ float CCameraManager::sub80009148() const
std::cos(zeus::degToRad(30.f))), 1.f); std::cos(zeus::degToRad(30.f))), 1.f);
} }
void CCameraManager::SetPathCamera(TUniqueId id, CStateManager& mgr)
{
xa4_pathCamId = id;
if (TCastToPtr<CPathCamera> cam = mgr.ObjectById(id))
{
cam->Reset(GetCurrentCameraTransform(mgr), mgr);
x80_ballCamera->TeleportCamera(cam->GetTransform(), mgr);
}
}
void CCameraManager::SetSpindleCamera(TUniqueId id, CStateManager& mgr)
{
xa2_spindleCamId = id;
if (TCastToPtr<CScriptSpindleCamera> cam = mgr.ObjectById(id))
{
cam->Reset(GetCurrentCameraTransform(mgr), mgr);
x80_ballCamera->TeleportCamera(cam->GetTransform(), mgr);
}
}
void CCameraManager::InterpolateToBallCamera(const zeus::CTransform& xf, TUniqueId camId,
const zeus::CVector3f& lookDir, float f1, float f2, float f3,
bool b1, CStateManager& mgr)
{
if (!IsInFirstPersonCamera())
{
x88_interpCamera->SetInterpolation(xf, lookDir, f1, f2, f3, camId, b1, mgr);
if (!ShouldBypassInterpolation())
SetCurrentCameraId(x88_interpCamera->GetUniqueId(), mgr);
}
}
void CCameraManager::RestoreHintlessCamera(CStateManager& mgr)
{
TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(xa6_camHintId);
zeus::CTransform ballCamXf = x80_ballCamera->GetTransform();
xa6_camHintId = kInvalidUniqueId;
xa8_hintPriority = 1000;
if (hint)
{
zeus::CVector3f camToPlayerFlat = mgr.GetPlayer().GetTranslation() - ballCamXf.origin;
camToPlayerFlat.z = 0.f;
if (camToPlayerFlat.canBeNormalized())
camToPlayerFlat.normalize();
else
camToPlayerFlat = mgr.GetPlayer().GetMoveDir();
x80_ballCamera->ResetToTweaks(mgr);
x80_ballCamera->UpdateLookAtPosition(0.f, mgr);
if (!mgr.GetPlayer().IsMorphBallTransitioning() &&
hint->GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Zero)
{
if ((hint->GetHint().GetOverrideFlags() & 0x1000) != 0)
{
x80_ballCamera->SetX474(hint->GetHint().GetX4C());
x80_ballCamera->SetX470(hint->GetHint().GetX5C());
}
else
{
x80_ballCamera->TeleportCamera(x80_ballCamera->UpdateLookDirection(camToPlayerFlat, mgr), mgr);
InterpolateToBallCamera(ballCamXf, x80_ballCamera->GetUniqueId(), x80_ballCamera->GetX1D8(),
hint->GetHint().GetX5C(), hint->GetHint().GetX4C(), hint->GetHint().GetX50(),
((hint->GetHint().GetOverrideFlags() >> 11) & 0x1) != 0, mgr);
}
}
}
}
void CCameraManager::SkipBallCameraCinematic(CStateManager& mgr)
{
if (IsInCinematicCamera())
{
x80_ballCamera->TeleportCamera(GetLastCineCamera(mgr)->GetTransform(), mgr);
x80_ballCamera->SetFovInterpolation(GetLastCineCamera(mgr)->GetFov(), x80_ballCamera->GetFov(), 1.f, 0.f);
SkipCinematic(mgr);
SetCurrentCameraId(x80_ballCamera->GetUniqueId(), mgr);
}
}
void CCameraManager::ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr)
{
if (x80_ballCamera->GetState() == CBallCamera::EBallCameraState::Four)
{
x80_ballCamera->SetState(CBallCamera::EBallCameraState::Zero, mgr);
mgr.GetPlayer().SetCameraState(CPlayer::EPlayerCameraState::Ball, mgr);
}
TCastToPtr<CScriptCameraHint> oldHint = mgr.ObjectById(xa6_camHintId);
xa6_camHintId = hint.GetUniqueId();
xa8_hintPriority = hint.GetPriority();
zeus::CTransform camXf = GetCurrentCameraTransform(mgr);
x80_ballCamera->ApplyCameraHint(mgr);
if ((hint.GetHint().GetOverrideFlags() & 0x20) != 0)
x80_ballCamera->ResetPosition();
switch (hint.GetHint().GetBehaviourType())
{
case CBallCamera::EBallCameraBehaviour::Six:
case CBallCamera::EBallCameraBehaviour::Seven:
SetPathCamera(hint.GetDelegatedCamera(), mgr);
break;
case CBallCamera::EBallCameraBehaviour::Eight:
SetSpindleCamera(hint.GetDelegatedCamera(), mgr);
break;
default:
SetPathCamera(kInvalidUniqueId, mgr);
SetSpindleCamera(kInvalidUniqueId, mgr);
break;
}
if ((hint.GetHint().GetOverrideFlags() & 0x2000) != 0)
SkipBallCameraCinematic(mgr);
x80_ballCamera->UpdateLookAtPosition(0.f, mgr);
if ((hint.GetHint().GetOverrideFlags() & 0x20) == 0 &&
(hint.GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Zero ||
(oldHint && oldHint->GetHint().GetBehaviourType() != CBallCamera::EBallCameraBehaviour::Zero)))
{
InterpolateToBallCamera(camXf, x80_ballCamera->GetUniqueId(), x80_ballCamera->GetX1D8(),
hint.GetHint().GetX58(), hint.GetHint().GetX4C(), hint.GetHint().GetX50(),
((hint.GetHint().GetOverrideFlags() >> 10) & 0x1) != 0, mgr);
}
}
void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) void CCameraManager::UpdateCameraHints(float, CStateManager& mgr)
{ {
bool r27 = false;
for (auto it = xac_cameraHints.begin() ; it != xac_cameraHints.end() ;)
{
if (!TCastToPtr<CScriptCameraHint>(mgr.ObjectById(it->second)))
{
r27 = true;
it = xac_cameraHints.erase(it);
continue;
}
++it;
}
bool r26 = false;
for (TUniqueId id : x2b0_inactiveCameraHints)
{
if (TCastToConstPtr<CScriptCameraHint> hint = mgr.GetObjectById(id))
{
if (hint->GetHelperCount() == 0 || hint->GetInactive())
{
for (auto it = xac_cameraHints.begin() ; it != xac_cameraHints.end() ; ++it)
{
if (it->second == id)
{
xac_cameraHints.erase(it);
if (xa6_camHintId == id)
{
r26 = true;
SetPathCamera(kInvalidUniqueId, mgr);
SetSpindleCamera(kInvalidUniqueId, mgr);
}
break;
}
}
}
}
}
x2b0_inactiveCameraHints.clear();
bool r25 = false;
for (TUniqueId id : x334_activeCameraHints)
{
if (TCastToConstPtr<CScriptCameraHint> hint = mgr.GetObjectById(id))
{
bool newActiveHint = false;
for (auto it = xac_cameraHints.begin() ; it != xac_cameraHints.end() ; ++it)
{
if (it->second == id)
{
newActiveHint = true;
break;
}
}
if (!newActiveHint)
{
r25 = true;
xac_cameraHints.emplace_back(hint->GetPriority(), id);
}
}
}
x334_activeCameraHints.clear();
if (r26 || r25 || r27)
{
std::sort(xac_cameraHints.begin(), xac_cameraHints.end(),
[](const auto& a, const auto& b) { return a.first < b.first; });
zeus::CTransform ballCamXf = x80_ballCamera->GetTransform();
if ((r26 || r27) && xac_cameraHints.empty())
{
RestoreHintlessCamera(mgr);
return;
}
bool r26b = false;
CScriptCameraHint* foundHint = nullptr;
for (auto& h : xac_cameraHints)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(h.second))
{
foundHint = hint.GetPtr();
r26b = true;
break;
}
}
if (!r26b)
RestoreHintlessCamera(mgr);
bool r25b = false;
if (foundHint && r26b)
{
if ((foundHint->GetHint().GetOverrideFlags() & 0x80) != 0 && xac_cameraHints.size() > 1)
{
zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition();
if ((foundHint->GetHint().GetOverrideFlags() & 0x100) != 0)
{
zeus::CVector3f camToBall = ballPos - ballCamXf.origin;
if (camToBall.canBeNormalized())
camToBall.normalize();
else
camToBall = ballCamXf.basis[1];
for (auto it = xac_cameraHints.begin() + 1 ; it != xac_cameraHints.end() ; ++it)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(it->second))
{
if ((hint->GetHint().GetOverrideFlags() & 0x80) != 0 && hint->GetPriority() ==
foundHint->GetPriority() &&
hint->GetAreaIdAlways() == foundHint->GetAreaIdAlways())
{
zeus::CVector3f hintToBall = ballPos - foundHint->GetTranslation();
if (hintToBall.canBeNormalized())
hintToBall.normalize();
else
hintToBall = foundHint->GetTransform().basis[1];
float camHintDot = zeus::clamp(-1.f, camToBall.dot(hintToBall), 1.f);
zeus::CVector3f thisHintToBall = ballPos - hint->GetTranslation();
if (thisHintToBall.canBeNormalized())
thisHintToBall.normalize();
else
thisHintToBall = hint->GetTransform().basis[1];
float camThisHintDot = zeus::clamp(-1.f, camToBall.dot(thisHintToBall), 1.f);
if (camThisHintDot > camHintDot)
foundHint = hint.GetPtr();
}
else
{
break;
}
}
else
{
break;
}
}
}
else
{
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(foundHint->GetFirstHelper()))
{
zeus::CVector3f ballPos = mgr.GetPlayer().GetBallPosition();
zeus::CVector3f f26 = act->GetTranslation() - ballPos;
zeus::CVector3f ballToHelper = f26;
if (ballToHelper.canBeNormalized())
ballToHelper.normalize();
else
ballToHelper = foundHint->GetTransform().basis[1];
for (auto it = xac_cameraHints.begin() + 1 ; it != xac_cameraHints.end() ; ++it)
{
if (TCastToPtr<CScriptCameraHint> hint = mgr.ObjectById(it->second))
{
if ((hint->GetHint().GetOverrideFlags() & 0x80) != 0 && hint->GetPriority() ==
foundHint->GetPriority() &&
hint->GetAreaIdAlways() == foundHint->GetAreaIdAlways())
{
zeus::CVector3f hintToHelper = act->GetTranslation() - foundHint->GetTranslation();
if (hintToHelper.canBeNormalized())
hintToHelper.normalize();
else
hintToHelper = foundHint->GetTransform().basis[1];
float ballHintDot = zeus::clamp(-1.f, ballToHelper.dot(hintToHelper), 1.f);
zeus::CVector3f thisBallToHelper = f26;
if (thisBallToHelper.canBeNormalized())
thisBallToHelper.normalize();
else
thisBallToHelper = hint->GetTransform().basis[1];
zeus::CVector3f thisHintToHelper = act->GetTranslation() - hint->GetTranslation();
if (thisHintToHelper.canBeNormalized())
thisHintToHelper.normalize();
else
thisHintToHelper = hint->GetTransform().basis[1];
float thisBallHintDot =
zeus::clamp(-1.f, thisBallToHelper.dot(thisHintToHelper), 1.f);
if (thisBallHintDot > ballHintDot)
foundHint = hint.GetPtr();
}
else
{
break;
}
}
else
{
break;
}
}
}
}
if (foundHint->GetUniqueId() != xa6_camHintId)
r25b = true;
}
else if (xa6_camHintId != foundHint->GetUniqueId())
{
if (foundHint->GetHint().GetBehaviourType() == CBallCamera::EBallCameraBehaviour::Three)
{
if ((foundHint->GetHint().GetOverrideFlags() & 0x20) != 0)
{
x80_ballCamera->TeleportCamera(
zeus::lookAt(foundHint->GetTranslation(), x80_ballCamera->GetX1D8()), mgr);
}
DeleteCameraHint(foundHint->GetUniqueId(), mgr);
if ((foundHint->GetHint().GetOverrideFlags() & 0x2000) != 0)
SkipBallCameraCinematic(mgr);
r25b = false;
}
else
{
r25b = true;
}
}
if (r25b)
ApplyCameraHint(*foundHint, mgr);
}
}
} }
void CCameraManager::ThinkCameras(float dt, CStateManager& mgr) void CCameraManager::ThinkCameras(float dt, CStateManager& mgr)
@ -221,8 +514,7 @@ void CCameraManager::ThinkCameras(float dt, CStateManager& mgr)
for (CEntity* ent : gcList) for (CEntity* ent : gcList)
{ {
TCastToPtr<CGameCamera> gc(ent); if (TCastToPtr<CGameCamera> gc = ent)
if (gc)
{ {
gc->Think(dt, mgr); gc->Think(dt, mgr);
gc->UpdatePerspective(dt); gc->UpdatePerspective(dt);
@ -233,19 +525,83 @@ void CCameraManager::ThinkCameras(float dt, CStateManager& mgr)
return; return;
TUniqueId camId = GetLastCameraId(); TUniqueId camId = GetLastCameraId();
const CGameCamera* cam = TCastToConstPtr<CGameCamera>(mgr.GetObjectById(camId)); if (const CGameCamera* cam = TCastToConstPtr<CGameCamera>(mgr.GetObjectById(camId)))
if (cam != nullptr)
x3bc_curFov = cam->GetFov(); x3bc_curFov = cam->GetFov();
} }
void CCameraManager::UpdateFog(float, CStateManager&) void CCameraManager::UpdateFog(float dt, CStateManager& mgr)
{ {
if (x98_fogDensitySpeed != 0.f)
{
x94_fogDensityFactor += dt * x98_fogDensitySpeed;
if ((x98_fogDensitySpeed > 0.f) ? x94_fogDensityFactor > x9c_fogDensityFactorTarget :
x94_fogDensityFactor < x9c_fogDensityFactorTarget)
{
x94_fogDensityFactor = x9c_fogDensityFactorTarget;
x98_fogDensitySpeed = 0.f;
}
}
if (x74_fluidCounter)
{
if (TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(x78_fluidId))
{
zeus::CVector2f zRange(GetCurrentCamera(mgr)->GetNearClipDistance(),
CalculateFogDensity(mgr, water.GetPtr()));
x3c_fog.SetFogExplicit(ERglFogMode::PerspExp, water->GetFogColor(), zRange);
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Thermal)
mgr.GetCameraFilterPass(4).DisableFilter(0.f);
else
mgr.GetCameraFilterPass(4).SetFilter(EFilterType::Multiply, EFilterShape::Fullscreen,
0.f, water->GetFogColor(), {});
}
xa0_26_inWater = true;
}
else if (xa0_26_inWater)
{
mgr.GetCameraManager()->x3c_fog.DisableFog();
mgr.GetCameraFilterPass(4).DisableFilter(0.f);
xa0_26_inWater = false;
}
x3c_fog.Update(dt);
} }
void CCameraManager::UpdateRumble(float, CStateManager&) void CCameraManager::UpdateRumble(float dt, CStateManager& mgr)
{ {
x30_shakeOffset = zeus::CVector3f::skZero;
for (auto it = x14_shakers.begin() ; it != x14_shakers.end() ;)
{
CCameraShakeData& shaker = *it;
shaker.Update(dt, mgr);
if (shaker.x4_curTime >= shaker.x0_duration)
{
it = x14_shakers.erase(it);
continue;
}
x30_shakeOffset += shaker.GetPoint();
++it;
}
if (!x14_shakers.empty() && !xa0_25_rumbling && xa0_24_pendingRumble)
{
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Six, 1.f, ERumblePriority::Two);
xa0_25_rumbling = true;
}
if (x90_rumbleCooldown > 0.f)
{
x90_rumbleCooldown -= dt;
}
else if (xa0_25_rumbling)
{
xa0_24_pendingRumble = false;
xa0_25_rumbling = false;
}
if (mgr.GetPlayer().GetCameraState() != CPlayer::EPlayerCameraState::FirstPerson &&
!IsInCinematicCamera())
x30_shakeOffset = zeus::CVector3f::skZero;
} }
void CCameraManager::UpdateListener(CStateManager& mgr) void CCameraManager::UpdateListener(CStateManager& mgr)
@ -256,14 +612,14 @@ void CCameraManager::UpdateListener(CStateManager& mgr)
float CCameraManager::CalculateFogDensity(CStateManager& mgr, const CScriptWater* water) float CCameraManager::CalculateFogDensity(CStateManager& mgr, const CScriptWater* water)
{ {
float f31 = water->GetFluidPlane().GetAlpha(); float distanceFactor = 1.f - water->GetFluidPlane().GetAlpha();
float f1 = 0; float distance = 0;
if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit)) if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit))
f1 = (g_tweakPlayer->GetPlayerTranslationFriction(4) * g_tweakPlayer->GetPlayerTranslationFriction(3)) + f31; distance = g_tweakGame->x5c_gravityWaterFogDistanceRange * distanceFactor + g_tweakGame->x58_gravityWaterFogDistanceBase;
else else
f1 = (g_tweakPlayer->GetPlayerTranslationFriction(6) * g_tweakPlayer->GetPlayerTranslationFriction(5)) + f31; distance = g_tweakGame->x54_waterFogDistanceRange * distanceFactor + g_tweakGame->x50_waterFogDistanceBase;
return f1 * x94_; return distance * x94_fogDensityFactor;
} }
void CCameraManager::ResetCameras(CStateManager& mgr) void CCameraManager::ResetCameras(CStateManager& mgr)
@ -364,9 +720,33 @@ void CCameraManager::AddActiveCameraHint(TUniqueId id, CStateManager& mgr)
{ {
auto search = std::find_if(x334_activeCameraHints.begin(), x334_activeCameraHints.end(), auto search = std::find_if(x334_activeCameraHints.begin(), x334_activeCameraHints.end(),
[id](TUniqueId tid) { return tid == id; }); [id](TUniqueId tid) { return tid == id; });
if (search == x334_activeCameraHints.end() && xac_ != 64 && if (search == x334_activeCameraHints.end() && xac_cameraHints.size() != 64 &&
x334_activeCameraHints.size() != 64) x334_activeCameraHints.size() != 64)
x334_activeCameraHints.push_back(id); x334_activeCameraHints.push_back(id);
} }
} }
TUniqueId CCameraManager::GetLastCineCameraId() const
{
if (x4_cineCameras.empty())
return kInvalidUniqueId;
return x4_cineCameras.back();
}
const CCinematicCamera* CCameraManager::GetLastCineCamera(CStateManager& mgr) const
{
return static_cast<const CCinematicCamera*>(mgr.GetObjectById(GetLastCineCameraId()));
}
const CScriptCameraHint* CCameraManager::GetCameraHint(CStateManager& mgr) const
{
return TCastToConstPtr<CScriptCameraHint>(mgr.GetObjectById(xa6_camHintId)).GetPtr();
}
bool CCameraManager::HasCameraHint(CStateManager& mgr) const
{
if (xac_cameraHints.empty() || xa6_camHintId == kInvalidUniqueId)
return false;
return mgr.GetObjectById(xa6_camHintId) != nullptr;
}
} }

View File

@ -15,6 +15,8 @@ class CCameraShakeData;
class CScriptWater; class CScriptWater;
class CInterpolationCamera; class CInterpolationCamera;
class CFinalInput; class CFinalInput;
class CScriptCameraHint;
class CCinematicCamera;
class CCameraManager class CCameraManager
{ {
@ -35,28 +37,27 @@ class CCameraManager
CBallCamera* x80_ballCamera = nullptr; CBallCamera* x80_ballCamera = nullptr;
s16 x84_rumbleId = -1; s16 x84_rumbleId = -1;
CInterpolationCamera* x88_interpCamera = nullptr; CInterpolationCamera* x88_interpCamera = nullptr;
float x90_ = 0.f; float x90_rumbleCooldown = 0.f;
float x94_ = 1.f; float x94_fogDensityFactor = 1.f;
float x98_ = 0.f; float x98_fogDensitySpeed = 0.f;
float x9c_ = 1.f; float x9c_fogDensityFactorTarget = 1.f;
union union
{ {
struct struct
{ {
bool xa0_24_ : 1; bool xa0_24_pendingRumble : 1;
bool xa0_25_rumbling : 1; bool xa0_25_rumbling : 1;
bool xa0_26_inWater : 1; bool xa0_26_inWater : 1;
}; };
u8 _dummy1 = 0; u8 _dummy1 = 0;
}; };
TUniqueId xa2_ = kInvalidUniqueId; TUniqueId xa2_spindleCamId = kInvalidUniqueId;
TUniqueId xa4_ = kInvalidUniqueId; TUniqueId xa4_pathCamId = kInvalidUniqueId;
TUniqueId xa6_ = kInvalidUniqueId; TUniqueId xa6_camHintId = kInvalidUniqueId;
u32 xa8_ = 1000; s32 xa8_hintPriority = 1000;
u32 xac_ = 0; rstl::reserved_vector<std::pair<s32, TUniqueId>, 64> xac_cameraHints;
rstl::reserved_vector<TUniqueId, 64> x2b0_inactiveCameraHints; rstl::reserved_vector<TUniqueId, 64> x2b0_inactiveCameraHints;
rstl::reserved_vector<TUniqueId, 64> x334_activeCameraHints; rstl::reserved_vector<TUniqueId, 64> x334_activeCameraHints;
@ -71,6 +72,16 @@ class CCameraManager
}; };
float x3bc_curFov = 60.f; float x3bc_curFov = 60.f;
void SetPathCamera(TUniqueId id, CStateManager& mgr);
void SetSpindleCamera(TUniqueId id, CStateManager& mgr);
void RestoreHintlessCamera(CStateManager& mgr);
void InterpolateToBallCamera(const zeus::CTransform& xf, TUniqueId camId, const zeus::CVector3f& lookDir,
float f1, float f2, float f3, bool b1, CStateManager& mgr);
static constexpr bool ShouldBypassInterpolation() { return false; }
void SkipBallCameraCinematic(CStateManager& mgr);
void ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr);
public: public:
CCameraManager(TUniqueId curCameraId=kInvalidUniqueId); CCameraManager(TUniqueId curCameraId=kInvalidUniqueId);
@ -117,11 +128,11 @@ public:
float sub80009148() const; float sub80009148() const;
void UpdateCameraHints(float, CStateManager&); void UpdateCameraHints(float dt, CStateManager& mgr);
void ThinkCameras(float, CStateManager&); void ThinkCameras(float dt, CStateManager& mgr);
void UpdateFog(float, CStateManager&); void UpdateFog(float dt, CStateManager& mgr);
void UpdateRumble(float, CStateManager&); void UpdateRumble(float dt, CStateManager& mgr);
void UpdateListener(CStateManager&); void UpdateListener(CStateManager& mgr);
float CalculateFogDensity(CStateManager&, const CScriptWater*); float CalculateFogDensity(CStateManager&, const CScriptWater*);
@ -138,6 +149,13 @@ public:
void AddInactiveCameraHint(TUniqueId id, CStateManager& mgr); void AddInactiveCameraHint(TUniqueId id, CStateManager& mgr);
void AddActiveCameraHint(TUniqueId id, CStateManager& mgr); void AddActiveCameraHint(TUniqueId id, CStateManager& mgr);
TUniqueId GetLastCineCameraId() const;
TUniqueId GetSpindleCameraId() const { return xa2_spindleCamId; }
TUniqueId GetPathCameraId() const { return xa4_pathCamId; }
const CCinematicCamera* GetLastCineCamera(CStateManager& mgr) const;
const CScriptCameraHint* GetCameraHint(CStateManager& mgr) const;
bool HasCameraHint(CStateManager& mgr) const;
}; };
} }

View File

@ -79,6 +79,16 @@ CCameraShakeData CCameraShakeData::BuildPhazonCameraShakeData(float duration, fl
SCameraShakePoint(1, 0.f, 0.f, 0.5f * duration, 0.5f))}; SCameraShakePoint(1, 0.f, 0.f, 0.5f * duration, 0.5f))};
} }
void CCameraShakeData::Update(float dt, CStateManager& mgr)
{
}
zeus::CVector3f CCameraShakeData::GetPoint() const
{
return {x8_shaker1.x38_value, x44_shaker2.x38_value, x80_shaker3.x38_value};
}
float CCameraShakeData::GetSomething() const float CCameraShakeData::GetSomething() const
{ {
float ret = 0.f; float ret = 0.f;

View File

@ -7,6 +7,7 @@
namespace urde namespace urde
{ {
class CRandom16; class CRandom16;
class CStateManager;
struct SCameraShakePoint struct SCameraShakePoint
{ {
@ -29,7 +30,7 @@ class CCameraShakerComponent
friend class CCameraShakeData; friend class CCameraShakeData;
u32 x4_w1 = 0; u32 x4_w1 = 0;
SCameraShakePoint x8_sp1, x20_sp2; SCameraShakePoint x8_sp1, x20_sp2;
float x38_ = 0.f; float x38_value = 0.f;
public: public:
CCameraShakerComponent() = default; CCameraShakerComponent() = default;
CCameraShakerComponent(u32 w1, const SCameraShakePoint& sp1, const SCameraShakePoint& sp2) CCameraShakerComponent(u32 w1, const SCameraShakePoint& sp1, const SCameraShakePoint& sp2)
@ -41,7 +42,7 @@ class CCameraShakeData
{ {
friend class CCameraManager; friend class CCameraManager;
float x0_duration; float x0_duration;
float x4_ = 0.f; float x4_curTime = 0.f;
CCameraShakerComponent x8_shaker1; CCameraShakerComponent x8_shaker1;
CCameraShakerComponent x44_shaker2; CCameraShakerComponent x44_shaker2;
CCameraShakerComponent x80_shaker3; CCameraShakerComponent x80_shaker3;
@ -62,6 +63,8 @@ public:
const zeus::CVector3f& sfxPos); const zeus::CVector3f& sfxPos);
static CCameraShakeData BuildPhazonCameraShakeData(float duration, float magnitude); static CCameraShakeData BuildPhazonCameraShakeData(float duration, float magnitude);
//zeus::CVector3f GeneratePoint(float dt, CRandom16& r); //zeus::CVector3f GeneratePoint(float dt, CRandom16& r);
void Update(float dt, CStateManager& mgr);
zeus::CVector3f GetPoint() const;
float GetSomething() const; float GetSomething() const;
float GetSomething2() const; float GetSomething2() const;
void SetShakerId(u32 id) { xbc_shakerId = id; } void SetShakerId(u32 id) { xbc_shakerId = id; }

View File

@ -44,4 +44,10 @@ void CInterpolationCamera::Think(float, CStateManager& mgr)
} }
void CInterpolationCamera::SetInterpolation(const zeus::CTransform& xf, const zeus::CVector3f& lookDir,
float f1, float f2, float f3, TUniqueId camId, bool b1, CStateManager& mgr)
{
}
} }

View File

@ -16,6 +16,8 @@ public:
void Render(const CStateManager&) const; void Render(const CStateManager&) const;
void Reset(const zeus::CTransform&, CStateManager& mgr); void Reset(const zeus::CTransform&, CStateManager& mgr);
void Think(float, CStateManager &); void Think(float, CStateManager &);
void SetInterpolation(const zeus::CTransform& xf, const zeus::CVector3f& lookDir,
float f1, float f2, float f3, TUniqueId camId, bool b1, CStateManager& mgr);
}; };
} }

View File

@ -7,6 +7,7 @@ namespace urde
{ {
enum class ERumbleFxId enum class ERumbleFxId
{ {
Six = 6,
Seven = 7, Seven = 7,
Eleven = 11, Eleven = 11,
Twelve = 12, Twelve = 12,

View File

@ -675,6 +675,7 @@ public:
float GetDistanceUnderWater() const { return x828_distanceUnderWater; } float GetDistanceUnderWater() const { return x828_distanceUnderWater; }
TUniqueId GetRidingPlatformId() const { return x82e_ridingPlatform; } TUniqueId GetRidingPlatformId() const { return x82e_ridingPlatform; }
const zeus::CVector3f& GetLastVelocity() const { return x794_lastVelocity; } const zeus::CVector3f& GetLastVelocity() const { return x794_lastVelocity; }
const zeus::CVector3f& GetMoveDir() const { return x50c_moveDir; }
}; };
} }

View File

@ -7,14 +7,14 @@ namespace urde
{ {
CScriptCameraHint::CScriptCameraHint(TUniqueId uid, const std::string& name, const CEntityInfo& info, CScriptCameraHint::CScriptCameraHint(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, s32 w1, const zeus::CTransform& xf, bool active, s32 priority,
CBallCamera::EBallCameraBehaviour behaviour, s32 r4, float f1, CBallCamera::EBallCameraBehaviour behaviour, s32 overrideFlags, float f1,
float f2, float f3, const zeus::CVector3f& r6, const zeus::CVector3f& r7, float f2, float f3, const zeus::CVector3f& r6, const zeus::CVector3f& r7,
const zeus::CVector3f& r8, float f4, float f5, float f6, float f7, const zeus::CVector3f& r8, float f4, float f5, float f6, float f7,
float f8, float f9, float f10, float f11, float f12, float f13) float f8, float f9, float f10, float f11, float f12, float f13)
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Unknown), : CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::Unknown),
CActorParameters::None(), kInvalidUniqueId), xe8_w1(w1), CActorParameters::None(), kInvalidUniqueId), xe8_priority(priority),
xec_hint(r4, behaviour, f1, f2, f3, r6, r7, r8, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13), xec_hint(overrideFlags, behaviour, f1, f2, f3, r6, r7, r8, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13),
x168_origXf(xf) x168_origXf(xf)
{ {
} }

View File

@ -9,7 +9,7 @@ namespace urde
class CCameraHint class CCameraHint
{ {
s32 x4_r4; s32 x4_overrideFlags;
CBallCamera::EBallCameraBehaviour x8_behaviour; CBallCamera::EBallCameraBehaviour x8_behaviour;
float xc_f1; float xc_f1;
float x10_f2; float x10_f2;
@ -29,17 +29,24 @@ class CCameraHint
float x60_f13; float x60_f13;
public: public:
CCameraHint(s32 r4, CBallCamera::EBallCameraBehaviour behaviour, float f1, float f2, float f3, CCameraHint(s32 overrideFlags, CBallCamera::EBallCameraBehaviour behaviour, float f1, float f2, float f3,
const zeus::CVector3f& r6, const zeus::CVector3f& r7, const zeus::CVector3f& r8, float f4, const zeus::CVector3f& r6, const zeus::CVector3f& r7, const zeus::CVector3f& r8, float f4,
float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13) float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13)
: x4_r4(r4), x8_behaviour(behaviour), xc_f1(f1), x10_f2(f2), x14_f3(f3), x18_r6(r6), x24_r7(r7), : x4_overrideFlags(overrideFlags), x8_behaviour(behaviour), xc_f1(f1), x10_f2(f2), x14_f3(f3), x18_r6(r6),
x30_r8(r8), x3c_f4(f4), x40_f5(f5), x44_f6(f6), x48_f7(f7), x4c_f8(f8), x50_f9(f9), x54_f10(f10), x24_r7(r7), x30_r8(r8), x3c_f4(f4), x40_f5(f5), x44_f6(f6), x48_f7(f7), x4c_f8(f8), x50_f9(f9), x54_f10(f10),
x58_f11(f11), x5c_f12(f12), x60_f13(f13) {} x58_f11(f11), x5c_f12(f12), x60_f13(f13) {}
s32 GetOverrideFlags() const { return x4_overrideFlags; }
CBallCamera::EBallCameraBehaviour GetBehaviourType() const { return x8_behaviour; }
float GetX4C() const { return x4c_f8; }
float GetX50() const { return x50_f9; }
float GetX58() const { return x58_f11; }
float GetX5C() const { return x5c_f12; }
}; };
class CScriptCameraHint : public CActor class CScriptCameraHint : public CActor
{ {
s32 xe8_w1; s32 xe8_priority;
CCameraHint xec_hint; CCameraHint xec_hint;
rstl::reserved_vector<TUniqueId, 8> x150_helpers; rstl::reserved_vector<TUniqueId, 8> x150_helpers;
TUniqueId x164_delegatedCamera = kInvalidUniqueId; TUniqueId x164_delegatedCamera = kInvalidUniqueId;
@ -50,17 +57,22 @@ class CScriptCameraHint : public CActor
void RemoveHelper(TUniqueId id); void RemoveHelper(TUniqueId id);
public: public:
CScriptCameraHint(TUniqueId, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf, CScriptCameraHint(TUniqueId, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf,
bool active, s32 w1, CBallCamera::EBallCameraBehaviour behaviour, s32 r4, float f1, float f2, bool active, s32 priority, CBallCamera::EBallCameraBehaviour behaviour, s32 overrideFlags,
float f3, const zeus::CVector3f& r6, const zeus::CVector3f& r7, const zeus::CVector3f& r8, float f1, float f2, float f3, const zeus::CVector3f& r6, const zeus::CVector3f& r7,
float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, const zeus::CVector3f& r8, float f4, float f5, float f6, float f7, float f8, float f9, float f10,
float f13); float f11, float f12, float f13);
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr); void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr);
void ClearIdList() { x150_helpers.clear(); } void ClearIdList() { x150_helpers.clear(); }
void SetInactive(bool inactive) { x166_inactive = inactive; } void SetInactive(bool inactive) { x166_inactive = inactive; }
bool GetInactive() const { return x166_inactive; }
size_t GetHelperCount() const { return x150_helpers.size(); }
TUniqueId GetFirstHelper() const { return x150_helpers.empty() ? kInvalidUniqueId : x150_helpers[0]; } TUniqueId GetFirstHelper() const { return x150_helpers.empty() ? kInvalidUniqueId : x150_helpers[0]; }
s32 GetPriority() const { return xe8_priority; }
const CCameraHint& GetHint() const { return xec_hint; }
TUniqueId GetDelegatedCamera() const { return x164_delegatedCamera; }
}; };
} }

View File

@ -0,0 +1,49 @@
#include "CScriptSpindleCamera.hpp"
#include "Camera/CCameraManager.hpp"
#include "ScriptLoader.hpp"
#include "TCastTo.hpp"
namespace urde
{
SSpindleSegment::SSpindleSegment(CInputStream& in)
: x0_(in.readUint32Big()), x4_paramFlags(ScriptLoader::LoadParameterFlags(in)),
x8_(in.readFloatBig()), xc_(in.readFloatBig()), x10_(in.readFloatBig()), x14_(in.readFloatBig())
{}
CScriptSpindleCamera::CScriptSpindleCamera(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, u32 r9,
float f1, float f2, float f3, float f4, const SSpindleSegment& seg1,
const SSpindleSegment& seg2, const SSpindleSegment& seg3,
const SSpindleSegment& seg4, const SSpindleSegment& seg5,
const SSpindleSegment& seg6, const SSpindleSegment& seg7,
const SSpindleSegment& seg8, const SSpindleSegment& seg9,
const SSpindleSegment& seg10, const SSpindleSegment& seg11,
const SSpindleSegment& seg12, const SSpindleSegment& seg13,
const SSpindleSegment& seg14, const SSpindleSegment& seg15)
: CGameCamera(uid, active, name, info, xf, CCameraManager::ThirdPersonFOV(), CCameraManager::NearPlane(),
CCameraManager::FarPlane(), CCameraManager::Aspect(), kInvalidUniqueId, false, 0),
x188_r9(r9), x1b0_f1(f1), x1b4_f2(f2), x1b8_f3(f2), x1bc_f4(f4), x1c0_seg1(seg1), x1d8_seg2(seg2),
x1f0_seg3(seg3), x208_seg4(seg4), x220_seg5(seg5), x238_seg6(seg6), x250_seg7(seg7),
x268_seg8(seg8), x280_seg9(seg9), x298_seg10(seg10), x2b0_seg11(seg11), x2c8_seg12(seg12),
x2e0_seg13(seg13), x2f8_seg14(seg14), x310_seg15(seg15), x330_lookDir(xf.basis[1])
{
}
void CScriptSpindleCamera::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptSpindleCamera::ProcessInput(const CFinalInput& input, CStateManager& mgr)
{
}
void CScriptSpindleCamera::Reset(const zeus::CTransform& xf, CStateManager& mgr)
{
}
}

View File

@ -0,0 +1,71 @@
#ifndef __URDE_CSCRIPTSPINDLECAMERA_HPP__
#define __URDE_CSCRIPTSPINDLECAMERA_HPP__
#include "Camera/CGameCamera.hpp"
namespace urde
{
struct SSpindleSegment
{
u32 x0_;
u32 x4_paramFlags;
float x8_;
float xc_;
float x10_;
float x14_;
SSpindleSegment(CInputStream& in);
void FixupAngles()
{
x8_ = zeus::degToRad(x8_);
xc_ = zeus::degToRad(xc_);
}
};
class CScriptSpindleCamera : public CGameCamera
{
u32 x188_r9;
u32 x18c_ = 0;
float x1b0_f1;
float x1b4_f2;
float x1b8_f3;
float x1bc_f4;
SSpindleSegment x1c0_seg1;
SSpindleSegment x1d8_seg2;
SSpindleSegment x1f0_seg3;
SSpindleSegment x208_seg4;
SSpindleSegment x220_seg5;
SSpindleSegment x238_seg6;
SSpindleSegment x250_seg7;
SSpindleSegment x268_seg8;
SSpindleSegment x280_seg9;
SSpindleSegment x298_seg10;
SSpindleSegment x2b0_seg11;
SSpindleSegment x2c8_seg12;
SSpindleSegment x2e0_seg13;
SSpindleSegment x2f8_seg14;
SSpindleSegment x310_seg15;
float x328_ = 0.f;
bool x32c_24 = false;
zeus::CVector3f x330_lookDir;
public:
CScriptSpindleCamera(TUniqueId uid, const std::string& name, const CEntityInfo& info,
const zeus::CTransform& xf, bool active, u32 r9,
float f1, float f2, float f3, float f4, const SSpindleSegment& seg1,
const SSpindleSegment& seg2, const SSpindleSegment& seg3,
const SSpindleSegment& seg4, const SSpindleSegment& seg5,
const SSpindleSegment& seg6, const SSpindleSegment& seg7,
const SSpindleSegment& seg8, const SSpindleSegment& seg9,
const SSpindleSegment& seg10, const SSpindleSegment& seg11,
const SSpindleSegment& seg12, const SSpindleSegment& seg13,
const SSpindleSegment& seg14, const SSpindleSegment& seg15);
void Accept(IVisitor& visitor);
void ProcessInput(const CFinalInput& input, CStateManager& mgr);
void Reset(const zeus::CTransform& xf, CStateManager& mgr);
};
}
#endif // __URDE_CSCRIPTSPINDLECAMERA_HPP__

View File

@ -44,7 +44,7 @@ CScriptWater::CScriptWater(CStateManager& mgr, TUniqueId uid, const std::string&
x24c_unmorphVisorRunoffParticleId(unmorphVisorRunoffparticle), x24c_unmorphVisorRunoffParticleId(unmorphVisorRunoffparticle),
x260_visorRunoffSfx(CSfxManager::TranslateSFXID(visorRunoffSfx)), x260_visorRunoffSfx(CSfxManager::TranslateSFXID(visorRunoffSfx)),
x262_unmorphVisorRunoffSfx(CSfxManager::TranslateSFXID(unmorphVisorRunoffSfx)), x262_unmorphVisorRunoffSfx(CSfxManager::TranslateSFXID(unmorphVisorRunoffSfx)),
x2a4_splashColor(splashColor), x2a8_unkColor(unkColor), x2ac_alphaInTime(alphaInTime), x2b0_alphaOutTime(alphaOutTime), x2a4_splashColor(splashColor), x2a8_fogColor(unkColor), x2ac_alphaInTime(alphaInTime), x2b0_alphaOutTime(alphaOutTime),
x2b4_alphaInRecip((alphaInTime != 0.f) ? 1.f / alphaInTime : 0.f), x2b4_alphaInRecip((alphaInTime != 0.f) ? 1.f / alphaInTime : 0.f),
x2b8_alphaOutRecip((alphaOutTime != 0.f) ? 1.f / alphaOutTime : 0.f), x2bc_alpha(alpha), x2c0_tileSize(tileSize) x2b8_alphaOutRecip((alphaOutTime != 0.f) ? 1.f / alphaOutTime : 0.f), x2bc_alpha(alpha), x2c0_tileSize(tileSize)
{ {

View File

@ -43,7 +43,7 @@ private:
rstl::reserved_vector<std::experimental::optional<TLockedToken<CGenDescription>>, 3> x264_splashEffects; rstl::reserved_vector<std::experimental::optional<TLockedToken<CGenDescription>>, 3> x264_splashEffects;
rstl::reserved_vector<u16, 3> x298_splashSounds; rstl::reserved_vector<u16, 3> x298_splashSounds;
zeus::CColor x2a4_splashColor; zeus::CColor x2a4_splashColor;
zeus::CColor x2a8_unkColor; zeus::CColor x2a8_fogColor;
float x2ac_alphaInTime; float x2ac_alphaInTime;
float x2b0_alphaOutTime; float x2b0_alphaOutTime;
float x2b4_alphaInRecip; float x2b4_alphaInRecip;
@ -131,6 +131,7 @@ public:
int GetPatchDimensionX() const { return x2d0_patchDimX; } int GetPatchDimensionX() const { return x2d0_patchDimX; }
int GetPatchDimensionY() const { return x2d4_patchDimY; } int GetPatchDimensionY() const { return x2d4_patchDimY; }
bool CanRippleAtPoint(const zeus::CVector3f& point) const; bool CanRippleAtPoint(const zeus::CVector3f& point) const;
const zeus::CColor& GetFogColor() const { return x2a8_fogColor; }
}; };
} }

View File

@ -4,10 +4,8 @@
#include "CDamageInfo.hpp" #include "CDamageInfo.hpp"
#include "CFluidUVMotion.hpp" #include "CFluidUVMotion.hpp"
#include "CGrappleParameters.hpp" #include "CGrappleParameters.hpp"
#include "CLightParameters.hpp"
#include "CPatternedInfo.hpp" #include "CPatternedInfo.hpp"
#include "CRepulsor.hpp" #include "CRepulsor.hpp"
#include "CScannableParameters.hpp"
#include "CScriptActor.hpp" #include "CScriptActor.hpp"
#include "CScriptActorKeyframe.hpp" #include "CScriptActorKeyframe.hpp"
#include "CScriptActorRotate.hpp" #include "CScriptActorRotate.hpp"
@ -56,15 +54,14 @@
#include "CScriptStreamedMusic.hpp" #include "CScriptStreamedMusic.hpp"
#include "CScriptSwitch.hpp" #include "CScriptSwitch.hpp"
#include "CScriptTimer.hpp" #include "CScriptTimer.hpp"
#include "CScriptTrigger.hpp"
#include "CScriptVisorFlare.hpp" #include "CScriptVisorFlare.hpp"
#include "CScriptWater.hpp" #include "CScriptWater.hpp"
#include "CScriptWaypoint.hpp" #include "CScriptWaypoint.hpp"
#include "CScriptWorldTeleporter.hpp" #include "CScriptWorldTeleporter.hpp"
#include "CScriptSpiderBallAttractionSurface.hpp" #include "CScriptSpiderBallAttractionSurface.hpp"
#include "CScriptSpindleCamera.hpp"
#include "CSimplePool.hpp" #include "CSimplePool.hpp"
#include "CStateManager.hpp" #include "CStateManager.hpp"
#include "CVisorParameters.hpp"
#include "CWallCrawlerSwarm.hpp" #include "CWallCrawlerSwarm.hpp"
#include "CWorld.hpp" #include "CWorld.hpp"
#include "Camera/CCinematicCamera.hpp" #include "Camera/CCinematicCamera.hpp"
@ -2311,9 +2308,49 @@ CEntity* ScriptLoader::LoadGeemer(CStateManager& mgr, CInputStream& in, int prop
return nullptr; return nullptr;
} }
CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{ {
return nullptr; if (!EnsurePropertyCount(propCount, 24, "SpindleCamera"))
return nullptr;
SActorHead aHead = LoadActorHead(in, mgr);
bool active = in.readBool();
u32 flags = LoadParameterFlags(in);
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
float f4 = in.readFloatBig();
SSpindleSegment seg1(in);
seg1.FixupAngles();
SSpindleSegment seg2(in);
SSpindleSegment seg3(in);
SSpindleSegment seg4(in);
SSpindleSegment seg5(in);
seg5.FixupAngles();
SSpindleSegment seg6(in);
seg6.FixupAngles();
SSpindleSegment seg7(in);
seg7.FixupAngles();
SSpindleSegment seg8(in);
seg8.FixupAngles();
SSpindleSegment seg9(in);
SSpindleSegment seg10(in);
SSpindleSegment seg11(in);
seg11.FixupAngles();
SSpindleSegment seg12(in);
seg12.FixupAngles();
SSpindleSegment seg13(in);
seg13.FixupAngles();
SSpindleSegment seg14(in);
SSpindleSegment seg15(in);
seg15.FixupAngles();
return new CScriptSpindleCamera(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform,
active, flags, f1, f2, f3, f4, seg1, seg2, seg3, seg4, seg5, seg6,
seg7, seg8, seg9, seg10, seg11, seg12, seg13, seg14, seg15);
} }
CEntity* ScriptLoader::LoadAtomicAlpha(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) CEntity* ScriptLoader::LoadAtomicAlpha(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)