More CFlameThrower imps, implement `CScriptSpecialFunction::ThinkChaffTarget` and `CScriptSpecialFunction::ObjectFollowObject`

This commit is contained in:
Phillip Stephens 2019-05-09 19:33:56 -07:00
parent 28071851ad
commit 81f1e22fc2
5 changed files with 146 additions and 6 deletions

View File

@ -34,5 +34,11 @@ public:
void Activate(bool val) { xa0_24_activated = val; }
bool IsActivated() { return xa0_24_activated; }
FourCC Get4CharID() { return FOURCC('FWRP'); }
void ResetPosition(const zeus::CVector3f& pos) {
for (auto& vec : x4_vecs) {
vec = pos;
}
xa0_26_processed = false;
}
};
} // namespace urde

View File

@ -44,6 +44,7 @@ public:
void Touch(CActor& act, CStateManager& mgr);
virtual bool Explode(const zeus::CVector3f& pos, const zeus::CVector3f& normal, EWeaponCollisionResponseTypes type,
CStateManager& mgr, const CDamageVulnerability& dVuln, TUniqueId hitActor);
void Set3d0_26(bool v) { x3d0_26_ = v; }
};
} // namespace urde

View File

@ -1,7 +1,9 @@
#include "Weapon/CFlameThrower.hpp"
#include "Weapon/CFlameInfo.hpp"
#include "World/CGameLight.hpp"
#include "Particle/CElementGen.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "CStateManager.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "TCastTo.hpp"
@ -33,15 +35,43 @@ CFlameThrower::CFlameThrower(const TToken<CWeaponDescription>& wDesc, std::strin
void CFlameThrower::Accept(IVisitor& visitor) { visitor.Visit(this); }
void CFlameThrower::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
if (msg == EScriptObjectMessage::Registered) {
xe6_27_thermalVisorFlags |= 2;
mgr.AddWeaponId(xec_ownerId, xf0_weaponType);
} else if (msg == EScriptObjectMessage::Deleted) {
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
DeleteProjectileLight(mgr);
}
CGameProjectile::AcceptScriptMsg(msg, uid, mgr);
}
void CFlameThrower::SetTransform(const zeus::CTransform& xf, float) { x2e8_ = xf; }
void CFlameThrower::Reset(CStateManager&, bool) {}
void CFlameThrower::Reset(CStateManager& mgr, bool resetWarp) {
SetFlameLightActive(mgr, false);
if (resetWarp) {
SetActive(false);
x400_25_ = false;
x3f0_flameState = 0;
x330_ = 0.f;
x334_ = 0.f;
x318_ = zeus::skNullBox;
x348_flameGen->SetParticleEmission(false);
x34c_.ResetPosition(x2e8_.origin);
} else {
x348_flameGen->SetParticleEmission(false);
x400_25_ = false;
x3f0_flameState = 3;
}
}
void CFlameThrower::Fire(const zeus::CTransform&, CStateManager& mgr, bool) {
SetActive(true);
x400_25_ = true;
x400_24_ = true;
x3f0_ = 1;
x3f0_flameState = 1;
CreateFlameParticles(mgr);
}
@ -59,4 +89,45 @@ void CFlameThrower::AddToRenderer(const zeus::CFrustum&, const CStateManager& mg
g_Renderer->AddParticleGen(*x348_flameGen);
EnsureRendered(mgr, x2e8_.origin, GetRenderBounds());
}
void CFlameThrower::SetFlameLightActive(CStateManager& mgr, bool active) {
if (x2c8_projectileLight == kInvalidUniqueId)
return;
if (TCastToPtr<CGameLight> light = mgr.ObjectById(x2c8_projectileLight))
light->SetActive(active);
}
void CFlameThrower::UpdateFlameState(float dt, CStateManager& mgr) {
switch(x3f0_flameState) {
case 1:
x3f0_flameState = 2;
break;
case 3:
x334_ += 4.f * dt;
if (x334_ > 1.f) {
x334_ = 1.f;
x3f0_flameState = 4;
x400_24_ = false;
}
break;
case 4:
x330_ += dt;
if (x330_ > 0.1f && x348_flameGen && x348_flameGen->GetParticleCountAll() == 0) {
x3f0_flameState = 0;
Reset(mgr, true);
}
break;
default:
break;
}
}
void CFlameThrower::Think(float dt, CStateManager& mgr) {
CWeapon::Think(dt, mgr);
if (!GetActive())
return;
UpdateFlameState(dt, mgr);
}
} // namespace urde

View File

