mirror of https://github.com/AxioDL/metaforce.git
More CFlameThrower imps, implement `CScriptSpecialFunction::ThinkChaffTarget` and `CScriptSpecialFunction::ObjectFollowObject`
This commit is contained in:
parent
28071851ad
commit
81f1e22fc2
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue