Implement CBomb

This commit is contained in:
Phillip Stephens 2018-09-08 18:13:56 -07:00
parent 0a0a581f2d
commit 489470feda
8 changed files with 212 additions and 9 deletions

View File

@ -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

View File

@ -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);
}
};

View File

@ -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());

View File

@ -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*);

View File

@ -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;

View File

@ -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());
}
}

View File

@ -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;
};
}

View File

@ -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)