diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index d7e7012ec..e3b0700a2 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -12,6 +12,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8a11abe5d..4e3f3d560 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -130,7 +130,7 @@ else()
message(STATUS "Building with x87 Vector ISA")
endif()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar -fno-exceptions -fno-rtti -Werror")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar -Werror=implicit-fallthrough -fno-exceptions -fno-rtti -Werror")
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations")
diff --git a/DataSpec/DNACommon/ANIM.cpp b/DataSpec/DNACommon/ANIM.cpp
index 0f9177734..e41dda999 100644
--- a/DataSpec/DNACommon/ANIM.cpp
+++ b/DataSpec/DNACommon/ANIM.cpp
@@ -11,6 +11,7 @@ size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector& ch
switch (chan.type) {
case Channel::Type::Rotation:
bitsPerKeyFrame += 1;
+ [[fallthrough]];
case Channel::Type::Translation:
case Channel::Type::Scale:
bitsPerKeyFrame += chan.q[0];
diff --git a/DataSpec/DNACommon/CMDL.cpp b/DataSpec/DNACommon/CMDL.cpp
index 5fde36861..095667d40 100644
--- a/DataSpec/DNACommon/CMDL.cpp
+++ b/DataSpec/DNACommon/CMDL.cpp
@@ -652,6 +652,7 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
lastDlSec = s + reader.readUint32Big() + 1;
break;
}
+ [[fallthrough]];
}
default: {
if (!visitedDLOffsets) {
@@ -786,6 +787,7 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::I
visitedDLOffsets = true;
break;
}
+ [[fallthrough]];
}
default: {
if (!visitedDLOffsets) {
diff --git a/DataSpec/DNACommon/DPSC.cpp b/DataSpec/DNACommon/DPSC.cpp
index e7fa74359..31c3d6544 100644
--- a/DataSpec/DNACommon/DPSC.cpp
+++ b/DataSpec/DNACommon/DPSC.cpp
@@ -32,6 +32,7 @@ void DPSM::_read(athena::io::YAMLDocReader& r) {
case SBIG('1TEX'):
case SBIG('1ADD'):
loadFirstDesc = true;
+ [[fallthrough]];
case SBIG('2SZE'):
case SBIG('2LFT'):
case SBIG('2ROT'):
@@ -250,6 +251,7 @@ void DPSM::_read(athena::io::IStreamReader& r) {
case SBIG('1TEX'):
case SBIG('1ADD'):
loadFirstDesc = true;
+ [[fallthrough]];
case SBIG('2SZE'):
case SBIG('2LFT'):
case SBIG('2ROT'):
diff --git a/DataSpec/DNAMP1/FRME.cpp b/DataSpec/DNAMP1/FRME.cpp
index 93a3e641a..8b2cc4405 100644
--- a/DataSpec/DNAMP1/FRME.cpp
+++ b/DataSpec/DNAMP1/FRME.cpp
@@ -373,6 +373,7 @@ bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl:
case LITEInfo::ELightType::Spot:
case LITEInfo::ELightType::Directional:
os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n";
+ [[fallthrough]];
default: {
zeus::simd_floats colorF(w.header.color.simd);
os.format(
diff --git a/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp b/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp
index af871ef57..b3dde0a40 100644
--- a/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp
+++ b/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp
@@ -13,105 +13,105 @@ struct GunTurret : IScriptObject {
Value location;
Value orientation;
Value scale;
- Value unknown2;
- Value scanOffset;
+ Value collisionExtent;
+ Value collisionOffset;
AnimationParameters animationParameters;
ActorParameters actorParameters;
HealthInfo healthInfo;
DamageVulnerability damageVulnerabilty;
- Value unknown3;
- Value unknown4;
- Value unknown5;
- Value unknown6;
- Value unknown7;
- Value unknown8;
- Value unknown9;
- Value unknown10;
- Value unknown11;
- Value unknown12;
- Value unknown13;
- Value unknown14;
- Value unknown15;
- Value unknown16;
- Value unknown17;
- UniqueID32 unknown18;
- DamageInfo damageInfo;
- UniqueID32 particle1;
- UniqueID32 particle2;
- UniqueID32 particle3;
- UniqueID32 particle4;
- UniqueID32 particle5;
- UniqueID32 particle6;
- UniqueID32 particle7;
- Value unknown19;
- Value unknown20;
- Value unknown21;
- Value unknown22;
- Value unknown23;
- Value unknown24;
- UniqueID32 model;
- Value unknown25;
- Value unknown26;
- Value unknown27;
- Value unknown28;
- Value unknown29;
- Value unknown30;
+ Value intoDeactivateDelay;
+ Value reloadTime;
+ Value reloadTimeVariance;
+ Value panStartTime;
+ Value panHoldTime;
+ Value totalPanSearchTime;
+ Value leftMaxAngle;
+ Value rightMaxAngle;
+ Value downMaxAngle;
+ Value turnSpeed;
+ Value detectionRange;
+ Value detectionZRange;
+ Value freezeDuration;
+ Value freezeVariance;
+ Value freezeTimeout;
+ UniqueID32 projectileRes;
+ DamageInfo projectileDamage;
+ UniqueID32 idleLightRes;
+ UniqueID32 deactivateLightRes;
+ UniqueID32 targettingLightRes;
+ UniqueID32 frozenEffectRes;
+ UniqueID32 chargingEffectRes;
+ UniqueID32 panningEffectRes;
+ UniqueID32 visorEffectRes;
+ Value trackingSoundId;
+ Value lockOnSoundId;
+ Value unfreezeSoundId;
+ Value stopClankSoundId;
+ Value chargingSoundId;
+ Value visorSoundId;
+ UniqueID32 extensionModelResId;
+ Value extensionDropDownDist;
+ Value numInitialShots;
+ Value initialShotTableIndex;
+ Value numSubsequentShots;
+ Value frenzyDuration;
+ Value scriptedStartOnly;
void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const {
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters);
}
void nameIDs(PAKRouter& pakRouter) const {
- if (unknown18) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown18);
- ent->name = name + "_unknown18";
+ if (projectileRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileRes);
+ ent->name = name + "_projectileRes";
}
- if (model) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model);
- ent->name = name + "_model";
+ if (idleLightRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(idleLightRes);
+ ent->name = name + "_idleLightRes";
}
- if (particle1) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
- ent->name = name + "_part1";
+ if (deactivateLightRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deactivateLightRes);
+ ent->name = name + "_deactivateLightRes";
}
- if (particle2) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
- ent->name = name + "_part2";
+ if (targettingLightRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(targettingLightRes);
+ ent->name = name + "_targettingLightRes";
}
- if (particle3) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3);
- ent->name = name + "_part3";
+ if (frozenEffectRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(frozenEffectRes);
+ ent->name = name + "_frozenEffectRes";
}
- if (particle4) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4);
- ent->name = name + "_part4";
+ if (chargingEffectRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(chargingEffectRes);
+ ent->name = name + "_chargingEffectRes";
}
- if (particle5) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5);
- ent->name = name + "_part5";
+ if (panningEffectRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(panningEffectRes);
+ ent->name = name + "_panningEffectRes";
}
- if (particle6) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6);
- ent->name = name + "_part6";
+ if (visorEffectRes) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(visorEffectRes);
+ ent->name = name + "_visorEffectRes";
}
- if (particle7) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7);
- ent->name = name + "_part7";
+ if (extensionModelResId) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(extensionModelResId);
+ ent->name = name + "_extensionModelResId";
}
animationParameters.nameANCS(pakRouter, name + "_animp");
actorParameters.nameIDs(pakRouter, name + "_actp");
}
void gatherDependencies(std::vector& pathsOut, std::vector& lazyOut) const {
- g_curSpec->flattenDependencies(unknown18, pathsOut);
- g_curSpec->flattenDependencies(model, pathsOut);
- g_curSpec->flattenDependencies(particle1, pathsOut);
- g_curSpec->flattenDependencies(particle2, pathsOut);
- g_curSpec->flattenDependencies(particle3, pathsOut);
- g_curSpec->flattenDependencies(particle4, pathsOut);
- g_curSpec->flattenDependencies(particle5, pathsOut);
- g_curSpec->flattenDependencies(particle6, pathsOut);
- g_curSpec->flattenDependencies(particle7, pathsOut);
+ g_curSpec->flattenDependencies(projectileRes, pathsOut);
+ g_curSpec->flattenDependencies(idleLightRes, pathsOut);
+ g_curSpec->flattenDependencies(deactivateLightRes, pathsOut);
+ g_curSpec->flattenDependencies(targettingLightRes, pathsOut);
+ g_curSpec->flattenDependencies(frozenEffectRes, pathsOut);
+ g_curSpec->flattenDependencies(chargingEffectRes, pathsOut);
+ g_curSpec->flattenDependencies(panningEffectRes, pathsOut);
+ g_curSpec->flattenDependencies(visorEffectRes, pathsOut);
+ g_curSpec->flattenDependencies(extensionModelResId, pathsOut);
animationParameters.depANCS(pathsOut);
actorParameters.depIDs(pathsOut, lazyOut);
}
diff --git a/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp b/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp
index 0e0beb5b8..49b9d675b 100644
--- a/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp
+++ b/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp
@@ -5,6 +5,7 @@
#include "Parameters.hpp"
namespace DataSpec::DNAMP1 {
+
struct Pickup : IScriptObject {
AT_DECL_DNA_YAML
AT_DECL_DNAV
@@ -17,23 +18,23 @@ struct Pickup : IScriptObject {
Value pickupType;
Value capacity;
Value amount;
- Value dropRate;
- Value lifetime;
- Value spawnDelay;
+ Value possibility;
+ Value lifeTime;
+ Value fadeInTime;
UniqueID32 model;
AnimationParameters animationParameters;
ActorParameters actorParameters;
Value active;
- Value unknown1;
- UniqueID32 particle;
+ Value startDelay;
+ UniqueID32 pickupParticle;
void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const {
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters);
}
void nameIDs(PAKRouter& pakRouter) const {
- if (particle) {
- PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle);
+ if (pickupParticle) {
+ PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(pickupParticle);
ent->name = name + "_part";
}
if (model) {
@@ -45,7 +46,7 @@ struct Pickup : IScriptObject {
}
void gatherDependencies(std::vector& pathsOut, std::vector& lazyOut) const {
- g_curSpec->flattenDependencies(particle, pathsOut);
+ g_curSpec->flattenDependencies(pickupParticle, pathsOut);
g_curSpec->flattenDependencies(model, pathsOut);
animationParameters.depANCS(pathsOut);
actorParameters.depIDs(pathsOut, lazyOut);
@@ -53,4 +54,5 @@ struct Pickup : IScriptObject {
void gatherScans(std::vector& scansOut) const { actorParameters.scanIDs(scansOut); }
};
+
} // namespace DataSpec::DNAMP1
diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp
index a96a8c485..08d97e02b 100644
--- a/Runtime/AutoMapper/CAutoMapper.cpp
+++ b/Runtime/AutoMapper/CAutoMapper.cpp
@@ -124,12 +124,14 @@ bool CAutoMapper::CheckLoadComplete() {
if (!x3c_hintBeacon.IsLoaded())
return false;
x4_loadPhase = ELoadPhase::LoadUniverse;
+ [[fallthrough]];
case ELoadPhase::LoadUniverse:
if (!x8_mapu.IsLoaded())
return false;
x14_dummyWorlds.resize(x8_mapu->GetNumMapWorldDatas());
SetCurWorldAssetId(x24_world->IGetWorldAssetId());
x4_loadPhase = ELoadPhase::Done;
+ [[fallthrough]];
case ELoadPhase::Done:
return true;
default:
diff --git a/Runtime/AutoMapper/CMappableObject.cpp b/Runtime/AutoMapper/CMappableObject.cpp
index e535dc4d8..6688e09d1 100644
--- a/Runtime/AutoMapper/CMappableObject.cpp
+++ b/Runtime/AutoMapper/CMappableObject.cpp
@@ -85,6 +85,7 @@ std::pair CMappableObject::GetDoorColors(int curArea
case EMappableObjectType::PlasmaDoorFloor:
case EMappableObjectType::PlasmaDoorFloor2:
colorIdx = 4;
+ break;
default:
break;
}
diff --git a/Runtime/CGameOptions.cpp b/Runtime/CGameOptions.cpp
index 06d5298ad..36849484d 100644
--- a/Runtime/CGameOptions.cpp
+++ b/Runtime/CGameOptions.cpp
@@ -639,6 +639,7 @@ void CHintOptions::Update(float dt, const CStateManager& stateMgr) {
case EHintState::Displaying:
if (x10_nextHintIdx == -1)
x10_nextHintIdx = idx;
+ break;
default:
break;
}
diff --git a/Runtime/CIOWinManager.cpp b/Runtime/CIOWinManager.cpp
index dde1e8a4c..c4ffdf77a 100644
--- a/Runtime/CIOWinManager.cpp
+++ b/Runtime/CIOWinManager.cpp
@@ -73,6 +73,7 @@ bool CIOWinManager::DistributeOneMessage(const CArchitectureMessage& msg, CArchi
case CIOWin::EMessageReturn::RemoveIOWinAndExit:
case CIOWin::EMessageReturn::RemoveIOWin:
RemoveIOWin(iow);
+ break;
default:
break;
}
diff --git a/Runtime/CPlayerState.cpp b/Runtime/CPlayerState.cpp
index dc8084b49..cdaa7b8a4 100644
--- a/Runtime/CPlayerState.cpp
+++ b/Runtime/CPlayerState.cpp
@@ -322,7 +322,7 @@ void CPlayerState::IncrPickup(EItemType type, u32 amount) {
}
case EItemType::HealthRefill:
xc_health.SetHP(std::min(amount + xc_health.GetHP(), CalculateHealth()));
- [[fallthrough]];
+ break;
default:
break;
}
diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp
index a07e59683..b50c03db2 100644
--- a/Runtime/CStateManager.cpp
+++ b/Runtime/CStateManager.cpp
@@ -1691,6 +1691,7 @@ void CStateManager::SetGameState(EGameState state) {
if (!x88c_rumbleManager->IsDisabled())
x88c_rumbleManager->SetDisabled(true);
x850_world->SetLoadPauseState(true);
+ break;
default:
break;
}
diff --git a/Runtime/Camera/CBallCamera.cpp b/Runtime/Camera/CBallCamera.cpp
index 6f0b87dc0..a6b552c4e 100644
--- a/Runtime/Camera/CBallCamera.cpp
+++ b/Runtime/Camera/CBallCamera.cpp
@@ -249,6 +249,7 @@ void CBallCamera::SetState(EBallCameraState state, CStateManager& mgr) {
SetFovInterpolation(mgr.GetCameraManager()->GetFirstPersonCamera()->GetFov(), CCameraManager::ThirdPersonFOV(), 1.f,
0.f);
x36c_splineState = ESplineState::Invalid;
+ [[fallthrough]];
}
case EBallCameraState::Default:
case EBallCameraState::Chase:
@@ -1804,6 +1805,7 @@ void CBallCamera::Think(float dt, CStateManager& mgr) {
colAct->SetActive(false);
return;
}
+ [[fallthrough]];
case CPlayer::EPlayerCameraState::Ball:
case CPlayer::EPlayerCameraState::Transitioning:
case CPlayer::EPlayerCameraState::Two: {
diff --git a/Runtime/Character/CAdditiveAnimPlayback.cpp b/Runtime/Character/CAdditiveAnimPlayback.cpp
index 91e1fe619..f1e9d57ac 100644
--- a/Runtime/Character/CAdditiveAnimPlayback.cpp
+++ b/Runtime/Character/CAdditiveAnimPlayback.cpp
@@ -50,6 +50,7 @@ void CAdditiveAnimPlayback::Update(float dt) {
if (std::fabs(x10_curWeight) < 0.00001f)
x1c_phase = EAdditivePlaybackPhase::FadedOut;
+ break;
}
default:
break;
@@ -64,6 +65,7 @@ void CAdditiveAnimPlayback::FadeOut() {
break;
case EAdditivePlaybackPhase::FadingIn:
x18_weightTimer = x18_weightTimer / x0_info.GetFadeInDuration() * x0_info.GetFadeOutDuration();
+ break;
default:
break;
}
diff --git a/Runtime/Character/CAllFormatsAnimSource.cpp b/Runtime/Character/CAllFormatsAnimSource.cpp
index bf129efa2..0a940076e 100644
--- a/Runtime/Character/CAllFormatsAnimSource.cpp
+++ b/Runtime/Character/CAllFormatsAnimSource.cpp
@@ -36,6 +36,7 @@ CAnimFormatUnion::~CAnimFormatUnion() {
case EAnimFormat::BitstreamCompressed:
case EAnimFormat::BitstreamCompressed24:
reinterpret_cast(x4_storage)->~CFBStreamedCompression();
+ break;
default:
break;
}
diff --git a/Runtime/Collision/CCollisionActorManager.hpp b/Runtime/Collision/CCollisionActorManager.hpp
index 824eddbfd..3f68519be 100644
--- a/Runtime/Collision/CCollisionActorManager.hpp
+++ b/Runtime/Collision/CCollisionActorManager.hpp
@@ -27,6 +27,7 @@ public:
void Update(float dt, CStateManager& mgr, CCollisionActorManager::EUpdateOptions opts);
void Destroy(CStateManager& mgr) const;
void SetActive(CStateManager& mgr, bool active);
+ bool GetActive() const { return x12_active; }
void AddMaterial(CStateManager& mgr, const CMaterialList& list);
void SetMovable(CStateManager& mgr, bool movable);
diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp
index 25cb797aa..eff091e2b 100644
--- a/Runtime/Graphics/CBooRenderer.cpp
+++ b/Runtime/Graphics/CBooRenderer.cpp
@@ -799,6 +799,7 @@ void CBooRenderer::DrawUnsortedGeometry(int areaIdx, int mask, int targetMask, b
model->x40_25_modelVisible = false;
continue;
}
+ break;
}
default:
break;
diff --git a/Runtime/GuiSys/CGuiWidget.cpp b/Runtime/GuiSys/CGuiWidget.cpp
index c01088418..d0cdc7842 100644
--- a/Runtime/GuiSys/CGuiWidget.cpp
+++ b/Runtime/GuiSys/CGuiWidget.cpp
@@ -161,11 +161,13 @@ void CGuiWidget::RecalcWidgetColor(ETraversalMode mode) {
CGuiWidget* nextSib = static_cast(GetNextSibling());
if (nextSib)
nextSib->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings);
+ [[fallthrough]];
}
case ETraversalMode::Children: {
CGuiWidget* child = static_cast(GetChildObject());
if (child)
child->RecalcWidgetColor(ETraversalMode::ChildrenAndSiblings);
+ break;
}
default:
break;
diff --git a/Runtime/GuiSys/CHudMissileInterface.cpp b/Runtime/GuiSys/CHudMissileInterface.cpp
index 6713fc364..fb1768ad5 100644
--- a/Runtime/GuiSys/CHudMissileInterface.cpp
+++ b/Runtime/GuiSys/CHudMissileInterface.cpp
@@ -153,6 +153,7 @@ void CHudMissileInterface::Update(float dt, const CStateManager& mgr) {
break;
case EInventoryStatus::Depleted:
string = g_MainStringTable->GetString(13); // Depleted
+ break;
default:
break;
}
diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp
index 0a4369f57..ddd93d5b9 100644
--- a/Runtime/MP1/CFrontEndUI.cpp
+++ b/Runtime/MP1/CFrontEndUI.cpp
@@ -1816,6 +1816,7 @@ void CFrontEndUI::StartStateTransition(EScreen screen) {
CSfxManager::SfxStart(SFXfnt_fromfusion_L, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
CSfxManager::SfxStart(SFXfnt_fromfusion_R, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
}
+ break;
default:
break;
}
@@ -1829,6 +1830,7 @@ void CFrontEndUI::StartStateTransition(EScreen screen) {
case EScreen::AttractMovie:
StartAttractMovie();
SetFadeBlackWithMovie();
+ break;
default:
break;
}
@@ -2202,6 +2204,7 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue)
/* No memory card available, fallback to non-save UI */
xe0_frontendCardFrme.reset();
xdc_saveUI.reset();
+ break;
default:
break;
}
@@ -2218,6 +2221,7 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue)
FinishedLoadingDepsGroup();
x20_depsGroup.Unlock();
x14_phase = EPhase::LoadDeps;
+ [[fallthrough]];
case EPhase::LoadDeps:
/* Poll loading DGRP resources */
@@ -2233,6 +2237,7 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue)
}
if (x14_phase == EPhase::LoadDeps)
return EMessageReturn::Exit;
+ [[fallthrough]];
case EPhase::LoadFrames:
/* Poll loading music and FRME resources */
@@ -2242,6 +2247,7 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue)
xf4_curAudio = xd4_audio1.get();
xf4_curAudio->StartMixing();
x14_phase = EPhase::LoadMovies;
+ [[fallthrough]];
case EPhase::LoadMovies: {
/* Poll loading movies */
@@ -2263,8 +2269,10 @@ CIOWin::EMessageReturn CFrontEndUI::Update(float dt, CArchitectureQueue& queue)
x14_phase = EPhase::DisplayFrontEnd;
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::PressStart);
StartStateTransition(EScreen::Title);
- } else
+ } else {
return EMessageReturn::Exit;
+ }
+ [[fallthrough]];
}
case EPhase::DisplayFrontEnd:
diff --git a/Runtime/MP1/CGBASupport.cpp b/Runtime/MP1/CGBASupport.cpp
index 6aa2d758d..503791355 100644
--- a/Runtime/MP1/CGBASupport.cpp
+++ b/Runtime/MP1/CGBASupport.cpp
@@ -127,6 +127,7 @@ void CGBASupport::Update(float dt) {
case EPhase::StartProbeTimeout:
x38_timeout = 4.f;
x34_phase = EPhase::PollProbe;
+ [[fallthrough]];
case EPhase::PollProbe:
/* SIProbe poll normally occurs here with 4 second timeout */
@@ -136,6 +137,7 @@ void CGBASupport::Update(float dt) {
}
x40_siChan = g_JbusEndpoint->getChan();
x34_phase = EPhase::StartJoyBusBoot;
+ [[fallthrough]];
case EPhase::StartJoyBusBoot:
x34_phase = EPhase::PollJoyBusBoot;
diff --git a/Runtime/MP1/CInGameGuiManager.cpp b/Runtime/MP1/CInGameGuiManager.cpp
index 112e8a4d8..338829e32 100644
--- a/Runtime/MP1/CInGameGuiManager.cpp
+++ b/Runtime/MP1/CInGameGuiManager.cpp
@@ -143,6 +143,7 @@ void CInGameGuiManager::DoStateTransition(CStateManager& stateMgr) {
CDependencyGroup* suitGrp = x5c_pauseScreenDGRPs[suitResIdx].GetObj();
x48_pauseScreen = std::make_unique(screen, *suitGrp, *suitGrp);
}
+ [[fallthrough]];
case EInGameGuiState::MapScreen:
case EInGameGuiState::PauseSaveGame:
@@ -201,6 +202,7 @@ bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) {
}
x0_iggmPreLoad.Unlock();
x18_loadPhase = ELoadPhase::PreLoadDeps;
+ [[fallthrough]];
}
case ELoadPhase::PreLoadDeps: {
for (CToken& tok : x8_preLoadDeps)
@@ -212,6 +214,7 @@ bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) {
x38_autoMapper = std::make_unique(stateMgr);
x3c_pauseScreenBlur = std::make_unique();
x40_samusReflection = std::make_unique(stateMgr);
+ [[fallthrough]];
}
case ELoadPhase::LoadDeps: {
if (!x38_autoMapper->CheckLoadComplete())
@@ -241,6 +244,7 @@ bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) {
BeginStateTransition(EInGameGuiState::InGame, stateMgr);
x18_loadPhase = ELoadPhase::Done;
+ [[fallthrough]];
}
case ELoadPhase::Done: {
x34_samusHud->Touch();
diff --git a/Runtime/MP1/CMFGame.cpp b/Runtime/MP1/CMFGame.cpp
index adeae38de..469cc142a 100644
--- a/Runtime/MP1/CMFGame.cpp
+++ b/Runtime/MP1/CMFGame.cpp
@@ -50,6 +50,7 @@ CIOWin::EMessageReturn CMFGame::OnMessage(const CArchitectureMessage& msg, CArch
x28_skippedCineCam = kInvalidUniqueId;
break;
}
+ [[fallthrough]];
}
case EGameFlowState::InGame: {
x14_stateManager->SetActiveRandomToDefault();
@@ -101,6 +102,7 @@ CIOWin::EMessageReturn CMFGame::OnMessage(const CArchitectureMessage& msg, CArch
x14_stateManager->Update(dt);
x14_stateManager->ClearActiveRandom();
}
+ break;
}
default:
break;
@@ -261,6 +263,7 @@ CMFGameLoader::CMFGameLoader() : CMFGameLoaderBase("CMFGameLoader") {
16.f, 1.f);
}
}
+ break;
}
default:
break;
@@ -346,6 +349,7 @@ CIOWin::EMessageReturn CMFGameLoader::OnMessage(const CArchitectureMessage& msg,
std::make_shared(x14_stateMgr, x18_guiMgr, queue)));
return EMessageReturn::RemoveIOWinAndExit;
}
+ break;
}
default:
break;
diff --git a/Runtime/MP1/CMainFlow.cpp b/Runtime/MP1/CMainFlow.cpp
index 10a21a8db..d833f8b43 100644
--- a/Runtime/MP1/CMainFlow.cpp
+++ b/Runtime/MP1/CMainFlow.cpp
@@ -31,6 +31,7 @@ void CMainFlow::AdvanceGameState(CArchitectureQueue& queue) {
MP1::CMain* main = static_cast(g_Main);
if (main->GetFlowState() != EFlowState::None && main->GetFlowState() != EFlowState::StateSetter)
main->SetX30(true);
+ [[fallthrough]];
}
case EClientFlowStates::Unspecified:
SetGameState(EClientFlowStates::PreFrontEnd, queue);
diff --git a/Runtime/MP1/CMemoryCardDriver.cpp b/Runtime/MP1/CMemoryCardDriver.cpp
index 9a4d6632e..790e12854 100644
--- a/Runtime/MP1/CMemoryCardDriver.cpp
+++ b/Runtime/MP1/CMemoryCardDriver.cpp
@@ -709,6 +709,7 @@ void CMemoryCardDriver::HandleCardError(ECardResult result, EState state) {
case ECardResult::IOERROR:
x10_state = state;
x14_error = EError::CardIOError;
+ [[fallthrough]];
case ECardResult::ENCODING:
x10_state = state;
x14_error = EError::CardWrongCharacterSet;
diff --git a/Runtime/MP1/CSamusHud.cpp b/Runtime/MP1/CSamusHud.cpp
index bf67500cc..088de1c83 100644
--- a/Runtime/MP1/CSamusHud.cpp
+++ b/Runtime/MP1/CSamusHud.cpp
@@ -267,6 +267,7 @@ void CSamusHud::InitializeFrameGlueMutable(const CStateManager& mgr) {
}
case EHudState::None:
UninitializeFrameGlueMutable();
+ break;
default:
break;
}
@@ -1137,10 +1138,13 @@ void CSamusHud::Update(float dt, const CStateManager& mgr, CInGameGuiManager::EH
break;
case CInGameGuiManager::EHelmetVisMode::GlowHelmetDeco:
glowVisible = true;
+ [[fallthrough]];
case CInGameGuiManager::EHelmetVisMode::HelmetDeco:
helmetVisible = true;
+ [[fallthrough]];
case CInGameGuiManager::EHelmetVisMode::Deco:
decoVisible = true;
+ break;
default:
break;
}
@@ -1492,6 +1496,7 @@ void CSamusHud::UpdateStateTransition(float dt, const CStateManager& mgr) {
}
if (x2c4_activeTransState != ETransitionState::Loading)
return;
+ [[fallthrough]];
case ETransitionState::Loading:
if (x278_selectedHud) {
if (!x278_selectedHud.IsLoaded() || !x278_selectedHud->GetIsFinishedLoading())
@@ -1513,6 +1518,7 @@ void CSamusHud::UpdateStateTransition(float dt, const CStateManager& mgr) {
x2c8_transT = std::min(1.f, 5.f * dt + x2c8_transT);
if (x2c8_transT == 1.f)
x2c4_activeTransState = ETransitionState::NotTransitioning;
+ break;
default:
break;
}
@@ -1524,17 +1530,20 @@ bool CSamusHud::CheckLoadComplete(CStateManager& stateMgr) {
if (!x8_targetingMgr.CheckLoadComplete())
return false;
x4_loadPhase = ELoadPhase::One;
+ [[fallthrough]];
case ELoadPhase::One:
UpdateStateTransition(1.f, stateMgr);
if (x2bc_nextState != x2c0_setState)
return false;
x4_loadPhase = ELoadPhase::Two;
+ [[fallthrough]];
case ELoadPhase::Two:
if (!x264_loadedFrmeHelmet->GetIsFinishedLoading())
return false;
if (!x274_loadedFrmeBaseHud->GetIsFinishedLoading())
return false;
x4_loadPhase = ELoadPhase::Three;
+ [[fallthrough]];
case ELoadPhase::Three:
return true;
default:
diff --git a/Runtime/MP1/CSaveGameScreen.cpp b/Runtime/MP1/CSaveGameScreen.cpp
index 00440054d..ffe41233a 100644
--- a/Runtime/MP1/CSaveGameScreen.cpp
+++ b/Runtime/MP1/CSaveGameScreen.cpp
@@ -509,6 +509,7 @@ void CSaveGameScreen::DoAdvance(CGuiTableGroup* caller) {
sfx = x8c_navBackSfx;
}
}
+ break;
default:
break;
diff --git a/Runtime/MP1/CSlideShow.cpp b/Runtime/MP1/CSlideShow.cpp
index 8fc257218..f4b31e093 100644
--- a/Runtime/MP1/CSlideShow.cpp
+++ b/Runtime/MP1/CSlideShow.cpp
@@ -85,6 +85,7 @@ CIOWin::EMessageReturn CSlideShow::OnMessage(const CArchitectureMessage& msg, CA
// return EMessageReturn::Exit;
//}
x14_phase = Phase::One;
+ [[fallthrough]];
}
case Phase::One: {
if (x18_galleryTXTRDeps.empty()) {
@@ -100,12 +101,13 @@ CIOWin::EMessageReturn CSlideShow::OnMessage(const CArchitectureMessage& msg, CA
return EMessageReturn::Exit;
x14_phase = Phase::Three;
+ [[fallthrough]];
}
case Phase::Two:
- case Phase::Three: {
- }
+ case Phase::Three:
case Phase::Four:
case Phase::Five:
+ break;
default:
break;
}
diff --git a/Runtime/MP1/World/CBeetle.cpp b/Runtime/MP1/World/CBeetle.cpp
index c5eac05e2..1471ad14b 100644
--- a/Runtime/MP1/World/CBeetle.cpp
+++ b/Runtime/MP1/World/CBeetle.cpp
@@ -526,6 +526,7 @@ void CBeetle::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) {
default:
break;
}
+ break;
default:
break;
}
diff --git a/Runtime/MP1/World/CMagdolite.cpp b/Runtime/MP1/World/CMagdolite.cpp
index b8518bf21..32c586c28 100644
--- a/Runtime/MP1/World/CMagdolite.cpp
+++ b/Runtime/MP1/World/CMagdolite.cpp
@@ -34,6 +34,7 @@ void CMagdolite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState
//x584_boneTracker.SetActive(false);
CreateShadow(false);
/* TODO Finish */
+ break;
default:
break;
}
diff --git a/Runtime/MP1/World/CParasite.cpp b/Runtime/MP1/World/CParasite.cpp
index 1dcc28a61..0c65516e9 100644
--- a/Runtime/MP1/World/CParasite.cpp
+++ b/Runtime/MP1/World/CParasite.cpp
@@ -63,6 +63,7 @@ CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, c
switch (x5d0_walkerType) {
case EWalkerType::Geemer:
x460_knockBackController.SetEnableFreeze(false);
+ [[fallthrough]];
case EWalkerType::Oculus:
x460_knockBackController.SetAutoResetImpulse(false);
break;
@@ -72,6 +73,7 @@ CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, c
x624_extraModel =
CToken(TObjOwnerDerivedFromIObj::GetNewDerivedObject(std::make_unique(
model, skin, x64_modelData->AnimationData()->GetModelData()->GetLayoutInfo(), 1, 1)));
+ break;
}
default:
break;
diff --git a/Runtime/Particle/CDecalDataFactory.cpp b/Runtime/Particle/CDecalDataFactory.cpp
index 272a95773..a87a2db98 100644
--- a/Runtime/Particle/CDecalDataFactory.cpp
+++ b/Runtime/Particle/CDecalDataFactory.cpp
@@ -43,6 +43,7 @@ bool CDecalDataFactory::CreateDPSM(CDecalDescription* desc, CInputStream& in, CS
case SBIG('1TEX'):
case SBIG('1ADD'):
loadFirstDesc = true;
+ [[fallthrough]];
case SBIG('2LFT'):
case SBIG('2SZE'):
case SBIG('2ROT'):
diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp
index 4f3fdcf1f..a801690ed 100644
--- a/Runtime/Particle/CElementGen.cpp
+++ b/Runtime/Particle/CElementGen.cpp
@@ -710,6 +710,7 @@ void CElementGen::UpdateLightParameters() {
if (CRealElement* lsla = desc->x11c_x108_LSLA.get())
lsla->GetValue(x74_curFrame, x334_LSLA);
}
+ [[fallthrough]];
}
case LightType::Directional: {
if (x308_lightType != LightType::Custom) {
diff --git a/Runtime/Weapon/CGunController.cpp b/Runtime/Weapon/CGunController.cpp
index 35443dd89..bd17a1379 100644
--- a/Runtime/Weapon/CGunController.cpp
+++ b/Runtime/Weapon/CGunController.cpp
@@ -131,8 +131,10 @@ void CGunController::ReturnToDefault(CStateManager& mgr, float dt, bool setState
switch (x50_gunState) {
case EGunState::Strike:
x50_gunState = EGunState::FreeLook;
+ [[fallthrough]];
case EGunState::Idle:
x4_freeLook.SetIdle(false);
+ [[fallthrough]];
case EGunState::FreeLook:
if (setState)
break;
diff --git a/Runtime/Weapon/CIceBeam.cpp b/Runtime/Weapon/CIceBeam.cpp
index acc662340..349306d06 100644
--- a/Runtime/Weapon/CIceBeam.cpp
+++ b/Runtime/Weapon/CIceBeam.cpp
@@ -77,6 +77,7 @@ void CIceBeam::EnableSecondaryFx(ESecondaryFxType type) {
case ESecondaryFxType::None:
if (x1cc_enabledSecondaryEffect == ESecondaryFxType::None)
break;
+ [[fallthrough]];
default:
switch (type) {
case ESecondaryFxType::None:
diff --git a/Runtime/Weapon/CPlasmaBeam.cpp b/Runtime/Weapon/CPlasmaBeam.cpp
index 2a4d75ac7..e47d2614c 100644
--- a/Runtime/Weapon/CPlasmaBeam.cpp
+++ b/Runtime/Weapon/CPlasmaBeam.cpp
@@ -94,6 +94,7 @@ void CPlasmaBeam::EnableSecondaryFx(ESecondaryFxType type) {
case ESecondaryFxType::Charge:
x228_chargeFx = std::make_unique(x21c_plasma2nd1);
x228_chargeFx->SetGlobalScale(x4_scale);
+ break;
default:
break;
}
diff --git a/Runtime/Weapon/CPlayerGun.cpp b/Runtime/Weapon/CPlayerGun.cpp
index 0ba869635..2eb447ba2 100644
--- a/Runtime/Weapon/CPlayerGun.cpp
+++ b/Runtime/Weapon/CPlayerGun.cpp
@@ -612,6 +612,7 @@ void CPlayerGun::ProcessInput(const CFinalInput& input, CStateManager& mgr) {
case CPlayer::EPlayerMorphBallState::Unmorphed:
if ((x2f8_stateFlags & 0x10) != 0x10)
HandleWeaponChange(input, mgr);
+ [[fallthrough]];
case CPlayer::EPlayerMorphBallState::Morphed:
x2f4_fireButtonStates = ControlMapper::GetDigitalInput(ControlMapper::ECommands::FireOrBomb, input) ? 1 : 0;
x2f4_fireButtonStates |=
@@ -1038,6 +1039,7 @@ void CPlayerGun::EnableChargeFx(EChargeState state, CStateManager& mgr) {
case CPlayerState::EBeamId::Plasma:
case CPlayerState::EBeamId::Power:
x832_25_chargeEffectVisible = true;
+ break;
default:
break;
}
diff --git a/Runtime/Weapon/CPowerBeam.cpp b/Runtime/Weapon/CPowerBeam.cpp
index d1069f469..983c92489 100644
--- a/Runtime/Weapon/CPowerBeam.cpp
+++ b/Runtime/Weapon/CPowerBeam.cpp
@@ -46,6 +46,7 @@ void CPowerBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr,
x234_shotSmokeGen->SetParticleEmission(false);
x240_smokeState = ESmokeState::Done;
}
+ [[fallthrough]];
case ESmokeState::Done:
if (x234_shotSmokeGen) {
zeus::CTransform locator = x10_solidModelData->GetScaledLocatorTransform("LBEAM");
diff --git a/Runtime/Weapon/CProjectileInfo.hpp b/Runtime/Weapon/CProjectileInfo.hpp
index e67e90cd5..530fc424e 100644
--- a/Runtime/Weapon/CProjectileInfo.hpp
+++ b/Runtime/Weapon/CProjectileInfo.hpp
@@ -21,7 +21,7 @@ public:
zeus::CVector3f PredictInterceptPos(const zeus::CVector3f& gunPos, const zeus::CVector3f& aimPos,
const CPlayer& player, bool gravity, float dt);
- CDamageInfo GetDamage() const { return xc_damageInfo; }
+ const CDamageInfo& GetDamage() const { return xc_damageInfo; }
TToken& Token() { return x0_weaponDescription; }
};
} // namespace urde
diff --git a/Runtime/Weapon/CWaveBeam.cpp b/Runtime/Weapon/CWaveBeam.cpp
index e37fc141e..712cef614 100644
--- a/Runtime/Weapon/CWaveBeam.cpp
+++ b/Runtime/Weapon/CWaveBeam.cpp
@@ -88,6 +88,7 @@ void CWaveBeam::EnableSecondaryFx(ESecondaryFxType type) {
case ESecondaryFxType::CancelCharge:
if (x1cc_enabledSecondaryEffect == ESecondaryFxType::None)
break;
+ [[fallthrough]];
default:
if (x1cc_enabledSecondaryEffect != ESecondaryFxType::ToCombo) {
auto& fx = type == ESecondaryFxType::Charge ? x228_wave2nd1 : x234_wave2nd2;
@@ -111,6 +112,7 @@ void CWaveBeam::EnableSecondaryFx(ESecondaryFxType type) {
x254_chargeFx->SetGlobalScale(x4_scale);
x24c_effectTimer = 0.f;
x258_25_effectTimerActive = true;
+ break;
default:
break;
}
diff --git a/Runtime/World/CMorphBall.cpp b/Runtime/World/CMorphBall.cpp
index b2a5f1ba4..3ed4aa009 100644
--- a/Runtime/World/CMorphBall.cpp
+++ b/Runtime/World/CMorphBall.cpp
@@ -296,6 +296,7 @@ void CMorphBall::UpdateMorphBallSounds(float dt) {
CSfxManager::UpdateEmitter(x1e2c_rollSfxHandle, x0_player.GetTranslation(), zeus::CVector3f::skZero, maxVol);
break;
}
+ [[fallthrough]];
}
default:
if (x1e2c_rollSfxHandle) {
diff --git a/Runtime/World/CPatterned.cpp b/Runtime/World/CPatterned.cpp
index 5afa68325..d20d72319 100644
--- a/Runtime/World/CPatterned.cpp
+++ b/Runtime/World/CPatterned.cpp
@@ -487,6 +487,7 @@ void CPatterned::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, c
break;
case EKnockBackAnimationFollowUp::LaggedBurnDeath:
x401_29_laggedBurnDeath = true;
+ [[fallthrough]];
case EKnockBackAnimationFollowUp::BurnDeath:
Burn(x460_knockBackController.GetActiveParms().x8_followupDuration, -1.f);
Death(mgr, zeus::CVector3f::skZero, EScriptObjectState::DeathRattle);
@@ -518,6 +519,7 @@ void CPatterned::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, c
MassiveFrozenDeath(mgr);
else if (x450_bodyController->IsFrozen())
x450_bodyController->FrozenBreakout();
+ break;
default:
break;
}
@@ -1639,6 +1641,7 @@ void CPatterned::ThinkAboutMove(float dt) {
case EMoveState::Zero:
if (!x328_26_solidCollision)
break;
+ [[fallthrough]];
case EMoveState::One:
doMove = false;
if (mag > 0.85f) {
@@ -1650,6 +1653,7 @@ void CPatterned::ThinkAboutMove(float dt) {
break;
case EMoveState::Two:
x3f8_moveState = EMoveState::Three;
+ [[fallthrough]];
case EMoveState::Three:
doMove = true;
if (!x328_26_solidCollision) {
diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp
index f5ea9d8b3..98df03b0a 100644
--- a/Runtime/World/CPlayer.cpp
+++ b/Runtime/World/CPlayer.cpp
@@ -508,6 +508,7 @@ void CPlayer::Update(float dt, CStateManager& mgr) {
case EPlayerMorphBallState::Morphing:
case EPlayerMorphBallState::Unmorphing:
x7f4_gunWorldXf = x34_transform * x64_modelData->GetScaledLocatorTransform("GUN_LCTR");
+ break;
case EPlayerMorphBallState::Morphed:
break;
}
@@ -838,6 +839,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location, floa
break;
case EWeaponType::Lava:
damageLoopSfx = SFXpds_lava_damage_lp;
+ [[fallthrough]];
case EWeaponType::Heat:
damageSamusVoiceSfx = SFXsam_vox_damage_heat;
break;
@@ -4382,6 +4384,7 @@ void CPlayer::UpdateOrbitOrientation(CStateManager& mgr) {
case EPlayerOrbitState::OrbitPoint:
if (x3dc_inFreeLook)
return;
+ [[fallthrough]];
case EPlayerOrbitState::OrbitObject:
case EPlayerOrbitState::OrbitCarcass:
case EPlayerOrbitState::ForcedOrbitObject: {
@@ -5382,6 +5385,7 @@ void CPlayer::UpdateCinematicState(CStateManager& mgr) {
ForceGunOrientation(x34_transform, mgr);
DrawGun(mgr);
}
+ break;
default:
break;
}
@@ -5405,6 +5409,7 @@ void CPlayer::UpdateCinematicState(CStateManager& mgr) {
ActivateMorphBallCamera(mgr);
mgr.GetCameraManager()->SetupBallCamera(mgr);
mgr.GetCameraManager()->GetBallCamera()->Reset(CreateTransformFromMovementDirection(), mgr);
+ break;
default:
break;
}
diff --git a/Runtime/World/CScriptGunTurret.cpp b/Runtime/World/CScriptGunTurret.cpp
index 9b446ed8e..e1a251af3 100644
--- a/Runtime/World/CScriptGunTurret.cpp
+++ b/Runtime/World/CScriptGunTurret.cpp
@@ -11,6 +11,8 @@
#include "Character/CPASAnimParmData.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "TCastTo.hpp"
+#include "Weapon/CEnergyProjectile.hpp"
+
namespace urde {
static const CMaterialList skGunMaterialList = {EMaterialTypes::Solid, EMaterialTypes::Character, EMaterialTypes::Orbit,
@@ -18,43 +20,43 @@ static const CMaterialList skGunMaterialList = {EMaterialTypes::Solid, EMaterial
static const CMaterialList skTurretMaterialList = {EMaterialTypes::Character};
CScriptGunTurretData::CScriptGunTurretData(CInputStream& in, s32 propCount)
-: x0_(in.readFloatBig())
-, x4_(in.readFloatBig())
-, x8_(in.readFloatBig())
-, xc_(in.readFloatBig())
-, x10_(in.readFloatBig())
-, x14_(in.readFloatBig())
-, x1c_(zeus::degToRad(in.readFloatBig()))
-, x20_(zeus::degToRad(in.readFloatBig()))
-, x24_(zeus::degToRad(in.readFloatBig()))
-, x28_(zeus::degToRad(in.readFloatBig()))
-, x2c_(in.readFloatBig())
-, x30_(in.readFloatBig())
-, x34_(in.readFloatBig())
-, x38_(in.readFloatBig())
-, x3c_(propCount >= 48 ? in.readBool() : false)
+: x0_intoDeactivateDelay(in.readFloatBig())
+, x4_intoActivateDelay(in.readFloatBig())
+, x8_reloadTime(in.readFloatBig())
+, xc_reloadTimeVariance(in.readFloatBig())
+, x10_panStartTime(in.readFloatBig())
+, x14_panHoldTime(in.readFloatBig())
+, x1c_leftMaxAngle(zeus::degToRad(in.readFloatBig()))
+, x20_rightMaxAngle(zeus::degToRad(in.readFloatBig()))
+, x24_downMaxAngle(zeus::degToRad(in.readFloatBig()))
+, x28_turnSpeed(zeus::degToRad(in.readFloatBig()))
+, x2c_detectionRange(in.readFloatBig())
+, x30_detectionZRange(in.readFloatBig())
+, x34_freezeDuration(in.readFloatBig())
+, x38_freezeVariance(in.readFloatBig())
+, x3c_freezeTimeout(propCount >= 48 ? in.readBool() : false)
, x40_projectileRes(in)
, x44_projectileDamage(in)
-, x60_(in.readUint32Big())
-, x64_(in.readUint32Big())
-, x68_(in.readUint32Big())
-, x6c_(in.readUint32Big())
-, x70_(in.readUint32Big())
-, x74_(in.readUint32Big())
-, x78_(propCount >= 44 ? in.readUint32Big() : -1)
-, x7c_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF))
-, x7e_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF))
-, x80_unfreezeSound(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF))
-, x82_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF))
-, x84_(CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF))
-, x86_(propCount >= 45 ? CSfxManager::TranslateSFXID(in.readUint32Big() & 0xFFFF) : -1)
-, x88_(in.readUint32Big())
-, x8c_(in.readUint32Big())
-, x90_(in.readUint32Big())
-, x94_(in.readUint32Big())
-, x98_(in.readUint32Big())
-, x9c_(propCount >= 47 ? in.readFloatBig() : 3.f)
-, xa0_(propCount >= 46 ? in.readBool() : false) {}
+, x60_idleLightRes(in.readUint32Big())
+, x64_deactivateLightRes(in.readUint32Big())
+, x68_targettingLightRes(in.readUint32Big())
+, x6c_frozenEffectRes(in.readUint32Big())
+, x70_chargingEffectRes(in.readUint32Big())
+, x74_panningEffectRes(in.readUint32Big())
+, x78_visorEffectRes(propCount >= 44 ? in.readUint32Big() : -1)
+, x7c_trackingSoundId(CSfxManager::TranslateSFXID(u16(in.readUint32Big())))
+, x7e_lockOnSoundId(CSfxManager::TranslateSFXID(u16(in.readUint32Big())))
+, x80_unfreezeSoundId(CSfxManager::TranslateSFXID(u16(in.readUint32Big())))
+, x82_stopClankSoundId(CSfxManager::TranslateSFXID(u16(in.readUint32Big())))
+, x84_chargingSoundId(CSfxManager::TranslateSFXID(u16(in.readUint32Big())))
+, x86_visorSoundId(propCount >= 45 ? CSfxManager::TranslateSFXID(u16(in.readUint32Big())) : u16(0xFFFF))
+, x88_extensionModelResId(in.readUint32Big())
+, x8c_extensionDropDownDist(in.readFloatBig())
+, x90_numInitialShots(in.readUint32Big())
+, x94_initialShotTableIndex(in.readUint32Big())
+, x98_numSubsequentShots(in.readUint32Big())
+, x9c_frenzyDuration(propCount >= 47 ? in.readFloatBig() : 3.f)
+, xa0_scriptedStartOnly(propCount >= 46 ? in.readBool() : false) {}
const SBurst CScriptGunTurret::skBurst2InfoTemplate[] = {
{3, {1, 2, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000}, {3, {7, 6, -1, -1, 0, 0, 0, 0}, 0.150000, 0.050000},
@@ -115,37 +117,37 @@ CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurret
, x2d4_data(turretData)
, x37c_projectileInfo(turretData.GetProjectileRes(), turretData.GetProjectileDamage())
, x3a4_burstFire(skBursts, 1)
-, x410_(g_SimplePool->GetObj({SBIG('PART'), turretData.x60_}))
-, x41c_(g_SimplePool->GetObj({SBIG('PART'), turretData.x64_}))
-, x428_(g_SimplePool->GetObj({SBIG('PART'), turretData.x68_}))
-, x434_(g_SimplePool->GetObj({SBIG('PART'), turretData.x6c_}))
-, x440_(g_SimplePool->GetObj({SBIG('PART'), turretData.x70_}))
-, x44c_(g_SimplePool->GetObj({SBIG('PART'), turretData.x74_})) {
- if (turretData.x78_.IsValid())
- x458_ = g_SimplePool->GetObj({SBIG('PART'), turretData.x78_});
- x468_.reset(new CElementGen(x410_));
- x470_.reset(new CElementGen(x41c_));
- x478_.reset(new CElementGen(x428_));
- x480_.reset(new CElementGen(x434_));
- x488_.reset(new CElementGen(x440_));
- x490_.reset(new CElementGen(x44c_));
- x4fc_ = xf.origin;
- x514_ = xf.frontVector();
- x544_ = xf.frontVector();
- x550_ = xf.rightVector();
- x560_24_ = false;
- x560_25_ = false;
- x560_26_ = false;
- x560_27_ = false;
- x560_28_ = false;
- x560_29_ = false;
- x560_30_ = true;
- x560_31_ = false;
+, x410_idleLightDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetIdleLightRes()}))
+, x41c_deactivateLightDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetDeactivateLightRes()}))
+, x428_targettingLightDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetTargettingLightRes()}))
+, x434_frozenEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetFrozenEffectRes()}))
+, x440_chargingEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetChargingEffectRes()}))
+, x44c_panningEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetPanningEffectRes()})) {
+ if (turretData.GetVisorEffectRes().IsValid())
+ x458_visorEffectDesc = g_SimplePool->GetObj({SBIG('PART'), turretData.GetVisorEffectRes()});
+ x468_idleLight.reset(new CElementGen(x410_idleLightDesc));
+ x470_deactivateLight.reset(new CElementGen(x41c_deactivateLightDesc));
+ x478_targettingLight.reset(new CElementGen(x428_targettingLightDesc));
+ x480_frozenEffect.reset(new CElementGen(x434_frozenEffectDesc));
+ x488_chargingEffect.reset(new CElementGen(x440_chargingEffectDesc));
+ x490_panningEffect.reset(new CElementGen(x44c_panningEffectDesc));
+ x4fc_extensionOffset = xf.origin;
+ x514_lastFrontVector = xf.frontVector();
+ x544_originalFrontVec = xf.frontVector();
+ x550_originalRightVec = xf.rightVector();
+ x560_24_dead = false;
+ x560_25_frozen = false;
+ x560_26_firedWithSetBurst = false;
+ x560_27_burstSet = false;
+ x560_28_hasBeenActivated = false;
+ x560_29_scriptedStart = false;
+ x560_30_needsStopClankSound = true;
+ x560_31_frenzyReverse = false;
if (comp == ETurretComponent::Base && HasModelData() && GetModelData()->HasAnimData())
ModelData()->EnableLooping(true);
- const_cast*>(&x37c_projectileInfo.Token())->Lock();
+ x37c_projectileInfo.Token().Lock();
}
void CScriptGunTurret::Accept(IVisitor& visitor) { visitor.Visit(this); }
@@ -164,21 +166,21 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
break;
case EScriptObjectMessage::Registered:
if (x258_type == ETurretComponent::Gun) {
- if (x478_->SystemHasLight()) {
+ if (x478_targettingLight->SystemHasLight()) {
x498_lightId = mgr.AllocateUniqueId();
mgr.AddObject(new CGameLight(x498_lightId, GetAreaIdAlways(), GetActive(),
std::string("ParticleLight_") + GetName().data(), GetTransform(), GetUniqueId(),
- x478_->GetLight(), 0, 1, 0.f));
+ x478_targettingLight->GetLight(), 0, 1, 0.f));
}
SetupCollisionManager(mgr);
} else if (x258_type == ETurretComponent::Base) {
zeus::CVector3f scale = GetModelData()->GetScale();
- if (x2d4_data.x88_.IsValid()) {
- CModelData mData(CStaticRes(x2d4_data.x88_, scale));
- x4a4_.emplace(std::move(mData));
- x4f4_ = x4a4_->GetBounds().max.z() - x4a4_->GetBounds().min.z();
+ if (x2d4_data.GetExtensionModelResId().IsValid()) {
+ CModelData mData(CStaticRes(x2d4_data.GetExtensionModelResId(), scale));
+ x4a4_extensionModel.emplace(std::move(mData));
+ x4f4_extensionRange = x4a4_extensionModel->GetBounds().max.z() - x4a4_extensionModel->GetBounds().min.z();
}
- sub80219b18(5, mgr);
+ SetTurretState(ETurretState::Inactive, mgr);
}
break;
case EScriptObjectMessage::Deleted: {
@@ -186,35 +188,37 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
if (x498_lightId != kInvalidUniqueId)
mgr.FreeScriptObject(x498_lightId);
}
- if (x50c_)
- CSfxManager::RemoveEmitter(x50c_);
+ if (x50c_targetingEmitter)
+ CSfxManager::RemoveEmitter(x50c_targetingEmitter);
if (x49c_collisionManager)
x49c_collisionManager->Destroy(mgr);
break;
}
case EScriptObjectMessage::Start:
- if (x258_type == ETurretComponent::Base && x520_ == 5)
- x560_29_ = true;
+ if (x258_type == ETurretComponent::Base && x520_state == ETurretState::Inactive)
+ x560_29_scriptedStart = true;
break;
case EScriptObjectMessage::Stop:
- if (x258_type == ETurretComponent::Base && x520_ != 1 && x520_ != 2 && x520_ != 3)
- sub80219b18((!x560_28_ ? 3 : 4), mgr);
+ if (x258_type == ETurretComponent::Base && x520_state != ETurretState::Deactive &&
+ x520_state != ETurretState::DeactiveFromReady && x520_state != ETurretState::Deactivating)
+ SetTurretState((x560_28_hasBeenActivated ?
+ ETurretState::DeactivatingFromReady : ETurretState::Deactivating), mgr);
break;
case EScriptObjectMessage::Action: {
if (x258_type == ETurretComponent::Gun)
- sub80217408(mgr);
+ LaunchProjectile(mgr);
else if (x258_type == ETurretComponent::Base)
- sub802172b8(mgr);
+ PlayAdditiveFlinchAnimation(mgr);
break;
}
case EScriptObjectMessage::SetToMax: {
- x560_25_ = false;
+ x560_25_frozen = false;
SetMuted(false);
break;
}
case EScriptObjectMessage::SetToZero: {
- x560_25_ = true;
+ x560_25_frozen = true;
SetMuted(true);
break;
}
@@ -226,7 +230,7 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
if (TCastToConstPtr gun = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) {
x25c_gunId = mgr.GetIdForScript(conn.x8_objId);
- x260_ = gun->GetHealthInfo(mgr)->GetHP();
+ x260_lastGunHP = gun->GetHealthInfo(mgr)->GetHP();
return;
}
}
@@ -237,11 +241,11 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
if (x258_type == ETurretComponent::Gun && GetHealthInfo(mgr)->GetHP() > 0.f) {
if (TCastToConstPtr proj = mgr.GetObjectById(uid)) {
if ((proj->GetAttribField() & EProjectileAttrib::Wave) == EProjectileAttrib::Wave) {
- x520_ = 12;
+ x520_state = ETurretState::Frenzy;
RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), CPlayer::EPlayerOrbitRequest::ActivateOrbitSource,
mgr);
- x53c_ = 0.f;
+ x53c_freezeRemTime = 0.f;
}
}
}
@@ -257,26 +261,27 @@ void CScriptGunTurret::Think(float dt, CStateManager& mgr) {
return;
if (x258_type == ETurretComponent::Base) {
- if (!x560_25_) {
- sub80219a00(dt, mgr);
- sub802189c8();
- sub80217f5c(dt, mgr);
- zeus::CVector3f vec = sub80217e34(dt);
+ if (!x560_25_frozen) {
+ ProcessGunStateMachine(dt, mgr);
+ UpdateTurretAnimation();
+ UpdateGunOrientation(dt, mgr);
+ zeus::CVector3f vec = UpdateExtensionModelState(dt);
SAdvancementDeltas advancementDeltas = UpdateAnimation(dt, mgr, true);
SetTranslation(vec + advancementDeltas.x0_posDelta + GetTranslation());
RotateToOR(advancementDeltas.xc_rotDelta, dt);
} else
Stop();
- sub80216288(dt);
+ UpdateTargettingSound(dt);
} else if (x258_type == ETurretComponent::Gun) {
UpdateGunParticles(dt, mgr);
SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true);
MoveToOR(deltas.x0_posDelta, dt);
RotateToOR(deltas.xc_rotDelta, dt);
UpdateGunCollisionManager(dt, mgr);
- GetUnFreezeSoundId(dt, mgr);
+ UpdateFrozenState(dt, mgr);
}
+ UpdateHealthInfo(mgr);
}
void CScriptGunTurret::Touch(CActor& act, CStateManager& mgr) {
@@ -286,11 +291,13 @@ void CScriptGunTurret::Touch(CActor& act, CStateManager& mgr) {
const CPlayer& player = mgr.GetPlayer();
if (proj->GetOwnerId() == player.GetUniqueId()) {
const CDamageVulnerability* dVuln = GetDamageVulnerability();
- if (!x560_24_ && x520_ != 12 && (proj->GetAttribField() & EProjectileAttrib::Ice) == EProjectileAttrib::Ice &&
+ if (!x560_24_dead && x520_state != ETurretState::Frenzy &&
+ (proj->GetAttribField() & EProjectileAttrib::Ice) == EProjectileAttrib::Ice &&
dVuln->WeaponHits(CWeaponMode::Ice(), false)) {
- x560_24_ = true;
+ x560_25_frozen = true;
SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None);
- x53c_ = mgr.GetActiveRandom()->Float() * x2d4_data.x38_ + x2d4_data.x34_;
+ x53c_freezeRemTime = mgr.GetActiveRandom()->Float() *
+ x2d4_data.GetFreezeVariance() + x2d4_data.GetFreezeDuration();
SetMuted(true);
}
SendScriptMsgs(EScriptObjectState::Damage, mgr, EScriptObjectMessage::None);
@@ -324,48 +331,130 @@ void CScriptGunTurret::SetupCollisionManager(CStateManager& mgr) {
jointDescs.push_back(CJointCollisionDescription::SphereCollision(blastLCTR, 0.3f, "Blast_LCTR"sv, 1000.f));
x49c_collisionManager.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), jointDescs, true));
+
+ x49c_collisionManager->SetActive(mgr, GetActive());
+
+ for (int i = 0; i < x49c_collisionManager->GetNumCollisionActors(); ++i) {
+ auto& desc = x49c_collisionManager->GetCollisionDescFromIndex(i);
+ if (TCastToPtr cAct = mgr.ObjectById(desc.GetCollisionActorId())) {
+ cAct->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr);
+ cAct->SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Player},
+ {EMaterialTypes::Character, EMaterialTypes::NoStaticCollision, EMaterialTypes::NoPlatformCollision}));
+ if (desc.GetName().find("Blast_LCTR"sv) != std::string_view::npos)
+ x4a0_collisionActor = desc.GetCollisionActorId();
+ }
+ }
}
-void CScriptGunTurret::sub80219b18(s32 w1, CStateManager& mgr) {
+static const char* StateNames[] = {
+ "Destroyed",
+ "Deactive",
+ "DeactiveFromReady",
+ "Deactivating",
+ "DeactivatingFromReady",
+ "Inactive",
+ "Ready",
+ "PanningA",
+ "PanningB",
+ "Targeting",
+ "Firing",
+ "ExitTargeting",
+ "Frenzy"
+};
- if (w1 < 0 || w1 > 12)
+void CScriptGunTurret::SetTurretState(ETurretState state, CStateManager& mgr) {
+ if (state < ETurretState::Destroyed || state > ETurretState::Frenzy)
return;
- if (x520_ != -1)
- sub8021998c(2, mgr, 0.f);
+ if (x520_state != ETurretState::Invalid)
+ ProcessCurrentState(EStateMsg::Deactivate, mgr, 0.f);
- x520_ = w1;
- x524_ = 0.f;
- sub8021998c(0, mgr, 0.f);
+ if (state != ETurretState::Invalid && x520_state != state)
+ printf("%04X %08X %s - %s\n", GetUniqueId().Value(), GetEditorId().id, GetName().data(), StateNames[int(state)]);
+ x520_state = state;
+ x524_curStateTime = 0.f;
+ ProcessCurrentState(EStateMsg::Activate, mgr, 0.f);
}
-void CScriptGunTurret::sub80217408(CStateManager&) {}
+static const u32 skStateToLocoTypeLookup[13] = {5, 7, 9, 0, 1, 0, 1, 2, 3, 1, 1, 1, 1};
-void CScriptGunTurret::sub802172b8(CStateManager& mgr) {
+void CScriptGunTurret::LaunchProjectile(CStateManager& mgr) {
+ if (x37c_projectileInfo.Token().IsLoaded() && mgr.CanCreateProjectile(GetUniqueId(), EWeaponType::AI, 8)) {
+ zeus::CTransform xf = GetLocatorTransform("Blast_LCTR"sv);
+ zeus::CVector3f projPt = GetTranslation() + GetTransform().rotate(xf.origin);
+ zeus::CVector3f lookPt = x404_targetPosition;
+ zeus::CVector3f aimDelta = x404_targetPosition - projPt;
+ if (zeus::CVector3f::getAngleDiff(GetTransform().frontVector(), aimDelta) > zeus::degToRad(20.f)) {
+ if (aimDelta.canBeNormalized()) {
+ zeus::CVector3f lookDir =
+ zeus::CVector3f::slerp(GetTransform().frontVector(), aimDelta.normalized(), zeus::degToRad(20.f));
+ lookPt = lookDir * aimDelta.magnitude() + projPt;
+ } else {
+ lookPt = projPt + GetTransform().frontVector();
+ }
+ } else if (!aimDelta.canBeNormalized()) {
+ lookPt = projPt + GetTransform().frontVector();
+ }
+ zeus::CTransform useXf = zeus::lookAt(projPt, lookPt);
+ CEnergyProjectile* proj =
+ new CEnergyProjectile(true, x37c_projectileInfo.Token(), EWeaponType::AI, useXf, EMaterialTypes::Character,
+ x37c_projectileInfo.GetDamage(), mgr.AllocateUniqueId(), GetAreaIdAlways(), GetUniqueId(),
+ kInvalidUniqueId, EProjectileAttrib::None, false, zeus::CVector3f::skOne,
+ x458_visorEffectDesc, x2d4_data.GetVisorSoundId(), false);
+ mgr.AddObject(proj);
+ auto pair =
+ x64_modelData->AnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(
+ CPASAnimParmData(18, CPASAnimParm::FromEnum(1), CPASAnimParm::FromReal32(90.f),
+ CPASAnimParm::FromEnum(skStateToLocoTypeLookup[int(x520_state)])), -1);
+ if (pair.first > 0.f) {
+ x64_modelData->EnableLooping(false);
+ x64_modelData->AnimationData()->SetAnimation(CAnimPlaybackParms(pair.second, -1, 1.f, true), false);
+ }
+ }
+}
+
+void CScriptGunTurret::PlayAdditiveFlinchAnimation(CStateManager& mgr) {
auto pair = ModelData()->AnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(
CPASAnimParmData(23), *mgr.GetActiveRandom(), -1);
if (pair.first > 0.f)
ModelData()->AnimationData()->AddAdditiveAnimation(pair.second, 1.f, false, true);
}
-void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) {
+void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const {
CActor::AddToRenderer(frustum, mgr);
if (x258_type != ETurretComponent::Gun)
return;
- if (!x560_25_) {
- if (x520_ == 6 || (x520_ >= 9 && x520_ <= 12)) {
- g_Renderer->AddParticleGen(*x478_);
- if (x520_ == 10 || x520_ == 12)
- g_Renderer->AddParticleGen(*x488_);
- } else if (x520_ == 5) {
- g_Renderer->AddParticleGen(*x468_);
- } else if (x520_ >= 1) {
- g_Renderer->AddParticleGen(*x470_);
+ if (!x560_25_frozen) {
+ switch (x520_state) {
+ case ETurretState::Deactive:
+ case ETurretState::DeactiveFromReady:
+ case ETurretState::Deactivating:
+ case ETurretState::DeactivatingFromReady:
+ g_Renderer->AddParticleGen(*x470_deactivateLight);
+ break;
+ case ETurretState::Inactive:
+ g_Renderer->AddParticleGen(*x468_idleLight);
+ break;
+ case ETurretState::PanningA:
+ case ETurretState::PanningB:
+ g_Renderer->AddParticleGen(*x490_panningEffect);
+ break;
+ case ETurretState::Ready:
+ case ETurretState::Targeting:
+ case ETurretState::Firing:
+ case ETurretState::ExitTargeting:
+ case ETurretState::Frenzy:
+ g_Renderer->AddParticleGen(*x478_targettingLight);
+ if (x520_state == ETurretState::Firing || x520_state == ETurretState::Frenzy)
+ g_Renderer->AddParticleGen(*x488_chargingEffect);
+ break;
+ default:
+ break;
}
} else {
- g_Renderer->AddParticleGen(*x480_);
+ g_Renderer->AddParticleGen(*x480_frozenEffect);
}
}
@@ -373,47 +462,70 @@ void CScriptGunTurret::Render(const CStateManager& mgr) const {
CPhysicsActor::Render(mgr);
if (x258_type == ETurretComponent::Gun) {
- if (!x560_25_) {
- if (x520_ == 6 || (x520_ >= 9 && x520_ <= 12)) {
- x478_->Render(x90_actorLights.get());
- if (x520_ == 10)
- x488_->Render(x90_actorLights.get());
- } else if (x520_ == 5)
- x468_->Render(x90_actorLights.get());
- else if (x520_ >= 1)
- x470_->Render(x90_actorLights.get());
+ if (!x560_25_frozen) {
+ switch (x520_state) {
+ case ETurretState::Deactive:
+ case ETurretState::DeactiveFromReady:
+ case ETurretState::Deactivating:
+ case ETurretState::DeactivatingFromReady:
+ x470_deactivateLight->Render(x90_actorLights.get());
+ break;
+ case ETurretState::Inactive:
+ x468_idleLight->Render(x90_actorLights.get());
+ break;
+ case ETurretState::PanningA:
+ case ETurretState::PanningB:
+ x490_panningEffect->Render(x90_actorLights.get());
+ break;
+ case ETurretState::Ready:
+ case ETurretState::Targeting:
+ case ETurretState::Firing:
+ case ETurretState::ExitTargeting:
+ case ETurretState::Frenzy:
+ x478_targettingLight->Render(x90_actorLights.get());
+ if (x520_state == ETurretState::Firing)
+ x488_chargingEffect->Render(x90_actorLights.get());
+ break;
+ default:
+ break;
+ }
+ } else {
+ x480_frozenEffect->Render(x90_actorLights.get());
}
} else if (x258_type == ETurretComponent::Base) {
- if (x4a4_ && x4f8_ > 0.f) {
+ if (x4a4_extensionModel && x4f8_extensionT > 0.f) {
zeus::CTransform xf = GetTransform();
- xf.origin = x4fc_ + (x4f4_ * 0.5f * zeus::CVector3f::skDown);
+ xf.origin = x4fc_extensionOffset + (x4f4_extensionRange * 0.5f * zeus::CVector3f::skDown);
CModelFlags flags;
flags.x2_flags = 3;
flags.x1_matSetIdx = 0;
flags.x4_color = zeus::CColor::skWhite;
- x4a4_->Render(mgr, xf, x90_actorLights.get(), flags);
+ x4a4_extensionModel->Render(mgr, xf, x90_actorLights.get(), flags);
}
}
}
void CScriptGunTurret::UpdateGunCollisionManager(float dt, CStateManager& mgr) {
- if (TCastToPtr colAct = mgr.ObjectById(x4a0_))
- colAct->SetActive(mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphed);
+ if (TCastToPtr colAct = mgr.ObjectById(x4a0_collisionActor))
+ colAct->SetActive(mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed);
x49c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
}
-void CScriptGunTurret::GetUnFreezeSoundId(float dt, CStateManager& mgr) {
- if (x560_25_) {
- if (x53c_ <= 0.f) {
+void CScriptGunTurret::UpdateFrozenState(float dt, CStateManager& mgr) {
+ if (x560_25_frozen) {
+ if (x53c_freezeRemTime <= 0.f) {
+ x560_25_frozen = false;
SendScriptMsgs(EScriptObjectState::UnFrozen, mgr, EScriptObjectMessage::None);
- CSfxManager::AddEmitter(x2d4_data.x80_unfreezeSound, GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f,
- GetAreaIdAlways());
+ CSfxManager::AddEmitter(x2d4_data.GetUnFreezeSoundId(), GetTranslation(), zeus::CVector3f::skUp, false, false,
+ 0x7f, GetAreaIdAlways());
SetMuted(false);
- } else if (x2d4_data.x3c_)
- x53c_ -= dt;
- } else
- x53c_ = 0.f;
+ } else if (x2d4_data.GetFreezeTimeout()) {
+ x53c_freezeRemTime -= dt;
+ }
+ } else {
+ x53c_freezeRemTime = 0.f;
+ }
}
void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
@@ -421,29 +533,80 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
if (x498_lightId != kInvalidUniqueId)
light = TCastToPtr(mgr.ObjectById(x498_lightId));
- if (!x560_25_) {
+ if (!x560_25_frozen) {
zeus::CTransform lightXf = GetLocatorTransform("light_LCTR"sv);
zeus::CVector3f pos = x34_transform.rotate(lightXf.origin);
pos += GetTranslation();
if (light)
light->SetActive(true);
- if (x520_ == 6 || (x520_ >= 9 && x520_ <= 12)) {
- bool doEmission = false;
- if (x520_ != 10 && x520_ != 12)
- doEmission = true;
-
- x468_->SetParticleEmission(false);
- x470_->SetParticleEmission(false);
- x478_->SetParticleEmission(true);
- x480_->SetParticleEmission(false);
- x488_->SetParticleEmission(doEmission);
- x478_->SetOrientation(GetTransform().getRotation());
- x478_->SetGlobalTranslation(pos);
- x478_->SetGlobalScale(GetModelData()->GetScale());
- x478_->Update(dt);
- if (x478_->SystemHasLight())
- light->SetLight(x478_->GetLight());
+ switch (x520_state) {
+ case ETurretState::Deactive:
+ case ETurretState::DeactiveFromReady:
+ case ETurretState::Deactivating:
+ case ETurretState::DeactivatingFromReady:
+ x468_idleLight->SetParticleEmission(false);
+ x470_deactivateLight->SetParticleEmission(true);
+ x478_targettingLight->SetParticleEmission(false);
+ x480_frozenEffect->SetParticleEmission(false);
+ x488_chargingEffect->SetParticleEmission(false);
+ x490_panningEffect->SetParticleEmission(false);
+ x470_deactivateLight->SetOrientation(GetTransform().getRotation());
+ x470_deactivateLight->SetGlobalTranslation(pos);
+ x470_deactivateLight->SetGlobalScale(GetModelData()->GetScale());
+ x470_deactivateLight->Update(dt);
+ if (light) {
+ if (x470_deactivateLight->SystemHasLight())
+ light->SetLight(x470_deactivateLight->GetLight());
+ else
+ light->SetActive(false);
+ }
+ break;
+ case ETurretState::Inactive:
+ x468_idleLight->SetParticleEmission(true);
+ x470_deactivateLight->SetParticleEmission(false);
+ x478_targettingLight->SetParticleEmission(false);
+ x480_frozenEffect->SetParticleEmission(false);
+ x488_chargingEffect->SetParticleEmission(false);
+ x490_panningEffect->SetParticleEmission(false);
+ x468_idleLight->SetOrientation(GetTransform().getRotation());
+ x468_idleLight->SetGlobalTranslation(pos);
+ x468_idleLight->SetGlobalScale(GetModelData()->GetScale());
+ x468_idleLight->Update(dt);
+ if (light)
+ light->SetActive(false);
+ break;
+ case ETurretState::PanningA:
+ case ETurretState::PanningB:
+ x468_idleLight->SetParticleEmission(false);
+ x470_deactivateLight->SetParticleEmission(false);
+ x478_targettingLight->SetParticleEmission(false);
+ x480_frozenEffect->SetParticleEmission(false);
+ x488_chargingEffect->SetParticleEmission(false);
+ x490_panningEffect->SetParticleEmission(true);
+ x490_panningEffect->SetOrientation(GetTransform().getRotation());
+ x490_panningEffect->SetGlobalTranslation(GetTranslation());
+ x490_panningEffect->SetGlobalScale(GetModelData()->GetScale());
+ x490_panningEffect->Update(dt);
+ if (light)
+ light->SetActive(false);
+ break;
+ case ETurretState::Targeting:
+ case ETurretState::Firing:
+ case ETurretState::ExitTargeting:
+ case ETurretState::Frenzy: {
+ bool doEmission = x520_state == ETurretState::Firing || x520_state == ETurretState::Frenzy;
+ x468_idleLight->SetParticleEmission(false);
+ x470_deactivateLight->SetParticleEmission(false);
+ x478_targettingLight->SetParticleEmission(true);
+ x480_frozenEffect->SetParticleEmission(false);
+ x488_chargingEffect->SetParticleEmission(doEmission);
+ x478_targettingLight->SetOrientation(GetTransform().getRotation());
+ x478_targettingLight->SetGlobalTranslation(pos);
+ x478_targettingLight->SetGlobalScale(GetModelData()->GetScale());
+ x478_targettingLight->Update(dt);
+ if (x478_targettingLight->SystemHasLight())
+ light->SetLight(x478_targettingLight->GetLight());
else
light->SetActive(false);
@@ -451,74 +614,51 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
zeus::CTransform blastXf = GetLocatorTransform("Blast_LCTR"sv);
zeus::CVector3f blastPos = GetTransform().rotate(blastXf.origin);
blastPos += GetTranslation();
- x488_->SetOrientation(GetTransform().getRotation());
- x488_->SetGlobalTranslation(blastPos);
- x488_->SetGlobalScale(GetModelData()->GetScale());
- x488_->Update(dt);
+ x488_chargingEffect->SetOrientation(GetTransform().getRotation());
+ x488_chargingEffect->SetGlobalTranslation(blastPos);
+ x488_chargingEffect->SetGlobalScale(GetModelData()->GetScale());
+ x488_chargingEffect->Update(dt);
}
- } else if (x520_ == 5) {
- x468_->SetParticleEmission(true);
- x470_->SetParticleEmission(false);
- x478_->SetParticleEmission(false);
- x480_->SetParticleEmission(false);
- x488_->SetParticleEmission(false);
- x490_->SetParticleEmission(false);
- x468_->SetOrientation(GetTransform().getRotation());
- x468_->SetGlobalTranslation(pos);
- x468_->SetGlobalScale(GetModelData()->GetScale());
- } else if (x520_ > 0 && x520_ < 5) {
- x468_->SetParticleEmission(false);
- x470_->SetParticleEmission(true);
- x478_->SetParticleEmission(false);
- x480_->SetParticleEmission(false);
- x488_->SetParticleEmission(false);
- x490_->SetParticleEmission(false);
- x470_->SetOrientation(GetTransform().getRotation());
- x470_->SetGlobalTranslation(pos);
- x470_->SetGlobalScale(GetModelData()->GetScale());
- x470_->Update(dt);
- if (light && x470_->SystemHasLight())
- light->SetLight(x470_->GetLight());
- } else {
- x468_->SetParticleEmission(false);
- x470_->SetParticleEmission(false);
- x478_->SetParticleEmission(false);
- x480_->SetParticleEmission(false);
- x488_->SetParticleEmission(false);
- x490_->SetParticleEmission(false);
- x480_->SetOrientation(GetTransform().getRotation());
- x480_->SetGlobalTranslation(GetTranslation());
- x480_->SetGlobalScale(GetModelData()->GetScale());
- x480_->Update(dt);
+ break;
+ }
+ default:
+ x468_idleLight->SetParticleEmission(false);
+ x470_deactivateLight->SetParticleEmission(false);
+ x478_targettingLight->SetParticleEmission(false);
+ x480_frozenEffect->SetParticleEmission(false);
+ x488_chargingEffect->SetParticleEmission(false);
+ x490_panningEffect->SetParticleEmission(false);
+ x490_panningEffect->Update(dt);
if (light)
light->SetActive(false);
+ break;
}
} else {
- x468_->SetParticleEmission(false);
- x470_->SetParticleEmission(false);
- x478_->SetParticleEmission(false);
- x480_->SetParticleEmission(false);
- x488_->SetParticleEmission(false);
- x490_->SetParticleEmission(false);
- x480_->SetOrientation(GetTransform().getRotation());
- x480_->SetGlobalTranslation(GetTranslation());
- x480_->SetGlobalScale(GetModelData()->GetScale());
- x480_->Update(dt);
+ x468_idleLight->SetParticleEmission(false);
+ x470_deactivateLight->SetParticleEmission(false);
+ x478_targettingLight->SetParticleEmission(false);
+ x480_frozenEffect->SetParticleEmission(true);
+ x488_chargingEffect->SetParticleEmission(false);
+ x490_panningEffect->SetParticleEmission(false);
+ x480_frozenEffect->SetOrientation(GetTransform().getRotation());
+ x480_frozenEffect->SetGlobalTranslation(GetTranslation());
+ x480_frozenEffect->SetGlobalScale(GetModelData()->GetScale());
+ x480_frozenEffect->Update(dt);
if (light)
light->SetActive(false);
}
}
-void CScriptGunTurret::sub80219a00(float dt, CStateManager& mgr) {
- sub80219b18(1, mgr);
- x524_ += dt;
- sub80217124(mgr);
+void CScriptGunTurret::ProcessGunStateMachine(float dt, CStateManager& mgr) {
+ ProcessCurrentState(EStateMsg::Update, mgr, dt);
+ x524_curStateTime += dt;
+ PlayAdditiveChargingAnimation(mgr);
if (x25c_gunId != kInvalidUniqueId) {
if (TCastToPtr gunTurret = mgr.ObjectById(x25c_gunId)) {
- if (gunTurret->x520_ != 12)
- gunTurret->x520_ = x520_;
- else if (x520_ != 12) {
- sub80219b18(12, mgr);
+ if (gunTurret->x520_state != ETurretState::Frenzy)
+ gunTurret->x520_state = x520_state;
+ else if (x520_state != ETurretState::Frenzy) {
+ SetTurretState(ETurretState::Frenzy, mgr);
gunTurret->RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr);
}
@@ -526,252 +666,342 @@ void CScriptGunTurret::sub80219a00(float dt, CStateManager& mgr) {
}
}
-void CScriptGunTurret::sub802189c8() {
+void CScriptGunTurret::UpdateTurretAnimation() {
if (!HasModelData() || !GetModelData()->HasAnimData())
return;
- if (x520_ > 12)
+ if (x520_state > ETurretState::Frenzy)
return;
- static const u32 animIds[13] = {5, 7, 9, 0, 1, 0, 1, 2, 3, 1, 1, 1, 1};
- CPASAnimParmData parmData = CPASAnimParmData(5, CPASAnimParm::FromEnum(0), CPASAnimParm::FromEnum(animIds[x520_]));
+ CPASAnimParmData parmData = CPASAnimParmData(5, CPASAnimParm::FromEnum(0),
+ CPASAnimParm::FromEnum(skStateToLocoTypeLookup[int(x520_state)]));
auto pair = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(parmData, -1);
- if (pair.first > 0.f && pair.second != x540_) {
+ if (pair.first > 0.f && pair.second != x540_turretAnim) {
ModelData()->AnimationData()->SetAnimation(CAnimPlaybackParms(pair.second, -1, 1.f, true), false);
ModelData()->AnimationData()->EnableLooping(true);
- x540_ = pair.second;
+ x540_turretAnim = pair.second;
}
}
-void CScriptGunTurret::sub8021998c(s32 w1, CStateManager& mgr, float dt) {
- switch (x520_) {
- case 3:
- case 4:
- sub80219938(w1, mgr);
+void CScriptGunTurret::ProcessCurrentState(EStateMsg msg, CStateManager& mgr, float dt) {
+ switch (x520_state) {
+ case ETurretState::Deactivating:
+ case ETurretState::DeactivatingFromReady:
+ ProcessDeactivatingState(msg, mgr);
break;
- case 5:
- sub802196c4(w1, mgr, dt);
+ case ETurretState::Inactive:
+ ProcessInactiveState(msg, mgr, dt);
break;
- case 6:
- sub802195bc(w1, mgr, dt);
+ case ETurretState::Ready:
+ ProcessReadyState(msg, mgr, dt);
break;
- case 7:
- case 8:
- sub8021942c(w1, mgr, dt);
+ case ETurretState::PanningA:
+ case ETurretState::PanningB:
+ ProcessPanningState(msg, mgr, dt);
break;
- case 9:
- case 10:
- sub80218f50(w1, mgr, dt);
+ case ETurretState::Targeting:
+ case ETurretState::Firing:
+ ProcessTargettingState(msg, mgr, dt);
break;
- case 11:
- sub80218e34(w1, mgr);
+ case ETurretState::ExitTargeting:
+ ProcessExitTargettingState(msg, mgr);
break;
- case 12:
- sub80218bb4(w1, mgr, dt);
+ case ETurretState::Frenzy:
+ ProcessFrenzyState(msg, mgr, dt);
break;
default:
break;
}
}
-void CScriptGunTurret::sub80219938(s32 w1, CStateManager& mgr) {
- if (w1 == 1) {
- float f1 = x524_;
- float f0 = x2d4_data.x0_;
- if (f1 >= f0 && x560_28_)
- w1 = 2;
+void CScriptGunTurret::ProcessDeactivatingState(EStateMsg msg, CStateManager& mgr) {
+ if (msg == EStateMsg::Update && x524_curStateTime >= x2d4_data.GetIntoDeactivateDelay())
+ SetTurretState(x560_28_hasBeenActivated ? ETurretState::DeactiveFromReady : ETurretState::Deactive, mgr);
+}
- sub80219b18(w1, mgr);
+void CScriptGunTurret::ProcessInactiveState(EStateMsg msg, CStateManager& mgr, float dt) {
+ if (msg == EStateMsg::Activate) {
+ x528_curInactiveTime = 0.f;
+ x560_27_burstSet = false;
+ if (TCastToPtr gunTurret = mgr.ObjectById(x25c_gunId))
+ x260_lastGunHP = gunTurret->HealthInfo(mgr)->GetHP();
+ } else if (msg == EStateMsg::Update) {
+ bool forceActivate = false;
+ if (x25c_gunId != kInvalidUniqueId)
+ if (TCastToPtr gun = mgr.ObjectById(x25c_gunId))
+ forceActivate = gun->HealthInfo(mgr)->GetHP() < x260_lastGunHP;
+ if (x2d4_data.GetScriptedStartOnly() ? (forceActivate || x560_29_scriptedStart) :
+ (forceActivate || x560_29_scriptedStart || InDetectionRange(mgr))) {
+ x528_curInactiveTime += dt;
+ if (forceActivate || x528_curInactiveTime >= x2d4_data.GetIntoActivateDelay())
+ SetTurretState(ETurretState::Ready, mgr);
+ } else {
+ x468_idleLight->SetParticleEmission(true);
+ }
+ } else if (msg == EStateMsg::Deactivate) {
+ x560_28_hasBeenActivated = true;
+ x468_idleLight->SetParticleEmission(false);
+
+ if (TCastToPtr gunTurret = mgr.ObjectById(x25c_gunId))
+ x260_lastGunHP = gunTurret->GetHealthInfo(mgr)->GetHP();
}
}
-void CScriptGunTurret::sub802196c4(s32 w1, CStateManager& mgr, float dt) {
- if (w1 == 0) {
- x528_ = 0.f;
- x560_27_ = false;
- if (TCastToPtr gunTurret = mgr.ObjectById(x25c_gunId))
- x260_ = gunTurret->HealthInfo(mgr)->GetHP();
- } else if (w1 == 1) {
- } else if (w1 == 2) {
- x560_28_ = true;
- x468_->SetParticleEmission(false);
-
- if (TCastToPtr gunTurret = mgr.ObjectById(x25c_gunId))
- x260_ = gunTurret->GetHealthInfo(mgr)->GetHP();
- }
-}
-
-void CScriptGunTurret::sub802195bc(s32 w1, CStateManager& mgr, float dt) {
- if (w1 == 0) {
- x52c_ = 0.f;
- } else if (w1 == 1) {
- x52c_ += dt;
- if (x52c_ < x2d4_data.x10_)
+void CScriptGunTurret::ProcessReadyState(EStateMsg msg, CStateManager& mgr, float dt) {
+ if (msg == EStateMsg::Activate) {
+ x52c_curActiveTime = 0.f;
+ } else if (msg == EStateMsg::Update) {
+ x52c_curActiveTime += dt;
+ if (x52c_curActiveTime < x2d4_data.GetPanStartTime())
return;
- if (sub80217ad8(mgr) && sub802179a4(mgr)) {
- sub80219b18(9, mgr);
- CSfxManager::AddEmitter(x2d4_data.x7e_, GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f,
+ if (IsPlayerInFiringRange(mgr) && InDetectionRange(mgr)) {
+ SetTurretState(ETurretState::Targeting, mgr);
+ CSfxManager::AddEmitter(x2d4_data.GetLockOnSoundId(), GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f,
GetAreaIdAlways());
} else {
- sub80219b18(7, mgr);
- x530_ = 0.f;
+ SetTurretState(ETurretState::PanningA, mgr);
+ x530_curPanTime = 0.f;
}
}
}
-void CScriptGunTurret::sub8021942c(s32 state, CStateManager& mgr, float dt) {
- if (state == 0) {
- x52c_ = 0.f;
- } else if (state == 1) {
- if (sub80217ad8(mgr) && sub802179a4(mgr)) {
- sub80219b18(9, mgr);
- CSfxManager::AddEmitter(x2d4_data.x7e_, GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f,
+void CScriptGunTurret::ProcessPanningState(EStateMsg msg, CStateManager& mgr, float dt) {
+ if (msg == EStateMsg::Activate) {
+ x52c_curActiveTime = 0.f;
+ } else if (msg == EStateMsg::Update) {
+ if (IsPlayerInFiringRange(mgr) && InDetectionRange(mgr)) {
+ SetTurretState(ETurretState::Targeting, mgr);
+ CSfxManager::AddEmitter(x2d4_data.GetLockOnSoundId(), GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f,
GetAreaIdAlways());
} else {
- x52c_ += dt;
- x530_ += dt;
- if (x530_ >= x2d4_data.x18_ && !x4a4_ && !x2d4_data.xa0_)
- sub80219b18(5, mgr);
- else if (x52c_ >= x2d4_data.x14_)
- sub80219b18(x520_ != 7 ? 7 : 8, mgr);
+ x52c_curActiveTime += dt;
+ x530_curPanTime += dt;
+ if (x530_curPanTime >= x2d4_data.GetTotalPanSearchTime() &&
+ !x4a4_extensionModel && !x2d4_data.GetScriptedStartOnly())
+ SetTurretState(ETurretState::Inactive, mgr);
+ else if (x52c_curActiveTime >= x2d4_data.GetPanHoldTime())
+ SetTurretState(x520_state != ETurretState::PanningA ? ETurretState::PanningA : ETurretState::PanningB, mgr);
}
}
}
-void CScriptGunTurret::sub80218f50(s32 state, CStateManager& mgr, float dt) {
- if (state == 0) {
- x52c_ = 0.f;
- } else if (state == 1) {
- if (!x560_26_) {
- if (sub802179a4(mgr)) {
- sub80218830(dt, mgr);
- if (x25c_gunId != kInvalidUniqueId) {
- if (TCastToPtr gun = mgr.ObjectById(x25c_gunId)) {
- zeus::CVector3f vec = x404_;
- if (sub80217ad8(mgr)) {
- zeus::CTransform blastXf = gun->GetLocatorTransform("Blast_LCTR"sv);
- zeus::CVector3f rotatedBlastVec = GetTransform().rotate(blastXf.origin) + GetTranslation();
- x404_ = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
- vec = x37c_projectileInfo.PredictInterceptPos(rotatedBlastVec, mgr.GetPlayer().GetAimPosition(mgr, dt),
- mgr.GetPlayer(), false, dt);
- }
-
- zeus::CVector3f compensated =
- x3a4_burstFire.GetDistanceCompensatedError((x404_ - gun->GetTranslation()).magnitude(), 20.f);
-
- compensated = gun->GetTransform().rotate(compensated);
-
- gun->x404_ = x404_ + (vec - x404_) + compensated;
+void CScriptGunTurret::ProcessTargettingState(EStateMsg msg, CStateManager& mgr, float dt) {
+ if (msg == EStateMsg::Activate) {
+ x52c_curActiveTime = 0.f;
+ } else if (msg == EStateMsg::Update) {
+ if (x560_26_firedWithSetBurst || InDetectionRange(mgr)) {
+ UpdateTargettingMode(dt, mgr);
+ if (x25c_gunId != kInvalidUniqueId) {
+ if (TCastToPtr gun = mgr.ObjectById(x25c_gunId)) {
+ zeus::CVector3f vec = x404_targetPosition;
+ if (IsPlayerInFiringRange(mgr)) {
+ zeus::CTransform blastXf = gun->GetLocatorTransform("Blast_LCTR"sv);
+ zeus::CVector3f rotatedBlastVec = GetTransform().rotate(blastXf.origin) + GetTranslation();
+ x404_targetPosition = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
+ vec = x37c_projectileInfo.PredictInterceptPos(rotatedBlastVec, mgr.GetPlayer().GetAimPosition(mgr, dt),
+ mgr.GetPlayer(), false, dt);
}
- }
- zeus::CVector3f diffVec = x404_ - GetTranslation();
- if (diffVec.canBeNormalized()) {
- zeus::CVector3f normDiff = diffVec.normalized();
- float angDif = zeus::CVector3f::getAngleDiff(normDiff, GetTransform().frontVector());
- zeus::CQuaternion quat = zeus::CQuaternion::lookAt(GetTransform().frontVector(), normDiff,
- std::min(angDif, (dt * x2d4_data.x28_)));
+ zeus::CVector3f compensated =
+ x3a4_burstFire.GetDistanceCompensatedError(
+ (x404_targetPosition - gun->GetTranslation()).magnitude(), 20.f);
- quat.setImaginary(GetTransform().transposeRotate(quat.getImaginary()));
- RotateInOneFrameOR(quat, dt);
+ compensated = gun->GetTransform().rotate(compensated);
+
+ gun->x404_targetPosition = x404_targetPosition + (vec - x404_targetPosition) + compensated;
}
}
- if (sub80217950(mgr)) {
+ zeus::CVector3f diffVec = x404_targetPosition - GetTranslation();
+ if (diffVec.canBeNormalized()) {
+ zeus::CVector3f normDiff = diffVec.normalized();
+ float angDif = zeus::CVector3f::getAngleDiff(normDiff, GetTransform().frontVector());
+ zeus::CQuaternion quat = zeus::CQuaternion::lookAt(GetTransform().frontVector(), normDiff,
+ std::min(angDif, (dt * x2d4_data.GetTurnSpeed())));
+
+ quat.setImaginary(GetTransform().transposeRotate(quat.getImaginary()));
+ RotateInOneFrameOR(quat, dt);
+ }
+
+ if (ShouldFire(mgr)) {
SendScriptMsgs(EScriptObjectState::Attack, mgr, EScriptObjectMessage::None);
- x560_26_ = true;
+ x560_26_firedWithSetBurst = true;
}
- x52c_ = 0.f;
+ x52c_curActiveTime = 0.f;
} else {
- x52c_ += dt;
- if (x52c_ >= 10.f)
- sub80219b18(11, mgr);
+ x52c_curActiveTime += dt;
+ if (x52c_curActiveTime >= 10.f)
+ SetTurretState(ETurretState::ExitTargeting, mgr);
}
- } else if (state == 2) {
- x560_30_ = true;
+ } else if (msg == EStateMsg::Deactivate) {
+ x560_30_needsStopClankSound = true;
}
}
-void CScriptGunTurret::sub80218e34(s32 state, CStateManager& mgr) {
- if (state != 1 || x25c_gunId == kInvalidUniqueId)
+void CScriptGunTurret::ProcessExitTargettingState(EStateMsg msg, CStateManager& mgr) {
+ if (msg != EStateMsg::Update || x25c_gunId == kInvalidUniqueId)
return;
if (TCastToPtr gun = mgr.ObjectById(x25c_gunId)) {
zeus::CTransform gunXf = GetTransform() * GetLocatorTransform("Gun_SDK"sv);
- if (zeus::CVector3f::getAngleDiff(gun->GetTransform().frontVector(), x544_) < zeus::degToRad(0.9f))
- sub80219b18(6, mgr);
+ if (zeus::CVector3f::getAngleDiff(gun->GetTransform().frontVector(), x544_originalFrontVec) < zeus::degToRad(0.9f))
+ SetTurretState(ETurretState::Ready, mgr);
}
}
-void CScriptGunTurret::sub80218bb4(s32 state, CStateManager& mgr, float dt) {
- if (state == 0) {
- x560_31_ = mgr.GetActiveRandom()->Float() < 0.f;
- x534_ = 0.15f;
+void CScriptGunTurret::ProcessFrenzyState(EStateMsg msg, CStateManager& mgr, float dt) {
+ if (msg == EStateMsg::Activate) {
+ x560_31_frenzyReverse = mgr.GetActiveRandom()->Float() < 0.f;
+ x534_fireCycleRemTime = 0.15f;
RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr);
- } else if (state == 1) {
- if (x524_ >= x2d4_data.x9c_) {
- sub80219b18(0, mgr);
+ } else if (msg == EStateMsg::Update) {
+ if (x524_curStateTime >= x2d4_data.GetFrenzyDuration()) {
+ SetTurretState(ETurretState::Destroyed, mgr);
if (TCastToPtr gun = mgr.ObjectById(x25c_gunId))
- gun->x520_ = 0;
+ gun->x520_state = ETurretState::Destroyed;
return;
}
zeus::CVector3f frontVec = GetTransform().frontVector();
- if (x560_31_ && x550_.magSquared() < 0.f &&
- zeus::CVector3f::getAngleDiff(x544_, frontVec) >= zeus::degToRad(45.f)) {
- x560_31_ = false;
- } else if (!x560_31_ && x550_.magSquared() < 0.f &&
- zeus::CVector3f::getAngleDiff(x544_, frontVec) >= zeus::degToRad(45.f)) {
- x560_31_ = true;
+ if (x560_31_frenzyReverse && x550_originalRightVec.magSquared() < 0.f &&
+ zeus::CVector3f::getAngleDiff(x544_originalFrontVec, frontVec) >= zeus::degToRad(45.f)) {
+ x560_31_frenzyReverse = false;
+ } else if (!x560_31_frenzyReverse && x550_originalRightVec.magSquared() < 0.f &&
+ zeus::CVector3f::getAngleDiff(x544_originalFrontVec, frontVec) >= zeus::degToRad(45.f)) {
+ x560_31_frenzyReverse = true;
}
if (TCastToPtr gun = mgr.ObjectById(x25c_gunId)) {
- x534_ -= dt;
- if (x534_ >= 0.f)
+ x534_fireCycleRemTime -= dt;
+ if (x534_fireCycleRemTime >= 0.f)
return;
- x404_ = gun->GetTranslation() + (100.f * gun->GetTransform().frontVector());
+ x404_targetPosition = gun->GetTranslation() + (100.f * gun->GetTransform().frontVector());
SendScriptMsgs(EScriptObjectState::Attack, mgr, EScriptObjectMessage::None);
- x534_ = 0.15f;
+ x534_fireCycleRemTime = 0.15f;
}
}
}
-bool CScriptGunTurret::sub80217ad8(CStateManager& mgr) {
+bool CScriptGunTurret::IsPlayerInFiringRange(CStateManager& mgr) const {
zeus::CVector3f posDif = mgr.GetPlayer().GetTranslation() - GetTranslation();
zeus::CVector3f someVec(posDif.x(), posDif.y(), 0.f);
- if (x550_.dot(posDif) >= 0.f)
- return zeus::CVector3f::getAngleDiff(x544_, someVec) <= x2d4_data.x20_;
+ if (x550_originalRightVec.dot(posDif) >= 0.f)
+ return zeus::CVector3f::getAngleDiff(x544_originalFrontVec, someVec) <= x2d4_data.GetRightMaxAngle();
- if (zeus::CVector3f::getAngleDiff(x544_, someVec) <= x2d4_data.x20_)
+ if (zeus::CVector3f::getAngleDiff(x544_originalFrontVec, someVec) <= x2d4_data.GetLeftMaxAngle())
return true;
float biasedAngle = zeus::CVector3f::getAngleDiff(posDif, zeus::CVector3f::skUp) - zeus::degToRad(90.f);
- return (biasedAngle >= zeus::degToRad(-20.f) && biasedAngle <= x2d4_data.x24_);
+ return (biasedAngle >= zeus::degToRad(-20.f) && biasedAngle <= x2d4_data.GetDownMaxAngle());
}
-bool CScriptGunTurret::sub802179a4(CStateManager&) { return false; }
+bool CScriptGunTurret::LineOfSightTest(CStateManager& mgr) const {
+ if (x25c_gunId == kInvalidUniqueId)
+ return false;
+ if (TCastToPtr gun = mgr.ObjectById(x25c_gunId)) {
+ if (x560_27_burstSet || (x520_state == ETurretState::Inactive && x4a4_extensionModel))
+ return true;
+ zeus::CTransform xf = GetLocatorTransform("Blast_LCTR"sv);
+ zeus::CVector3f muzzlePos = gun->GetTransform().rotate(xf.origin) + gun->GetTranslation();
+ zeus::CVector3f dir = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - muzzlePos;
+ float mag = dir.magnitude();
+ dir = dir / mag;
+ rstl::reserved_vector nearList;
+ CMaterialFilter filter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid},
+ {EMaterialTypes::Player, EMaterialTypes::CollisionActor});
+ mgr.BuildNearList(nearList, muzzlePos, dir, mag, filter, gun.GetPtr());
+ TUniqueId id = kInvalidUniqueId;
+ return mgr.RayWorldIntersection(id, muzzlePos, dir, mag, filter, nearList).IsInvalid();
+ }
+ return false;
+}
-zeus::CVector3f CScriptGunTurret::sub80217e34(float dt) {
- if (!x4a4_)
+bool CScriptGunTurret::InDetectionRange(CStateManager& mgr) const {
+ zeus::CVector3f delta = mgr.GetPlayer().GetTranslation() - GetTranslation();
+ if (delta.dot(zeus::CVector3f::skDown) >= 0.f ||
+ zeus::CVector3f::getAngleDiff(GetTransform().frontVector(), delta) <= zeus::degToRad(20.f))
+ if (delta.magSquared() <= x2d4_data.GetDetectionRange() * x2d4_data.GetDetectionRange())
+ if (x2d4_data.GetDetectionZRange() == 0.f || std::fabs(delta.z()) < x2d4_data.GetDetectionZRange())
+ return LineOfSightTest(mgr);
+ return false;
+}
+
+zeus::CVector3f CScriptGunTurret::UpdateExtensionModelState(float dt) {
+ if (!x4a4_extensionModel)
return {};
- if (x520_ >= 7 && x520_ < 12)
- x4f8_ = std::min(0.9f, x4f8_ + 1.5f * dt);
- else if ((x520_ >= 0 && x520_ < 3) || x520_ == 5 || x520_ == 13)
- x4f8_ = std::max(0.f, x4f8_ - 1.f * dt);
-
- return (x4fc_ + (x2d4_data.x8c_ * x4f8_ * zeus::CVector3f::skDown)) - GetTranslation();
+ switch (x520_state) {
+ case ETurretState::PanningA:
+ case ETurretState::PanningB:
+ case ETurretState::Targeting:
+ case ETurretState::Firing:
+ case ETurretState::ExitTargeting:
+ x4f8_extensionT = std::min(0.9f, x4f8_extensionT + 1.5f * dt);
+ break;
+ default:
+ x4f8_extensionT = std::max(0.f, x4f8_extensionT - 1.5f * dt);
+ break;
+ case ETurretState::Ready:
+ case ETurretState::Deactivating:
+ case ETurretState::DeactivatingFromReady:
+ case ETurretState::Frenzy:
+ break;
+ }
+ return (x4fc_extensionOffset + (x2d4_data.GetExtensionDropDownDist() * x4f8_extensionT * zeus::CVector3f::skDown)) -
+ GetTranslation();
}
-void CScriptGunTurret::sub80217f5c(float dt, CStateManager& mgr) {
- /* TODO: Finish */
+void CScriptGunTurret::UpdateHealthInfo(CStateManager& mgr) {
+ switch (x258_type) {
+ case ETurretComponent::Base:
+ if (x25c_gunId != kInvalidUniqueId) {
+ if (!TCastToPtr(mgr.ObjectById(x25c_gunId))) {
+ SetTurretState(ETurretState::Destroyed, mgr);
+ x560_25_frozen = false;
+ x25c_gunId = kInvalidUniqueId;
+ if (x50c_targetingEmitter) {
+ CSfxManager::RemoveEmitter(x50c_targetingEmitter);
+ x50c_targetingEmitter.reset();
+ }
+ }
+ } else {
+ SetTurretState(ETurretState::Destroyed, mgr);
+ }
+ break;
+ case ETurretComponent::Gun:
+ if (!x560_24_dead && x520_state != ETurretState::Frenzy && HealthInfo(mgr)->GetHP() <= 0.f) {
+ x560_24_dead = true;
+ SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
+ mgr.FreeScriptObject(GetUniqueId());
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+bool CScriptGunTurret::PlayerInsideTurretSphere(CStateManager& mgr) const {
+ if (TCastToConstPtr cAct = mgr.GetObjectById(x4a0_collisionActor)) {
+ if (cAct->GetActive()) {
+ zeus::CVector3f delta = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation();
+ if (delta.z() < 0.f) {
+ float rad = cAct->GetSphereRadius() * 2.f +
+ (cAct->GetTranslation() - GetTranslation()).magnitude();
+ return delta.magSquared() < rad * rad;
+ }
+ }
+ }
+ return false;
+}
+
+void CScriptGunTurret::UpdateGunOrientation(float dt, CStateManager& mgr) {
if (x25c_gunId == kInvalidUniqueId)
return;
@@ -779,19 +1009,70 @@ void CScriptGunTurret::sub80217f5c(float dt, CStateManager& mgr) {
zeus::CTransform xf = GetLocatorTransform("Gun_SDK"sv);
xf = GetTransform() * xf;
- switch (x520_) {
- case 11: {
- zeus::CVector3f frontVec = GetTransform().frontVector();
- zeus::CVector3f gunFrontVec = gun->GetTransform().frontVector();
- zeus::CQuaternion quat = zeus::CQuaternion::lookAt(gunFrontVec, frontVec, 0.3f * dt * x2d4_data.x28_);
- zeus::CVector3f xposVec = gun->GetTransform().transposeRotate(quat.getImaginary());
- quat.setImaginary(xposVec);
- gun->RotateInOneFrameOR(quat, dt);
- RotateInOneFrameOR(quat, dt);
+ switch (x520_state) {
+ case ETurretState::Targeting:
+ case ETurretState::Firing: {
+ float xyMagSq = xf.frontVector().toVec2f().magSquared();
+ float useYaw = 0.f;
+ if (std::sqrt(xyMagSq) > 0.001f)
+ useYaw = -std::atan2(xf.frontVector().x(), xf.frontVector().y());
+ float oldPitch = gun->GetPitch();
+ float usePitch = 0.f;
+ if (!gun->PlayerInsideTurretSphere(mgr)) {
+ zeus::CTransform newXf;
+ if ((x404_targetPosition - xf.origin).canBeNormalized())
+ newXf = zeus::lookAt(xf.origin, x404_targetPosition);
+ else
+ newXf = GetTransform();
+ float newPitch = -std::atan2(-newXf.frontVector().z(), newXf.frontVector().toVec2f().magnitude());
+ float newPitchDelta = newPitch - oldPitch;
+ float f2 = newPitchDelta > 0.f ? dt * x2d4_data.GetTurnSpeed() : dt * -x2d4_data.GetTurnSpeed();
+ usePitch = std::max(std::fabs(newPitchDelta) <=
+ std::fabs(f2) ? newPitch : oldPitch + f2, -x2d4_data.GetDownMaxAngle());
+ }
+ zeus::CQuaternion qy, qx, qz;
+ qy.rotateY(0.f);
+ qx.rotateX(usePitch);
+ qz.rotateZ(useYaw);
+ gun->SetTransform((qz * qx * qy).toTransform(xf.origin));
break;
}
- case 12:
+ case ETurretState::ExitTargeting: {
+ zeus::CVector3f frontVec = GetTransform().frontVector();
+ zeus::CVector3f gunFrontVec = gun->GetTransform().frontVector();
+ float rotAngle = 0.3f * dt * x2d4_data.GetTurnSpeed();
+ zeus::CQuaternion quat = zeus::CQuaternion::lookAt(gunFrontVec, frontVec, rotAngle);
+ quat.setImaginary(gun->GetTransform().transposeRotate(quat.getImaginary()));
+ gun->RotateInOneFrameOR(quat, dt);
+ zeus::CQuaternion quat2 = zeus::CQuaternion::lookAt(frontVec, x544_originalFrontVec, rotAngle);
+ quat2.setImaginary(GetTransform().transposeRotate(quat2.getImaginary()));
+ RotateInOneFrameOR(quat2, dt);
break;
+ }
+ case ETurretState::Frenzy: {
+ float xyMagSq = xf.frontVector().toVec2f().magSquared();
+ float useYaw = 0.f;
+ if (std::sqrt(xyMagSq) > 0.001f)
+ useYaw = -std::atan2(xf.frontVector().x(), xf.frontVector().y());
+ float f28 = -0.5f * x2d4_data.GetDownMaxAngle() *
+ (1.f - std::cos(2.f * x524_curStateTime * x2d4_data.GetTurnSpeed()));
+ float pitch = gun->GetPitch();
+ float f2 = f28 - pitch;
+ float f31 = x2d4_data.GetTurnSpeed() * dt;
+ float f3 = f2 > 0.f ? f31 : -f31;
+ float usePitch = std::fabs(f2) <= std::fabs(f3) ? f28 : pitch + f3;
+ usePitch = std::max(usePitch, -x2d4_data.GetDownMaxAngle());
+ zeus::CQuaternion qy, qx, qz;
+ qy.rotateY(0.f);
+ qx.rotateX(usePitch);
+ qz.rotateZ(useYaw);
+ gun->SetTransform((qz * qx * qy).toTransform(xf.origin));
+ zeus::CQuaternion rot = zeus::CQuaternion::lookAt(GetTransform().frontVector(),
+ x560_31_frenzyReverse ? -x550_originalRightVec : x550_originalRightVec, f31);
+ rot.setImaginary(GetTransform().transposeRotate(rot.getImaginary()));
+ RotateInOneFrameOR(rot, dt);
+ break;
+ }
default:
gun->SetTransform(xf);
break;
@@ -799,130 +1080,136 @@ void CScriptGunTurret::sub80217f5c(float dt, CStateManager& mgr) {
}
}
-void CScriptGunTurret::sub80216288(float dt) {
- x510_ += dt;
- float angleDiff2D = zeus::CVector2f::getAngleDiff(x514_.toVec2f(), GetTransform().frontVector().toVec2f());
+void CScriptGunTurret::UpdateTargettingSound(float dt) {
+ x510_timeSinceLastTargetSfx += dt;
+ float angleDiff2D = zeus::CVector2f::getAngleDiff(x514_lastFrontVector.toVec2f(),
+ GetTransform().frontVector().toVec2f());
- if (x560_30_ && angleDiff2D < zeus::degToRad(20.f) && (x520_ == 9 || x520_ == 10)) {
- if (!x560_25_)
- CSfxManager::AddEmitter(x2d4_data.x82_, GetTranslation(), zeus::CVector3f::skUp, false, false, 127,
- GetAreaIdAlways());
- x560_30_ = false;
+ if (x560_30_needsStopClankSound && angleDiff2D < zeus::degToRad(20.f) &&
+ (x520_state == ETurretState::Targeting || x520_state == ETurretState::Firing)) {
+ if (!x560_25_frozen)
+ CSfxManager::AddEmitter(x2d4_data.GetStopClankSoundId(), GetTranslation(), zeus::CVector3f::skUp, false, false,
+ 127, GetAreaIdAlways());
+ x560_30_needsStopClankSound = false;
}
- if (x510_ >= 0.5f && !x560_25_) {
- if (x520_ == 9 || x520_ == 10 || x520_ == 12) {
- bool res = sub80217c24(dt);
- if (!res && !x50c_)
- x50c_ = CSfxManager::AddEmitter(x2d4_data.x7c_, GetTranslation(), zeus::CVector3f::skUp, false, true, 127,
- GetAreaIdAlways());
- else if (res && x50c_) {
- CSfxManager::RemoveEmitter(x50c_);
- x50c_.reset();
- x510_ = 0.f;
+ if (x510_timeSinceLastTargetSfx >= 0.5f && !x560_25_frozen) {
+ if (x520_state == ETurretState::Targeting || x520_state == ETurretState::Firing ||
+ x520_state == ETurretState::Frenzy) {
+ bool insignificant = IsInsignificantRotation(dt);
+ if (!insignificant && !x50c_targetingEmitter)
+ x50c_targetingEmitter = CSfxManager::AddEmitter(x2d4_data.GetTrackingSoundId(), GetTranslation(),
+ zeus::CVector3f::skUp, false, true, 127, GetAreaIdAlways());
+ else if (insignificant && x50c_targetingEmitter) {
+ CSfxManager::RemoveEmitter(x50c_targetingEmitter);
+ x50c_targetingEmitter.reset();
+ x510_timeSinceLastTargetSfx = 0.f;
}
- if (x50c_) {
- float bendScale = dt * x2d4_data.x28_;
- CSfxManager::PitchBend(x50c_, std::max(1.f, 8192.f * (bendScale > 0.f ? angleDiff2D / bendScale : 0.f)) + 8192);
+ if (x50c_targetingEmitter) {
+ float bendScale = dt * x2d4_data.GetTurnSpeed();
+ CSfxManager::PitchBend(x50c_targetingEmitter,
+ std::max(0.f, (bendScale > 0.f ? angleDiff2D / bendScale : 0.f)));
}
}
- } else if (x560_25_ && x50c_) {
- CSfxManager::RemoveEmitter(x50c_);
- x50c_.reset();
+ } else if (x560_25_frozen && x50c_targetingEmitter) {
+ CSfxManager::RemoveEmitter(x50c_targetingEmitter);
+ x50c_targetingEmitter.reset();
}
- x514_ = GetTransform().frontVector();
+ x514_lastFrontVector = GetTransform().frontVector();
}
-void CScriptGunTurret::sub80217124(CStateManager& mgr) {
- if (x520_ == 10) {
- if (x55c_ != -1)
+void CScriptGunTurret::PlayAdditiveChargingAnimation(CStateManager& mgr) {
+ if (x520_state == ETurretState::Firing) {
+ if (x55c_additiveChargeAnim != -1)
return;
auto pair = ModelData()->AnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(
CPASAnimParmData(24, CPASAnimParm::FromEnum(2)), *mgr.GetActiveRandom(), -1);
if (pair.first > 0.f) {
- x55c_ = pair.second;
+ x55c_additiveChargeAnim = pair.second;
ModelData()->AnimationData()->AddAdditiveAnimation(pair.second, 1.f, true, false);
}
- } else if (x55c_ != -1) {
- ModelData()->AnimationData()->DelAdditiveAnimation(x55c_);
- x55c_ = -1;
+ } else if (x55c_additiveChargeAnim != -1) {
+ ModelData()->AnimationData()->DelAdditiveAnimation(x55c_additiveChargeAnim);
+ x55c_additiveChargeAnim = -1;
}
}
-void CScriptGunTurret::sub80218830(float dt, CStateManager& mgr) {
+void CScriptGunTurret::UpdateTargettingMode(float dt, CStateManager& mgr) {
if (mgr.GetCameraManager()->IsInCinematicCamera()) {
- x534_ = mgr.GetActiveRandom()->Float() * x2d4_data.xc_ + x2d4_data.x8_;
- x538_ = 0.5f * x534_;
+ x534_fireCycleRemTime = mgr.GetActiveRandom()->Float() * x2d4_data.GetReloadTimeVariance() +
+ x2d4_data.GetReloadTime();
+ x538_halfFireCycleDur = 0.5f * x534_fireCycleRemTime;
}
- if (x534_ > 0.f) {
- x534_ -= dt;
- if (x534_ < x538_ && x520_ != 10) {
- CSfxManager::AddEmitter(x2d4_data.x84_, GetTranslation(), zeus::CVector3f::skUp, false, false, 0x7f,
- GetAreaIdAlways());
- sub80219b18(10, mgr);
+ if (x534_fireCycleRemTime > 0.f) {
+ x534_fireCycleRemTime -= dt;
+ if (x534_fireCycleRemTime < x538_halfFireCycleDur && x520_state != ETurretState::Firing) {
+ CSfxManager::AddEmitter(x2d4_data.GetChargingSoundId(), GetTranslation(), zeus::CVector3f::skUp, false, false,
+ 0x7f, GetAreaIdAlways());
+ SetTurretState(ETurretState::Firing, mgr);
return;
}
+ } else {
+ if (x520_state != ETurretState::Targeting)
+ SetTurretState(ETurretState::Targeting, mgr);
- if (x520_ != 9)
- sub80219b18(9, mgr);
-
- if (x2d4_data.x18_ == 0) {
- sub80216594(mgr);
- x534_ = mgr.GetActiveRandom()->Float() * x2d4_data.xc_ + x2d4_data.x8_;
- x538_ = 0.5f * x534_;
- return;
+ if (!x3a4_burstFire.IsBurstSet()) {
+ UpdateBurstType(mgr);
+ x534_fireCycleRemTime = mgr.GetActiveRandom()->Float() * x2d4_data.GetReloadTimeVariance() +
+ x2d4_data.GetReloadTime();
+ x538_halfFireCycleDur = 0.5f * x534_fireCycleRemTime;
+ } else {
+ x3a4_burstFire.Update(mgr, dt);
}
-
- x3a4_burstFire.Update(mgr, dt);
}
}
-void CScriptGunTurret::sub80216594(CStateManager& mgr) {
- if (x560_27_) {
- u32 r0 = 1;
+void CScriptGunTurret::UpdateBurstType(CStateManager& mgr) {
+ if (x560_27_burstSet) {
+ bool inView = true;
if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed) {
zeus::CVector3f frontVec = GetTransform().frontVector();
zeus::CVector3f plFrontVec = mgr.GetPlayer().GetTransform().frontVector();
float dot = frontVec.dot(plFrontVec);
- if (dot > 0.f)
- r0 = 0;
+ if (dot >= 0.f)
+ inView = false;
}
- bool r29 = r0 != 0;
u32 r3 = mgr.GetActiveRandom()->Range(0, 3);
r3 += 2;
- if (r3 > 2 && x2d4_data.x98_ < 3)
- r0 = 0;
- else if (r3 > 5 || r3 > 3)
- r0 = 2;
+ u32 type;
+ if (r3 <= 2 || x2d4_data.GetNumSubsequentShots() < 3)
+ type = 0;
+ else if (r3 >= 5 && x2d4_data.GetNumSubsequentShots() > 3)
+ type = 2;
else
- r0 = 1;
+ type = 1;
- x3a4_burstFire.SetBurstType(r0 + r29);
+ x3a4_burstFire.SetBurstType(type + (inView ? 0 : 3));
} else {
- u32 r3 = x2d4_data.x90_ - 2;
- x3a4_burstFire.SetBurstType(r3);
- x3a4_burstFire.SetFirstBurstIndex(x2d4_data.x94_);
+ u32 type = x2d4_data.GetNumInitialShots() - 2;
+ x3a4_burstFire.SetBurstType(type);
+ x3a4_burstFire.SetFirstBurstIndex(x2d4_data.GetInitialShotTableIndex());
}
x3a4_burstFire.Start(mgr);
- x560_26_ = false;
- x560_27_ = true;
+ x560_26_firedWithSetBurst = false;
+ x560_27_burstSet = true;
}
-bool CScriptGunTurret::sub80217950(CStateManager& mgr) {
- if (x520_ == 9 && x534_ <= 0.f && x3a4_burstFire.ShouldFire())
- return sub80217ad8(mgr);
+bool CScriptGunTurret::ShouldFire(CStateManager& mgr) const {
+ if (x520_state == ETurretState::Targeting && x534_fireCycleRemTime <= 0.f && x3a4_burstFire.ShouldFire())
+ return IsPlayerInFiringRange(mgr);
return false;
}
-bool CScriptGunTurret::sub80217c24(float) {
- return zeus::CVector2f::getAngleDiff(x514_.toVec2f(), GetTransform().frontVector().toVec2f()) < zeus::degToRad(20.f);
+bool CScriptGunTurret::IsInsignificantRotation(float dt) const {
+ return zeus::CVector2f::getAngleDiff(x514_lastFrontVector.toVec2f(), GetTransform().frontVector().toVec2f()) <
+ zeus::degToRad(2.f) * dt;
}
} // namespace urde
diff --git a/Runtime/World/CScriptGunTurret.hpp b/Runtime/World/CScriptGunTurret.hpp
index dda6935db..509d28a09 100644
--- a/Runtime/World/CScriptGunTurret.hpp
+++ b/Runtime/World/CScriptGunTurret.hpp
@@ -11,59 +11,86 @@
namespace urde {
class CCollisionActorManager;
class CScriptGunTurretData {
- friend class CScriptGunTurret;
- float x0_;
- float x4_;
- float x8_;
- float xc_;
- float x10_;
- float x14_;
- float x18_ = 30.f;
- float x1c_;
- float x20_;
- float x24_;
- float x28_;
- float x2c_;
- float x30_;
- float x34_;
- float x38_;
- bool x3c_;
+ float x0_intoDeactivateDelay;
+ float x4_intoActivateDelay;
+ float x8_reloadTime;
+ float xc_reloadTimeVariance;
+ float x10_panStartTime;
+ float x14_panHoldTime;
+ float x18_totalPanSearchTime = 30.f;
+ float x1c_leftMaxAngle;
+ float x20_rightMaxAngle;
+ float x24_downMaxAngle;
+ float x28_turnSpeed;
+ float x2c_detectionRange;
+ float x30_detectionZRange;
+ float x34_freezeDuration;
+ float x38_freezeVariance;
+ bool x3c_freezeTimeout;
CAssetId x40_projectileRes;
CDamageInfo x44_projectileDamage;
- CAssetId x60_;
- CAssetId x64_;
- CAssetId x68_;
- CAssetId x6c_;
- CAssetId x70_;
- CAssetId x74_;
- CAssetId x78_;
- u16 x7c_;
- u16 x7e_;
- u16 x80_unfreezeSound;
- u16 x82_;
- u16 x84_;
- u16 x86_;
- CAssetId x88_;
- float x8c_;
- u32 x90_;
- u32 x94_;
- u32 x98_;
- float x9c_;
- bool xa0_;
+ CAssetId x60_idleLightRes;
+ CAssetId x64_deactivateLightRes;
+ CAssetId x68_targettingLightRes;
+ CAssetId x6c_frozenEffectRes;
+ CAssetId x70_chargingEffectRes;
+ CAssetId x74_panningEffectRes;
+ CAssetId x78_visorEffectRes;
+ u16 x7c_trackingSoundId;
+ u16 x7e_lockOnSoundId;
+ u16 x80_unfreezeSoundId;
+ u16 x82_stopClankSoundId;
+ u16 x84_chargingSoundId;
+ u16 x86_visorSoundId;
+ CAssetId x88_extensionModelResId;
+ float x8c_extensionDropDownDist;
+ u32 x90_numInitialShots;
+ u32 x94_initialShotTableIndex;
+ u32 x98_numSubsequentShots;
+ float x9c_frenzyDuration;
+ bool xa0_scriptedStartOnly;
static constexpr s32 skMinProperties = 43;
public:
CScriptGunTurretData(CInputStream&, s32);
- CAssetId GetPanningEffectRes() const;
- CAssetId GetChargingEffectRes() const;
- CAssetId GetFrozenEffectRes() const;
- CAssetId GetTargettingLightRes() const;
- CAssetId GetDeactivateLightRes() const;
- CAssetId GetIdleLightRes() const;
+ CAssetId GetPanningEffectRes() const { return x74_panningEffectRes; }
+ CAssetId GetChargingEffectRes() const { return x70_chargingEffectRes; }
+ CAssetId GetFrozenEffectRes() const { return x6c_frozenEffectRes; }
+ CAssetId GetTargettingLightRes() const { return x68_targettingLightRes; }
+ CAssetId GetDeactivateLightRes() const { return x64_deactivateLightRes; }
+ CAssetId GetIdleLightRes() const { return x60_idleLightRes; }
+ CAssetId GetVisorEffectRes() const { return x78_visorEffectRes; }
const CDamageInfo& GetProjectileDamage() const { return x44_projectileDamage; }
CAssetId GetProjectileRes() const { return x40_projectileRes; }
- u16 GetUnFreezeSoundId() const;
- float GetIntoDeactivateDelay() const;
+ u16 GetUnFreezeSoundId() const { return x80_unfreezeSoundId; }
+ float GetIntoDeactivateDelay() const { return x0_intoDeactivateDelay; }
+ CAssetId GetExtensionModelResId() const { return x88_extensionModelResId; }
+ float GetFreezeVariance() const { return x38_freezeVariance; }
+ float GetFreezeDuration() const { return x34_freezeDuration; }
+ bool GetFreezeTimeout() const { return x3c_freezeTimeout; }
+ float GetIntoActivateDelay() const { return x4_intoActivateDelay; }
+ u16 GetLockOnSoundId() const { return x7e_lockOnSoundId; }
+ float GetPanStartTime() const { return x10_panStartTime; }
+ float GetPanHoldTime() const { return x14_panHoldTime; }
+ float GetTotalPanSearchTime() const { return x18_totalPanSearchTime; }
+ float GetTurnSpeed() const { return x28_turnSpeed; }
+ float GetReloadTimeVariance() const { return xc_reloadTimeVariance; }
+ float GetReloadTime() const { return x8_reloadTime; }
+ u16 GetChargingSoundId() const { return x84_chargingSoundId; }
+ float GetDownMaxAngle() const { return x24_downMaxAngle; }
+ float GetExtensionDropDownDist() const { return x8c_extensionDropDownDist; }
+ float GetLeftMaxAngle() const { return x1c_leftMaxAngle; }
+ float GetRightMaxAngle() const { return x20_rightMaxAngle; }
+ float GetDetectionRange() const { return x2c_detectionRange; }
+ float GetDetectionZRange() const { return x30_detectionZRange; }
+ u32 GetNumSubsequentShots() const { return x98_numSubsequentShots; }
+ u32 GetInitialShotTableIndex() const { return x94_initialShotTableIndex; }
+ u32 GetNumInitialShots() const { return x90_numInitialShots; }
+ u16 GetTrackingSoundId() const { return x7c_trackingSoundId; }
+ u16 GetStopClankSoundId() const { return x82_stopClankSoundId; }
+ u16 GetVisorSoundId() const { return x86_visorSoundId; }
+ bool GetScriptedStartOnly() const { return xa0_scriptedStartOnly; }
+ float GetFrenzyDuration() const { return x9c_frenzyDuration; }
static s32 GetMinProperties() { return skMinProperties; }
};
@@ -79,72 +106,114 @@ class CScriptGunTurret : public CPhysicsActor {
public:
enum class ETurretComponent { Base, Gun };
enum class ETurretState {
-
+ Invalid = -1,
+ Destroyed,
+ Deactive,
+ DeactiveFromReady,
+ Deactivating,
+ DeactivatingFromReady,
+ Inactive,
+ Ready,
+ PanningA,
+ PanningB,
+ Targeting,
+ Firing,
+ ExitTargeting,
+ Frenzy
};
private:
ETurretComponent x258_type;
TUniqueId x25c_gunId = kInvalidUniqueId;
- float x260_ = 0.f;
+ float x260_lastGunHP = 0.f;
CHealthInfo x264_healthInfo;
CDamageVulnerability x26c_damageVuln;
CScriptGunTurretData x2d4_data;
TUniqueId x378_ = kInvalidUniqueId;
CProjectileInfo x37c_projectileInfo;
CBurstFire x3a4_burstFire;
- zeus::CVector3f x404_;
- TToken x410_;
- TToken x41c_;
- TToken x428_;
- TToken x434_;
- TToken x440_;
- TToken x44c_;
- TLockedToken x458_;
- std::unique_ptr x468_;
- std::unique_ptr x470_;
- std::unique_ptr x478_;
- std::unique_ptr x480_;
- std::unique_ptr x488_;
- std::unique_ptr x490_;
+ zeus::CVector3f x404_targetPosition;
+ TToken x410_idleLightDesc;
+ TToken x41c_deactivateLightDesc;
+ TToken x428_targettingLightDesc;
+ TToken x434_frozenEffectDesc;
+ TToken x440_chargingEffectDesc;
+ TToken x44c_panningEffectDesc;
+ TLockedToken x458_visorEffectDesc;
+ std::unique_ptr x468_idleLight;
+ std::unique_ptr x470_deactivateLight;
+ std::unique_ptr x478_targettingLight;
+ std::unique_ptr x480_frozenEffect;
+ std::unique_ptr x488_chargingEffect;
+ std::unique_ptr x490_panningEffect;
TUniqueId x498_lightId = kInvalidUniqueId;
std::unique_ptr x49c_collisionManager;
- TUniqueId x4a0_ = kInvalidUniqueId;
- rstl::optional x4a4_;
- float x4f4_ = 0.f;
- float x4f8_ = 0.f;
- zeus::CVector3f x4fc_;
+ TUniqueId x4a0_collisionActor = kInvalidUniqueId;
+ rstl::optional x4a4_extensionModel;
+ float x4f4_extensionRange = 0.f;
+ float x4f8_extensionT = 0.f;
+ zeus::CVector3f x4fc_extensionOffset;
u8 x508_gunSDKSeg = 0xFF;
- CSfxHandle x50c_;
- float x510_ = 0.f;
- zeus::CVector3f x514_;
- s32 x520_ = -1;
- float x524_ = 0.f;
- float x528_ = 0.f;
- float x52c_ = 0.f;
- float x530_ = 0.f;
- float x534_ = 0.f;
- float x538_ = 0.f;
- float x53c_ = 0.f;
- s32 x540_ = -1;
- zeus::CVector3f x544_;
- zeus::CVector3f x550_;
- s32 x55c_ = -1;
+ CSfxHandle x50c_targetingEmitter;
+ float x510_timeSinceLastTargetSfx = 0.f;
+ zeus::CVector3f x514_lastFrontVector;
+ ETurretState x520_state = ETurretState::Invalid;
+ float x524_curStateTime = 0.f;
+ float x528_curInactiveTime = 0.f;
+ float x52c_curActiveTime = 0.f;
+ float x530_curPanTime = 0.f;
+ float x534_fireCycleRemTime = 0.f;
+ float x538_halfFireCycleDur = 0.f;
+ float x53c_freezeRemTime = 0.f;
+ s32 x540_turretAnim = -1;
+ zeus::CVector3f x544_originalFrontVec;
+ zeus::CVector3f x550_originalRightVec;
+ s32 x55c_additiveChargeAnim = -1;
union {
struct {
- bool x560_24_ : 1;
- bool x560_25_ : 1;
- bool x560_26_ : 1;
- bool x560_27_ : 1;
- bool x560_28_ : 1;
- bool x560_29_ : 1;
- bool x560_30_ : 1;
- bool x560_31_ : 1;
+ bool x560_24_dead : 1;
+ bool x560_25_frozen : 1;
+ bool x560_26_firedWithSetBurst : 1;
+ bool x560_27_burstSet : 1;
+ bool x560_28_hasBeenActivated : 1;
+ bool x560_29_scriptedStart : 1;
+ bool x560_30_needsStopClankSound : 1;
+ bool x560_31_frenzyReverse : 1;
};
u32 _dummy = 0;
};
private:
void SetupCollisionManager(CStateManager&);
+ void SetTurretState(ETurretState, CStateManager&);
+ void ProcessCurrentState(EStateMsg, CStateManager&, float);
+ void LaunchProjectile(CStateManager&);
+ void PlayAdditiveFlinchAnimation(CStateManager&);
+ void ProcessGunStateMachine(float, CStateManager&);
+ void UpdateTurretAnimation();
+ void UpdateGunCollisionManager(float, CStateManager&);
+ void UpdateFrozenState(float, CStateManager&);
+ void UpdateGunParticles(float, CStateManager&);
+ void ProcessDeactivatingState(EStateMsg, CStateManager&);
+ void ProcessInactiveState(EStateMsg, CStateManager&, float);
+ void ProcessReadyState(EStateMsg, CStateManager&, float);
+ void ProcessPanningState(EStateMsg, CStateManager&, float);
+ void ProcessTargettingState(EStateMsg, CStateManager&, float);
+ void ProcessExitTargettingState(EStateMsg, CStateManager&);
+ void ProcessFrenzyState(EStateMsg, CStateManager&, float);
+ bool IsPlayerInFiringRange(CStateManager&) const;
+ bool LineOfSightTest(CStateManager&) const;
+ bool InDetectionRange(CStateManager&) const;
+ bool PlayerInsideTurretSphere(CStateManager&) const;
+ void UpdateGunOrientation(float, CStateManager&);
+ zeus::CVector3f UpdateExtensionModelState(float);
+ void UpdateHealthInfo(CStateManager&);
+ void UpdateTargettingSound(float);
+ void PlayAdditiveChargingAnimation(CStateManager&);
+ void UpdateTargettingMode(float, CStateManager&);
+ void UpdateBurstType(CStateManager&);
+ bool ShouldFire(CStateManager&) const;
+ bool IsInsignificantRotation(float) const;
public:
CScriptGunTurret(TUniqueId uid, std::string_view name, ETurretComponent comp, const CEntityInfo& info,
@@ -156,7 +225,7 @@ public:
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float, CStateManager&);
void Touch(CActor&, CStateManager&);
- void AddToRenderer(const zeus::CFrustum&, const CStateManager&);
+ void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
void Render(const CStateManager&) const;
rstl::optional GetTouchBounds() const;
zeus::CVector3f GetOrbitPosition(const CStateManager&) const;
@@ -164,31 +233,5 @@ public:
CHealthInfo* HealthInfo(CStateManager&) { return &x264_healthInfo; }
const CDamageVulnerability* GetDamageVulnerability() const { return &x26c_damageVuln; }
- void sub80219b18(s32, CStateManager&);
- void sub8021998c(s32, CStateManager&, float);
- void sub80217408(CStateManager&);
- void sub802172b8(CStateManager&);
- void sub80219a00(float, CStateManager&);
- void sub802189c8();
- void UpdateGunCollisionManager(float, CStateManager&);
- void GetUnFreezeSoundId(float, CStateManager&);
- void UpdateGunParticles(float, CStateManager&);
- void sub80219938(s32, CStateManager&);
- void sub802196c4(s32, CStateManager&, float);
- void sub802195bc(s32, CStateManager&, float);
- void sub8021942c(s32, CStateManager&, float);
- void sub80218f50(s32, CStateManager&, float);
- void sub80218e34(s32, CStateManager&);
- void sub80218bb4(s32, CStateManager&, float);
- bool sub80217ad8(CStateManager&);
- bool sub802179a4(CStateManager&);
- void sub80217f5c(float, CStateManager&);
- zeus::CVector3f sub80217e34(float);
- void sub80216288(float);
- void sub80217124(CStateManager&);
- void sub80218830(float, CStateManager&);
- void sub80216594(CStateManager&);
- bool sub80217950(CStateManager&);
- bool sub80217c24(float);
};
} // namespace urde
diff --git a/Runtime/World/CScriptPickup.cpp b/Runtime/World/CScriptPickup.cpp
index cdf7fe50e..e94753ba2 100644
--- a/Runtime/World/CScriptPickup.cpp
+++ b/Runtime/World/CScriptPickup.cpp
@@ -15,27 +15,27 @@
namespace urde {
CScriptPickup::CScriptPickup(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CActorParameters& aParams, const zeus::CAABox& aabb,
- CPlayerState::EItemType itemType, s32 amount, s32 capacity, CAssetId explosionEffect,
- float possibility, float f2, float f3, float f4, bool active)
+ CPlayerState::EItemType itemType, s32 amount, s32 capacity, CAssetId pickupEffect,
+ float possibility, float lifeTime, float fadeInTime, float startDelay, bool active)
: CPhysicsActor(uid, active, name, info, xf, std::move(mData), CMaterialList(), aabb, SMoverData(1.f), aParams, 0.3f,
0.1f)
, x258_itemType(itemType)
, x25c_amount(amount)
, x260_capacity(capacity)
, x264_possibility(possibility)
-, x268_(f3)
-, x26c_(f2)
-, x278_(f4)
-, x28c_24_(false)
-, x28c_25_(false)
-, x28c_26_(false) {
- if (explosionEffect.IsValid())
- x27c_explosionDesc = g_SimplePool->GetObj({SBIG('PART'), explosionEffect});
+, x268_fadeInTime(fadeInTime)
+, x26c_lifeTime(lifeTime)
+, x278_delayTimer(startDelay)
+, x28c_24_generated(false)
+, x28c_25_inTractor(false)
+, x28c_26_enableTractorTest(false) {
+ if (pickupEffect.IsValid())
+ x27c_pickupParticleDesc = g_SimplePool->GetObj({SBIG('PART'), pickupEffect});
if (x64_modelData && x64_modelData->AnimationData())
x64_modelData->AnimationData()->SetAnimation(CAnimPlaybackParms(0, -1, 1.f, true), false);
- if (x278_ != 0.f) {
+ if (x278_delayTimer != 0.f) {
xb4_drawFlags = CModelFlags(5, 0, 3, zeus::CColor(1.f, 1.f, 1.f, 0.f));
xb4_drawFlags.x2_flags &= 0xFFFC;
xb4_drawFlags.x2_flags |= 1;
@@ -48,93 +48,90 @@ void CScriptPickup::Think(float dt, CStateManager& mgr) {
if (!GetActive())
return;
- if (x278_ >= 0.f) {
+ if (x278_delayTimer >= 0.f) {
CPhysicsActor::Stop();
- x278_ -= dt;
+ x278_delayTimer -= dt;
return;
}
- x270_ += dt;
- if (x28c_25_ && (x270_ - x26c_) < 2.f)
- x270_ = zeus::max(2.f * dt - x270_, (2.f - x26c_) - FLT_EPSILON);
+ x270_curTime += dt;
+ if (x28c_25_inTractor && (x26c_lifeTime - x270_curTime) < 2.f)
+ x270_curTime = zeus::max(x270_curTime - 2.f * dt, x26c_lifeTime - 2.f - FLT_EPSILON);
CModelFlags drawFlags{0, 0, 3, zeus::CColor(1.f, 1.f, 1.f, 1.f)};
- if (x268_ != 0.f) {
- if (x270_ < x268_) {
- drawFlags = CModelFlags(5, 0, 3, zeus::CColor(1.f, 1.f, x270_ / x268_));
+ if (x268_fadeInTime != 0.f) {
+ if (x270_curTime < x268_fadeInTime) {
+ drawFlags = CModelFlags(5, 0, 3, zeus::CColor(1.f, x270_curTime / x268_fadeInTime));
drawFlags.x2_flags &= 0xFFFC;
drawFlags.x2_flags |= 1;
- } else
- x268_ = 0.f;
- } else if (x26c_ != 0.f) {
+ } else {
+ x268_fadeInTime = 0.f;
+ }
+ } else if (x26c_lifeTime != 0.f) {
float alpha = 1.f;
- if (x26c_ < 2.f)
- alpha = 1.f - (x26c_ / x270_);
- else if ((x270_ - x26c_) < 2.f)
- alpha = (x270_ - x26c_) * 0.5f;
+ if (x26c_lifeTime < 2.f)
+ alpha = 1.f - (x26c_lifeTime / x270_curTime);
+ else if ((x26c_lifeTime - x270_curTime) < 2.f)
+ alpha = (x26c_lifeTime - x270_curTime) * 0.5f;
- drawFlags = CModelFlags(5, 0, 3, zeus::CColor(1.f, 1.f, 1.f, alpha));
+ drawFlags = CModelFlags(5, 0, 3, zeus::CColor(1.f, alpha));
drawFlags.x2_flags &= 0xFFFC;
drawFlags.x2_flags |= 1;
}
xb4_drawFlags = drawFlags;
- if (x64_modelData) {
- if (x64_modelData->HasAnimData()) {
- SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true);
- MoveToOR(deltas.x0_posDelta, dt);
- RotateToOR(deltas.xc_rotDelta, dt);
+ if (x64_modelData && x64_modelData->HasAnimData()) {
+ SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true);
+ MoveToOR(deltas.x0_posDelta, dt);
+ RotateToOR(deltas.xc_rotDelta, dt);
+ }
+
+ if (x28c_25_inTractor) {
+ zeus::CVector3f posDelta = mgr.GetPlayer().GetTranslation() + (2.f * zeus::CVector3f::skUp) - GetTranslation();
+ x274_tractorTime += dt;
+ posDelta = (20.f * (0.5f * zeus::min(2.f, x274_tractorTime))) * posDelta.normalized();
+
+ if (x28c_26_enableTractorTest && (mgr.GetPlayer().GetPlayerGun()->IsCharging() ?
+ mgr.GetPlayer().GetPlayerGun()->GetChargeBeamFactor() : 0.f) < CPlayerGun::skTractorBeamFactor) {
+ x28c_26_enableTractorTest = false;
+ x28c_25_inTractor = false;
+ posDelta.zeroOut();
}
+ SetVelocityOR(posDelta);
+ } else if (x28c_24_generated) {
+ float chargeFactor =
+ mgr.GetPlayer().GetPlayerGun()->IsCharging() ? mgr.GetPlayer().GetPlayerGun()->GetChargeBeamFactor() : 0.f;
- if (x28c_25_) {
- zeus::CVector3f posVec = GetTranslation() - mgr.GetPlayer().GetTranslation() + (2.f * zeus::CVector3f::skUp);
- posVec = (20.f * (0.5f * zeus::max(2.f, x274_ + dt))) * posVec.normalized();
-
- float chargeFactor = 0.f;
- if (x28c_26_ && mgr.GetPlayer().GetPlayerGun()->IsCharging())
- chargeFactor = mgr.GetPlayer().GetPlayerGun()->GetChargeBeamFactor();
-
- if (chargeFactor < CPlayerGun::skTractorBeamFactor) {
- x28c_26_ = false;
- x28c_25_ = false;
- posVec.zeroOut();
- }
- SetVelocityOR(posVec);
- } else if (x28c_24_) {
- float chargeFactor =
- mgr.GetPlayer().GetPlayerGun()->IsCharging() ? mgr.GetPlayer().GetPlayerGun()->GetChargeBeamFactor() : 0.f;
-
- if (chargeFactor > CPlayerGun::skTractorBeamFactor) {
- zeus::CVector3f posVec =
- (GetTranslation() - mgr.GetCameraManager()->GetFirstPersonCamera()->GetTranslation()).normalized();
- float relFov = zeus::CRelAngle(zeus::degToRad(g_tweakGame->GetFirstPersonFOV())).asRel();
- if (mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform().upVector().dot(posVec) > std::cos(relFov) &&
- posVec.magSquared() < (30.f * 30.f)) {
- x28c_25_ = true;
- x28c_26_ = true;
- x274_ = 0.f;
- }
+ if (chargeFactor > CPlayerGun::skTractorBeamFactor) {
+ zeus::CVector3f posDelta = GetTranslation() - mgr.GetCameraManager()->GetFirstPersonCamera()->GetTranslation();
+ float relFov = zeus::CRelAngle(zeus::degToRad(g_tweakGame->GetFirstPersonFOV())).asRel();
+ if (mgr.GetCameraManager()->GetFirstPersonCamera()->GetTransform().
+ frontVector().dot(posDelta.normalized()) > std::cos(relFov) &&
+ posDelta.magSquared() < (30.f * 30.f)) {
+ x28c_25_inTractor = true;
+ x28c_26_enableTractorTest = true;
+ x274_tractorTime = 0.f;
}
}
}
- if (x26c_ != 0.f && x270_ > x26c_)
+ if (x26c_lifeTime != 0.f && x270_curTime > x26c_lifeTime)
mgr.FreeScriptObject(GetUniqueId());
}
void CScriptPickup::Touch(CActor& act, CStateManager& mgr) {
- if (GetActive() && x278_ < 0.f && TCastToPtr(act)) {
+ if (GetActive() && x278_delayTimer < 0.f && TCastToPtr(act)) {
if (x258_itemType >= CPlayerState::EItemType::Truth && x258_itemType <= CPlayerState::EItemType::Newborn) {
CAssetId id = MP1::CArtifactDoll::GetArtifactHeadScanFromItemType(x258_itemType);
if (id.IsValid())
mgr.GetPlayerState()->SetScanTime(id, 0.5f);
}
- if (x27c_explosionDesc) {
+ if (x27c_pickupParticleDesc) {
if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::Thermal) {
- mgr.AddObject(new CExplosion(x27c_explosionDesc, mgr.AllocateUniqueId(), true,
+ mgr.AddObject(new CExplosion(x27c_pickupParticleDesc, mgr.AllocateUniqueId(), true,
CEntityInfo(GetAreaIdAlways(), CEntity::NullConnectionList, kInvalidEditorId),
"Explosion - Pickup Effect", x34_transform, 0, zeus::CVector3f::skOne,
zeus::CColor::skWhite));
diff --git a/Runtime/World/CScriptPickup.hpp b/Runtime/World/CScriptPickup.hpp
index 0c5008681..c6798fb31 100644
--- a/Runtime/World/CScriptPickup.hpp
+++ b/Runtime/World/CScriptPickup.hpp
@@ -6,30 +6,32 @@
namespace urde {
class CScriptPickup : public CPhysicsActor {
CPlayerState::EItemType x258_itemType;
- u32 x25c_amount;
- u32 x260_capacity;
+ s32 x25c_amount;
+ s32 x260_capacity;
float x264_possibility;
- float x268_;
- float x26c_;
- float x270_ = 0.f;
- float x274_;
- float x278_;
- TLockedToken x27c_explosionDesc;
+ float x268_fadeInTime;
+ float x26c_lifeTime;
+ float x270_curTime = 0.f;
+ float x274_tractorTime;
+ float x278_delayTimer;
+ TLockedToken x27c_pickupParticleDesc;
- u8 x28c_24_ : 1;
- u8 x28c_25_ : 1;
- u8 x28c_26_ : 1;
+ bool x28c_24_generated : 1;
+ bool x28c_25_inTractor : 1;
+ bool x28c_26_enableTractorTest : 1;
public:
- CScriptPickup(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
- const CActorParameters&, const zeus::CAABox&, CPlayerState::EItemType, s32, s32, CAssetId, float, float,
- float, float, bool);
+ CScriptPickup(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
+ CModelData&& mData, const CActorParameters& aParams, const zeus::CAABox& aabb,
+ CPlayerState::EItemType itemType, s32 amount, s32 capacity, CAssetId pickupEffect,
+ float possibility, float lifeTime, float fadeInTime, float startDelay, bool active);
void Accept(IVisitor& visitor);
void Think(float, CStateManager&);
void Touch(CActor&, CStateManager&);
rstl::optional GetTouchBounds() const { return CPhysicsActor::GetBoundingBox(); }
float GetPossibility() const { return x264_possibility; }
- CPlayerState::EItemType GetItem() { return x258_itemType; }
+ CPlayerState::EItemType GetItem() const { return x258_itemType; }
+ void SetGenerated() { x28c_24_generated = true; }
};
} // namespace urde
diff --git a/Runtime/World/CScriptPickupGenerator.cpp b/Runtime/World/CScriptPickupGenerator.cpp
index fd847e128..bcda153d9 100644
--- a/Runtime/World/CScriptPickupGenerator.cpp
+++ b/Runtime/World/CScriptPickupGenerator.cpp
@@ -1,29 +1,159 @@
#include "CScriptPickupGenerator.hpp"
#include "TCastTo.hpp"
+#include "CStateManager.hpp"
+#include "CScriptPickup.hpp"
+#include "CWallCrawlerSwarm.hpp"
namespace urde {
+
CScriptPickupGenerator::CScriptPickupGenerator(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CVector3f& pos, float frequency, bool active)
-: CEntity(uid, info, active, name), x34_position(pos), x40_frequency(frequency) {}
+: CEntity(uid, info, active, name), x34_position(pos), x40_frequency(frequency) {
+ ResetDelayTimer();
+}
void CScriptPickupGenerator::Accept(IVisitor& visitor) { visitor.Visit(this); }
-void CScriptPickupGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) {
- if (msg == EScriptObjectMessage::SetToZero && x30_24_active && x44_ != 100.f) {
- x44_ -= 1.f;
- if (x44_ < 0.000009f)
- sub8015E220();
- else {
+void CScriptPickupGenerator::ResetDelayTimer() {
+ if (x40_frequency > 0.f)
+ x44_delayTimer += 100.f / x40_frequency;
+ else
+ x44_delayTimer = FLT_MAX;
+}
+
+void CScriptPickupGenerator::GetGeneratorIds(CStateManager& mgr, TUniqueId sender,
+ std::vector& idsOut) const {
+ idsOut.reserve(std::max(size_t(1), GetConnectionList().size()));
+ for (const auto& conn : GetConnectionList()) {
+ if (conn.x0_state == EScriptObjectState::Zero && conn.x4_msg == EScriptObjectMessage::Follow) {
+ TUniqueId id = mgr.GetIdForScript(conn.x8_objId);
+ if (id != kInvalidUniqueId) {
+ if (const CEntity* ent = mgr.GetObjectById(id)) {
+ if (ent->GetActive())
+ idsOut.push_back(id);
+ }
+ }
+ }
+ }
+ if (idsOut.empty())
+ idsOut.push_back(sender);
+}
+
+float CScriptPickupGenerator::GetPickupTemplates(CStateManager& mgr,
+ std::vector>& idsOut) const {
+ float totalPossibility = 0.f;
+ CPlayerState& pState = *mgr.GetPlayerState();
+ idsOut.reserve(GetConnectionList().size());
+ for (const auto& conn : GetConnectionList()) {
+ if (conn.x0_state == EScriptObjectState::Zero && conn.x4_msg == EScriptObjectMessage::Activate) {
+ TUniqueId id = mgr.GetIdForScript(conn.x8_objId);
+ if (id != kInvalidUniqueId) {
+ if (TCastToConstPtr pickup = mgr.GetObjectById(id)) {
+ CPlayerState::EItemType item = pickup->GetItem();
+ float possibility = pickup->GetPossibility();
+ float multiplier = 1.f;
+ bool doAlways = false;
+ bool doThirtyPerc = false;
+ switch (item) {
+ case CPlayerState::EItemType::Missiles:
+ if (pState.HasPowerUp(CPlayerState::EItemType::Missiles)) {
+ if (pState.GetItemAmount(CPlayerState::EItemType::Missiles) <
+ pState.GetItemCapacity(CPlayerState::EItemType::Missiles))
+ doAlways = true;
+ else
+ doThirtyPerc = true;
+ }
+ break;
+ case CPlayerState::EItemType::PowerBombs:
+ if (pState.HasPowerUp(CPlayerState::EItemType::PowerBombs)) {
+ if (pState.GetItemAmount(CPlayerState::EItemType::PowerBombs) <
+ pState.GetItemCapacity(CPlayerState::EItemType::PowerBombs)) {
+ doAlways = true;
+ if (pState.GetItemAmount(CPlayerState::EItemType::PowerBombs) < 2 &&
+ possibility >= 10.f && possibility < 25.f)
+ multiplier = 2.f;
+ } else {
+ doThirtyPerc = true;
+ }
+ }
+ break;
+ case CPlayerState::EItemType::HealthRefill:
+ if (pState.GetHealthInfo().GetHP() < pState.CalculateHealth())
+ doAlways = true;
+ else
+ doThirtyPerc = true;
+ break;
+ default:
+ doAlways = true;
+ break;
+ }
+ bool thirtyPercTest = mgr.GetActiveRandom()->Float() < 0.3f;
+ if ((doAlways || (doThirtyPerc && thirtyPercTest)) && possibility > 0.f) {
+ totalPossibility += possibility * multiplier;
+ idsOut.push_back(std::make_pair(possibility, conn.x8_objId));
+ }
+ }
+ }
+ }
+ }
+ return totalPossibility;
+}
+
+void CScriptPickupGenerator::GeneratePickup(CStateManager& mgr, TEditorId templateId, TUniqueId generatorId) const {
+ CEntity* pickupTempl = mgr.ObjectById(mgr.GetIdForScript(templateId));
+ CEntity* generator = mgr.ObjectById(generatorId);
+ if (pickupTempl && generator) {
+ bool oldGeneratingObject = mgr.GetIsGeneratingObject();
+ mgr.SetIsGeneratingObject(true);
+ auto p = mgr.GenerateObject(templateId);
+ mgr.SetIsGeneratingObject(oldGeneratingObject);
+ if (p.second != kInvalidUniqueId) {
+ CEntity* newObj = mgr.ObjectById(p.second);
+ CActor* newAct = TCastToPtr(newObj).GetPtr();
+ CScriptPickup* newPickup = TCastToPtr(newObj).GetPtr();
+ CActor* generatorAct = TCastToPtr(generator).GetPtr();
+ CWallCrawlerSwarm* swarmAct = TCastToPtr(generator).GetPtr();
+ if (newAct && swarmAct)
+ newAct->SetTranslation(swarmAct->GetLastKilledOffset() + x34_position);
+ else if (newAct && generatorAct)
+ newAct->SetTranslation(generatorAct->GetTranslation() + x34_position);
+ if (newPickup)
+ newPickup->SetGenerated();
+ mgr.SendScriptMsg(newObj, GetUniqueId(), EScriptObjectMessage::Activate);
+ }
+ }
+}
+
+void CScriptPickupGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& stateMgr) {
+ if (msg == EScriptObjectMessage::SetToZero && x30_24_active && x40_frequency != 100.f) {
+ x44_delayTimer -= 1.f;
+ if (x44_delayTimer < 0.000009f) {
+ ResetDelayTimer();
+ } else {
+ std::vector generatorIds;
+ GetGeneratorIds(stateMgr, sender, generatorIds);
+ std::vector> pickupTemplates;
+ float totalProb = GetPickupTemplates(stateMgr, pickupTemplates);
+ if (!pickupTemplates.empty()) {
+ float r = stateMgr.GetActiveRandom()->Range(0.f, totalProb);
+ float f2 = 0.f;
+ size_t count = 0;
+ for (const auto id : pickupTemplates) {
+ if (r >= f2 && r <= f2 + id.first)
+ break;
+ f2 += id.first;
+ ++count;
+ }
+ if (count != pickupTemplates.size()) {
+ TEditorId templateId = pickupTemplates[count].second;
+ GeneratePickup(stateMgr, templateId,
+ generatorIds[stateMgr.GetActiveRandom()->Float() * generatorIds.size() * 0.99f]);
+ }
+ }
}
}
- CEntity::AcceptScriptMsg(msg, objId, stateMgr);
+ CEntity::AcceptScriptMsg(msg, sender, stateMgr);
}
-void CScriptPickupGenerator::sub8015E220() {
- if (x40_frequency > 0.f)
- x44_ = (100.f / x40_frequency) + 100.f;
- else
- x44_ = std::numeric_limits::max();
-}
} // namespace urde
diff --git a/Runtime/World/CScriptPickupGenerator.hpp b/Runtime/World/CScriptPickupGenerator.hpp
index 78753533a..359d9935b 100644
--- a/Runtime/World/CScriptPickupGenerator.hpp
+++ b/Runtime/World/CScriptPickupGenerator.hpp
@@ -7,13 +7,16 @@ namespace urde {
class CScriptPickupGenerator : public CEntity {
zeus::CVector3f x34_position;
float x40_frequency;
- float x44_ = 0.f;
- void sub8015E220();
+ float x44_delayTimer = 0.f;
+ void ResetDelayTimer();
+ void GetGeneratorIds(CStateManager& mgr, TUniqueId sender, std::vector& idsOut) const;
+ float GetPickupTemplates(CStateManager& mgr, std::vector>& idsOut) const;
+ void GeneratePickup(CStateManager& mgr, TEditorId templateId, TUniqueId generatorId) const;
public:
CScriptPickupGenerator(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CVector3f&, float, bool);
void Accept(IVisitor& visitor);
- void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr);
+ void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& stateMgr);
};
} // namespace urde
diff --git a/Runtime/World/CScriptPlayerActor.cpp b/Runtime/World/CScriptPlayerActor.cpp
index 2293b0608..dcbb00e16 100644
--- a/Runtime/World/CScriptPlayerActor.cpp
+++ b/Runtime/World/CScriptPlayerActor.cpp
@@ -314,6 +314,7 @@ void CScriptPlayerActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid
}
if (!(x350_flags & 0x4))
break;
+ [[fallthrough]];
case EScriptObjectMessage::Reset:
if (GetActive() || msg == EScriptObjectMessage::Reset) {
x30c_setBeamId = CPlayerState::EBeamId::Invalid;
diff --git a/Runtime/World/CScriptSpecialFunction.cpp b/Runtime/World/CScriptSpecialFunction.cpp
index 7a76da790..d987879d6 100644
--- a/Runtime/World/CScriptSpecialFunction.cpp
+++ b/Runtime/World/CScriptSpecialFunction.cpp
@@ -431,6 +431,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
case ESpecialFunction::Ending: {
if (msg == EScriptObjectMessage::Action && GetSpecialEnding(mgr) == u32(xfc_))
SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None);
+ break;
}
default:
break;
diff --git a/Runtime/World/CScriptVisorGoo.cpp b/Runtime/World/CScriptVisorGoo.cpp
index c5967f0ab..0c748b005 100644
--- a/Runtime/World/CScriptVisorGoo.cpp
+++ b/Runtime/World/CScriptVisorGoo.cpp
@@ -94,6 +94,7 @@ void CScriptVisorGoo::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId,
xe8_particleDesc.Lock();
if (x100_electricId.IsValid())
xf0_electricDesc.Lock();
+ break;
default:
break;
}
diff --git a/Runtime/World/CWallCrawlerSwarm.hpp b/Runtime/World/CWallCrawlerSwarm.hpp
index 45a61c50d..6d5f17fa1 100644
--- a/Runtime/World/CWallCrawlerSwarm.hpp
+++ b/Runtime/World/CWallCrawlerSwarm.hpp
@@ -57,7 +57,7 @@ public:
u32, const CActorParameters&);
void Accept(IVisitor& visitor);
- zeus::CVector3f GetLastKilledOffset() const { return x130_lastKilledOffset; }
+ const zeus::CVector3f& GetLastKilledOffset() const { return x130_lastKilledOffset; }
void ApplyRadiusDamage(const zeus::CVector3f& pos, const CDamageInfo& info, CStateManager& stateMgr) {}
const std::vector& GetBoids() const { return x108_boids; }
int GetCurrentLockOnId() const { return x42c_lockOnId; }
diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp
index 73d8f4575..2def0abd7 100644
--- a/Runtime/World/CWorld.cpp
+++ b/Runtime/World/CWorld.cpp
@@ -147,6 +147,7 @@ bool CDummyWorld::ICheckWorldComplete() {
x8_phase = Phase::Done;
return false;
}
+ [[fallthrough]];
}
case Phase::LoadingMap: {
if (!x2c_mapWorld.IsLoaded() || !x2c_mapWorld.GetObj())
@@ -154,12 +155,14 @@ bool CDummyWorld::ICheckWorldComplete() {
x2c_mapWorld->SetWhichMapAreasLoaded(*this, 0, 9999);
x8_phase = Phase::LoadingMapAreas;
+ [[fallthrough]];
}
case Phase::LoadingMapAreas: {
if (x2c_mapWorld->IsMapAreasStreaming())
return false;
x8_phase = Phase::Done;
+ [[fallthrough]];
}
case Phase::Done:
return true;
@@ -336,6 +339,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId)
CWorldLayers::ReadWorldLayers(r, version, x8_mlvlId);
x4_phase = Phase::LoadingMap;
+ [[fallthrough]];
}
case Phase::LoadingMap: {
if (!x28_mapWorld.IsLoaded() || !x28_mapWorld.GetObj())
@@ -347,12 +351,14 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId)
x28_mapWorld->SetWhichMapAreasLoaded(*this, x68_curAreaId, 3);
x4_phase = Phase::LoadingMapAreas;
+ [[fallthrough]];
}
case Phase::LoadingMapAreas: {
if (x28_mapWorld->IsMapAreasStreaming())
return false;
x4_phase = Phase::LoadingSkyBox;
+ [[fallthrough]];
}
case Phase::LoadingSkyBox: {
x70_26_skyboxActive = true;
@@ -375,6 +381,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId)
group.x1c_groupData.Lock();
x4_phase = Phase::LoadingSoundGroups;
+ [[fallthrough]];
}
case Phase::LoadingSoundGroups: {
bool allLoaded = true;
@@ -392,6 +399,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId)
LoadSoundGroups();
x4_phase = Phase::Done;
+ [[fallthrough]];
}
case Phase::Done:
return true;
diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp
index 2df31b8b0..a06edaf7a 100644
--- a/Runtime/World/ScriptLoader.cpp
+++ b/Runtime/World/ScriptLoader.cpp
@@ -900,18 +900,18 @@ CEntity* ScriptLoader::LoadPickup(CStateManager& mgr, CInputStream& in, int prop
SScaledActorHead head = LoadScaledActorHead(in, mgr);
zeus::CVector3f extent = zeus::CVector3f::ReadBig(in);
zeus::CVector3f offset = zeus::CVector3f::ReadBig(in);
- CPlayerState::EItemType w1 = CPlayerState::EItemType(in.readUint32Big());
- u32 w2 = in.readUint32Big();
- u32 w3 = in.readUint32Big();
- float f1 = in.readFloatBig();
- float f2 = in.readFloatBig();
- float f3 = in.readFloatBig();
+ CPlayerState::EItemType itemType = CPlayerState::EItemType(in.readUint32Big());
+ u32 capacity = in.readUint32Big();
+ u32 amount = in.readUint32Big();
+ float possibility = in.readFloatBig();
+ float lifeTime = in.readFloatBig();
+ float fadeInTime = in.readFloatBig();
CAssetId staticModel = in.readUint32Big();
CAnimationParameters animParms = LoadAnimationParameters(in);
CActorParameters actorParms = LoadActorParameters(in);
bool active = in.readBool();
- float f4 = in.readFloatBig();
- CAssetId w4(in);
+ float startDelay = in.readFloatBig();
+ CAssetId pickupEffect(in);
FourCC acsType = g_ResFactory->GetResourceTypeById(animParms.GetACSFile());
if (g_ResFactory->GetResourceTypeById(staticModel) == 0 && acsType == 0)
@@ -931,7 +931,8 @@ CEntity* ScriptLoader::LoadPickup(CStateManager& mgr, CInputStream& in, int prop
aabb = data.GetBounds(head.x10_transform.getRotation());
return new CScriptPickup(mgr.AllocateUniqueId(), head.x0_name, info, head.x10_transform, std::move(data), actorParms,
- aabb, w1, w3, w2, w4, f1, f2, f3, f4, active);
+ aabb, itemType, amount, capacity, pickupEffect, possibility, lifeTime, fadeInTime,
+ startDelay, active);
}
CEntity* ScriptLoader::LoadMemoryRelay(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
diff --git a/amuse b/amuse
index 54ef2dd73..9f2bb1b37 160000
--- a/amuse
+++ b/amuse
@@ -1 +1 @@
-Subproject commit 54ef2dd73bd606f00a27192f23e66fbc6d896207
+Subproject commit 9f2bb1b371f2bd652d6d130f789da0a263e5678a
diff --git a/assetnameparser/CMakeLists.txt b/assetnameparser/CMakeLists.txt
index ee8c30453..2fc86ec45 100644
--- a/assetnameparser/CMakeLists.txt
+++ b/assetnameparser/CMakeLists.txt
@@ -8,16 +8,19 @@ set_target_properties(tinyxml2_static PROPERTIES
VERSION "${TINYXML_LIB_VERSION}"
SOVERSION "${TINYXML_LIB_SOVERSION}")
set_target_properties( tinyxml2_static PROPERTIES OUTPUT_NAME tinyxml2 )
+if (NOT MSVC)
+ set_target_properties( tinyxml2_static PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough )
+endif()
add_executable(assetnameparser "main.cpp")
include_directories(${LOGVISOR_INCLUDE_DIR})
set(AN_PARSER_LIBS "")
if (UNIX)
- list(APPEND AN_PARSER_LIBS pthread)
- if(UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
- list(APPEND AN_PARSER_LIBS dl)
- endif()
+ list(APPEND AN_PARSER_LIBS pthread)
+ if(UNIX AND ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ list(APPEND AN_PARSER_LIBS dl)
+ endif()
endif()
diff --git a/gbalink/main.cpp b/gbalink/main.cpp
index 709e4260f..aa5f15f68 100644
--- a/gbalink/main.cpp
+++ b/gbalink/main.cpp
@@ -159,11 +159,13 @@ void CGBASupport::Update(float dt) {
case EPhase::StartProbeTimeout:
x38_timeout = 4.f;
x34_phase = EPhase::PollProbe;
+ [[fallthrough]];
case EPhase::PollProbe:
/* SIProbe poll normally occurs here with 4 second timeout */
x40_siChan = m_endpoint->getChan();
x34_phase = EPhase::StartJoyBusBoot;
+ [[fallthrough]];
case EPhase::StartJoyBusBoot:
x34_phase = EPhase::PollJoyBusBoot;
diff --git a/hecl b/hecl
index 829f3dba2..7477fb1ef 160000
--- a/hecl
+++ b/hecl
@@ -1 +1 @@
-Subproject commit 829f3dba27b1acf59a274c6dbcb156b72c9ff483
+Subproject commit 7477fb1ef79d314523e1c306f87540322052a8d3
diff --git a/nod b/nod
index be8409681..95ed2ae7d 160000
--- a/nod
+++ b/nod
@@ -1 +1 @@
-Subproject commit be8409681fd5e921be72a04f460e87f2de5f6280
+Subproject commit 95ed2ae7dc8619054bff5a6d0d63d51f07334943
diff --git a/specter b/specter
index b28b91a91..0d8470c4b 160000
--- a/specter
+++ b/specter
@@ -1 +1 @@
-Subproject commit b28b91a91f4a30400707efc50f27e79114b72abc
+Subproject commit 0d8470c4bfceb14374092a1426df26ceb7e16c71