CScriptGunTurret: Brace conditionals where applicable

This commit is contained in:
Lioncash 2020-05-07 13:18:09 -04:00
parent 34d989c443
commit bea6709cc4
1 changed files with 251 additions and 183 deletions

View File

@ -159,8 +159,9 @@ CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurret
, x434_frozenEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetFrozenEffectRes()})) , x434_frozenEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetFrozenEffectRes()}))
, x440_chargingEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetChargingEffectRes()})) , x440_chargingEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetChargingEffectRes()}))
, x44c_panningEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetPanningEffectRes()})) { , x44c_panningEffectDesc(g_SimplePool->GetObj({SBIG('PART'), turretData.GetPanningEffectRes()})) {
if (turretData.GetVisorEffectRes().IsValid()) if (turretData.GetVisorEffectRes().IsValid()) {
x458_visorEffectDesc = g_SimplePool->GetObj({SBIG('PART'), turretData.GetVisorEffectRes()}); x458_visorEffectDesc = g_SimplePool->GetObj({SBIG('PART'), turretData.GetVisorEffectRes()});
}
x468_idleLight = std::make_unique<CElementGen>(x410_idleLightDesc); x468_idleLight = std::make_unique<CElementGen>(x410_idleLightDesc);
x470_deactivateLight = std::make_unique<CElementGen>(x41c_deactivateLightDesc); x470_deactivateLight = std::make_unique<CElementGen>(x41c_deactivateLightDesc);
x478_targettingLight = std::make_unique<CElementGen>(x428_targettingLightDesc); x478_targettingLight = std::make_unique<CElementGen>(x428_targettingLightDesc);
@ -172,8 +173,9 @@ CScriptGunTurret::CScriptGunTurret(TUniqueId uid, std::string_view name, ETurret
x544_originalFrontVec = xf.frontVector(); x544_originalFrontVec = xf.frontVector();
x550_originalRightVec = xf.rightVector(); x550_originalRightVec = xf.rightVector();
if (comp == ETurretComponent::Base && HasModelData() && GetModelData()->HasAnimData()) if (comp == ETurretComponent::Base && HasModelData() && GetModelData()->HasAnimData()) {
GetModelData()->EnableLooping(true); GetModelData()->EnableLooping(true);
}
x37c_projectileInfo.Token().Lock(); x37c_projectileInfo.Token().Lock();
} }
@ -187,12 +189,14 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
switch (msg) { switch (msg) {
case EScriptObjectMessage::Activate: case EScriptObjectMessage::Activate:
if (x49c_collisionManager) if (x49c_collisionManager) {
x49c_collisionManager->SetActive(mgr, true); x49c_collisionManager->SetActive(mgr, true);
}
break; break;
case EScriptObjectMessage::Deactivate: case EScriptObjectMessage::Deactivate:
if (x49c_collisionManager) if (x49c_collisionManager) {
x49c_collisionManager->SetActive(mgr, false); x49c_collisionManager->SetActive(mgr, false);
}
break; break;
case EScriptObjectMessage::Registered: case EScriptObjectMessage::Registered:
if (x258_type == ETurretComponent::Gun) { if (x258_type == ETurretComponent::Gun) {
@ -204,7 +208,7 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
} }
SetupCollisionManager(mgr); SetupCollisionManager(mgr);
} else if (x258_type == ETurretComponent::Base) { } else if (x258_type == ETurretComponent::Base) {
zeus::CVector3f scale = GetModelData()->GetScale(); const zeus::CVector3f scale = GetModelData()->GetScale();
if (x2d4_data.GetExtensionModelResId().IsValid()) { if (x2d4_data.GetExtensionModelResId().IsValid()) {
CModelData mData(CStaticRes(x2d4_data.GetExtensionModelResId(), scale)); CModelData mData(CStaticRes(x2d4_data.GetExtensionModelResId(), scale));
x4a4_extensionModel.emplace(std::move(mData)); x4a4_extensionModel.emplace(std::move(mData));
@ -215,31 +219,37 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
break; break;
case EScriptObjectMessage::Deleted: { case EScriptObjectMessage::Deleted: {
if (x258_type == ETurretComponent::Gun) { if (x258_type == ETurretComponent::Gun) {
if (x498_lightId != kInvalidUniqueId) if (x498_lightId != kInvalidUniqueId) {
mgr.FreeScriptObject(x498_lightId); mgr.FreeScriptObject(x498_lightId);
} }
if (x50c_targetingEmitter) }
if (x50c_targetingEmitter) {
CSfxManager::RemoveEmitter(x50c_targetingEmitter); CSfxManager::RemoveEmitter(x50c_targetingEmitter);
}
if (x49c_collisionManager) if (x49c_collisionManager) {
x49c_collisionManager->Destroy(mgr); x49c_collisionManager->Destroy(mgr);
}
break; break;
} }
case EScriptObjectMessage::Start: case EScriptObjectMessage::Start:
if (x258_type == ETurretComponent::Base && x520_state == ETurretState::Inactive) if (x258_type == ETurretComponent::Base && x520_state == ETurretState::Inactive) {
x560_29_scriptedStart = true; x560_29_scriptedStart = true;
}
break; break;
case EScriptObjectMessage::Stop: case EScriptObjectMessage::Stop:
if (x258_type == ETurretComponent::Base && x520_state != ETurretState::Deactive && if (x258_type == ETurretComponent::Base && x520_state != ETurretState::Deactive &&
x520_state != ETurretState::DeactiveFromReady && x520_state != ETurretState::Deactivating) x520_state != ETurretState::DeactiveFromReady && x520_state != ETurretState::Deactivating) {
SetTurretState((x560_28_hasBeenActivated ? SetTurretState((x560_28_hasBeenActivated ? ETurretState::DeactivatingFromReady : ETurretState::Deactivating),
ETurretState::DeactivatingFromReady : ETurretState::Deactivating), mgr); mgr);
}
break; break;
case EScriptObjectMessage::Action: { case EScriptObjectMessage::Action: {
if (x258_type == ETurretComponent::Gun) if (x258_type == ETurretComponent::Gun) {
LaunchProjectile(mgr); LaunchProjectile(mgr);
else if (x258_type == ETurretComponent::Base) } else if (x258_type == ETurretComponent::Base) {
PlayAdditiveFlinchAnimation(mgr); PlayAdditiveFlinchAnimation(mgr);
}
break; break;
} }
case EScriptObjectMessage::SetToMax: { case EScriptObjectMessage::SetToMax: {
@ -255,8 +265,9 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
case EScriptObjectMessage::InitializedInArea: { case EScriptObjectMessage::InitializedInArea: {
if (x258_type == ETurretComponent::Base) { if (x258_type == ETurretComponent::Base) {
for (const SConnection& conn : x20_conns) { for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) if (conn.x0_state != EScriptObjectState::Play || conn.x4_msg != EScriptObjectMessage::Activate) {
continue; continue;
}
if (TCastToConstPtr<CScriptGunTurret> gun = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) { if (TCastToConstPtr<CScriptGunTurret> gun = mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId))) {
x25c_gunId = mgr.GetIdForScript(conn.x8_objId); x25c_gunId = mgr.GetIdForScript(conn.x8_objId);
@ -269,7 +280,7 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
} }
case EScriptObjectMessage::Damage: { case EScriptObjectMessage::Damage: {
if (x258_type == ETurretComponent::Gun && GetHealthInfo(mgr)->GetHP() > 0.f) { if (x258_type == ETurretComponent::Gun && GetHealthInfo(mgr)->GetHP() > 0.f) {
if (TCastToConstPtr<CGameProjectile> proj = mgr.GetObjectById(uid)) { if (const TCastToConstPtr<CGameProjectile> proj = mgr.GetObjectById(uid)) {
if ((proj->GetAttribField() & EProjectileAttrib::Wave) == EProjectileAttrib::Wave) { if ((proj->GetAttribField() & EProjectileAttrib::Wave) == EProjectileAttrib::Wave) {
x520_state = ETurretState::Frenzy; x520_state = ETurretState::Frenzy;
RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr); RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
@ -287,25 +298,27 @@ void CScriptGunTurret::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid,
} }
void CScriptGunTurret::Think(float dt, CStateManager& mgr) { void CScriptGunTurret::Think(float dt, CStateManager& mgr) {
if (!GetActive()) if (!GetActive()) {
return; return;
}
if (x258_type == ETurretComponent::Base) { if (x258_type == ETurretComponent::Base) {
if (!x560_25_frozen) { if (!x560_25_frozen) {
ProcessGunStateMachine(dt, mgr); ProcessGunStateMachine(dt, mgr);
UpdateTurretAnimation(); UpdateTurretAnimation();
UpdateGunOrientation(dt, mgr); UpdateGunOrientation(dt, mgr);
zeus::CVector3f vec = UpdateExtensionModelState(dt); const zeus::CVector3f vec = UpdateExtensionModelState(dt);
SAdvancementDeltas advancementDeltas = UpdateAnimation(dt, mgr, true); const SAdvancementDeltas advancementDeltas = UpdateAnimation(dt, mgr, true);
SetTranslation(vec + advancementDeltas.x0_posDelta + GetTranslation()); SetTranslation(vec + advancementDeltas.x0_posDelta + GetTranslation());
RotateToOR(advancementDeltas.xc_rotDelta, dt); RotateToOR(advancementDeltas.xc_rotDelta, dt);
} else } else {
Stop(); Stop();
}
UpdateTargettingSound(dt); UpdateTargettingSound(dt);
} else if (x258_type == ETurretComponent::Gun) { } else if (x258_type == ETurretComponent::Gun) {
UpdateGunParticles(dt, mgr); UpdateGunParticles(dt, mgr);
SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true); const SAdvancementDeltas deltas = UpdateAnimation(dt, mgr, true);
MoveToOR(deltas.x0_posDelta, dt); MoveToOR(deltas.x0_posDelta, dt);
RotateToOR(deltas.xc_rotDelta, dt); RotateToOR(deltas.xc_rotDelta, dt);
UpdateGunCollisionManager(dt, mgr); UpdateGunCollisionManager(dt, mgr);
@ -315,9 +328,11 @@ void CScriptGunTurret::Think(float dt, CStateManager& mgr) {
} }
void CScriptGunTurret::Touch(CActor& act, CStateManager& mgr) { void CScriptGunTurret::Touch(CActor& act, CStateManager& mgr) {
if (x258_type != ETurretComponent::Gun) if (x258_type != ETurretComponent::Gun) {
return; return;
if (TCastToPtr<CGameProjectile> proj = act) { }
if (const TCastToConstPtr<CGameProjectile> proj = act) {
const CPlayer& player = mgr.GetPlayer(); const CPlayer& player = mgr.GetPlayer();
if (proj->GetOwnerId() == player.GetUniqueId()) { if (proj->GetOwnerId() == player.GetUniqueId()) {
const CDamageVulnerability* dVuln = GetDamageVulnerability(); const CDamageVulnerability* dVuln = GetDamageVulnerability();
@ -345,8 +360,9 @@ std::optional<zeus::CAABox> CScriptGunTurret::GetTouchBounds() const {
zeus::CVector3f CScriptGunTurret::GetOrbitPosition(const CStateManager& mgr) const { return GetAimPosition(mgr, 0.f); } zeus::CVector3f CScriptGunTurret::GetOrbitPosition(const CStateManager& mgr) const { return GetAimPosition(mgr, 0.f); }
zeus::CVector3f CScriptGunTurret::GetAimPosition(const CStateManager&, float) const { zeus::CVector3f CScriptGunTurret::GetAimPosition(const CStateManager&, float) const {
if (x258_type == ETurretComponent::Base) if (x258_type == ETurretComponent::Base) {
return GetTranslation() + x34_transform.rotate(GetLocatorTransform("Gun_SDK"sv).origin); return GetTranslation() + x34_transform.rotate(GetLocatorTransform("Gun_SDK"sv).origin);
}
return GetTranslation(); return GetTranslation();
} }
@ -356,7 +372,7 @@ void CScriptGunTurret::SetupCollisionManager(CStateManager& mgr) {
jointDescs.reserve(2); jointDescs.reserve(2);
const CAnimData* animData = GetModelData()->GetAnimationData(); const CAnimData* animData = GetModelData()->GetAnimationData();
x508_gunSDKSeg = animData->GetLocatorSegId("Gun_SDK"sv); x508_gunSDKSeg = animData->GetLocatorSegId("Gun_SDK"sv);
CSegId blastLCTR = animData->GetLocatorSegId("Blast_LCTR"sv); const CSegId blastLCTR = animData->GetLocatorSegId("Blast_LCTR"sv);
jointDescs.push_back(CJointCollisionDescription::SphereSubdivideCollision( jointDescs.push_back(CJointCollisionDescription::SphereSubdivideCollision(
x508_gunSDKSeg, blastLCTR, 0.6f, 1.f, CJointCollisionDescription::EOrientationType::One, "Gun_SDK"sv, 1000.f)); x508_gunSDKSeg, blastLCTR, 0.6f, 1.f, CJointCollisionDescription::EOrientationType::One, "Gun_SDK"sv, 1000.f));
jointDescs.push_back(CJointCollisionDescription::SphereCollision(blastLCTR, 0.3f, "Blast_LCTR"sv, 1000.f)); jointDescs.push_back(CJointCollisionDescription::SphereCollision(blastLCTR, 0.3f, "Blast_LCTR"sv, 1000.f));
@ -370,11 +386,12 @@ void CScriptGunTurret::SetupCollisionManager(CStateManager& mgr) {
cAct->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr); cAct->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr);
cAct->SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Player}, cAct->SetMaterialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Player},
{EMaterialTypes::Character, EMaterialTypes::NoStaticCollision, EMaterialTypes::NoPlatformCollision})); {EMaterialTypes::Character, EMaterialTypes::NoStaticCollision, EMaterialTypes::NoPlatformCollision}));
if (desc.GetName().find("Blast_LCTR"sv) != std::string_view::npos) if (desc.GetName().find("Blast_LCTR"sv) != std::string_view::npos) {
x4a0_collisionActor = desc.GetCollisionActorId(); x4a0_collisionActor = desc.GetCollisionActorId();
} }
} }
} }
}
void CScriptGunTurret::SetTurretState(ETurretState state, CStateManager& mgr) { void CScriptGunTurret::SetTurretState(ETurretState state, CStateManager& mgr) {
if (state < ETurretState::Destroyed || state > ETurretState::Frenzy) { if (state < ETurretState::Destroyed || state > ETurretState::Frenzy) {
@ -397,14 +414,17 @@ void CScriptGunTurret::SetTurretState(ETurretState state, CStateManager& mgr) {
} }
void CScriptGunTurret::LaunchProjectile(CStateManager& mgr) { void CScriptGunTurret::LaunchProjectile(CStateManager& mgr) {
if (x37c_projectileInfo.Token().IsLoaded() && mgr.CanCreateProjectile(GetUniqueId(), EWeaponType::AI, 8)) { if (!x37c_projectileInfo.Token().IsLoaded() || !mgr.CanCreateProjectile(GetUniqueId(), EWeaponType::AI, 8)) {
zeus::CTransform xf = GetLocatorTransform("Blast_LCTR"sv); return;
zeus::CVector3f projPt = GetTranslation() + GetTransform().rotate(xf.origin); }
const zeus::CTransform xf = GetLocatorTransform("Blast_LCTR"sv);
const zeus::CVector3f projPt = GetTranslation() + GetTransform().rotate(xf.origin);
zeus::CVector3f lookPt = x404_targetPosition; zeus::CVector3f lookPt = x404_targetPosition;
zeus::CVector3f aimDelta = x404_targetPosition - projPt; const zeus::CVector3f aimDelta = x404_targetPosition - projPt;
if (zeus::CVector3f::getAngleDiff(GetTransform().frontVector(), aimDelta) > zeus::degToRad(20.f)) { if (zeus::CVector3f::getAngleDiff(GetTransform().frontVector(), aimDelta) > zeus::degToRad(20.f)) {
if (aimDelta.canBeNormalized()) { if (aimDelta.canBeNormalized()) {
zeus::CVector3f lookDir = const zeus::CVector3f lookDir =
zeus::CVector3f::slerp(GetTransform().frontVector(), aimDelta.normalized(), zeus::degToRad(20.f)); zeus::CVector3f::slerp(GetTransform().frontVector(), aimDelta.normalized(), zeus::degToRad(20.f));
lookPt = lookDir * aimDelta.magnitude() + projPt; lookPt = lookDir * aimDelta.magnitude() + projPt;
} else { } else {
@ -413,14 +433,13 @@ void CScriptGunTurret::LaunchProjectile(CStateManager& mgr) {
} else if (!aimDelta.canBeNormalized()) { } else if (!aimDelta.canBeNormalized()) {
lookPt = projPt + GetTransform().frontVector(); lookPt = projPt + GetTransform().frontVector();
} }
zeus::CTransform useXf = zeus::lookAt(projPt, lookPt); const zeus::CTransform useXf = zeus::lookAt(projPt, lookPt);
CEnergyProjectile* proj = auto* proj = new CEnergyProjectile(true, x37c_projectileInfo.Token(), EWeaponType::AI, useXf,
new CEnergyProjectile(true, x37c_projectileInfo.Token(), EWeaponType::AI, useXf, EMaterialTypes::Character, EMaterialTypes::Character, x37c_projectileInfo.GetDamage(), mgr.AllocateUniqueId(),
x37c_projectileInfo.GetDamage(), mgr.AllocateUniqueId(), GetAreaIdAlways(), GetUniqueId(), GetAreaIdAlways(), GetUniqueId(), kInvalidUniqueId, EProjectileAttrib::None, false,
kInvalidUniqueId, EProjectileAttrib::None, false, zeus::skOne3f, zeus::skOne3f, x458_visorEffectDesc, x2d4_data.GetVisorSoundId(), false);
x458_visorEffectDesc, x2d4_data.GetVisorSoundId(), false);
mgr.AddObject(proj); mgr.AddObject(proj);
auto pair = const auto pair =
x64_modelData->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation( x64_modelData->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(
CPASAnimParmData(18, CPASAnimParm::FromEnum(1), CPASAnimParm::FromReal32(90.f), CPASAnimParmData(18, CPASAnimParm::FromEnum(1), CPASAnimParm::FromReal32(90.f),
CPASAnimParm::FromEnum(skStateToLocoTypeLookup[size_t(x520_state)])), -1); CPASAnimParm::FromEnum(skStateToLocoTypeLookup[size_t(x520_state)])), -1);
@ -429,14 +448,14 @@ void CScriptGunTurret::LaunchProjectile(CStateManager& mgr) {
x64_modelData->GetAnimationData()->SetAnimation(CAnimPlaybackParms(pair.second, -1, 1.f, true), false); x64_modelData->GetAnimationData()->SetAnimation(CAnimPlaybackParms(pair.second, -1, 1.f, true), false);
} }
} }
}
void CScriptGunTurret::PlayAdditiveFlinchAnimation(CStateManager& mgr) { void CScriptGunTurret::PlayAdditiveFlinchAnimation(CStateManager& mgr) {
auto pair = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation( const auto pair = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(
CPASAnimParmData(23), *mgr.GetActiveRandom(), -1); CPASAnimParmData(23), *mgr.GetActiveRandom(), -1);
if (pair.first > 0.f) if (pair.first > 0.f) {
GetModelData()->GetAnimationData()->AddAdditiveAnimation(pair.second, 1.f, false, true); GetModelData()->GetAnimationData()->AddAdditiveAnimation(pair.second, 1.f, false, true);
} }
}
void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) { void CScriptGunTurret::AddToRenderer(const zeus::CFrustum& frustum, CStateManager& mgr) {
CActor::AddToRenderer(frustum, mgr); CActor::AddToRenderer(frustum, mgr);
@ -503,8 +522,9 @@ void CScriptGunTurret::Render(CStateManager& mgr) {
case ETurretState::ExitTargeting: case ETurretState::ExitTargeting:
case ETurretState::Frenzy: case ETurretState::Frenzy:
x478_targettingLight->Render(x90_actorLights.get()); x478_targettingLight->Render(x90_actorLights.get());
if (x520_state == ETurretState::Firing) if (x520_state == ETurretState::Firing) {
x488_chargingEffect->Render(x90_actorLights.get()); x488_chargingEffect->Render(x90_actorLights.get());
}
break; break;
default: default:
break; break;
@ -526,8 +546,9 @@ void CScriptGunTurret::Render(CStateManager& mgr) {
} }
void CScriptGunTurret::UpdateGunCollisionManager(float dt, CStateManager& mgr) { void CScriptGunTurret::UpdateGunCollisionManager(float dt, CStateManager& mgr) {
if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(x4a0_collisionActor)) if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(x4a0_collisionActor)) {
colAct->SetActive(mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed); colAct->SetActive(mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed);
}
x49c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace); x49c_collisionManager->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
} }
@ -537,8 +558,8 @@ void CScriptGunTurret::UpdateFrozenState(float dt, CStateManager& mgr) {
if (x53c_freezeRemTime <= 0.f) { if (x53c_freezeRemTime <= 0.f) {
x560_25_frozen = false; x560_25_frozen = false;
SendScriptMsgs(EScriptObjectState::UnFrozen, mgr, EScriptObjectMessage::None); SendScriptMsgs(EScriptObjectState::UnFrozen, mgr, EScriptObjectMessage::None);
CSfxManager::AddEmitter(x2d4_data.GetUnFreezeSoundId(), GetTranslation(), zeus::skUp, false, false, CSfxManager::AddEmitter(x2d4_data.GetUnFreezeSoundId(), GetTranslation(), zeus::skUp, false, false, 0x7f,
0x7f, GetAreaIdAlways()); GetAreaIdAlways());
SetMuted(false); SetMuted(false);
} else if (x2d4_data.GetFreezeTimeout()) { } else if (x2d4_data.GetFreezeTimeout()) {
x53c_freezeRemTime -= dt; x53c_freezeRemTime -= dt;
@ -550,15 +571,17 @@ void CScriptGunTurret::UpdateFrozenState(float dt, CStateManager& mgr) {
void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) { void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
CGameLight* light = nullptr; CGameLight* light = nullptr;
if (x498_lightId != kInvalidUniqueId) if (x498_lightId != kInvalidUniqueId) {
light = TCastToPtr<CGameLight>(mgr.ObjectById(x498_lightId)); light = TCastToPtr<CGameLight>(mgr.ObjectById(x498_lightId));
}
if (!x560_25_frozen) { if (!x560_25_frozen) {
zeus::CTransform lightXf = GetLocatorTransform("light_LCTR"sv); const zeus::CTransform lightXf = GetLocatorTransform("light_LCTR"sv);
zeus::CVector3f pos = x34_transform.rotate(lightXf.origin); zeus::CVector3f pos = x34_transform.rotate(lightXf.origin);
pos += GetTranslation(); pos += GetTranslation();
if (light) if (light) {
light->SetActive(true); light->SetActive(true);
}
switch (x520_state) { switch (x520_state) {
case ETurretState::Deactive: case ETurretState::Deactive:
@ -576,11 +599,12 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
x470_deactivateLight->SetGlobalScale(GetModelData()->GetScale()); x470_deactivateLight->SetGlobalScale(GetModelData()->GetScale());
x470_deactivateLight->Update(dt); x470_deactivateLight->Update(dt);
if (light) { if (light) {
if (x470_deactivateLight->SystemHasLight()) if (x470_deactivateLight->SystemHasLight()) {
light->SetLight(x470_deactivateLight->GetLight()); light->SetLight(x470_deactivateLight->GetLight());
else } else {
light->SetActive(false); light->SetActive(false);
} }
}
break; break;
case ETurretState::Inactive: case ETurretState::Inactive:
x468_idleLight->SetParticleEmission(true); x468_idleLight->SetParticleEmission(true);
@ -593,8 +617,9 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
x468_idleLight->SetGlobalTranslation(pos); x468_idleLight->SetGlobalTranslation(pos);
x468_idleLight->SetGlobalScale(GetModelData()->GetScale()); x468_idleLight->SetGlobalScale(GetModelData()->GetScale());
x468_idleLight->Update(dt); x468_idleLight->Update(dt);
if (light) if (light) {
light->SetActive(false); light->SetActive(false);
}
break; break;
case ETurretState::PanningA: case ETurretState::PanningA:
case ETurretState::PanningB: case ETurretState::PanningB:
@ -608,14 +633,15 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
x490_panningEffect->SetGlobalTranslation(GetTranslation()); x490_panningEffect->SetGlobalTranslation(GetTranslation());
x490_panningEffect->SetGlobalScale(GetModelData()->GetScale()); x490_panningEffect->SetGlobalScale(GetModelData()->GetScale());
x490_panningEffect->Update(dt); x490_panningEffect->Update(dt);
if (light) if (light) {
light->SetActive(false); light->SetActive(false);
}
break; break;
case ETurretState::Targeting: case ETurretState::Targeting:
case ETurretState::Firing: case ETurretState::Firing:
case ETurretState::ExitTargeting: case ETurretState::ExitTargeting:
case ETurretState::Frenzy: { case ETurretState::Frenzy: {
bool doEmission = x520_state == ETurretState::Firing || x520_state == ETurretState::Frenzy; const bool doEmission = x520_state == ETurretState::Firing || x520_state == ETurretState::Frenzy;
x468_idleLight->SetParticleEmission(false); x468_idleLight->SetParticleEmission(false);
x470_deactivateLight->SetParticleEmission(false); x470_deactivateLight->SetParticleEmission(false);
x478_targettingLight->SetParticleEmission(true); x478_targettingLight->SetParticleEmission(true);
@ -625,13 +651,14 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
x478_targettingLight->SetGlobalTranslation(pos); x478_targettingLight->SetGlobalTranslation(pos);
x478_targettingLight->SetGlobalScale(GetModelData()->GetScale()); x478_targettingLight->SetGlobalScale(GetModelData()->GetScale());
x478_targettingLight->Update(dt); x478_targettingLight->Update(dt);
if (x478_targettingLight->SystemHasLight()) if (x478_targettingLight->SystemHasLight()) {
light->SetLight(x478_targettingLight->GetLight()); light->SetLight(x478_targettingLight->GetLight());
else } else {
light->SetActive(false); light->SetActive(false);
}
if (doEmission) { if (doEmission) {
zeus::CTransform blastXf = GetLocatorTransform("Blast_LCTR"sv); const zeus::CTransform blastXf = GetLocatorTransform("Blast_LCTR"sv);
zeus::CVector3f blastPos = GetTransform().rotate(blastXf.origin); zeus::CVector3f blastPos = GetTransform().rotate(blastXf.origin);
blastPos += GetTranslation(); blastPos += GetTranslation();
x488_chargingEffect->SetOrientation(GetTransform().getRotation()); x488_chargingEffect->SetOrientation(GetTransform().getRotation());
@ -649,8 +676,9 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
x488_chargingEffect->SetParticleEmission(false); x488_chargingEffect->SetParticleEmission(false);
x490_panningEffect->SetParticleEmission(false); x490_panningEffect->SetParticleEmission(false);
x490_panningEffect->Update(dt); x490_panningEffect->Update(dt);
if (light) if (light) {
light->SetActive(false); light->SetActive(false);
}
break; break;
} }
} else { } else {
@ -664,27 +692,31 @@ void CScriptGunTurret::UpdateGunParticles(float dt, CStateManager& mgr) {
x480_frozenEffect->SetGlobalTranslation(GetTranslation()); x480_frozenEffect->SetGlobalTranslation(GetTranslation());
x480_frozenEffect->SetGlobalScale(GetModelData()->GetScale()); x480_frozenEffect->SetGlobalScale(GetModelData()->GetScale());
x480_frozenEffect->Update(dt); x480_frozenEffect->Update(dt);
if (light) if (light) {
light->SetActive(false); light->SetActive(false);
} }
} }
}
void CScriptGunTurret::ProcessGunStateMachine(float dt, CStateManager& mgr) { void CScriptGunTurret::ProcessGunStateMachine(float dt, CStateManager& mgr) {
ProcessCurrentState(EStateMsg::Update, mgr, dt); ProcessCurrentState(EStateMsg::Update, mgr, dt);
x524_curStateTime += dt; x524_curStateTime += dt;
PlayAdditiveChargingAnimation(mgr); PlayAdditiveChargingAnimation(mgr);
if (x25c_gunId != kInvalidUniqueId) {
if (TCastToPtr<CScriptGunTurret> gunTurret = mgr.ObjectById(x25c_gunId)) { if (x25c_gunId == kInvalidUniqueId) {
if (gunTurret->x520_state != ETurretState::Frenzy) return;
}
if (const TCastToPtr<CScriptGunTurret> gunTurret = mgr.ObjectById(x25c_gunId)) {
if (gunTurret->x520_state != ETurretState::Frenzy) {
gunTurret->x520_state = x520_state; gunTurret->x520_state = x520_state;
else if (x520_state != ETurretState::Frenzy) { } else if (x520_state != ETurretState::Frenzy) {
SetTurretState(ETurretState::Frenzy, mgr); SetTurretState(ETurretState::Frenzy, mgr);
gunTurret->RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr); gunTurret->RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr); mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr);
} }
} }
} }
}
void CScriptGunTurret::UpdateTurretAnimation() { void CScriptGunTurret::UpdateTurretAnimation() {
if (!HasModelData() || !GetModelData()->HasAnimData()) { if (!HasModelData() || !GetModelData()->HasAnimData()) {
@ -739,21 +771,24 @@ void CScriptGunTurret::ProcessCurrentState(EStateMsg msg, CStateManager& mgr, fl
} }
void CScriptGunTurret::ProcessDeactivatingState(EStateMsg msg, CStateManager& mgr) { void CScriptGunTurret::ProcessDeactivatingState(EStateMsg msg, CStateManager& mgr) {
if (msg == EStateMsg::Update && x524_curStateTime >= x2d4_data.GetIntoDeactivateDelay()) if (msg == EStateMsg::Update && x524_curStateTime >= x2d4_data.GetIntoDeactivateDelay()) {
SetTurretState(x560_28_hasBeenActivated ? ETurretState::DeactiveFromReady : ETurretState::Deactive, mgr); SetTurretState(x560_28_hasBeenActivated ? ETurretState::DeactiveFromReady : ETurretState::Deactive, mgr);
} }
}
void CScriptGunTurret::ProcessInactiveState(EStateMsg msg, CStateManager& mgr, float dt) { void CScriptGunTurret::ProcessInactiveState(EStateMsg msg, CStateManager& mgr, float dt) {
if (msg == EStateMsg::Activate) { if (msg == EStateMsg::Activate) {
x528_curInactiveTime = 0.f; x528_curInactiveTime = 0.f;
x560_27_burstSet = false; x560_27_burstSet = false;
if (TCastToPtr<CScriptGunTurret> gunTurret = mgr.ObjectById(x25c_gunId)) if (const TCastToPtr<CScriptGunTurret> gunTurret = mgr.ObjectById(x25c_gunId)) {
x260_lastGunHP = gunTurret->HealthInfo(mgr)->GetHP(); x260_lastGunHP = gunTurret->HealthInfo(mgr)->GetHP();
}
} else if (msg == EStateMsg::Update) { } else if (msg == EStateMsg::Update) {
bool forceActivate = false; bool forceActivate = false;
if (x25c_gunId != kInvalidUniqueId) if (x25c_gunId != kInvalidUniqueId)
if (TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) if (const TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) {
forceActivate = gun->HealthInfo(mgr)->GetHP() < x260_lastGunHP; forceActivate = gun->HealthInfo(mgr)->GetHP() < x260_lastGunHP;
}
if (x2d4_data.GetScriptedStartOnly() ? (forceActivate || x560_29_scriptedStart) : if (x2d4_data.GetScriptedStartOnly() ? (forceActivate || x560_29_scriptedStart) :
(forceActivate || x560_29_scriptedStart || InDetectionRange(mgr))) { (forceActivate || x560_29_scriptedStart || InDetectionRange(mgr))) {
x528_curInactiveTime += dt; x528_curInactiveTime += dt;
@ -766,18 +801,20 @@ void CScriptGunTurret::ProcessInactiveState(EStateMsg msg, CStateManager& mgr, f
x560_28_hasBeenActivated = true; x560_28_hasBeenActivated = true;
x468_idleLight->SetParticleEmission(false); x468_idleLight->SetParticleEmission(false);
if (TCastToPtr<CScriptGunTurret> gunTurret = mgr.ObjectById(x25c_gunId)) if (const TCastToConstPtr<CScriptGunTurret> gunTurret = mgr.ObjectById(x25c_gunId)) {
x260_lastGunHP = gunTurret->GetHealthInfo(mgr)->GetHP(); x260_lastGunHP = gunTurret->GetHealthInfo(mgr)->GetHP();
} }
} }
}
void CScriptGunTurret::ProcessReadyState(EStateMsg msg, CStateManager& mgr, float dt) { void CScriptGunTurret::ProcessReadyState(EStateMsg msg, CStateManager& mgr, float dt) {
if (msg == EStateMsg::Activate) { if (msg == EStateMsg::Activate) {
x52c_curActiveTime = 0.f; x52c_curActiveTime = 0.f;
} else if (msg == EStateMsg::Update) { } else if (msg == EStateMsg::Update) {
x52c_curActiveTime += dt; x52c_curActiveTime += dt;
if (x52c_curActiveTime < x2d4_data.GetPanStartTime()) if (x52c_curActiveTime < x2d4_data.GetPanStartTime()) {
return; return;
}
if (IsPlayerInFiringRange(mgr) && InDetectionRange(mgr)) { if (IsPlayerInFiringRange(mgr) && InDetectionRange(mgr)) {
SetTurretState(ETurretState::Targeting, mgr); SetTurretState(ETurretState::Targeting, mgr);
@ -801,14 +838,15 @@ void CScriptGunTurret::ProcessPanningState(EStateMsg msg, CStateManager& mgr, fl
} else { } else {
x52c_curActiveTime += dt; x52c_curActiveTime += dt;
x530_curPanTime += dt; x530_curPanTime += dt;
if (x530_curPanTime >= x2d4_data.GetTotalPanSearchTime() && if (x530_curPanTime >= x2d4_data.GetTotalPanSearchTime() && !x4a4_extensionModel &&
!x4a4_extensionModel && !x2d4_data.GetScriptedStartOnly()) !x2d4_data.GetScriptedStartOnly()) {
SetTurretState(ETurretState::Inactive, mgr); SetTurretState(ETurretState::Inactive, mgr);
else if (x52c_curActiveTime >= x2d4_data.GetPanHoldTime()) } else if (x52c_curActiveTime >= x2d4_data.GetPanHoldTime()) {
SetTurretState(x520_state != ETurretState::PanningA ? ETurretState::PanningA : ETurretState::PanningB, mgr); SetTurretState(x520_state != ETurretState::PanningA ? ETurretState::PanningA : ETurretState::PanningB, mgr);
} }
} }
} }
}
void CScriptGunTurret::ProcessTargettingState(EStateMsg msg, CStateManager& mgr, float dt) { void CScriptGunTurret::ProcessTargettingState(EStateMsg msg, CStateManager& mgr, float dt) {
if (msg == EStateMsg::Activate) { if (msg == EStateMsg::Activate) {
@ -820,8 +858,8 @@ void CScriptGunTurret::ProcessTargettingState(EStateMsg msg, CStateManager& mgr,
if (TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) { if (TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) {
zeus::CVector3f vec = x404_targetPosition; zeus::CVector3f vec = x404_targetPosition;
if (IsPlayerInFiringRange(mgr)) { if (IsPlayerInFiringRange(mgr)) {
zeus::CTransform blastXf = gun->GetLocatorTransform("Blast_LCTR"sv); const zeus::CTransform blastXf = gun->GetLocatorTransform("Blast_LCTR"sv);
zeus::CVector3f rotatedBlastVec = GetTransform().rotate(blastXf.origin) + GetTranslation(); const zeus::CVector3f rotatedBlastVec = GetTransform().rotate(blastXf.origin) + GetTranslation();
x404_targetPosition = mgr.GetPlayer().GetAimPosition(mgr, 0.f); x404_targetPosition = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
vec = x37c_projectileInfo.PredictInterceptPos(rotatedBlastVec, mgr.GetPlayer().GetAimPosition(mgr, dt), vec = x37c_projectileInfo.PredictInterceptPos(rotatedBlastVec, mgr.GetPlayer().GetAimPosition(mgr, dt),
mgr.GetPlayer(), false, dt); mgr.GetPlayer(), false, dt);
@ -840,8 +878,8 @@ void CScriptGunTurret::ProcessTargettingState(EStateMsg msg, CStateManager& mgr,
zeus::CVector3f diffVec = x404_targetPosition - GetTranslation(); zeus::CVector3f diffVec = x404_targetPosition - GetTranslation();
diffVec.z() = 0.f; diffVec.z() = 0.f;
if (diffVec.canBeNormalized()) { if (diffVec.canBeNormalized()) {
zeus::CVector3f normDiff = diffVec.normalized(); const zeus::CVector3f normDiff = diffVec.normalized();
float angDif = zeus::CVector3f::getAngleDiff(normDiff, GetTransform().frontVector()); const float angDif = zeus::CVector3f::getAngleDiff(normDiff, GetTransform().frontVector());
zeus::CQuaternion quat = zeus::CQuaternion::lookAt(GetTransform().frontVector(), normDiff, zeus::CQuaternion quat = zeus::CQuaternion::lookAt(GetTransform().frontVector(), normDiff,
std::min(angDif, (dt * x2d4_data.GetTurnSpeed()))); std::min(angDif, (dt * x2d4_data.GetTurnSpeed())));
@ -857,9 +895,10 @@ void CScriptGunTurret::ProcessTargettingState(EStateMsg msg, CStateManager& mgr,
x52c_curActiveTime = 0.f; x52c_curActiveTime = 0.f;
} else { } else {
x52c_curActiveTime += dt; x52c_curActiveTime += dt;
if (x52c_curActiveTime >= 10.f) if (x52c_curActiveTime >= 10.f) {
SetTurretState(ETurretState::ExitTargeting, mgr); SetTurretState(ETurretState::ExitTargeting, mgr);
} }
}
} else if (msg == EStateMsg::Deactivate) { } else if (msg == EStateMsg::Deactivate) {
x560_30_needsStopClankSound = true; x560_30_needsStopClankSound = true;
} }
@ -886,12 +925,13 @@ void CScriptGunTurret::ProcessFrenzyState(EStateMsg msg, CStateManager& mgr, flo
} else if (msg == EStateMsg::Update) { } else if (msg == EStateMsg::Update) {
if (x524_curStateTime >= x2d4_data.GetFrenzyDuration()) { if (x524_curStateTime >= x2d4_data.GetFrenzyDuration()) {
SetTurretState(ETurretState::Destroyed, mgr); SetTurretState(ETurretState::Destroyed, mgr);
if (TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) if (const TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) {
gun->x520_state = ETurretState::Destroyed; gun->x520_state = ETurretState::Destroyed;
}
return; return;
} }
zeus::CVector3f frontVec = GetTransform().frontVector(); const zeus::CVector3f frontVec = GetTransform().frontVector();
if (x560_31_frenzyReverse && x550_originalRightVec.magSquared() < 0.f && if (x560_31_frenzyReverse && x550_originalRightVec.magSquared() < 0.f &&
zeus::CVector3f::getAngleDiff(x544_originalFrontVec, frontVec) >= zeus::degToRad(45.f)) { zeus::CVector3f::getAngleDiff(x544_originalFrontVec, frontVec) >= zeus::degToRad(45.f)) {
x560_31_frenzyReverse = false; x560_31_frenzyReverse = false;
@ -900,10 +940,11 @@ void CScriptGunTurret::ProcessFrenzyState(EStateMsg msg, CStateManager& mgr, flo
x560_31_frenzyReverse = true; x560_31_frenzyReverse = true;
} }
if (TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) { if (const TCastToConstPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) {
x534_fireCycleRemTime -= dt; x534_fireCycleRemTime -= dt;
if (x534_fireCycleRemTime >= 0.f) if (x534_fireCycleRemTime >= 0.f) {
return; return;
}
x404_targetPosition = gun->GetTranslation() + (100.f * gun->GetTransform().frontVector()); x404_targetPosition = gun->GetTranslation() + (100.f * gun->GetTransform().frontVector());
SendScriptMsgs(EScriptObjectState::Attack, mgr, EScriptObjectMessage::None); SendScriptMsgs(EScriptObjectState::Attack, mgr, EScriptObjectMessage::None);
@ -913,33 +954,38 @@ void CScriptGunTurret::ProcessFrenzyState(EStateMsg msg, CStateManager& mgr, flo
} }
bool CScriptGunTurret::IsPlayerInFiringRange(CStateManager& mgr) const { bool CScriptGunTurret::IsPlayerInFiringRange(CStateManager& mgr) const {
zeus::CVector3f posDif = mgr.GetPlayer().GetTranslation() - GetTranslation(); const zeus::CVector3f posDif = mgr.GetPlayer().GetTranslation() - GetTranslation();
zeus::CVector3f someVec(posDif.x(), posDif.y(), 0.f); const zeus::CVector3f someVec(posDif.x(), posDif.y(), 0.f);
if (x550_originalRightVec.dot(posDif) >= 0.f) if (x550_originalRightVec.dot(posDif) >= 0.f) {
return zeus::CVector3f::getAngleDiff(x544_originalFrontVec, someVec) <= x2d4_data.GetRightMaxAngle(); return zeus::CVector3f::getAngleDiff(x544_originalFrontVec, someVec) <= x2d4_data.GetRightMaxAngle();
}
if (zeus::CVector3f::getAngleDiff(x544_originalFrontVec, someVec) <= x2d4_data.GetLeftMaxAngle()) if (zeus::CVector3f::getAngleDiff(x544_originalFrontVec, someVec) <= x2d4_data.GetLeftMaxAngle()) {
return true; return true;
}
float biasedAngle = zeus::CVector3f::getAngleDiff(posDif, zeus::skUp) - zeus::degToRad(90.f); const float biasedAngle = zeus::CVector3f::getAngleDiff(posDif, zeus::skUp) - zeus::degToRad(90.f);
return biasedAngle >= zeus::degToRad(-20.f) && biasedAngle <= x2d4_data.GetDownMaxAngle();
return (biasedAngle >= zeus::degToRad(-20.f) && biasedAngle <= x2d4_data.GetDownMaxAngle());
} }
bool CScriptGunTurret::LineOfSightTest(CStateManager& mgr) const { bool CScriptGunTurret::LineOfSightTest(CStateManager& mgr) const {
if (x25c_gunId == kInvalidUniqueId) if (x25c_gunId == kInvalidUniqueId) {
return false; return false;
if (TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) { }
if (x560_27_burstSet || (x520_state == ETurretState::Inactive && x4a4_extensionModel))
if (const TCastToConstPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) {
if (x560_27_burstSet || (x520_state == ETurretState::Inactive && x4a4_extensionModel)) {
return true; return true;
zeus::CTransform xf = GetLocatorTransform("Blast_LCTR"sv); }
zeus::CVector3f muzzlePos = gun->GetTransform().rotate(xf.origin) + gun->GetTranslation();
const zeus::CTransform xf = GetLocatorTransform("Blast_LCTR"sv);
const zeus::CVector3f muzzlePos = gun->GetTransform().rotate(xf.origin) + gun->GetTranslation();
zeus::CVector3f dir = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - muzzlePos; zeus::CVector3f dir = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - muzzlePos;
float mag = dir.magnitude(); const float mag = dir.magnitude();
dir = dir / mag; dir = dir / mag;
rstl::reserved_vector<TUniqueId, 1024> nearList; rstl::reserved_vector<TUniqueId, 1024> nearList;
CMaterialFilter filter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, constexpr auto filter = CMaterialFilter::MakeIncludeExclude(
{EMaterialTypes::Player, EMaterialTypes::CollisionActor}); {EMaterialTypes::Solid}, {EMaterialTypes::Player, EMaterialTypes::CollisionActor});
mgr.BuildNearList(nearList, muzzlePos, dir, mag, filter, gun.GetPtr()); mgr.BuildNearList(nearList, muzzlePos, dir, mag, filter, gun.GetPtr());
TUniqueId id = kInvalidUniqueId; TUniqueId id = kInvalidUniqueId;
return mgr.RayWorldIntersection(id, muzzlePos, dir, mag, filter, nearList).IsInvalid(); return mgr.RayWorldIntersection(id, muzzlePos, dir, mag, filter, nearList).IsInvalid();
@ -948,18 +994,28 @@ bool CScriptGunTurret::LineOfSightTest(CStateManager& mgr) const {
} }
bool CScriptGunTurret::InDetectionRange(CStateManager& mgr) const { bool CScriptGunTurret::InDetectionRange(CStateManager& mgr) const {
zeus::CVector3f delta = mgr.GetPlayer().GetTranslation() - GetTranslation(); const zeus::CVector3f delta = mgr.GetPlayer().GetTranslation() - GetTranslation();
if (delta.dot(zeus::skDown) >= 0.f ||
zeus::CVector3f::getAngleDiff(GetTransform().frontVector(), delta) <= zeus::degToRad(20.f)) if (delta.dot(zeus::skDown) < 0.f &&
if (delta.magSquared() <= x2d4_data.GetDetectionRange() * x2d4_data.GetDetectionRange()) zeus::CVector3f::getAngleDiff(GetTransform().frontVector(), delta) > zeus::degToRad(20.f)) {
if (x2d4_data.GetDetectionZRange() == 0.f || std::fabs(delta.z()) < x2d4_data.GetDetectionZRange())
return LineOfSightTest(mgr);
return false; return false;
} }
if (delta.magSquared() > x2d4_data.GetDetectionRange() * x2d4_data.GetDetectionRange()) {
return false;
}
if (x2d4_data.GetDetectionZRange() != 0.f && std::fabs(delta.z()) >= x2d4_data.GetDetectionZRange()) {
return false;
}
return LineOfSightTest(mgr);
}
zeus::CVector3f CScriptGunTurret::UpdateExtensionModelState(float dt) { zeus::CVector3f CScriptGunTurret::UpdateExtensionModelState(float dt) {
if (!x4a4_extensionModel) if (!x4a4_extensionModel) {
return {}; return {};
}
switch (x520_state) { switch (x520_state) {
case ETurretState::PanningA: case ETurretState::PanningA:
@ -986,7 +1042,7 @@ void CScriptGunTurret::UpdateHealthInfo(CStateManager& mgr) {
switch (x258_type) { switch (x258_type) {
case ETurretComponent::Base: case ETurretComponent::Base:
if (x25c_gunId != kInvalidUniqueId) { if (x25c_gunId != kInvalidUniqueId) {
if (!TCastToPtr<CScriptGunTurret>(mgr.ObjectById(x25c_gunId))) { if (!TCastToConstPtr<CScriptGunTurret>(mgr.ObjectById(x25c_gunId))) {
SetTurretState(ETurretState::Destroyed, mgr); SetTurretState(ETurretState::Destroyed, mgr);
x560_25_frozen = false; x560_25_frozen = false;
x25c_gunId = kInvalidUniqueId; x25c_gunId = kInvalidUniqueId;
@ -1012,11 +1068,11 @@ void CScriptGunTurret::UpdateHealthInfo(CStateManager& mgr) {
} }
bool CScriptGunTurret::PlayerInsideTurretSphere(CStateManager& mgr) const { bool CScriptGunTurret::PlayerInsideTurretSphere(CStateManager& mgr) const {
if (TCastToConstPtr<CCollisionActor> cAct = mgr.GetObjectById(x4a0_collisionActor)) { if (const TCastToConstPtr<CCollisionActor> cAct = mgr.GetObjectById(x4a0_collisionActor)) {
if (cAct->GetActive()) { if (cAct->GetActive()) {
zeus::CVector3f delta = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation(); zeus::CVector3f delta = mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation();
if (delta.z() < 0.f) { if (delta.z() < 0.f) {
float rad = cAct->GetSphereRadius() * 2.f + const float rad = cAct->GetSphereRadius() * 2.f +
(cAct->GetTranslation() - GetTranslation()).magnitude(); (cAct->GetTranslation() - GetTranslation()).magnitude();
return delta.magSquared() < rad * rad; return delta.magSquared() < rad * rad;
} }
@ -1026,33 +1082,38 @@ bool CScriptGunTurret::PlayerInsideTurretSphere(CStateManager& mgr) const {
} }
void CScriptGunTurret::UpdateGunOrientation(float dt, CStateManager& mgr) { void CScriptGunTurret::UpdateGunOrientation(float dt, CStateManager& mgr) {
if (x25c_gunId == kInvalidUniqueId) if (x25c_gunId == kInvalidUniqueId) {
return; return;
}
if (TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) { if (const TCastToPtr<CScriptGunTurret> gun = mgr.ObjectById(x25c_gunId)) {
zeus::CTransform xf = GetLocatorTransform("Gun_SDK"sv); zeus::CTransform xf = GetLocatorTransform("Gun_SDK"sv);
xf = GetTransform() * xf; xf = GetTransform() * xf;
switch (x520_state) { switch (x520_state) {
case ETurretState::Targeting: case ETurretState::Targeting:
case ETurretState::Firing: { case ETurretState::Firing: {
float xyMagSq = xf.frontVector().toVec2f().magSquared(); const float xyMagSq = xf.frontVector().toVec2f().magSquared();
float useYaw = 0.f; float useYaw = 0.f;
if (std::sqrt(xyMagSq) > 0.001f) if (std::sqrt(xyMagSq) > 0.001f) {
useYaw = -std::atan2(xf.frontVector().x(), xf.frontVector().y()); useYaw = -std::atan2(xf.frontVector().x(), xf.frontVector().y());
float oldPitch = gun->GetPitch(); }
const float oldPitch = gun->GetPitch();
float usePitch = 0.f; float usePitch = 0.f;
if (!gun->PlayerInsideTurretSphere(mgr)) { if (!gun->PlayerInsideTurretSphere(mgr)) {
zeus::CTransform newXf; zeus::CTransform newXf;
if ((x404_targetPosition - xf.origin).canBeNormalized()) if ((x404_targetPosition - xf.origin).canBeNormalized()) {
newXf = zeus::lookAt(xf.origin, x404_targetPosition); newXf = zeus::lookAt(xf.origin, x404_targetPosition);
else } else {
newXf = GetTransform(); 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(); const float newPitch = -std::atan2(-newXf.frontVector().z(), newXf.frontVector().toVec2f().magnitude());
usePitch = std::max(std::fabs(newPitchDelta) <= const float newPitchDelta = newPitch - oldPitch;
std::fabs(f2) ? newPitch : oldPitch + f2, -x2d4_data.GetDownMaxAngle()); const 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; zeus::CQuaternion qy, qx, qz;
qy.rotateY(0.f); qy.rotateY(0.f);
@ -1062,9 +1123,9 @@ void CScriptGunTurret::UpdateGunOrientation(float dt, CStateManager& mgr) {
break; break;
} }
case ETurretState::ExitTargeting: { case ETurretState::ExitTargeting: {
zeus::CVector3f frontVec = GetTransform().frontVector(); const zeus::CVector3f frontVec = GetTransform().frontVector();
zeus::CVector3f gunFrontVec = gun->GetTransform().frontVector(); const zeus::CVector3f gunFrontVec = gun->GetTransform().frontVector();
float rotAngle = 0.3f * dt * x2d4_data.GetTurnSpeed(); const float rotAngle = 0.3f * dt * x2d4_data.GetTurnSpeed();
zeus::CQuaternion quat = zeus::CQuaternion::lookAt(gunFrontVec, frontVec, rotAngle); zeus::CQuaternion quat = zeus::CQuaternion::lookAt(gunFrontVec, frontVec, rotAngle);
quat.setImaginary(gun->GetTransform().transposeRotate(quat.getImaginary())); quat.setImaginary(gun->GetTransform().transposeRotate(quat.getImaginary()));
gun->RotateInOneFrameOR(quat, dt); gun->RotateInOneFrameOR(quat, dt);
@ -1074,16 +1135,18 @@ void CScriptGunTurret::UpdateGunOrientation(float dt, CStateManager& mgr) {
break; break;
} }
case ETurretState::Frenzy: { case ETurretState::Frenzy: {
float xyMagSq = xf.frontVector().toVec2f().magSquared(); const float xyMagSq = xf.frontVector().toVec2f().magSquared();
float useYaw = 0.f; float useYaw = 0.f;
if (std::sqrt(xyMagSq) > 0.001f) if (std::sqrt(xyMagSq) > 0.001f) {
useYaw = -std::atan2(xf.frontVector().x(), xf.frontVector().y()); useYaw = -std::atan2(xf.frontVector().x(), xf.frontVector().y());
float f28 = -0.5f * x2d4_data.GetDownMaxAngle() * }
const float f28 = -0.5f * x2d4_data.GetDownMaxAngle() *
(1.f - std::cos(2.f * x524_curStateTime * x2d4_data.GetTurnSpeed())); (1.f - std::cos(2.f * x524_curStateTime * x2d4_data.GetTurnSpeed()));
float pitch = gun->GetPitch(); const float pitch = gun->GetPitch();
float f2 = f28 - pitch; const float f2 = f28 - pitch;
float f31 = x2d4_data.GetTurnSpeed() * dt; const float f31 = x2d4_data.GetTurnSpeed() * dt;
float f3 = f2 > 0.f ? f31 : -f31; const float f3 = f2 > 0.f ? f31 : -f31;
float usePitch = std::fabs(f2) <= std::fabs(f3) ? f28 : pitch + f3; float usePitch = std::fabs(f2) <= std::fabs(f3) ? f28 : pitch + f3;
usePitch = std::max(usePitch, -x2d4_data.GetDownMaxAngle()); usePitch = std::max(usePitch, -x2d4_data.GetDownMaxAngle());
zeus::CQuaternion qy, qx, qz; zeus::CQuaternion qy, qx, qz;
@ -1091,8 +1154,8 @@ void CScriptGunTurret::UpdateGunOrientation(float dt, CStateManager& mgr) {
qx.rotateX(usePitch); qx.rotateX(usePitch);
qz.rotateZ(useYaw); qz.rotateZ(useYaw);
gun->SetTransform((qz * qx * qy).toTransform(xf.origin)); gun->SetTransform((qz * qx * qy).toTransform(xf.origin));
zeus::CQuaternion rot = zeus::CQuaternion::lookAt(GetTransform().frontVector(), zeus::CQuaternion rot = zeus::CQuaternion::lookAt(
x560_31_frenzyReverse ? -x550_originalRightVec : x550_originalRightVec, f31); GetTransform().frontVector(), x560_31_frenzyReverse ? -x550_originalRightVec : x550_originalRightVec, f31);
rot.setImaginary(GetTransform().transposeRotate(rot.getImaginary())); rot.setImaginary(GetTransform().transposeRotate(rot.getImaginary()));
RotateInOneFrameOR(rot, dt); RotateInOneFrameOR(rot, dt);
break; break;
@ -1106,34 +1169,34 @@ void CScriptGunTurret::UpdateGunOrientation(float dt, CStateManager& mgr) {
void CScriptGunTurret::UpdateTargettingSound(float dt) { void CScriptGunTurret::UpdateTargettingSound(float dt) {
x510_timeSinceLastTargetSfx += dt; x510_timeSinceLastTargetSfx += dt;
float angleDiff2D = zeus::CVector2f::getAngleDiff(x514_lastFrontVector.toVec2f(), const float angleDiff2D =
GetTransform().frontVector().toVec2f()); zeus::CVector2f::getAngleDiff(x514_lastFrontVector.toVec2f(), GetTransform().frontVector().toVec2f());
if (x560_30_needsStopClankSound && angleDiff2D < zeus::degToRad(20.f) && if (x560_30_needsStopClankSound && angleDiff2D < zeus::degToRad(20.f) &&
(x520_state == ETurretState::Targeting || x520_state == ETurretState::Firing)) { (x520_state == ETurretState::Targeting || x520_state == ETurretState::Firing)) {
if (!x560_25_frozen) if (!x560_25_frozen) {
CSfxManager::AddEmitter(x2d4_data.GetStopClankSoundId(), GetTranslation(), zeus::skUp, false, false, CSfxManager::AddEmitter(x2d4_data.GetStopClankSoundId(), GetTranslation(), zeus::skUp, false, false, 127,
127, GetAreaIdAlways()); GetAreaIdAlways());
}
x560_30_needsStopClankSound = false; x560_30_needsStopClankSound = false;
} }
if (x510_timeSinceLastTargetSfx >= 0.5f && !x560_25_frozen) { if (x510_timeSinceLastTargetSfx >= 0.5f && !x560_25_frozen) {
if (x520_state == ETurretState::Targeting || x520_state == ETurretState::Firing || if (x520_state == ETurretState::Targeting || x520_state == ETurretState::Firing ||
x520_state == ETurretState::Frenzy) { x520_state == ETurretState::Frenzy) {
bool insignificant = IsInsignificantRotation(dt); const bool insignificant = IsInsignificantRotation(dt);
if (!insignificant && !x50c_targetingEmitter) if (!insignificant && !x50c_targetingEmitter) {
x50c_targetingEmitter = CSfxManager::AddEmitter(x2d4_data.GetTrackingSoundId(), GetTranslation(), x50c_targetingEmitter = CSfxManager::AddEmitter(x2d4_data.GetTrackingSoundId(), GetTranslation(), zeus::skUp,
zeus::skUp, false, true, 127, GetAreaIdAlways()); false, true, 127, GetAreaIdAlways());
else if (insignificant && x50c_targetingEmitter) { } else if (insignificant && x50c_targetingEmitter) {
CSfxManager::RemoveEmitter(x50c_targetingEmitter); CSfxManager::RemoveEmitter(x50c_targetingEmitter);
x50c_targetingEmitter.reset(); x50c_targetingEmitter.reset();
x510_timeSinceLastTargetSfx = 0.f; x510_timeSinceLastTargetSfx = 0.f;
} }
if (x50c_targetingEmitter) { if (x50c_targetingEmitter) {
float bendScale = dt * x2d4_data.GetTurnSpeed(); const float bendScale = dt * x2d4_data.GetTurnSpeed();
CSfxManager::PitchBend(x50c_targetingEmitter, CSfxManager::PitchBend(x50c_targetingEmitter, std::max(0.f, (bendScale > 0.f ? angleDiff2D / bendScale : 0.f)));
std::max(0.f, (bendScale > 0.f ? angleDiff2D / bendScale : 0.f)));
} }
} }
} else if (x560_25_frozen && x50c_targetingEmitter) { } else if (x560_25_frozen && x50c_targetingEmitter) {
@ -1146,10 +1209,11 @@ void CScriptGunTurret::UpdateTargettingSound(float dt) {
void CScriptGunTurret::PlayAdditiveChargingAnimation(CStateManager& mgr) { void CScriptGunTurret::PlayAdditiveChargingAnimation(CStateManager& mgr) {
if (x520_state == ETurretState::Firing) { if (x520_state == ETurretState::Firing) {
if (x55c_additiveChargeAnim != -1) if (x55c_additiveChargeAnim != -1) {
return; return;
}
auto pair = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation( const auto pair = GetModelData()->GetAnimationData()->GetCharacterInfo().GetPASDatabase().FindBestAnimation(
CPASAnimParmData(24, CPASAnimParm::FromEnum(2)), *mgr.GetActiveRandom(), -1); CPASAnimParmData(24, CPASAnimParm::FromEnum(2)), *mgr.GetActiveRandom(), -1);
if (pair.first > 0.f) { if (pair.first > 0.f) {
x55c_additiveChargeAnim = pair.second; x55c_additiveChargeAnim = pair.second;
@ -1163,27 +1227,28 @@ void CScriptGunTurret::PlayAdditiveChargingAnimation(CStateManager& mgr) {
void CScriptGunTurret::UpdateTargettingMode(float dt, CStateManager& mgr) { void CScriptGunTurret::UpdateTargettingMode(float dt, CStateManager& mgr) {
if (mgr.GetCameraManager()->IsInCinematicCamera()) { if (mgr.GetCameraManager()->IsInCinematicCamera()) {
x534_fireCycleRemTime = mgr.GetActiveRandom()->Float() * x2d4_data.GetReloadTimeVariance() + x534_fireCycleRemTime =
x2d4_data.GetReloadTime(); mgr.GetActiveRandom()->Float() * x2d4_data.GetReloadTimeVariance() + x2d4_data.GetReloadTime();
x538_halfFireCycleDur = 0.5f * x534_fireCycleRemTime; x538_halfFireCycleDur = 0.5f * x534_fireCycleRemTime;
} }
if (x534_fireCycleRemTime > 0.f) { if (x534_fireCycleRemTime > 0.f) {
x534_fireCycleRemTime -= dt; x534_fireCycleRemTime -= dt;
if (x534_fireCycleRemTime < x538_halfFireCycleDur && x520_state != ETurretState::Firing) { if (x534_fireCycleRemTime < x538_halfFireCycleDur && x520_state != ETurretState::Firing) {
CSfxManager::AddEmitter(x2d4_data.GetChargingSoundId(), GetTranslation(), zeus::skUp, false, false, CSfxManager::AddEmitter(x2d4_data.GetChargingSoundId(), GetTranslation(), zeus::skUp, false, false, 0x7f,
0x7f, GetAreaIdAlways()); GetAreaIdAlways());
SetTurretState(ETurretState::Firing, mgr); SetTurretState(ETurretState::Firing, mgr);
return; return;
} }
} else { } else {
if (x520_state != ETurretState::Targeting) if (x520_state != ETurretState::Targeting) {
SetTurretState(ETurretState::Targeting, mgr); SetTurretState(ETurretState::Targeting, mgr);
}
if (!x3a4_burstFire.IsBurstSet()) { if (!x3a4_burstFire.IsBurstSet()) {
UpdateBurstType(mgr); UpdateBurstType(mgr);
x534_fireCycleRemTime = mgr.GetActiveRandom()->Float() * x2d4_data.GetReloadTimeVariance() + x534_fireCycleRemTime =
x2d4_data.GetReloadTime(); mgr.GetActiveRandom()->Float() * x2d4_data.GetReloadTimeVariance() + x2d4_data.GetReloadTime();
x538_halfFireCycleDur = 0.5f * x534_fireCycleRemTime; x538_halfFireCycleDur = 0.5f * x534_fireCycleRemTime;
} else { } else {
x3a4_burstFire.Update(mgr, dt); x3a4_burstFire.Update(mgr, dt);
@ -1195,26 +1260,28 @@ void CScriptGunTurret::UpdateBurstType(CStateManager& mgr) {
if (x560_27_burstSet) { if (x560_27_burstSet) {
bool inView = true; bool inView = true;
if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed) { if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed) {
zeus::CVector3f frontVec = GetTransform().frontVector(); const zeus::CVector3f frontVec = GetTransform().frontVector();
zeus::CVector3f plFrontVec = mgr.GetPlayer().GetTransform().frontVector(); const zeus::CVector3f plFrontVec = mgr.GetPlayer().GetTransform().frontVector();
float dot = frontVec.dot(plFrontVec); const float dot = frontVec.dot(plFrontVec);
if (dot >= 0.f) if (dot >= 0.f) {
inView = false; inView = false;
} }
}
u32 r3 = mgr.GetActiveRandom()->Range(0, 3); u32 r3 = mgr.GetActiveRandom()->Range(0, 3);
r3 += 2; r3 += 2;
u32 type;
if (r3 <= 2 || x2d4_data.GetNumSubsequentShots() < 3) u32 type = 1;
if (r3 <= 2 || x2d4_data.GetNumSubsequentShots() < 3) {
type = 0; type = 0;
else if (r3 >= 5 && x2d4_data.GetNumSubsequentShots() > 3) } else if (r3 >= 5 && x2d4_data.GetNumSubsequentShots() > 3) {
type = 2; type = 2;
else }
type = 1;
x3a4_burstFire.SetBurstType(type + (inView ? 0 : 3)); x3a4_burstFire.SetBurstType(type + (inView ? 0 : 3));
} else { } else {
u32 type = x2d4_data.GetNumInitialShots() - 2; const u32 type = x2d4_data.GetNumInitialShots() - 2;
x3a4_burstFire.SetBurstType(type); x3a4_burstFire.SetBurstType(type);
x3a4_burstFire.SetFirstBurstIndex(x2d4_data.GetInitialShotTableIndex()); x3a4_burstFire.SetFirstBurstIndex(x2d4_data.GetInitialShotTableIndex());
} }
@ -1225,8 +1292,9 @@ void CScriptGunTurret::UpdateBurstType(CStateManager& mgr) {
} }
bool CScriptGunTurret::ShouldFire(CStateManager& mgr) const { bool CScriptGunTurret::ShouldFire(CStateManager& mgr) const {
if (x520_state == ETurretState::Targeting && x534_fireCycleRemTime <= 0.f && x3a4_burstFire.ShouldFire()) if (x520_state == ETurretState::Targeting && x534_fireCycleRemTime <= 0.f && x3a4_burstFire.ShouldFire()) {
return IsPlayerInFiringRange(mgr); return IsPlayerInFiringRange(mgr);
}
return false; return false;
} }