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 SFXsfx06DC 1756
|
||||
#define SFXwpn_bomb_drop 1756
|
||||
#define SFXsfx06DD 1757
|
||||
#define SFXsfx06DE 1758
|
||||
#define SFXwpn_bomb_explo 1758
|
||||
#define SFXwpn_chargeup_ice 1759
|
||||
#define SFXsfx06E0 1760
|
||||
#define SFXsfx06E1 1761
|
||||
|
|
|
@ -294,7 +294,7 @@ struct PatternedInfo : BigDNA
|
|||
Value<atUint32> unknown11;
|
||||
Value<atVec3f> unknown12;
|
||||
UniqueID32 particle1;
|
||||
Value<atUint32> unknown13;
|
||||
UniqueID32 electric;
|
||||
Value<atVec3f> unknown14;
|
||||
UniqueID32 particle2;
|
||||
Value<atUint32> soundID2;
|
||||
|
@ -312,6 +312,11 @@ struct PatternedInfo : BigDNA
|
|||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
|
||||
ent->name = name + "_part1";
|
||||
}
|
||||
if (electric)
|
||||
{
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric);
|
||||
ent->name = name + "_elsc";
|
||||
}
|
||||
if (particle2)
|
||||
{
|
||||
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
|
||||
|
@ -324,6 +329,7 @@ struct PatternedInfo : BigDNA
|
|||
animationParameters.depANCS(pathsOut);
|
||||
g_curSpec->flattenDependencies(stateMachine, pathsOut);
|
||||
g_curSpec->flattenDependencies(particle1, pathsOut);
|
||||
g_curSpec->flattenDependencies(electric, 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)
|
||||
{
|
||||
zeus::CVector3f closePoint = aabb.closestPointAlongVector(xb0_viewPlane.normal());
|
||||
|
|
|
@ -221,6 +221,7 @@ public:
|
|||
void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly);
|
||||
void PostRenderFogs();
|
||||
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 AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting);
|
||||
void SetDrawableCallback(TDrawableCallback, const void*);
|
||||
|
|
|
@ -57,6 +57,7 @@ public:
|
|||
virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly)=0;
|
||||
virtual void PostRenderFogs()=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 AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0;
|
||||
virtual void SetDrawableCallback(TDrawableCallback, const void*)=0;
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
#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
|
||||
{
|
||||
|
||||
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,
|
||||
const zeus::CTransform& xf, const CDamageInfo& dInfo)
|
||||
: 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}, dInfo, EProjectileAttrib::Bombs,
|
||||
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
|
||||
{
|
||||
|
||||
class CElementGen;
|
||||
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:
|
||||
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,
|
||||
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;
|
||||
if (!x835_31_actorAttached)
|
||||
{
|
||||
x835_28_bombReady = false;
|
||||
x835_28_bombReady = true;
|
||||
if (x53a_powerBomb != kInvalidUniqueId &&
|
||||
!mgr.CanCreateProjectile(x538_playerId, EWeaponType::PowerBomb, 1))
|
||||
{
|
||||
|
@ -2596,11 +2596,12 @@ void CPlayerGun::DropBomb(EBWeapon weapon, CStateManager& mgr)
|
|||
if (x308_bombCount <= 0)
|
||||
return;
|
||||
|
||||
zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation();
|
||||
zeus::CTransform xf = zeus::CTransform::Translate({plPos.x,
|
||||
plPos.y, plPos.z + g_tweakPlayer->GetPlayerBallHalfExtent()});
|
||||
CBomb* bomb =
|
||||
new CBomb(x784_bombEffects[u32(weapon)][0], x784_bombEffects[u32(weapon)][1], mgr.AllocateUniqueId(),
|
||||
mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime,
|
||||
zeus::CTransform::Translate(zeus::CVector3f{0.f, g_tweakPlayer->GetPlayerBallHalfExtent(), 0.f}),
|
||||
g_tweakPlayerGun->GetBombInfo());
|
||||
mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime, xf,g_tweakPlayerGun->GetBombInfo());
|
||||
mgr.AddObject(bomb);
|
||||
|
||||
if (x308_bombCount == 3)
|
||||
|
|
Loading…
Reference in New Issue