Implement CScriptSpecialFunction::ThinkAreaDamage, and more CThardus

This commit is contained in:
Phillip Stephens 2019-11-24 07:01:07 -08:00
parent 655dc01a06
commit 697a100bca
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
16 changed files with 241 additions and 119 deletions

View File

@ -935,6 +935,9 @@ void CBooRenderer::PostRenderFogs() {
x2ac_fogVolumes.clear(); x2ac_fogVolumes.clear();
} }
void CBooRenderer::SetModelMatrix(const zeus::CTransform& xf) {
CGraphics::SetModelMatrix(xf);
}
void CBooRenderer::AddParticleGen(const CParticleGen& gen) { void CBooRenderer::AddParticleGen(const CParticleGen& gen) {
if (auto bounds = gen.GetBounds()) { if (auto bounds = gen.GetBounds()) {
zeus::CVector3f pt = bounds.value().closestPointAlongVector(xb0_viewPlane.normal()); zeus::CVector3f pt = bounds.value().closestPointAlongVector(xb0_viewPlane.normal());

View File

@ -231,6 +231,7 @@ public:
void DrawStaticGeometry(int areaIdx, int mask, int targetMask) override; void DrawStaticGeometry(int areaIdx, int mask, int targetMask) override;
void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) override; void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) override;
void PostRenderFogs() override; void PostRenderFogs() override;
void SetModelMatrix(const zeus::CTransform& xf) override;
void AddParticleGen(const CParticleGen&) override; void AddParticleGen(const CParticleGen&) override;
void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&) override; void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&) override;
void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int) override; void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int) override;

View File

@ -46,6 +46,7 @@ public:
virtual void DrawStaticGeometry(int areaIdx, int mask, int targetMask) = 0; virtual void DrawStaticGeometry(int areaIdx, int mask, int targetMask) = 0;
virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) = 0; virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) = 0;
virtual void PostRenderFogs() = 0; virtual void PostRenderFogs() = 0;
virtual void SetModelMatrix(const zeus::CTransform& xf) = 0;
virtual void AddParticleGen(const CParticleGen&) = 0; virtual void AddParticleGen(const CParticleGen&) = 0;
virtual void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&) = 0; virtual void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&) = 0;
virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int) = 0; virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int) = 0;

View File

