mirror of https://github.com/AxioDL/metaforce.git
CShockWave: Implement Touch
This commit is contained in:
parent
6e5c32abfd
commit
d4ff239f91
|
@ -915,10 +915,11 @@ void CElitePirate::CreateGrenadeLauncher(CStateManager& mgr, TUniqueId uid) {
|
||||||
}
|
}
|
||||||
CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(),
|
CModelData mData(CAnimRes(params.GetACSFile(), params.GetCharacter(), GetModelData()->GetScale(),
|
||||||
params.GetInitialAnimation(), true));
|
params.GetInitialAnimation(), true));
|
||||||
mgr.AddObject(new CGrenadeLauncher(
|
const zeus::CAABox bounds = mData.GetBounds(GetTransform().getRotation());
|
||||||
uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, GetTransform(), std::move(mData),
|
mgr.AddObject(
|
||||||
mData.GetBounds(GetTransform().getRotation()), CHealthInfo(x5d8_data.GetLauncherHP(), 10.f), x56c_vulnerability,
|
new CGrenadeLauncher(uid, "Grenade Launcher", {GetAreaIdAlways(), CEntity::NullConnectionList}, GetTransform(),
|
||||||
x5d8_data.GetLauncherActParams(), GetUniqueId(), x5d8_data.GetGrenadeLauncherData(), 0.f));
|
std::move(mData), bounds, CHealthInfo(x5d8_data.GetLauncherHP(), 10.f), x56c_vulnerability,
|
||||||
|
x5d8_data.GetLauncherActParams(), GetUniqueId(), x5d8_data.GetGrenadeLauncherData(), 0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) {
|
void CElitePirate::ApplyDamageToHead(CStateManager& mgr, TUniqueId uid) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ private:
|
||||||
CAssetId xf8_;
|
CAssetId xf8_;
|
||||||
CDamageInfo xfc_;
|
CDamageInfo xfc_;
|
||||||
CAssetId x118_;
|
CAssetId x118_;
|
||||||
s16 x11c_;
|
u16 x11c_;
|
||||||
bool x11e_;
|
bool x11e_;
|
||||||
bool x11f_;
|
bool x11f_;
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ public:
|
||||||
[[nodiscard]] CAssetId GetXF8() const { return xf8_; }
|
[[nodiscard]] CAssetId GetXF8() const { return xf8_; }
|
||||||
[[nodiscard]] const CDamageInfo& GetXFC() const { return xfc_; }
|
[[nodiscard]] const CDamageInfo& GetXFC() const { return xfc_; }
|
||||||
[[nodiscard]] CAssetId GetX118() const { return x118_; }
|
[[nodiscard]] CAssetId GetX118() const { return x118_; }
|
||||||
[[nodiscard]] s16 GetX11C() const { return x11c_; }
|
[[nodiscard]] u16 GetX11C() const { return x11c_; }
|
||||||
[[nodiscard]] bool GetX11E() const { return x11e_; }
|
[[nodiscard]] bool GetX11E() const { return x11e_; }
|
||||||
[[nodiscard]] bool GetX11F() const { return x11f_; }
|
[[nodiscard]] bool GetX11F() const { return x11f_; }
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "Runtime/Graphics/CBooRenderer.hpp"
|
#include "Runtime/Graphics/CBooRenderer.hpp"
|
||||||
#include "Runtime/World/CActorParameters.hpp"
|
#include "Runtime/World/CActorParameters.hpp"
|
||||||
#include "Runtime/World/CGameLight.hpp"
|
#include "Runtime/World/CGameLight.hpp"
|
||||||
|
#include "Runtime/World/CHUDBillboardEffect.hpp"
|
||||||
|
#include "Runtime/World/CPlayer.hpp"
|
||||||
|
|
||||||
#include "TCastTo.hpp" // Generated file, do not modify include path
|
#include "TCastTo.hpp" // Generated file, do not modify include path
|
||||||
|
|
||||||
|
@ -16,16 +18,16 @@ CShockWave::CShockWave(TUniqueId uid, std::string_view name, const CEntityInfo&
|
||||||
: CActor(uid, true, name, info, xf, CModelData::CModelDataNull(), {EMaterialTypes::Projectile},
|
: CActor(uid, true, name, info, xf, CModelData::CModelDataNull(), {EMaterialTypes::Projectile},
|
||||||
CActorParameters::None(), kInvalidUniqueId)
|
CActorParameters::None(), kInvalidUniqueId)
|
||||||
, xe8_id1(parent)
|
, xe8_id1(parent)
|
||||||
, xec_damageInfo(data.x8_damageInfo)
|
, xec_damageInfo(data.GetDamageInfo())
|
||||||
, x108_elementGenDesc(g_SimplePool->GetObj({SBIG('PART'), data.x4_particleDesc}))
|
, x108_elementGenDesc(g_SimplePool->GetObj({SBIG('PART'), data.GetParticleDescId()}))
|
||||||
, x110_elementGen(std::make_unique<CElementGen>(x108_elementGenDesc))
|
, x110_elementGen(std::make_unique<CElementGen>(x108_elementGenDesc))
|
||||||
, x114_data(data)
|
, x114_data(data)
|
||||||
, x150_(data.x24_)
|
, x150_(data.GetX24())
|
||||||
, x154_(data.x2c_)
|
, x154_(data.GetX2C())
|
||||||
, x15c_(f1)
|
, x15c_(f1)
|
||||||
, x160_(f2) {
|
, x160_(f2) {
|
||||||
if (data.x34_weaponDesc.IsValid()) {
|
if (data.GetWeaponDescId().IsValid()) {
|
||||||
x974_electricDesc = g_SimplePool->GetObj({SBIG('ELSC'), data.x34_weaponDesc});
|
x974_electricDesc = g_SimplePool->GetObj({SBIG('ELSC'), data.GetWeaponDescId()});
|
||||||
}
|
}
|
||||||
x110_elementGen->SetParticleEmission(true);
|
x110_elementGen->SetParticleEmission(true);
|
||||||
x110_elementGen->SetOrientation(GetTransform().getRotation());
|
x110_elementGen->SetOrientation(GetTransform().getRotation());
|
||||||
|
@ -41,7 +43,7 @@ void CShockWave::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CState
|
||||||
x980_id2 = mgr.AllocateUniqueId();
|
x980_id2 = mgr.AllocateUniqueId();
|
||||||
mgr.AddObject(new CGameLight(x980_id2, GetAreaIdAlways(), GetActive(), "ShockWaveLight_" + x10_name,
|
mgr.AddObject(new CGameLight(x980_id2, GetAreaIdAlways(), GetActive(), "ShockWaveLight_" + x10_name,
|
||||||
GetTransform(), GetUniqueId(), x110_elementGen->GetLight(),
|
GetTransform(), GetUniqueId(), x110_elementGen->GetLight(),
|
||||||
x114_data.x4_particleDesc.Value(), 1, 0.f));
|
x114_data.GetParticleDescId().Value(), 1, 0.f));
|
||||||
}
|
}
|
||||||
} else if (msg == EScriptObjectMessage::Deleted) {
|
} else if (msg == EScriptObjectMessage::Deleted) {
|
||||||
mgr.FreeScriptObject(x980_id2);
|
mgr.FreeScriptObject(x980_id2);
|
||||||
|
@ -73,7 +75,7 @@ void CShockWave::Think(float dt, CStateManager& mgr) {
|
||||||
x110_elementGen->Update(dt);
|
x110_elementGen->Update(dt);
|
||||||
x158_ += dt;
|
x158_ += dt;
|
||||||
x150_ += x154_ * dt;
|
x150_ += x154_ * dt;
|
||||||
x154_ += dt * x114_data.x30_;
|
x154_ += dt * x114_data.GetX30();
|
||||||
x110_elementGen->SetExternalVar(0, x150_);
|
x110_elementGen->SetExternalVar(0, x150_);
|
||||||
for (int i = 0; i < x110_elementGen->GetNumActiveChildParticles(); i++) {
|
for (int i = 0; i < x110_elementGen->GetNumActiveChildParticles(); i++) {
|
||||||
auto& particle = static_cast<CElementGen&>(x110_elementGen->GetActiveChildParticle(i));
|
auto& particle = static_cast<CElementGen&>(x110_elementGen->GetActiveChildParticle(i));
|
||||||
|
@ -81,13 +83,13 @@ void CShockWave::Think(float dt, CStateManager& mgr) {
|
||||||
particle.SetExternalVar(0, x150_);
|
particle.SetExternalVar(0, x150_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x16c_) {
|
if (x16c_hitPlayerInAir) {
|
||||||
x164_ += dt;
|
x164_timeSinceHitPlayerInAir += dt;
|
||||||
x16c_ = false;
|
x16c_hitPlayerInAir = false;
|
||||||
}
|
}
|
||||||
if (x16d_) {
|
if (x16d_hitPlayer) {
|
||||||
x168_ += dt;
|
x168_timeSinceHitPlayer += dt;
|
||||||
x16d_ = false;
|
x16d_hitPlayer = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (x110_elementGen->IsSystemDeletable() && x15c_ > 0.f && x158_ >= x15c_) {
|
if (x110_elementGen->IsSystemDeletable() && x15c_ > 0.f && x158_ >= x15c_) {
|
||||||
|
@ -110,8 +112,66 @@ void CShockWave::Touch(CActor& actor, CStateManager& mgr) {
|
||||||
if (TCastToConstPtr<CCollisionActor> cactor = mgr.GetObjectById(actor.GetUniqueId())) {
|
if (TCastToConstPtr<CCollisionActor> cactor = mgr.GetObjectById(actor.GetUniqueId())) {
|
||||||
isParent = xe8_id1 == cactor->GetOwnerId();
|
isParent = xe8_id1 == cactor->GetOwnerId();
|
||||||
}
|
}
|
||||||
if (!isParent) {
|
if (isParent) {
|
||||||
// TODO
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float mmax = x150_ * x150_;
|
||||||
|
float mmin = mmax * x114_data.GetX28() * x114_data.GetX28();
|
||||||
|
zeus::CVector3f dist = actor.GetTranslation() - GetTranslation();
|
||||||
|
CDamageInfo damageInfo = xec_damageInfo;
|
||||||
|
float knockBackScale = std::max(0.f, 1.f - x160_ * x158_);
|
||||||
|
bool isPlayer = mgr.GetPlayer().GetUniqueId() == actor.GetUniqueId();
|
||||||
|
bool isPlayerInAir = isPlayer && mgr.GetPlayer().GetPlayerMovementState() != CPlayer::EPlayerMovementState::OnGround;
|
||||||
|
float distXYMag = dist.toVec2f().magSquared();
|
||||||
|
if (distXYMag < mmin || distXYMag > mmax) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPlayer) {
|
||||||
|
if (mgr.GetPlayer().GetPlayerMovementState() == CPlayer::EPlayerMovementState::OnGround) {
|
||||||
|
const zeus::CTransform& playerTransform = mgr.GetPlayer().GetTransform();
|
||||||
|
zeus::CVector3f playerDir = GetTranslation() - playerTransform.origin;
|
||||||
|
if (playerDir.canBeNormalized()) {
|
||||||
|
playerDir.normalize();
|
||||||
|
float dot = std::abs(playerDir.dot(playerTransform.frontVector()));
|
||||||
|
knockBackScale = std::max(0.12f, 0.88f * dot * dot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mgr.GetPlayer().GetVelocity().magnitude() > 40.f) {
|
||||||
|
x168_timeSinceHitPlayer = 0.2666f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
damageInfo.SetKnockBackPower(knockBackScale * damageInfo.GetKnockBackPower());
|
||||||
|
|
||||||
|
if (isPlayer && (x164_timeSinceHitPlayerInAir >= 0.1333f || x168_timeSinceHitPlayer >= 0.2666f)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!IsHit(actor.GetUniqueId())) {
|
||||||
|
mgr.ApplyDamage(GetUniqueId(), actor.GetUniqueId(), GetUniqueId(), damageInfo,
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f);
|
||||||
|
if (isPlayer && x974_electricDesc) {
|
||||||
|
mgr.AddObject(new CHUDBillboardEffect(std::nullopt, x974_electricDesc, mgr.AllocateUniqueId(), true,
|
||||||
|
"VisorElectricFx", CHUDBillboardEffect::GetNearClipDistance(mgr),
|
||||||
|
CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::skWhite, zeus::skOne3f,
|
||||||
|
zeus::skZero3f));
|
||||||
|
CSfxManager::SfxStart(x114_data.GetElectrocuteSfx(), 1.f, 1.f, false, 0x7f, false, kInvalidAreaId);
|
||||||
|
}
|
||||||
|
x170_hitIds.push_back(actor.GetUniqueId());
|
||||||
|
} else {
|
||||||
|
damageInfo.SetDamage(0.f);
|
||||||
|
mgr.ApplyDamage(GetUniqueId(), actor.GetUniqueId(), GetUniqueId(), damageInfo,
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), zeus::skZero3f);
|
||||||
|
}
|
||||||
|
if (isPlayerInAir) {
|
||||||
|
x16c_hitPlayerInAir = true;
|
||||||
|
}
|
||||||
|
if (isPlayer) {
|
||||||
|
x16d_hitPlayer = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CShockWave::IsHit(TUniqueId id) const {
|
||||||
|
return std::find(x170_hitIds.begin(), x170_hitIds.end(), id) != x170_hitIds.end();
|
||||||
|
}
|
||||||
} // namespace urde::MP1
|
} // namespace urde::MP1
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
namespace urde::MP1 {
|
namespace urde::MP1 {
|
||||||
struct SShockWaveData {
|
struct SShockWaveData {
|
||||||
|
private:
|
||||||
u32 x0_ = 8;
|
u32 x0_ = 8;
|
||||||
CAssetId x4_particleDesc;
|
CAssetId x4_particleDesc;
|
||||||
CDamageInfo x8_damageInfo;
|
CDamageInfo x8_damageInfo;
|
||||||
|
@ -14,10 +15,20 @@ struct SShockWaveData {
|
||||||
float x2c_ = 16.5217f;
|
float x2c_ = 16.5217f;
|
||||||
float x30_ = 0.f;
|
float x30_ = 0.f;
|
||||||
CAssetId x34_weaponDesc;
|
CAssetId x34_weaponDesc;
|
||||||
s16 x38_sfx;
|
u16 x38_electrocuteSfx;
|
||||||
|
|
||||||
SShockWaveData(CAssetId part, const CDamageInfo& dInfo, CAssetId weapon, s16 sfx)
|
public:
|
||||||
: x4_particleDesc(part), x8_damageInfo(dInfo), x34_weaponDesc(weapon), x38_sfx(sfx) {}
|
SShockWaveData(CAssetId part, const CDamageInfo& dInfo, CAssetId weapon, u16 sfx)
|
||||||
|
: x4_particleDesc(part), x8_damageInfo(dInfo), x34_weaponDesc(weapon), x38_electrocuteSfx(sfx) {}
|
||||||
|
|
||||||
|
[[nodiscard]] CAssetId GetParticleDescId() const { return x4_particleDesc; }
|
||||||
|
[[nodiscard]] const CDamageInfo& GetDamageInfo() const { return x8_damageInfo; }
|
||||||
|
[[nodiscard]] float GetX24() const { return x24_; }
|
||||||
|
[[nodiscard]] float GetX28() const { return x28_; }
|
||||||
|
[[nodiscard]] float GetX2C() const { return x2c_; }
|
||||||
|
[[nodiscard]] float GetX30() const { return x30_; }
|
||||||
|
[[nodiscard]] CAssetId GetWeaponDescId() const { return x34_weaponDesc; }
|
||||||
|
[[nodiscard]] u16 GetElectrocuteSfx() const { return x38_electrocuteSfx; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CShockWave : public CActor {
|
class CShockWave : public CActor {
|
||||||
|
@ -32,11 +43,11 @@ private:
|
||||||
float x158_ = 0.f;
|
float x158_ = 0.f;
|
||||||
float x15c_;
|
float x15c_;
|
||||||
float x160_;
|
float x160_;
|
||||||
float x164_ = 0.f;
|
float x164_timeSinceHitPlayerInAir = 0.f;
|
||||||
float x168_ = 0.f;
|
float x168_timeSinceHitPlayer = 0.f;
|
||||||
bool x16c_ = false;
|
bool x16c_hitPlayerInAir = false;
|
||||||
bool x16d_ = false;
|
bool x16d_hitPlayer = false;
|
||||||
// x368 => very large reserved_vector of ?
|
rstl::reserved_vector<TUniqueId, 1024> x170_hitIds;
|
||||||
std::optional<TToken<CElectricDescription>> x974_electricDesc;
|
std::optional<TToken<CElectricDescription>> x974_electricDesc;
|
||||||
TUniqueId x980_id2 = kInvalidUniqueId;
|
TUniqueId x980_id2 = kInvalidUniqueId;
|
||||||
|
|
||||||
|
@ -51,5 +62,8 @@ public:
|
||||||
void Render(const CStateManager& mgr) const override;
|
void Render(const CStateManager& mgr) const override;
|
||||||
void Think(float dt, CStateManager& mgr) override;
|
void Think(float dt, CStateManager& mgr) override;
|
||||||
void Touch(CActor& actor, CStateManager& mgr) override;
|
void Touch(CActor& actor, CStateManager& mgr) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
[[nodiscard]] bool IsHit(TUniqueId id) const;
|
||||||
};
|
};
|
||||||
} // namespace urde
|
} // namespace urde::MP1
|
||||||
|
|
Loading…
Reference in New Issue