Finalize CBloodFlower imps

This commit is contained in:
Phillip Stephens 2019-03-23 22:45:47 -07:00
parent d3a251589c
commit 799ff4a64b
6 changed files with 121 additions and 29 deletions

View File

@ -2,6 +2,7 @@
#include "Particle/CGenDescription.hpp" #include "Particle/CGenDescription.hpp"
#include "Particle/CElementGen.hpp" #include "Particle/CElementGen.hpp"
#include "Weapon/CProjectileWeapon.hpp" #include "Weapon/CProjectileWeapon.hpp"
#include "Weapon/CTargetableProjectile.hpp"
#include "World/CPlayer.hpp" #include "World/CPlayer.hpp"
#include "World/CScriptTrigger.hpp" #include "World/CScriptTrigger.hpp"
#include "CSimplePool.hpp" #include "CSimplePool.hpp"
@ -18,10 +19,10 @@ CBloodFlower::CBloodFlower(TUniqueId uid, std::string_view name, const CEntityIn
EMovementType::Ground, EColliderType::One, EBodyType::Restricted, actParms, EKnockBackVariant::Medium) EMovementType::Ground, EColliderType::One, EBodyType::Restricted, actParms, EKnockBackVariant::Medium)
, x568_podEffectDesc(g_SimplePool->GetObj({FOURCC('PART'), partId1})) , x568_podEffectDesc(g_SimplePool->GetObj({FOURCC('PART'), partId1}))
, x574_podEffect(new CElementGen(x568_podEffectDesc)) , x574_podEffect(new CElementGen(x568_podEffectDesc))
, x578_(g_SimplePool->GetObj({FOURCC('WPSC'), wpscId1})) , x578_projectileDesc(g_SimplePool->GetObj({FOURCC('WPSC'), wpscId1}))
, x590_projectileInfo(wpscId2, dInfo1) , x590_projectileInfo(wpscId2, dInfo1)
, x5d4_(CSfxManager::TranslateSFXID(soundId)) , x5d4_visorSfx(CSfxManager::TranslateSFXID(soundId))
, x5dc_(dInfo2) , x5dc_projectileDamage(dInfo2)
, x5f8_podDamage(dInfo3) , x5f8_podDamage(dInfo3)
, x614_(f1) , x614_(f1)
, x618_(partId2) , x618_(partId2)
@ -35,7 +36,7 @@ CBloodFlower::CBloodFlower(TUniqueId uid, std::string_view name, const CEntityIn
x590_projectileInfo.Token().Lock(); x590_projectileInfo.Token().Lock();
x460_knockBackController.SetAutoResetImpulse(false); x460_knockBackController.SetAutoResetImpulse(false);
if (partId5.IsValid()) { if (partId5.IsValid()) {
x5c4_ = g_SimplePool->GetObj({FOURCC('PART'), partId5}); x5c4_visorParticle = g_SimplePool->GetObj({FOURCC('PART'), partId5});
} }
} }
@ -60,12 +61,10 @@ void CBloodFlower::sub80119364(CStateManager& mgr) {
void CBloodFlower::UpdateFire(CStateManager& mgr) { void CBloodFlower::UpdateFire(CStateManager& mgr) {
if (x5d8_effectState == 0) { if (x5d8_effectState == 0) {
TurnEffectsOn(0, mgr); TurnEffectsOn(0, mgr);
} } else if (x5d8_effectState == 1) {
else if (x5d8_effectState == 1) {
TurnEffectsOff(0, mgr); TurnEffectsOff(0, mgr);
TurnEffectsOn(1, mgr); TurnEffectsOn(1, mgr);
} } else if (x5d8_effectState == 2) {
else if (x5d8_effectState == 2) {
TurnEffectsOff(1, mgr); TurnEffectsOff(1, mgr);
TurnEffectsOn(2, mgr); TurnEffectsOn(2, mgr);
} }
@ -74,9 +73,9 @@ void CBloodFlower::UpdateFire(CStateManager& mgr) {
} }
static std::string_view sFireEffects[3] = { static std::string_view sFireEffects[3] = {
"Fire1"sv, "Fire1"sv,
"Fire2"sv, "Fire2"sv,
"Fire3"sv, "Fire3"sv,
}; };
void CBloodFlower::TurnEffectsOn(u32 effect, CStateManager& mgr) { void CBloodFlower::TurnEffectsOn(u32 effect, CStateManager& mgr) {
@ -106,16 +105,40 @@ void CBloodFlower::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node
x58c_projectileState = 0; x58c_projectileState = 0;
x5bc_projectileDelay = 0.5f; x5bc_projectileDelay = 0.5f;
} }
return; return;
} } else if (type == EUserEventType::Delete) {
else if (type == EUserEventType::Delete) {
if (x5d8_effectState > 0) if (x5d8_effectState > 0)
TurnEffectsOff((x5d8_effectState > 3 ? x5d8_effectState - 1 : 2), mgr); TurnEffectsOff((x5d8_effectState > 3 ? x5d8_effectState - 1 : 2), mgr);
} }
CPatterned::DoUserAnimEvent(mgr, node, type, dt); CPatterned::DoUserAnimEvent(mgr, node, type, dt);
} }
void CBloodFlower::LaunchPollenProjectile(const zeus::CTransform& xf, CStateManager& mgr, float f1, s32 w1) { void CBloodFlower::LaunchPollenProjectile(const zeus::CTransform& xf, CStateManager& mgr, float var_f1, s32 w1) {
static float tickPeriod = CProjectileWeapon::GetTickPeriod();
CProjectileInfo* proj = GetProjectileInfo();
TLockedToken<CWeaponDescription> projToken = proj->Token();
if (!projToken)
return;
zeus::CVector3f aimPos = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
float zDiff = xf.origin.z() - aimPos.z();
float f2 = (zDiff > 0.f ? var_f1 : -zDiff + var_f1);
if (zDiff > 0.f)
var_f1 = zDiff + var_f1;
float f7 = std::sqrt(2.f * f2 / 4.9050002f) + std::sqrt(2.f * var_f1 / 4.9050002f);
float f4 = 1.f / f7;
zeus::CVector3f vel{f4 * (aimPos.x() - xf.origin.x()), f4 * (aimPos.y() - xf.origin.y()),
2.4525001f * f7 + (-zDiff / f7)};
if (CTargetableProjectile* targProj =
CreateArcProjectile(mgr, GetProjectileInfo()->Token(), zeus::CTransform::Translate(xf.origin),
GetProjectileInfo()->GetDamage(), kInvalidUniqueId)) {
targProj->ProjectileWeapon().SetVelocity(CProjectileWeapon::GetTickPeriod() * vel);
targProj->ProjectileWeapon().SetGravity(CProjectileWeapon::GetTickPeriod() *
zeus::CVector3f(0.f, 0.f, -4.9050002f));
mgr.AddObject(targProj);
}
} }
void CBloodFlower::Render(const CStateManager& mgr) const { void CBloodFlower::Render(const CStateManager& mgr) const {
@ -157,7 +180,7 @@ void CBloodFlower::Active(CStateManager& mgr, EStateMsg msg, float arg) {
x450_bodyController->GetCommandMgr().DeliverCmd(CBCAdditiveAimCmd()); x450_bodyController->GetCommandMgr().DeliverCmd(CBCAdditiveAimCmd());
x584_curAttackTime += arg; x584_curAttackTime += arg;
x450_bodyController->GetCommandMgr().DeliverAdditiveTargetVector( x450_bodyController->GetCommandMgr().DeliverAdditiveTargetVector(
GetTransform().transposeRotate(mgr.GetPlayer().GetTranslation() - GetTranslation())); GetTransform().transposeRotate(mgr.GetPlayer().GetTranslation() - GetTranslation()));
} else if (msg == EStateMsg::Deactivate) { } else if (msg == EStateMsg::Deactivate) {
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState)); x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState));
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::AdditiveIdle)); x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::AdditiveIdle));
@ -175,8 +198,8 @@ void CBloodFlower::InActive(CStateManager& mgr, EStateMsg msg, float) {
void CBloodFlower::BulbAttack(CStateManager& mgr, EStateMsg msg, float) { void CBloodFlower::BulbAttack(CStateManager& mgr, EStateMsg msg, float) {
if (msg == EStateMsg::Activate) { if (msg == EStateMsg::Activate) {
x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity::Zero, x450_bodyController->GetCommandMgr().DeliverCmd(
mgr.GetPlayer().GetTranslation(), true)); CBCProjectileAttackCmd(pas::ESeverity::Zero, mgr.GetPlayer().GetTranslation(), true));
x58c_projectileState = 1; x58c_projectileState = 1;
} }
} }
@ -211,4 +234,23 @@ void CBloodFlower::ActivateTriggers(CStateManager& mgr, bool activate) {
} }
} }
CTargetableProjectile* CBloodFlower::CreateArcProjectile(CStateManager& mgr, const TToken<CWeaponDescription>& desc,
const zeus::CTransform& xf, const CDamageInfo& damage,
TUniqueId uid) {
if (!x578_projectileDesc)
return nullptr;
TUniqueId projId = mgr.AllocateUniqueId();
CTargetableProjectile* targProj = new CTargetableProjectile(
desc, EWeaponType::AI, xf, EMaterialTypes::Character, damage, x5dc_projectileDamage, projId, GetAreaIdAlways(),
GetUniqueId(), x578_projectileDesc, uid, EProjectileAttrib::None, {x5c4_visorParticle}, x5d4_visorSfx, false);
if (mgr.GetPlayer().GetOrbitTargetId() == GetUniqueId()) {
mgr.GetPlayer().ResetAimTargetPrediction(projId);
mgr.GetPlayer().SetOrbitTargetId(projId, mgr);
}
return targProj;
}
} // namespace urde::MP1 } // namespace urde::MP1