@ -327,21 +327,25 @@ void CMain::AddWorldPaks() {
if (i != 0) if (i != 0)
path += '0' + i; path += '0' + i;
std::string lowerPath(path);
athena::utility::tolower(lowerPath);
if (CDvdFile::FileExists((path + ".upak").c_str())) if (CDvdFile::FileExists((path + ".upak").c_str()))
loader->AddPakFileAsync(path, false, true); loader->AddPakFileAsync(path, false, true);
else if (CDvdFile::FileExists((lowerPath + ".upak").c_str()))
loader->AddPakFileAsync(lowerPath, false, true);
} }
loader->WaitForPakFileLoadingComplete(); loader->WaitForPakFileLoadingComplete();
} }
void CMain::AddOverridePaks() { void CMain::AddOverridePaks() {
if (CResLoader* loader = g_ResFactory->GetResLoader()) { CResLoader* loader = g_ResFactory->GetResLoader();
loader->AddPakFileAsync("URDE", false, false, true); if (!loader)
loader->WaitForPakFileLoadingComplete(); return;
for (size_t i = 999; i > 0; --i) {
std::string path = fmt::format(fmt("Override{}"), i);
if (CDvdFile::FileExists((path + ".upak").c_str()))
loader->AddPakFileAsync(path, false, false, true);
} }
if (CDvdFile::FileExists("URDE.upak"))
loader->AddPakFile("URDE", false, false, true);
} }
void CMain::ResetGameState() { void CMain::ResetGameState() {

View File

@ -3,6 +3,8 @@
#include "Runtime/CStateManager.hpp" #include "Runtime/CStateManager.hpp"
#include "Runtime/Collision/CCollisionActor.hpp" #include "Runtime/Collision/CCollisionActor.hpp"
#include "Runtime/Collision/CCollisionActorManager.hpp" #include "Runtime/Collision/CCollisionActorManager.hpp"
#include "Runtime/World/CActorParameters.hpp"
#include "Runtime/World/CDestroyableRock.hpp"
#include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/World/CPatternedInfo.hpp"
#include "Runtime/World/CPlayer.hpp" #include "Runtime/World/CPlayer.hpp"
@ -11,7 +13,7 @@
namespace urde::MP1 { namespace urde::MP1 {
CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CThardus::CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo,
std::vector<CModelData> mData1, std::vector<CModelData> mData2, CAssetId particle1, const std::vector<CStaticRes>& mData1, const std::vector<CStaticRes>& mData2, CAssetId particle1,
CAssetId particle2, CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6, CAssetId particle2, CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6,
CAssetId stateMachine, CAssetId particle4, CAssetId particle5, CAssetId particle6, CAssetId stateMachine, CAssetId particle4, CAssetId particle5, CAssetId particle6,
CAssetId particle7, CAssetId particle8, CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle7, CAssetId particle8, CAssetId particle9, CAssetId texture, u32 sfxId1,
@ -101,24 +103,36 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa
break; break;
} }
case EScriptObjectMessage::Touched: { case EScriptObjectMessage::Touched: {
#if 0
if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(uid)) { if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(uid)) {
if (TCastToPtr<CPlayer> pl = mgr.ObjectById(colAct->GetLastTouchedObject())) { if (TCastToPtr<CPlayer> pl = mgr.ObjectById(colAct->GetLastTouchedObject())) {
if (x420_curDamageRemTime > 0.f)
} else if (TCastToConstPtr<CBomb> bomb = mgr.GetObjectById(colAct->GetLastTouchedObject())) { break;
u32 rand = mgr.GetActiveRandom()->Next(); u32 rand = mgr.GetActiveRandom()->Next();
float f = 1.f; float damageMult = 1.f;
zeus::CVector3f vec; zeus::CVector3f knockBack = zeus::skForward;
if (x644_ == 1) { if (x644_ == 1) {
f = 2.f; damageMult = 2.f;
if ((rand & (1 ^ rand) >> 0x1f) == rand >> 31) { knockBack = (rand % 2) ? zeus::skRight : zeus::skLeft;
vec = zeus::skRight;
} else
vec = zeus::skLeft;
} }
if (mgr.GetPlayer().GetFrozenState())
mgr.GetPlayer().UnFreeze(mgr);
knockBack = GetTransform().buildMatrix3f() * knockBack;
CDamageInfo dInfo = GetContactDamage();
dInfo.SetDamage(damageMult * dInfo.GetDamage());
mgr.ApplyDamage(GetUniqueId(), pl->GetUniqueId(), GetUniqueId(), dInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}),
x644_ == 1 ? knockBack : zeus::skZero3f);
x420_curDamageRemTime = x424_damageWaitTime;
} else if (TCastToConstPtr<CBomb>(mgr.GetObjectById(colAct->GetLastTouchedObject()))) {
#if 0
if (x644_ == 1 && x93c_)
sub801dae2c(mgr, x648_);
#endif
} }
} }
#endif
break; break;
} }
case EScriptObjectMessage::Registered: { case EScriptObjectMessage::Registered: {
@ -126,10 +140,27 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa
x6b0_.reserve(x5cc_.size()); x6b0_.reserve(x5cc_.size());
x6c0_.reserve(x5cc_.size()); x6c0_.reserve(x5cc_.size());
x90c_.reserve(x5cc_.size()); x90c_.reserve(x5cc_.size());
/* for (size_t i = 0; i < x5cc_.size(); ++i) {
for (const auto& mData : x5cc_) { float dVar24 = (i == x5cc_.size() - 1) ? 2.f * x6a8_ : x6a8_;
TUniqueId rockId = mgr.AllocateUniqueId();
}*/ CModelData mData1(x5cc_[i]);
CModelData mData2(x5dc_[i]);
mgr.AddObject(new CDestroyableRock(
rockId, true, "", CEntityInfo(GetAreaIdAlways(), NullConnectionList), {}, std::move(mData1), 0.f,
CHealthInfo(dVar24, 0.f),
CDamageVulnerability(
EVulnerability::Normal, EVulnerability::Deflect, EVulnerability::Normal, EVulnerability::Normal,
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Deflect,
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect,
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::One),
GetMaterialList(), x630_,
CActorParameters(CLightParameters(false, 0.f, CLightParameters::EShadowTesselation::Invalid, 0.f, 0.f,
zeus::skWhite, false, CLightParameters::EWorldLightingOptions::NoShadowCast,
CLightParameters::ELightRecalculationOptions::LargeFrameCount,
zeus::skZero3f, -1, -1, 0, 0),
{}, {}, {}, {}, true, true, false, false, 0.f, 0.f, 1.f),
std::move(mData2), 0));
}
AddMaterial(EMaterialTypes::ScanPassthrough, mgr); AddMaterial(EMaterialTypes::ScanPassthrough, mgr);
AddMaterial(EMaterialTypes::CameraPassthrough, mgr); AddMaterial(EMaterialTypes::CameraPassthrough, mgr);
@ -148,4 +179,26 @@ void CThardus::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMa
break; break;
} }
} }
void CThardus::Generate(CStateManager& mgr, EStateMsg msg, float arg) {
if (msg == EStateMsg::Activate) {
x5ec_ = 0;
} else if (msg == EStateMsg::Update) {
if (x5ec_ == 0) {
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Getup) {
x5ec_ = 2;
} else {
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType::Zero));
}
} else if (x5ec_ == 2 && x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Getup) {
x5ec_ = 3;
}
} else if (msg == EStateMsg::Deactivate) {
x93d_ = false;
}
}
void CThardus::GetUp(CStateManager& mgr, EStateMsg msg, float arg) {
if (msg != EStateMsg::Activate)
return;
RemoveMaterial(EMaterialTypes::RadarObject, mgr);
}
} }

View File

