mirror of https://github.com/AxioDL/metaforce.git
Implement CBomb
This commit is contained in:
parent
0a0a581f2d
commit
489470feda
|
@ -9,9 +9,9 @@
|
||||||
#define GRPgroup002B 43
|
#define GRPgroup002B 43
|
||||||
|
|
||||||
|
|
||||||
#define SFXsfx06DC 1756
|
#define SFXwpn_bomb_drop 1756
|
||||||
#define SFXsfx06DD 1757
|
#define SFXsfx06DD 1757
|
||||||
#define SFXsfx06DE 1758
|
#define SFXwpn_bomb_explo 1758
|
||||||
#define SFXwpn_chargeup_ice 1759
|
#define SFXwpn_chargeup_ice 1759
|
||||||
#define SFXsfx06E0 1760
|
#define SFXsfx06E0 1760
|
||||||
#define SFXsfx06E1 1761
|
#define SFXsfx06E1 1761
|
||||||
|
|
|
@ -294,7 +294,7 @@ struct PatternedInfo : BigDNA
|
||||||
Value<atUint32> unknown11;
|
Value<atUint32> unknown11;
|
||||||
Value<atVec3f> unknown12;
|
Value<atVec3f> unknown12;
|
||||||
UniqueID32 particle1;
|
UniqueID32 particle1;
|
||||||
Value<atUint32> unknown13;
|
UniqueID32 electric;
|
||||||
Value<atVec3f> unknown14;
|
Value<atVec3f> unknown14;
|
||||||
UniqueID32 particle2;
|
UniqueID32 particle2;
|
||||||
Value<atUint32> soundID2;
|
Value<atUint32> soundID2;
|
||||||
|
@ -312,6 +312,11 @@ struct PatternedInfo : BigDNA
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
|
||||||
ent->name = name + "_part1";
|
ent->name = name + "_part1";
|
||||||
}
|
}
|
||||||
|
if (electric)
|
||||||
|
{
|
||||||
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric);
|
||||||
|
ent->name = name + "_elsc";
|
||||||
|
}
|
||||||
if (particle2)
|
if (particle2)
|
||||||
{
|
{
|
||||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
|
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
|
||||||
|
@ -324,6 +329,7 @@ struct PatternedInfo : BigDNA
|
||||||
animationParameters.depANCS(pathsOut);
|
animationParameters.depANCS(pathsOut);
|
||||||
g_curSpec->flattenDependencies(stateMachine, pathsOut);
|
g_curSpec->flattenDependencies(stateMachine, pathsOut);
|
||||||
g_curSpec->flattenDependencies(particle1, pathsOut);
|
g_curSpec->flattenDependencies(particle1, pathsOut);
|
||||||
|
g_curSpec->flattenDependencies(electric, pathsOut);
|
||||||
g_curSpec->flattenDependencies(particle2, pathsOut);
|
g_curSpec->flattenDependencies(particle2, pathsOut);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1046,6 +1046,11 @@ void CBooRenderer::AddParticleGen(const CParticleGen& gen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBooRenderer::AddParticleGen(const CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds)
|
||||||
|
{
|
||||||
|
Buckets::Insert(pos, bounds, EDrawableType::Particle, &gen, xb0_viewPlane, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type)
|
void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type)
|
||||||
{
|
{
|
||||||
zeus::CVector3f closePoint = aabb.closestPointAlongVector(xb0_viewPlane.normal());
|
zeus::CVector3f closePoint = aabb.closestPointAlongVector(xb0_viewPlane.normal());
|
||||||
|
|
|
@ -221,6 +221,7 @@ public:
|
||||||
void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly);
|
void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly);
|
||||||
void PostRenderFogs();
|
void PostRenderFogs();
|
||||||
void AddParticleGen(const CParticleGen&);
|
void AddParticleGen(const CParticleGen&);
|
||||||
|
void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&);
|
||||||
void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int);
|
void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int);
|
||||||
void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting);
|
void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting);
|
||||||
void SetDrawableCallback(TDrawableCallback, const void*);
|
void SetDrawableCallback(TDrawableCallback, const void*);
|
||||||
|
|
|
@ -57,6 +57,7 @@ public:
|
||||||
virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly)=0;
|
virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly)=0;
|
||||||
virtual void PostRenderFogs()=0;
|
virtual void PostRenderFogs()=0;
|
||||||
virtual void AddParticleGen(const CParticleGen&)=0;
|
virtual void AddParticleGen(const CParticleGen&)=0;
|
||||||
|
virtual void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&)=0;
|
||||||
virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0;
|
virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0;
|
||||||
virtual void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0;
|
virtual void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0;
|
||||||
virtual void SetDrawableCallback(TDrawableCallback, const void*)=0;
|
virtual void SetDrawableCallback(TDrawableCallback, const void*)=0;
|
||||||
|
|
|
@ -1,9 +1,17 @@
|
||||||
#include "CBomb.hpp"
|
#include "CBomb.hpp"
|
||||||
|
#include "Particle/CElementGen.hpp"
|
||||||
|
#include "World/CPlayer.hpp"
|
||||||
|
#include "World/CMorphBall.hpp"
|
||||||
|
#include "GameGlobalObjects.hpp"
|
||||||
|
#include "Graphics/CBooRenderer.hpp"
|
||||||
|
#include "World/CGameLight.hpp"
|
||||||
|
#include "TCastTo.hpp"
|
||||||
|
#include "DataSpec/DNAMP1/SFX/Weapons.h"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CBomb::CBomb(const TToken<CGenDescription>& particle1, const TToken<CGenDescription>& particle2,
|
CBomb::CBomb(const TCachedToken<CGenDescription>& particle1, const TCachedToken<CGenDescription>& particle2,
|
||||||
TUniqueId uid, TAreaId aid, TUniqueId playerId, float f1,
|
TUniqueId uid, TAreaId aid, TUniqueId playerId, float f1,
|
||||||
const zeus::CTransform& xf, const CDamageInfo& dInfo)
|
const zeus::CTransform& xf, const CDamageInfo& dInfo)
|
||||||
: CWeapon(uid, aid, true, playerId, EWeaponType::Bomb, "Bomb", xf,
|
: CWeapon(uid, aid, true, playerId, EWeaponType::Bomb, "Bomb", xf,
|
||||||
|
@ -12,8 +20,166 @@ CBomb::CBomb(const TToken<CGenDescription>& particle1, const TToken<CGenDescript
|
||||||
{EMaterialTypes::Projectile, EMaterialTypes::Bomb}),
|
{EMaterialTypes::Projectile, EMaterialTypes::Bomb}),
|
||||||
{EMaterialTypes::Projectile, EMaterialTypes::Bomb}, dInfo, EProjectileAttrib::Bombs,
|
{EMaterialTypes::Projectile, EMaterialTypes::Bomb}, dInfo, EProjectileAttrib::Bombs,
|
||||||
CModelData::CModelDataNull())
|
CModelData::CModelDataNull())
|
||||||
|
, x17c_fuseTime(f1)
|
||||||
|
, x180_particle1(new CElementGen(particle1, CElementGen::EModelOrientationType::Normal,
|
||||||
|
CElementGen::EOptionalSystemFlags::One))
|
||||||
|
, x184_particle2(new CElementGen(particle2, CElementGen::EModelOrientationType::Normal,
|
||||||
|
CElementGen::EOptionalSystemFlags::One))
|
||||||
|
, x18c_(particle2.GetObj())
|
||||||
|
, x190_24_isNotDetonated(true)
|
||||||
|
, x190_25_(false)
|
||||||
|
, x190_26_disableFuse(false)
|
||||||
|
{
|
||||||
|
x180_particle1->SetGlobalTranslation(xf.origin);
|
||||||
|
x184_particle2->SetGlobalTranslation(xf.origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBomb::Accept(urde::IVisitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.Visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBomb::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
if (msg == EScriptObjectMessage::Registered)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
x188_lightId = mgr.AllocateUniqueId();
|
||||||
|
CGameLight* gameLight = new CGameLight(x188_lightId, GetAreaIdAlways(), false,
|
||||||
|
std::string("Bomb_PLight") + GetName().data(), GetTransform(), GetUniqueId(),
|
||||||
|
x184_particle2->GetLight(), reinterpret_cast<size_t>(x18c_), 1, 0.f);
|
||||||
|
mgr.AddObject(gameLight);
|
||||||
|
mgr.AddWeaponId(xec_ownerId, xf0_weaponType);
|
||||||
|
CSfxManager::AddEmitter(SFXwpn_bomb_drop, GetTranslation(), {}, true, false, 0x7f, -1);
|
||||||
|
mgr.InformListeners(GetTranslation(), EListenNoiseType::Bomb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (msg == EScriptObjectMessage::Deleted)
|
||||||
|
{
|
||||||
|
if (x188_lightId != kInvalidUniqueId)
|
||||||
|
mgr.FreeScriptObject(x188_lightId);
|
||||||
|
|
||||||
|
if (x190_24_isNotDetonated)
|
||||||
|
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CActor::AcceptScriptMsg(msg, uid, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static CMaterialFilter kSolidFilter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid},
|
||||||
|
{EMaterialTypes::Character, EMaterialTypes::Player,
|
||||||
|
EMaterialTypes::ProjectilePassthrough});
|
||||||
|
void CBomb::Think(float dt, urde::CStateManager& mgr)
|
||||||
|
{
|
||||||
|
CWeapon::Think(dt, mgr);
|
||||||
|
|
||||||
|
if (x190_24_isNotDetonated)
|
||||||
|
{
|
||||||
|
if (x17c_fuseTime <= 0.f)
|
||||||
|
{
|
||||||
|
Explode(GetTranslation(), mgr);
|
||||||
|
if (TCastToPtr<CGameLight> light = mgr.ObjectById(x188_lightId))
|
||||||
|
light->SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x17c_fuseTime > 0.5f)
|
||||||
|
x180_particle1->Update(dt);
|
||||||
|
else
|
||||||
|
UpdateLight(dt, mgr);
|
||||||
|
|
||||||
|
if (!x190_26_disableFuse)
|
||||||
|
x17c_fuseTime -= dt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateLight(dt, mgr);
|
||||||
|
if (x184_particle2->IsSystemDeletable())
|
||||||
|
mgr.FreeScriptObject(GetUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x190_24_isNotDetonated)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (x164_.magSquared() > 0.f)
|
||||||
|
x158_ += dt * x164_;
|
||||||
|
|
||||||
|
if (x158_.magSquared() > 0.f)
|
||||||
|
{
|
||||||
|
x170_prevLocation = GetTranslation();
|
||||||
|
CActor::SetTranslation((dt * x158_) + GetTranslation());
|
||||||
|
|
||||||
|
zeus::CVector3f diffVec = (GetTranslation() - x170_prevLocation);
|
||||||
|
float diffMag = diffVec.magnitude();
|
||||||
|
if (diffMag == 0.f)
|
||||||
|
Explode(GetTranslation(), mgr);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CRayCastResult res = mgr.RayStaticIntersection(x170_prevLocation, (1.f / diffMag) * diffVec, diffMag,
|
||||||
|
kSolidFilter);
|
||||||
|
if (res.IsValid())
|
||||||
|
Explode(GetTranslation(), mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x180_particle1->SetGlobalTranslation(GetTranslation());
|
||||||
|
x184_particle2->SetGlobalTranslation(GetTranslation());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBomb::AddToRenderer(const zeus::CFrustum& frustum, const urde::CStateManager& mgr) const
|
||||||
|
{
|
||||||
|
zeus::CVector3f origin = GetTranslation();
|
||||||
|
float ballRadius = mgr.GetPlayer().GetMorphBall()->GetBallRadius();
|
||||||
|
|
||||||
|
zeus::CAABox aabox(origin - (0.9f * ballRadius), origin + (0.9f * ballRadius));
|
||||||
|
zeus::CVector3f closestPoint = aabox.closestPointAlongVector(CGraphics::g_ViewMatrix.frontVector());
|
||||||
|
|
||||||
|
if (x190_24_isNotDetonated&& x17c_fuseTime > 0.5f)
|
||||||
|
g_Renderer->AddParticleGen(*x180_particle1, closestPoint, aabox);
|
||||||
|
else
|
||||||
|
g_Renderer->AddParticleGen(*x184_particle2, closestPoint, aabox);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBomb::Touch(CActor&, urde::CStateManager&)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
x190_24_isNotDetonated; /* wat? */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::experimental::optional<zeus::CAABox> CBomb::GetTouchBounds() const
|
||||||
|
{
|
||||||
|
float radius = (x190_24_isNotDetonated ? 0.2f : x12c_curDamageInfo.GetRadius());
|
||||||
|
float minX = (x170_prevLocation.x >= GetTranslation().x ? x170_prevLocation.x : GetTranslation().x) - radius;
|
||||||
|
float minY = (x170_prevLocation.y >= GetTranslation().y ? x170_prevLocation.y : GetTranslation().y) - radius;
|
||||||
|
float minZ = (x170_prevLocation.z >= GetTranslation().z ? x170_prevLocation.z : GetTranslation().z) - radius;
|
||||||
|
float maxX = (x170_prevLocation.x >= GetTranslation().x ? x170_prevLocation.x : GetTranslation().x) + radius;
|
||||||
|
float maxY = (x170_prevLocation.y >= GetTranslation().y ? x170_prevLocation.y : GetTranslation().y) + radius;
|
||||||
|
float maxZ = (x170_prevLocation.z >= GetTranslation().z ? x170_prevLocation.z : GetTranslation().z) + radius;
|
||||||
|
|
||||||
|
return {{minX, minY, minZ, maxX, maxY, maxZ}};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBomb::Explode(const zeus::CVector3f& pos, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
mgr.ApplyDamageToWorld(xec_ownerId, *this, pos, x12c_curDamageInfo, xf8_filter);
|
||||||
|
CSfxManager::AddEmitter(SFXwpn_bomb_explo, GetTranslation(), {}, true, false, 0x7f, -1);
|
||||||
|
mgr.InformListeners(pos, EListenNoiseType::Bomb);
|
||||||
|
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
|
||||||
|
x190_24_isNotDetonated = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
void CBomb::UpdateLight(float dt, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
x184_particle2->Update(dt);
|
||||||
|
if (x188_lightId == kInvalidUniqueId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (TCastToPtr<CGameLight> light = mgr.ObjectById(x188_lightId))
|
||||||
|
if (light->GetActive())
|
||||||
|
light->SetLight(x184_particle2->GetLight());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,35 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class CElementGen;
|
||||||
class CBomb : public CWeapon
|
class CBomb : public CWeapon
|
||||||
{
|
{
|
||||||
|
|
||||||
|
zeus::CVector3f x158_;
|
||||||
|
zeus::CVector3f x164_;
|
||||||
|
zeus::CVector3f x170_prevLocation;
|
||||||
|
float x17c_fuseTime;
|
||||||
|
std::unique_ptr<CElementGen> x180_particle1;
|
||||||
|
std::unique_ptr<CElementGen> x184_particle2;
|
||||||
|
TUniqueId x188_lightId = kInvalidUniqueId;
|
||||||
|
const CGenDescription* x18c_;
|
||||||
|
bool x190_24_isNotDetonated : 1;
|
||||||
|
bool x190_25_ : 1;
|
||||||
|
bool x190_26_disableFuse : 1;
|
||||||
public:
|
public:
|
||||||
CBomb(const TToken<CGenDescription>& particle1, const TToken<CGenDescription>& particle2,
|
CBomb(const TCachedToken<CGenDescription>& particle1, const TCachedToken<CGenDescription>& particle2,
|
||||||
TUniqueId uid, TAreaId aid, TUniqueId playerId, float f1,
|
TUniqueId uid, TAreaId aid, TUniqueId playerId, float f1,
|
||||||
const zeus::CTransform& xf, const CDamageInfo& dInfo);
|
const zeus::CTransform& xf, const CDamageInfo& dInfo);
|
||||||
|
|
||||||
|
void Accept(IVisitor&);
|
||||||
|
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||||
|
void Think(float, CStateManager&);
|
||||||
|
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
|
||||||
|
void Render(const CStateManager&) const {}
|
||||||
|
void Touch(CActor&, CStateManager&);
|
||||||
|
void Explode(const zeus::CVector3f&, CStateManager&);
|
||||||
|
void UpdateLight(float, CStateManager&);
|
||||||
|
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1720,7 +1720,7 @@ void CPlayerGun::UpdateWeaponFire(float dt, const CPlayerState& playerState, CSt
|
||||||
x835_29_powerBombReady = false;
|
x835_29_powerBombReady = false;
|
||||||
if (!x835_31_actorAttached)
|
if (!x835_31_actorAttached)
|
||||||
{
|
{
|
||||||
x835_28_bombReady = false;
|
x835_28_bombReady = true;
|
||||||
if (x53a_powerBomb != kInvalidUniqueId &&
|
if (x53a_powerBomb != kInvalidUniqueId &&
|
||||||
!mgr.CanCreateProjectile(x538_playerId, EWeaponType::PowerBomb, 1))
|
!mgr.CanCreateProjectile(x538_playerId, EWeaponType::PowerBomb, 1))
|
||||||
{
|
{
|
||||||
|
@ -2596,11 +2596,12 @@ void CPlayerGun::DropBomb(EBWeapon weapon, CStateManager& mgr)
|
||||||
if (x308_bombCount <= 0)
|
if (x308_bombCount <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation();
|
||||||
|
zeus::CTransform xf = zeus::CTransform::Translate({plPos.x,
|
||||||
|
plPos.y, plPos.z + g_tweakPlayer->GetPlayerBallHalfExtent()});
|
||||||
CBomb* bomb =
|
CBomb* bomb =
|
||||||
new CBomb(x784_bombEffects[u32(weapon)][0], x784_bombEffects[u32(weapon)][1], mgr.AllocateUniqueId(),
|
new CBomb(x784_bombEffects[u32(weapon)][0], x784_bombEffects[u32(weapon)][1], mgr.AllocateUniqueId(),
|
||||||
mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime,
|
mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime, xf,g_tweakPlayerGun->GetBombInfo());
|
||||||
zeus::CTransform::Translate(zeus::CVector3f{0.f, g_tweakPlayer->GetPlayerBallHalfExtent(), 0.f}),
|
|
||||||
g_tweakPlayerGun->GetBombInfo());
|
|
||||||
mgr.AddObject(bomb);
|
mgr.AddObject(bomb);
|
||||||
|
|
||||||
if (x308_bombCount == 3)
|
if (x308_bombCount == 3)
|
||||||
|
|
Loading…
Reference in New Issue