View File

@ -7,13 +7,14 @@ namespace urde {
class CGenDescription; class CGenDescription;
class CElementGen; class CElementGen;
class CWeaponDescription; class CWeaponDescription;
} class CTargetableProjectile;
} // namespace urde
namespace urde::MP1 { namespace urde::MP1 {
class CBloodFlower : public CPatterned { class CBloodFlower : public CPatterned {
TLockedToken<CGenDescription> x568_podEffectDesc; TLockedToken<CGenDescription> x568_podEffectDesc;
std::unique_ptr<CElementGen> x574_podEffect; std::unique_ptr<CElementGen> x574_podEffect;
TLockedToken<CWeaponDescription> x578_; TLockedToken<CWeaponDescription> x578_projectileDesc;
float x584_curAttackTime = 0.f; float x584_curAttackTime = 0.f;
float x588_projectileOffset = 0.f; float x588_projectileOffset = 0.f;
u32 x58c_projectileState = 0; u32 x58c_projectileState = 0;
@ -21,10 +22,10 @@ class CBloodFlower : public CPatterned {
float x5b8_ = 0.f; float x5b8_ = 0.f;
float x5bc_projectileDelay = 0.f; float x5bc_projectileDelay = 0.f;
float x5c0_ = 0.f; float x5c0_ = 0.f;
TLockedToken<CGenDescription> x5c4_; TLockedToken<CGenDescription> x5c4_visorParticle;
s16 x5d4_; s16 x5d4_visorSfx;
u32 x5d8_effectState = 0; u32 x5d8_effectState = 0;
CDamageInfo x5dc_; CDamageInfo x5dc_projectileDamage;
CDamageInfo x5f8_podDamage; CDamageInfo x5f8_podDamage;
float x614_; float x614_;
CAssetId x618_; CAssetId x618_;
@ -37,6 +38,9 @@ class CBloodFlower : public CPatterned {
void TurnEffectsOn(u32, CStateManager&); void TurnEffectsOn(u32, CStateManager&);
void TurnEffectsOff(u32, CStateManager&); void TurnEffectsOff(u32, CStateManager&);
void LaunchPollenProjectile(const zeus::CTransform&, CStateManager&, float, s32); void LaunchPollenProjectile(const zeus::CTransform&, CStateManager&, float, s32);
CTargetableProjectile* CreateArcProjectile(CStateManager&, const TToken<CWeaponDescription>&, const zeus::CTransform&,
const CDamageInfo&, TUniqueId);
public: public:
DEFINE_PATTERNED(BloodFlower) DEFINE_PATTERNED(BloodFlower)
@ -50,7 +54,6 @@ public:
void Render(const CStateManager& mgr) const; void Render(const CStateManager& mgr) const;
CProjectileInfo* GetProjectileInfo() { return &x590_projectileInfo; } CProjectileInfo* GetProjectileInfo() { return &x590_projectileInfo; }
bool ShouldAttack(CStateManager&, float); bool ShouldAttack(CStateManager&, float);
bool ShouldTurn(CStateManager&, float); bool ShouldTurn(CStateManager&, float);
bool Leash(CStateManager&, float) { return x5c0_ < x3d0_playerLeashTime; } bool Leash(CStateManager&, float) { return x5c0_ < x3d0_playerLeashTime; }

View File

@ -82,6 +82,8 @@ public:
CProjectileTouchResult CanCollideWithTrigger(CActor& act, CStateManager& mgr); CProjectileTouchResult CanCollideWithTrigger(CActor& act, CStateManager& mgr);
zeus::CAABox GetProjectileBounds() const; zeus::CAABox GetProjectileBounds() const;
rstl::optional<zeus::CAABox> GetTouchBounds() const; rstl::optional<zeus::CAABox> GetTouchBounds() const;
CProjectileWeapon& ProjectileWeapon() { return x170_projectile; }
const CProjectileWeapon& GetProjectileWeapon() const { return x170_projectile; }
TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; } TUniqueId GetHomingTargetId() const { return x2c0_homingTargetId; }
zeus::CVector3f GetPreviousPos() const { return x298_previousPos; } zeus::CVector3f GetPreviousPos() const { return x298_previousPos; }
}; };

View File

@ -93,9 +93,10 @@ public:
void UpdateParticleFX(); void UpdateParticleFX();
virtual void Update(float dt); virtual void Update(float dt);
void SetGravity(const zeus::CVector3f& grav) { xbc_gravity = grav; } void SetGravity(const zeus::CVector3f& grav) { xbc_gravity = grav; }
zeus::CVector3f GetGravity() const { return xbc_gravity; }
static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; } static void SetGlobalSeed(u16 seed) { g_GlobalSeed = seed; }
CElementGen* GetAttachedPS1() const { return xfc_APSMGen.get(); } CElementGen* GetAttachedPS1() const { return xfc_APSMGen.get(); }
double GameTime() const { return xd0_curTime; } double GameTime() const { return xd0_curTime; }
static float GetTickPeriod() { return 0.0166667f; } static constexpr float GetTickPeriod() { return 0.0166667f; }
}; };
} // namespace urde } // namespace urde