@ -22,8 +22,10 @@ class CThardus : public CPatterned {
u32 x578_ = 0; u32 x578_ = 0;
u32 x5c4_ = 1; u32 x5c4_ = 1;
bool x5c8_ = false; bool x5c8_ = false;
std::vector<CModelData> x5cc_; /* NOTE(phil) These two vectors used to vectors of CModelData, They have been converted to vectors of CStaticRes due to
std::vector<CModelData> x5dc_; * the use of move semantics to prevent deep copies */
std::vector<CStaticRes> x5cc_;
std::vector<CStaticRes> x5dc_;
s32 x5ec_ = -1; s32 x5ec_ = -1;
std::unique_ptr<CCollisionActorManager> x5f4_; std::unique_ptr<CCollisionActorManager> x5f4_;
std::unique_ptr<CCollisionActorManager> x5f8_; std::unique_ptr<CCollisionActorManager> x5f8_;
@ -119,36 +121,17 @@ public:
DEFINE_PATTERNED(Thardus) DEFINE_PATTERNED(Thardus)
CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf, CThardus(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo, CModelData&& mData, const CActorParameters& actParms, const CPatternedInfo& pInfo,
std::vector<CModelData> mData1, std::vector<CModelData> mData2, CAssetId particle1, CAssetId particle2, const std::vector<CStaticRes>& mData1, const std::vector<CStaticRes>& mData2, CAssetId particle1,
CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6, CAssetId stateMachine, CAssetId particle2, CAssetId particle3, float f1, float f2, float f3, float f4, float f5, float f6,
CAssetId particle4, CAssetId particle5, CAssetId particle6, CAssetId particle7, CAssetId particle8, CAssetId stateMachine, CAssetId particle4, CAssetId particle5, CAssetId particle6, CAssetId particle7,
CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle10, u32 sfxId2, u32 sfxId3, u32 sfxId4); CAssetId particle8, CAssetId particle9, CAssetId texture, u32 sfxId1, CAssetId particle10, u32 sfxId2,
u32 sfxId3, u32 sfxId4);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;
void Generate(CStateManager& mgr, EStateMsg msg, float arg) override { void Generate(CStateManager& mgr, EStateMsg msg, float arg) override;
if (msg == EStateMsg::Activate) {
x5ec_ = 0;
} else if (msg == EStateMsg::Update) {
if (x5ec_ == 0) {
if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Getup) {
x5ec_ = 2;
} else {
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType::Zero));
}
} else if (x5ec_ == 2 && x450_bodyController->GetCurrentStateId() != pas::EAnimationState::Getup) {
x5ec_ = 3;
}
} else if (msg == EStateMsg::Deactivate) {
x93d_ = false;
}
}
void GetUp(CStateManager& mgr, EStateMsg msg, float arg) override { void GetUp(CStateManager& mgr, EStateMsg msg, float arg) override;
if (msg != EStateMsg::Activate)
return;
RemoveMaterial(EMaterialTypes::RadarObject, mgr);
}
}; };
} // namespace MP1 } // namespace MP1
} // namespace urde } // namespace urde

View File

@ -270,7 +270,7 @@ void CPlasmaProjectile::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId send
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType); mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
DeletePlasmaLights(mgr); DeletePlasmaLights(mgr);
if (x548_29_activePlayerPhazon) { if (x548_29_activePlayerPhazon) {
mgr.GetPlayer().DecrementPhazon(); mgr.GetPlayer().DecrementEnvironmentDamage();
x548_29_activePlayerPhazon = false; x548_29_activePlayerPhazon = false;
} }
break; break;
@ -298,7 +298,7 @@ void CPlasmaProjectile::UpdatePlayerEffects(float dt, CStateManager& mgr) {
if ((x478_beamAttributes & 0x8) && !x548_29_activePlayerPhazon) { if ((x478_beamAttributes & 0x8) && !x548_29_activePlayerPhazon) {
x548_29_activePlayerPhazon = true; x548_29_activePlayerPhazon = true;
x4e4_playerDamageTimer = 0.f; x4e4_playerDamageTimer = 0.f;
mgr.GetPlayer().IncrementPhazon(); mgr.GetPlayer().IncrementEnvironmentDamage();
} }
switch (xf0_weaponType) { switch (xf0_weaponType) {
case EWeaponType::Ice: case EWeaponType::Ice:
@ -329,7 +329,7 @@ void CPlasmaProjectile::UpdatePlayerEffects(float dt, CStateManager& mgr) {
zeus::skZero3f); zeus::skZero3f);
x4e4_playerDamageTimer += dt; x4e4_playerDamageTimer += dt;
if (x4e4_playerDamageTimer >= x4e0_playerDamageDuration) { if (x4e4_playerDamageTimer >= x4e0_playerDamageDuration) {
mgr.GetPlayer().DecrementPhazon(); mgr.GetPlayer().DecrementEnvironmentDamage();
x4e4_playerDamageTimer = 0.f; x4e4_playerDamageTimer = 0.f;
x548_29_activePlayerPhazon = false; x548_29_activePlayerPhazon = false;
} }

View File

@ -1,13 +1,20 @@
#include "CDestroyableRock.hpp" #include "Runtime/World/CDestroyableRock.hpp"
#include "TCastTo.hpp" // Generated file, do not modify include path
namespace urde { namespace urde {
CDestroyableRock::CDestroyableRock(TUniqueId id, bool active, std::string_view name, const CEntityInfo& info, CDestroyableRock::CDestroyableRock(TUniqueId id, bool active, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& modelData, float mass, const zeus::CTransform& xf, CModelData&& modelData, float mass,
const CHealthInfo& health, const CDamageVulnerability& vulnerability, const CHealthInfo& health, const CDamageVulnerability& vulnerability,
const CMaterialList& matList, CAssetId fsm, const CActorParameters& actParams, const CMaterialList& matList, CAssetId fsm, const CActorParameters& actParams,
const CModelData& modelData2) const CModelData& modelData2, s32)
: CAi(id, active, name, info, xf, std::move(modelData), modelData.GetBounds(), mass, health, vulnerability, matList, : CAi(id, active, name, info, xf, std::move(modelData), modelData.GetBounds(), mass, health, vulnerability, matList,
fsm, actParams, 0.3f, 0.8f) {} fsm, actParams, 0.3f, 0.8f) {}
void CDestroyableRock::Accept(urde::IVisitor& visitor) {
visitor.Visit(this);
}
void CDestroyableRock::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) {}
void CDestroyableRock::KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type,
bool inDeferred, float magnitude) {}
} // namespace urde } // namespace urde

View File

@ -11,7 +11,12 @@ public:
CDestroyableRock(TUniqueId id, bool active, std::string_view name, const CEntityInfo& info, CDestroyableRock(TUniqueId id, bool active, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& modelData, float mass, const CHealthInfo& health, const zeus::CTransform& xf, CModelData&& modelData, float mass, const CHealthInfo& health,
const CDamageVulnerability& vulnerability, const CMaterialList& matList, CAssetId fsm, const CDamageVulnerability& vulnerability, const CMaterialList& matList, CAssetId fsm,
const CActorParameters& actParams, const CModelData& modelData2); const CActorParameters& actParams, const CModelData& modelData2, s32);
void Accept(IVisitor& visitor) override;
void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override;
void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred,
float magnitude) override;
}; };
} // namespace urde } // namespace urde