@ -17,7 +17,7 @@ class CFlameThrower : public CGameProjectile {
TToken<CGenDescription> x33c_flameDesc;
std::unique_ptr<CElementGen> x348_flameGen;
CFlameWarp x34c_;
u32 x3f0_;
u32 x3f0_flameState;
CAssetId x3f4_;
s16 x3f8_;
CAssetId x3fc_;
@ -33,6 +33,8 @@ class CFlameThrower : public CGameProjectile {
};
void CreateFlameParticles(CStateManager&);
void SetFlameLightActive(CStateManager&, bool);
void UpdateFlameState(float, CStateManager&);
public:
CFlameThrower(const TToken<CWeaponDescription>& wDesc, std::string_view name, EWeaponType wType,
const CFlameInfo& flameInfo, const zeus::CTransform& xf, EMaterialTypes matType,
@ -40,6 +42,8 @@ public:
CAssetId w2, s16 sId, CAssetId w3);
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float, CStateManager&);
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
void SetTransform(const zeus::CTransform& xf, float);
void Reset(CStateManager&, bool);

View File

@ -5,6 +5,7 @@
#include "Graphics/CTexture.hpp"
#include "World/CActorParameters.hpp"
#include "World/CPlayer.hpp"
#include "Weapon/CEnergyProjectile.hpp"
#include "GameGlobalObjects.hpp"
#include "CMemoryCardSys.hpp"
#include "CGameState.hpp"
@ -569,7 +570,8 @@ void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr)
TUniqueId followerAct = kInvalidUniqueId;
TUniqueId followedAct = kInvalidUniqueId;
for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play)
if (conn.x0_state != EScriptObjectState::Play || (conn.x4_msg != EScriptObjectMessage::Activate &&
conn.x4_msg != EScriptObjectMessage::Deactivate))
continue;
auto search = mgr.GetIdListForScript(conn.x8_objId);
@ -593,9 +595,65 @@ void CScriptSpecialFunction::ThinkObjectFollowLocator(float, CStateManager& mgr)
toAct->SetTransform(fromAct->GetTransform() * fromAct->GetScaledLocatorTransform(xec_locatorName));
}
void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager&) {}
void CScriptSpecialFunction::ThinkObjectFollowObject(float, CStateManager& mgr) {
TUniqueId followerAct = kInvalidUniqueId;
TUniqueId followedAct = kInvalidUniqueId;
for (const SConnection& conn : x20_conns) {
if (conn.x0_state != EScriptObjectState::Play || (conn.x4_msg != EScriptObjectMessage::Activate &&
conn.x4_msg != EScriptObjectMessage::Deactivate))
continue;
void CScriptSpecialFunction::ThinkChaffTarget(float, CStateManager&) {}
auto search = mgr.GetIdListForScript(conn.x8_objId);
for (auto it = search.first; it != search.second; ++it) {
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(it->second)) {
if (conn.x4_msg == EScriptObjectMessage::Activate && act->GetActive()) {
followedAct = it->second;
} else if (conn.x4_msg == EScriptObjectMessage::Deactivate) {
followerAct = it->second;
}
}
}
}
TCastToConstPtr<CActor> followed = mgr.GetObjectById(followedAct);
TCastToPtr<CActor> follower = mgr.ObjectById(followerAct);
if (followed && follower)
follower->SetTransform(followed->GetTransform());
}
void CScriptSpecialFunction::ThinkChaffTarget(float dt, CStateManager& mgr) {
zeus::CAABox box(5.f - GetTranslation(), 5.f + GetTranslation());
rstl::reserved_vector<TUniqueId, 1024> nearList;
mgr.BuildNearList(nearList, box, CMaterialFilter::MakeInclude({EMaterialTypes::Projectile}), nullptr);
CCameraFilterPassPoly& filter = mgr.GetCameraFilterPass(7);
for (TUniqueId uid : nearList) {
if (TCastToPtr<CEnergyProjectile> proj = mgr.ObjectById(uid)) {
if (proj->GetHomingTargetId() == GetUniqueId()) {
proj->Set3d0_26(true);
if (mgr.GetPlayer().GetAreaIdAlways() == GetAreaIdAlways()) {
mgr.GetPlayer().SetHudDisable(x100_float2, 0.5f, 2.5f);
filter.SetFilter(EFilterType::Blend, EFilterShape::Fullscreen, zeus::skWhite, {});
filter.DisableFilter(0.1f);
}
}
}
}
x194_ = zeus::max(0.f, x194_ - dt);
if (x194_ != 0.f && mgr.GetPlayer().GetAreaIdAlways() == GetAreaIdAlways()) {
float intfMag = x104_float3 * (0.5f + ((0.5f + x194_) / xfc_float1);
if (x194_ < 1.f)
intfMag *= x194_;
mgr.GetPlayerState()->GetStaticInterference().AddSource(GetUniqueId(), intfMag, .5f);
if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::Scan)
mgr.GetPlayer().AddOrbitDisableSource(mgr, GetUniqueId()).
else
mgr.GetPlayer().RemoveOrbitDisableSource(GetUniqueId());
}
}
void CScriptSpecialFunction::ThinkActorScale(float dt, CStateManager& mgr) {
float deltaScale = dt * xfc_float1;