From 489470feda7d68db0b26271a2a236e112013a0d4 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 8 Sep 2018 18:13:56 -0700 Subject: [PATCH] Implement CBomb --- DataSpec/DNAMP1/SFX/Weapons.h | 4 +- DataSpec/DNAMP1/ScriptObjects/Parameters.hpp | 8 +- Runtime/Graphics/CBooRenderer.cpp | 5 + Runtime/Graphics/CBooRenderer.hpp | 1 + Runtime/Graphics/IRenderer.hpp | 1 + Runtime/Weapon/CBomb.cpp | 168 ++++++++++++++++++- Runtime/Weapon/CBomb.hpp | 25 ++- Runtime/Weapon/CPlayerGun.cpp | 9 +- 8 files changed, 212 insertions(+), 9 deletions(-) diff --git a/DataSpec/DNAMP1/SFX/Weapons.h b/DataSpec/DNAMP1/SFX/Weapons.h index 203692015..be498bd91 100644 --- a/DataSpec/DNAMP1/SFX/Weapons.h +++ b/DataSpec/DNAMP1/SFX/Weapons.h @@ -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 diff --git a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp index 82de773d3..4833818b7 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp @@ -294,7 +294,7 @@ struct PatternedInfo : BigDNA Value unknown11; Value unknown12; UniqueID32 particle1; - Value unknown13; + UniqueID32 electric; Value unknown14; UniqueID32 particle2; Value 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); } }; diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 6c6aee444..b4ce8a0ae 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -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()); diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index ef4c5fef5..616b9dd31 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -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*); diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index 89eeded3e..3b6b1c7a4 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -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; diff --git a/Runtime/Weapon/CBomb.cpp b/Runtime/Weapon/CBomb.cpp index 274d5c01b..ef1c25b2a 100644 --- a/Runtime/Weapon/CBomb.cpp +++ b/Runtime/Weapon/CBomb.cpp @@ -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& particle1, const TToken& particle2, +CBomb::CBomb(const TCachedToken& particle1, const TCachedToken& 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& particle1, const TTokenSetGlobalTranslation(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(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 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 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 light = mgr.ObjectById(x188_lightId)) + if (light->GetActive()) + light->SetLight(x184_particle2->GetLight()); } } diff --git a/Runtime/Weapon/CBomb.hpp b/Runtime/Weapon/CBomb.hpp index 8e84cce45..77623e2eb 100644 --- a/Runtime/Weapon/CBomb.hpp +++ b/Runtime/Weapon/CBomb.hpp @@ -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 x180_particle1; + std::unique_ptr 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& particle1, const TToken& particle2, + CBomb(const TCachedToken& particle1, const TCachedToken& 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 GetTouchBounds() const; }; } diff --git a/Runtime/Weapon/CPlayerGun.cpp b/Runtime/Weapon/CPlayerGun.cpp index a297fb12b..ef5505081 100644 --- a/Runtime/Weapon/CPlayerGun.cpp +++ b/Runtime/Weapon/CPlayerGun.cpp @@ -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)