View File

@ -1,19 +1,56 @@
#include "CTargetableProjectile.hpp" #include "CTargetableProjectile.hpp"
#include "CStateManager.hpp"
#include "World/CPlayer.hpp"
#include "TCastTo.hpp"
namespace urde { namespace urde {
CTargetableProjectile::CTargetableProjectile( CTargetableProjectile::CTargetableProjectile(
const TToken<CWeaponDescription>& desc, EWeaponType type, const zeus::CTransform& xf, EMaterialTypes materials, const TToken<CWeaponDescription>& desc, EWeaponType type, const zeus::CTransform& xf, EMaterialTypes materials,
const CDamageInfo& damage, const CDamageInfo& damage2, TUniqueId uid, TAreaId aid, TUniqueId owner, const CDamageInfo& damage, const CDamageInfo& damage2, TUniqueId uid, TAreaId aid, TUniqueId owner,
TUniqueId homingTarget, EProjectileAttrib attribs, const TLockedToken<CWeaponDescription>& weapDesc, TUniqueId homingTarget, EProjectileAttrib attribs,
const rstl::optional<TLockedToken<CGenDescription>>& visorParticle, u16 visorSfx, bool sendCollideMsg) const rstl::optional<TLockedToken<CGenDescription>>& visorParticle, u16 visorSfx, bool sendCollideMsg)
: CEnergyProjectile(true, desc, type, xf, materials, damage, uid, aid, owner, homingTarget, : CEnergyProjectile(true, desc, type, xf, materials, damage, uid, aid, owner, homingTarget,
attribs | EProjectileAttrib::BigProjectile | EProjectileAttrib::PartialCharge | attribs | EProjectileAttrib::BigProjectile | EProjectileAttrib::PartialCharge |
EProjectileAttrib::PlasmaProjectile, EProjectileAttrib::PlasmaProjectile,
false, zeus::skOne3f, visorParticle, visorSfx, sendCollideMsg) false, zeus::skOne3f, visorParticle, visorSfx, sendCollideMsg)
, x3e0_dInfo2(damage2) { , x3d8_weaponDesc(weapDesc)
, x3e0_damage(damage2) {
x68_material.Add(EMaterialTypes::Target); x68_material.Add(EMaterialTypes::Target);
x68_material.Add(EMaterialTypes::Orbit); x68_material.Add(EMaterialTypes::Orbit);
} }
void CTargetableProjectile::Accept(IVisitor& visitor) { visitor.Visit(this); }
zeus::CVector3f CTargetableProjectile::GetAimPosition(const CStateManager& mgr, float dt) const {
static constexpr float tickRecip = 1.f / CProjectileWeapon::GetTickPeriod();
return (dt * dt * 0.5f * tickRecip * x170_projectile.GetGravity()) +
(dt * tickRecip * x170_projectile.GetVelocity() + GetTranslation());
}
bool CTargetableProjectile::Explode(const zeus::CVector3f& pos, const zeus::CVector3f& normal,
EWeaponCollisionResponseTypes type, CStateManager& mgr,
const CDamageVulnerability& dVuln, TUniqueId hitActor) {
bool ret = CEnergyProjectile::Explode(pos, normal, type, mgr, dVuln, hitActor);
if (x2e4_24_active || x2c4_ == kInvalidUniqueId || x2c4_ != mgr.GetPlayer().GetUniqueId())
return ret;
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(xec_ownerId)) {
TUniqueId uid = mgr.AllocateUniqueId();
zeus::CTransform xf =
zeus::lookAt(x170_projectile.GetTranslation(), act->GetAimPosition(mgr, 0.f), zeus::skUp);
CEnergyProjectile* projectile = new CEnergyProjectile(
true, x3d8_weaponDesc, xf0_weaponType, xf, EMaterialTypes::Player, x3e0_damage, uid, GetAreaIdAlways(),
kInvalidUniqueId, xec_ownerId, EProjectileAttrib::None, false, zeus::skOne3f, {}, 0xFFFF, false);
mgr.AddObject(projectile);
projectile->AddMaterial(EMaterialTypes::Orbit);
mgr.GetPlayer().ResetAimTargetPrediction(uid);
mgr.GetPlayer().SetOrbitTargetId(uid, mgr);
x2c4_ = kInvalidUniqueId;
}
return ret;
}
} // namespace urde } // namespace urde