View File

@ -14,7 +14,7 @@ class CLightParameters {
friend class CActor; friend class CActor;
public: public:
enum class EShadowTesselation { Zero }; enum class EShadowTesselation { Invalid=-1, Zero };
enum class EWorldLightingOptions { Zero, NormalWorld, NoShadowCast, DisableWorld }; enum class EWorldLightingOptions { Zero, NormalWorld, NoShadowCast, DisableWorld };

View File

@ -2068,14 +2068,14 @@ void CPlayer::UpdateWaterSurfaceCameraBias(CStateManager& mgr) {
} }
} }
void CPlayer::UpdatePhazonCameraShake(float dt, CStateManager& mgr) { void CPlayer::UpdateEnvironmentDamageCameraShake(float dt, CStateManager& mgr) {
xa2c_damageLoopSfxDelayTicks = std::min(2, xa2c_damageLoopSfxDelayTicks + 1); xa2c_damageLoopSfxDelayTicks = std::min(2, xa2c_damageLoopSfxDelayTicks + 1);
if (xa10_phazonCounter != 0) { if (xa10_envDmgCounter != 0) {
if (xa14_phazonCameraShakeTimer == 0.f) if (xa14_envDmgCameraShakeTimer == 0.f)
mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::BuildPhazonCameraShakeData(1.f, 0.075f), false); mgr.GetCameraManager()->AddCameraShaker(CCameraShakeData::BuildPhazonCameraShakeData(1.f, 0.075f), false);
xa14_phazonCameraShakeTimer += dt; xa14_envDmgCameraShakeTimer += dt;
if (xa14_phazonCameraShakeTimer > 2.f) if (xa14_envDmgCameraShakeTimer > 2.f)
xa14_phazonCameraShakeTimer = 0.f; xa14_envDmgCameraShakeTimer = 0.f;
} }
} }
@ -2380,7 +2380,7 @@ void CPlayer::UpdatePlayerControlDirection(float dt, CStateManager& mgr) {
void CPlayer::Think(float dt, CStateManager& mgr) { void CPlayer::Think(float dt, CStateManager& mgr) {
UpdateStepCameraZBias(dt); UpdateStepCameraZBias(dt);
UpdateWaterSurfaceCameraBias(mgr); UpdateWaterSurfaceCameraBias(mgr);
UpdatePhazonCameraShake(dt, mgr); UpdateEnvironmentDamageCameraShake(dt, mgr);
UpdatePhazonDamage(dt, mgr); UpdatePhazonDamage(dt, mgr);
UpdateFreeLook(dt); UpdateFreeLook(dt);
UpdatePlayerHints(mgr); UpdatePlayerHints(mgr);
@ -5681,18 +5681,18 @@ void CPlayer::SetSpawnedMorphBallState(EPlayerMorphBallState state, CStateManage
} }
} }
void CPlayer::DecrementPhazon() { void CPlayer::DecrementEnvironmentDamage() {
if (xa10_phazonCounter == 0) if (xa10_envDmgCounter == 0)
return; return;
xa10_phazonCounter--; xa10_envDmgCounter--;
} }
void CPlayer::IncrementPhazon() { void CPlayer::IncrementEnvironmentDamage() {
if (xa10_phazonCounter != 0) if (xa10_envDmgCounter != 0)
xa10_phazonCounter++; xa10_envDmgCounter++;
else else
xa14_phazonCameraShakeTimer = 0.f; xa14_envDmgCameraShakeTimer = 0.f;
} }
bool CPlayer::CheckSubmerged() const { bool CPlayer::CheckSubmerged() const {

View File

@ -332,8 +332,8 @@ private:
float xa04_preThinkDt = 0.f; float xa04_preThinkDt = 0.f;
CAssetId xa08_steamTextureId; CAssetId xa08_steamTextureId;
CAssetId xa0c_iceTextureId; CAssetId xa0c_iceTextureId;
u32 xa10_phazonCounter = 0; u32 xa10_envDmgCounter = 0;
float xa14_phazonCameraShakeTimer = 0.f; float xa14_envDmgCameraShakeTimer = 0.f;
float xa18_phazonDamageLag = 0.f; float xa18_phazonDamageLag = 0.f;
float xa1c_threatOverride = 0.f; float xa1c_threatOverride = 0.f;
float xa20_radarXYRadiusOverride = 1.f; float xa20_radarXYRadiusOverride = 1.f;
@ -421,7 +421,7 @@ public:
void UpdateFrozenState(const CFinalInput& input, CStateManager& mgr); void UpdateFrozenState(const CFinalInput& input, CStateManager& mgr);
void UpdateStepCameraZBias(float dt); void UpdateStepCameraZBias(float dt);
void UpdateWaterSurfaceCameraBias(CStateManager& mgr); void UpdateWaterSurfaceCameraBias(CStateManager& mgr);
void UpdatePhazonCameraShake(float dt, CStateManager& mgr); void UpdateEnvironmentDamageCameraShake(float dt, CStateManager& mgr);
void UpdatePhazonDamage(float dt, CStateManager& mgr); void UpdatePhazonDamage(float dt, CStateManager& mgr);
void ResetPlayerHintState(); void ResetPlayerHintState();
bool SetAreaPlayerHint(const CScriptPlayerHint& hint, CStateManager& mgr); bool SetAreaPlayerHint(const CScriptPlayerHint& hint, CStateManager& mgr);
@ -604,8 +604,8 @@ public:
ESurfaceRestraints GetSurfaceRestraint() const { ESurfaceRestraints GetSurfaceRestraint() const {
return x2b0_outOfWaterTicks == 2 ? GetCurrentSurfaceRestraint() : ESurfaceRestraints::Water; return x2b0_outOfWaterTicks == 2 ? GetCurrentSurfaceRestraint() : ESurfaceRestraints::Water;
} }
void DecrementPhazon(); void DecrementEnvironmentDamage();
void IncrementPhazon(); void IncrementEnvironmentDamage();
void ApplySubmergedPitchBend(CSfxHandle& sfx); void ApplySubmergedPitchBend(CSfxHandle& sfx);
void DetachActorFromPlayer(); void DetachActorFromPlayer();
bool AttachActorToPlayer(TUniqueId id, bool disableGun); bool AttachActorToPlayer(TUniqueId id, bool disableGun);

View File

@ -2,6 +2,7 @@
#include "Audio/CSfxManager.hpp" #include "Audio/CSfxManager.hpp"
#include "Camera/CCameraManager.hpp" #include "Camera/CCameraManager.hpp"
#include "Character/CModelData.hpp" #include "Character/CModelData.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "Graphics/CTexture.hpp" #include "Graphics/CTexture.hpp"
#include "World/CActorParameters.hpp" #include "World/CActorParameters.hpp"
#include "World/CPlayer.hpp" #include "World/CPlayer.hpp"
@ -39,13 +40,13 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n
, x170_sfx1(CSfxManager::TranslateSFXID(sId1)) , x170_sfx1(CSfxManager::TranslateSFXID(sId1))
, x172_sfx2(CSfxManager::TranslateSFXID(sId2)) , x172_sfx2(CSfxManager::TranslateSFXID(sId2))
, x174_sfx3(CSfxManager::TranslateSFXID(sId3)) , x174_sfx3(CSfxManager::TranslateSFXID(sId3))
, x184_(0.f) , x184_(6, 0.f)
, x1bc_areaSaveId(aId1) , x1bc_areaSaveId(aId1)
, x1c0_layerIdx(aId2) , x1c0_layerIdx(aId2)
, x1c4_item(itemType) { , x1c4_item(itemType) {
x1e4_26_sfx2Played = true; x1e4_26_sfx2Played = true;
if (xe8_function == ESpecialFunction::HUDTarget) if (xe8_function == ESpecialFunction::HUDTarget)
x1c8_ = {{zeus::CVector3f(-1.f), zeus::CVector3f(1.f)}}; x1c8_touchBounds = {{zeus::CVector3f(-1.f), zeus::CVector3f(1.f)}};
} }
void CScriptSpecialFunction::Accept(IVisitor& visitor) { visitor.Visit(this); } void CScriptSpecialFunction::Accept(IVisitor& visitor) { visitor.Visit(this); }
@ -375,9 +376,9 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
break; break;
} }
case ESpecialFunction::AreaDamage: { case ESpecialFunction::AreaDamage: {
if ((msg == EScriptObjectMessage::Deleted || msg == EScriptObjectMessage::Deactivate) && x1e4_31_) { if ((msg == EScriptObjectMessage::Deleted || msg == EScriptObjectMessage::Deactivate) && x1e4_31_inAreaDamage) {
x1e4_31_ = false; x1e4_31_inAreaDamage = false;
mgr.GetPlayer().DecrementPhazon(); mgr.GetPlayer().DecrementEnvironmentDamage();
mgr.SetIsFullThreat(false); mgr.SetIsFullThreat(false);
} }
break; break;
@ -456,11 +457,50 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
} }
} }
void CScriptSpecialFunction::PreRender(CStateManager&, const zeus::CFrustum&) {} void CScriptSpecialFunction::PreRender(CStateManager&, const zeus::CFrustum& frustum) {
if (xe8_function != ESpecialFunction::FogVolume && xe8_function != ESpecialFunction::ViewFrustumTester)
return;
if (!GetActive())
return;
void CScriptSpecialFunction::AddToRenderer(const zeus::CFrustum&, const CStateManager&) const {} bool val;
if (xe8_function == ESpecialFunction::FogVolume) {
val = frustum.aabbFrustumTest(zeus::CAABox(GetTranslation() - x10c_vector3f, GetTranslation() + x10c_vector3f));
} else {
val = frustum.pointFrustumTest(GetTranslation());
}
void CScriptSpecialFunction::Render(const CStateManager&) const {} if (x1e4_30_ == val)
return;
if (!val)
x1e4_29_frustumExited = true;
else
x1e4_28_frustumEntered = true;
}
void CScriptSpecialFunction::AddToRenderer(const zeus::CFrustum&, const CStateManager& mgr) const {
if (!GetActive())
return;
if (xe8_function == ESpecialFunction::FogVolume && x1e4_30_)
EnsureRendered(mgr);
}
void CScriptSpecialFunction::Render(const CStateManager& mgr) const {
if (xe8_function == ESpecialFunction::FogVolume) {
float z = mgr.IntegrateVisorFog(xfc_float1 * std::sin(CGraphics::GetSecondsMod900()));
if (z > 0.f) {
zeus::CVector3f max = GetTranslation() + x10c_vector3f;
max.z() += z;
zeus::CAABox box(GetTranslation() - x10c_vector3f, max);
zeus::CTransform modelMtx = zeus::CTransform::Translate(box.center()) * zeus::CTransform::Scale(box.extents());
g_Renderer->SetModelMatrix(modelMtx);
g_Renderer->RenderFogVolume(x118_color, zeus::CAABox(-1.f, 1.f), nullptr, nullptr);
}
} else
CActor::Render(mgr);
}
void CScriptSpecialFunction::SkipCinematic(CStateManager& stateMgr) { void CScriptSpecialFunction::SkipCinematic(CStateManager& stateMgr) {
SendScriptMsgs(EScriptObjectState::Zero, stateMgr, EScriptObjectMessage::None); SendScriptMsgs(EScriptObjectState::Zero, stateMgr, EScriptObjectMessage::None);
@ -511,8 +551,8 @@ void CScriptSpecialFunction::ThinkIntroBossRingController(float dt, CStateManage
} }
case ERingState::Rotate: { case ERingState::Rotate: {
x1ac_ringRotateTarget = x1ac_ringRotateTarget =
zeus::CQuaternion::fromAxisAngle(zeus::skUp, zeus::CQuaternion::fromAxisAngle(zeus::skUp, zeus::degToRad(xfc_float1 * (x1b8_ringReverse ? 1.f : -1.f) * dt))
zeus::degToRad(xfc_float1 * (x1b8_ringReverse ? 1.f : -1.f) * dt)).transform(x1ac_ringRotateTarget); .transform(x1ac_ringRotateTarget);
bool allReachedTarget = true; bool allReachedTarget = true;
for (auto& rc : x198_ringControllers) { for (auto& rc : x198_ringControllers) {
if (TCastToPtr<CActor> act = mgr.ObjectById(rc.x0_id)) { if (TCastToPtr<CActor> act = mgr.ObjectById(rc.x0_id)) {
@ -595,8 +635,8 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
if (angVel.canBeNormalized()) if (angVel.canBeNormalized())
mag = angVel.magnitude(); mag = angVel.magnitude();
float spinImpulse = (pl.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ? 0.025f * mag float spinImpulse =
: 0.f); (pl.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ? 0.025f * mag : 0.f);
if (spinImpulse > x180_) if (spinImpulse > x180_)
SendScriptMsgs(EScriptObjectState::Play, mgr, EScriptObjectMessage::None); SendScriptMsgs(EScriptObjectState::Play, mgr, EScriptObjectMessage::None);
@ -657,10 +697,6 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr
x1e4_26_sfx2Played = false; x1e4_26_sfx2Played = false;
(void)r23; (void)r23;
} }
auto average = x184_.GetAverage();
(void)average;
/* TODO Finish */
} }
} }
} }
@ -671,8 +707,8 @@ void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr)
TUniqueId followerAct = kInvalidUniqueId; TUniqueId followerAct = kInvalidUniqueId;
TUniqueId followedAct = kInvalidUniqueId; TUniqueId followedAct = kInvalidUniqueId;
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play || (conn.x4_msg != EScriptObjectMessage::Activate && if (conn.x0_state != EScriptObjectState::Play ||
conn.x4_msg != EScriptObjectMessage::Deactivate)) (conn.x4_msg != EScriptObjectMessage::Activate && conn.x4_msg != EScriptObjectMessage::Deactivate))
continue; continue;
auto search = mgr.GetIdListForScript(conn.x8_objId); auto search = mgr.GetIdListForScript(conn.x8_objId);
@ -700,8 +736,8 @@ void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr)
TUniqueId followerAct = kInvalidUniqueId; TUniqueId followerAct = kInvalidUniqueId;
TUniqueId followedAct = kInvalidUniqueId; TUniqueId followedAct = kInvalidUniqueId;
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play || (conn.x4_msg != EScriptObjectMessage::Activate && if (conn.x0_state != EScriptObjectState::Play ||
conn.x4_msg != EScriptObjectMessage::Deactivate)) (conn.x4_msg != EScriptObjectMessage::Activate && conn.x4_msg != EScriptObjectMessage::Deactivate))
continue; continue;
auto search = mgr.GetIdListForScript(conn.x8_objId); auto search = mgr.GetIdListForScript(conn.x8_objId);
@ -795,10 +831,43 @@ void CScriptSpecialFunction::ThinkRainSimulator(float, CStateManager& mgr) {
SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None);
} }
void CScriptSpecialFunction::ThinkAreaDamage(float, CStateManager& mgr) { void CScriptSpecialFunction::ThinkAreaDamage(float dt, CStateManager& mgr) {
const auto& playerState = mgr.GetPlayerState(); const auto& playerState = mgr.GetPlayerState();
const CPlayer& player = mgr.GetPlayer(); CPlayer& player = mgr.GetPlayer();
/* The following check is a URDE addition */
if (!playerState->CanTakeDamage()) {
/* Make sure we're not currently set to take damage, if so reset our state to be as if we're not */
if (x1e4_31_inAreaDamage) {
x1e4_31_inAreaDamage = false;
player.DecrementEnvironmentDamage();
SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::None);
mgr.SetIsFullThreat(false);
}
return;
}
/* End URDE Addition */
if (!x1e4_31_inAreaDamage) {
if (mgr.GetPlayer().GetAreaIdAlways() != GetAreaIdAlways() ||
playerState->GetCurrentSuitRaw() != CPlayerState::EPlayerSuit::Power)
return;
x1e4_31_inAreaDamage = true;
player.IncrementEnvironmentDamage();
SendScriptMsgs(EScriptObjectState::Entered, mgr, EScriptObjectMessage::None);
mgr.SetIsFullThreat(true);
} else if (mgr.GetPlayer().GetAreaIdAlways() != GetAreaIdAlways() ||
playerState->GetCurrentSuitRaw() != CPlayerState::EPlayerSuit::Power) {
x1e4_31_inAreaDamage = false;
player.DecrementEnvironmentDamage();
SendScriptMsgs(EScriptObjectState::Exited, mgr, EScriptObjectMessage::None);
mgr.SetIsFullThreat(false);
return;
}
CDamageInfo dInfo(CWeaponMode(EWeaponType::Heat), xfc_float1 * dt, 0.f, 0.f);
dInfo.SetNoImmunity(true);
mgr.ApplyDamage(GetUniqueId(), player.GetUniqueId(), GetUniqueId(), dInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
} }
void CScriptSpecialFunction::ThinkPlayerInArea(float dt, CStateManager& mgr) { void CScriptSpecialFunction::ThinkPlayerInArea(float dt, CStateManager& mgr) {

View File

@ -60,12 +60,7 @@ public:
One, One,
}; };
enum class ERingState { enum class ERingState { Scramble, Rotate, Stopped, Breakup };
Scramble,
Rotate,
Stopped,
Breakup
};
struct SRingController { struct SRingController {
TUniqueId x0_id; TUniqueId x0_id;
@ -94,7 +89,7 @@ private:
CSfxHandle x178_sfxHandle; CSfxHandle x178_sfxHandle;
u32 x17c_; u32 x17c_;
float x180_ = 0.f; float x180_ = 0.f;
TReservedAverage<float, 6> x184_; std::vector<float> x184_;
float x194_ = 0.f; float x194_ = 0.f;
std::vector<SRingController> x198_ringControllers; std::vector<SRingController> x198_ringControllers;
ERingState x1a8_ringState = ERingState::Stopped; ERingState x1a8_ringState = ERingState::Stopped;
@ -103,7 +98,7 @@ private:
s32 x1bc_areaSaveId; s32 x1bc_areaSaveId;
s32 x1c0_layerIdx; s32 x1c0_layerIdx;
CPlayerState::EItemType x1c4_item; CPlayerState::EItemType x1c4_item;
std::optional<zeus::CAABox> x1c8_; std::optional<zeus::CAABox> x1c8_touchBounds;
union { union {
struct { struct {
bool x1e4_24_ : 1; bool x1e4_24_ : 1;
@ -113,7 +108,7 @@ private:
bool x1e4_28_frustumEntered : 1; bool x1e4_28_frustumEntered : 1;
bool x1e4_29_frustumExited : 1; bool x1e4_29_frustumExited : 1;
bool x1e4_30_ : 1; bool x1e4_30_ : 1;
bool x1e4_31_ : 1; bool x1e4_31_inAreaDamage : 1;
bool x1e5_24_doSave : 1; bool x1e5_24_doSave : 1;
bool x1e5_25_playerInArea : 1; bool x1e5_25_playerInArea : 1;
bool x1e5_26_displayBillboard : 1; bool x1e5_26_displayBillboard : 1;
@ -132,6 +127,7 @@ public:
void PreRender(CStateManager&, const zeus::CFrustum&) override; void PreRender(CStateManager&, const zeus::CFrustum&) override;
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override; void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const override;
void Render(const CStateManager&) const override; void Render(const CStateManager&) const override;
std::optional<zeus::CAABox> GetTouchBounds() const override { return x1c8_touchBounds; }
void SkipCinematic(CStateManager&); void SkipCinematic(CStateManager&);
void RingScramble(CStateManager&); void RingScramble(CStateManager&);

View File

@ -45,7 +45,7 @@ void CScriptTrigger::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CS
if (x148_28_playerTriggerProc) { if (x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false; x148_28_playerTriggerProc = false;
if (x148_29_didPhazonDamage) { if (x148_29_didPhazonDamage) {
mgr.Player()->DecrementPhazon(); mgr.Player()->DecrementEnvironmentDamage();
x148_29_didPhazonDamage = false; x148_29_didPhazonDamage = false;
} }
@ -89,7 +89,7 @@ void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) {
if (x148_28_playerTriggerProc) { if (x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false; x148_28_playerTriggerProc = false;
if (x148_29_didPhazonDamage) { if (x148_29_didPhazonDamage) {
mgr.GetPlayer().DecrementPhazon(); mgr.GetPlayer().DecrementEnvironmentDamage();
x148_29_didPhazonDamage = false; x148_29_didPhazonDamage = false;
} }
@ -132,7 +132,7 @@ void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) {
if (mgr.GetPlayer().GetUniqueId() == tmpId && x148_28_playerTriggerProc) { if (mgr.GetPlayer().GetUniqueId() == tmpId && x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false; x148_28_playerTriggerProc = false;
if (x148_29_didPhazonDamage) { if (x148_29_didPhazonDamage) {
mgr.Player()->DecrementPhazon(); mgr.Player()->DecrementEnvironmentDamage();
x148_29_didPhazonDamage = false; x148_29_didPhazonDamage = false;
} }
@ -148,7 +148,7 @@ void CScriptTrigger::UpdateInhabitants(float dt, CStateManager& mgr) {
if (mgr.GetPlayer().GetUniqueId() == tmpId && x148_28_playerTriggerProc) { if (mgr.GetPlayer().GetUniqueId() == tmpId && x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = false; x148_28_playerTriggerProc = false;
if (x148_29_didPhazonDamage) { if (x148_29_didPhazonDamage) {
mgr.Player()->DecrementPhazon(); mgr.Player()->DecrementEnvironmentDamage();
x148_29_didPhazonDamage = false; x148_29_didPhazonDamage = false;
} }
@ -246,14 +246,14 @@ void CScriptTrigger::Touch(CActor& act, CStateManager& mgr) {
if (!x148_28_playerTriggerProc) { if (!x148_28_playerTriggerProc) {
x148_28_playerTriggerProc = true; x148_28_playerTriggerProc = true;
if (x148_29_didPhazonDamage) { if (x148_29_didPhazonDamage) {
mgr.Player()->DecrementPhazon(); mgr.Player()->DecrementEnvironmentDamage();
x148_29_didPhazonDamage = false; x148_29_didPhazonDamage = false;
} else if (x100_damageInfo.GetDamage() > 0.f) { } else if (x100_damageInfo.GetDamage() > 0.f) {
const CDamageVulnerability* dVuln = mgr.Player()->GetDamageVulnerability(); const CDamageVulnerability* dVuln = mgr.Player()->GetDamageVulnerability();
if (dVuln->WeaponHurts(x100_damageInfo.GetWeaponMode(), 0) && if (dVuln->WeaponHurts(x100_damageInfo.GetWeaponMode(), 0) &&
x100_damageInfo.GetWeaponMode().GetType() == EWeaponType::Phazon && x100_damageInfo.GetWeaponMode().GetType() == EWeaponType::Phazon &&
!mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PhazonSuit)) { !mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::PhazonSuit)) {
pl->IncrementPhazon(); pl->IncrementEnvironmentDamage();
x148_29_didPhazonDamage = true; x148_29_didPhazonDamage = true;
} }
} }

View File

@ -2559,14 +2559,14 @@ CEntity* ScriptLoader::LoadThardus(CStateManager& mgr, CInputStream& in, int pro
int sfxID2 = in.readUint32Big(); int sfxID2 = in.readUint32Big();
int sfxID3 = in.readUint32Big(); int sfxID3 = in.readUint32Big();
int sfxID4 = in.readUint32Big(); int sfxID4 = in.readUint32Big();
std::vector<CModelData> mData1(7); std::vector<CStaticRes> mData1(7);
std::vector<CModelData> mData2(7); std::vector<CStaticRes> mData2(7);
mData1.assign(std::rbegin(staticRes[1]), std::rend(staticRes[1])); mData1.assign(std::rbegin(staticRes[0]), std::rend(staticRes[0]));
mData2.assign(std::rbegin(staticRes[0]), std::rend(staticRes[0])); mData2.assign(std::rbegin(staticRes[1]), std::rend(staticRes[1]));
CModelData mData(CAnimRes(animParms.GetACSFile(), 0, actHead.x40_scale, animParms.GetInitialAnimation(), true)); CModelData mData(CAnimRes(animParms.GetACSFile(), 0, actHead.x40_scale, animParms.GetInitialAnimation(), true));
return new MP1::CThardus(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, std::move(mData), return new MP1::CThardus(mgr.AllocateUniqueId(), actHead.x0_name, info, actHead.x10_transform, std::move(mData),
actParms, pInfo, std::move(mData2), std::move(mData1), particle1, particle2, particle3, f1, actParms, pInfo, mData1, mData2, particle2, particle2, particle3, f1,
f2, f3, f4, f5, f6, stateMachine, particle4, particle5, particle6, particle7, particle8, f2, f3, f4, f5, f6, stateMachine, particle4, particle5, particle6, particle7, particle8,
particle9, texture, sfxID1, particle10, sfxID2, sfxID3, sfxID4); particle9, texture, sfxID1, particle10, sfxID2, sfxID3, sfxID4);
} }