View File

@ -5,14 +5,21 @@
namespace urde { namespace urde {
class CTargetableProjectile : public CEnergyProjectile { class CTargetableProjectile : public CEnergyProjectile {
CDamageInfo x3e0_dInfo2; TLockedToken<CWeaponDescription> x3d8_weaponDesc;
CDamageInfo x3e0_damage;
public: public:
CTargetableProjectile(const TToken<CWeaponDescription>& desc, EWeaponType type, const zeus::CTransform& xf, CTargetableProjectile(const TToken<CWeaponDescription>& desc, EWeaponType type, const zeus::CTransform& xf,
EMaterialTypes materials, const CDamageInfo& damage, const CDamageInfo& damage2, TUniqueId uid, EMaterialTypes materials, const CDamageInfo& damage, const CDamageInfo& damage2, TUniqueId uid,
TAreaId aid, TUniqueId owner, TUniqueId homingTarget, EProjectileAttrib attribs, TAreaId aid, TUniqueId owner, const TLockedToken<CWeaponDescription>& weapDesc,
TUniqueId homingTarget, EProjectileAttrib attribs,
const rstl::optional<TLockedToken<CGenDescription>>& visorParticle, u16 visorSfx, const rstl::optional<TLockedToken<CGenDescription>>& visorParticle, u16 visorSfx,
bool sendCollideMsg); bool sendCollideMsg);
void Accept(IVisitor&);
zeus::CVector3f GetAimPosition(const CStateManager&, float) const;
bool Explode(const zeus::CVector3f& pos, const zeus::CVector3f& normal, EWeaponCollisionResponseTypes type,
CStateManager& mgr, const CDamageVulnerability& dVuln, TUniqueId hitActor);
}; };
} // namespace urde } // namespace urde