From dea5168998e2ecc7350367d6db7d42b8e07a17a8 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Thu, 27 Jul 2023 13:29:58 -0700 Subject: [PATCH] NSProjectile: Implement "thrust", "thrust_start" and "thrust_end" spawn keys, as well as "thrust_homing" NSTimer: Destroy when receiver becomes invalidated. --- src/shared/NSProjectile.h | 6 ++++ src/shared/NSProjectile.qc | 58 ++++++++++++++++++++++++++++++++++++++ src/shared/NSTimer.qc | 5 ++++ 3 files changed, 69 insertions(+) diff --git a/src/shared/NSProjectile.h b/src/shared/NSProjectile.h index 40745fad..e093b3bf 100644 --- a/src/shared/NSProjectile.h +++ b/src/shared/NSProjectile.h @@ -100,9 +100,15 @@ private: /* Nuclide additions */ bool m_bStickToWorld; bool m_bStickToActor; + bool m_bThrustHoming; + + NSTimer m_thrustHandler; nonvirtual void _AnimateThink(void); + nonvirtual void _ThrustThink(void); nonvirtual void _AnimateThinkDead(void); + + virtual void OnRemoveEntity(void); #endif public: diff --git a/src/shared/NSProjectile.qc b/src/shared/NSProjectile.qc index 19b9f73f..dff1e081 100644 --- a/src/shared/NSProjectile.qc +++ b/src/shared/NSProjectile.qc @@ -217,6 +217,9 @@ NSProjectile::SpawnKey(string strKey, string strValue) case "maxs": m_vecSpawnMaxs = ReadVector(strValue); break; + case "thrust_homing": + m_bThrustHoming = ReadBool(strValue); + break; default: super::SpawnKey(strKey, strValue); break; @@ -272,6 +275,8 @@ NSProjectile::Save(float handle) SaveBool(handle, "m_bStickToActor", m_bStickToActor); SaveVector(handle, "m_vecSpawnMins", m_vecSpawnMins); SaveVector(handle, "m_vecSpawnMaxs", m_vecSpawnMaxs); + SaveBool(handle, "m_bThrustHoming", m_bThrustHoming); + SaveEntity(handle, "m_thrustHandler", m_thrustHandler); } void @@ -410,6 +415,12 @@ NSProjectile::Restore(string strKey, string strValue) case "m_vecSpawnMaxs": m_vecSpawnMaxs = ReadVector(strValue); break; + case "m_bThrustHoming": + m_bThrustHoming = ReadBool(strValue); + break; + case "m_thrustHandler": + m_thrustHandler = (NSTimer)ReadEntity(strValue); + break; default: super::Restore(strKey, strValue); break; @@ -595,6 +606,49 @@ NSProjectile::_LaunchHitscan(vector startPos, vector launchDir, float dmgMultipl } +void +NSProjectile::_ThrustThink(void) +{ + vector currentVelocity; + float currentSpeed; + float newSpeed; + vector newVelocity; + + currentVelocity = GetVelocity(); + currentSpeed = vlen(currentVelocity); + newSpeed = (currentSpeed + (m_flThrust * frametime)); + + /* homing mode */ + if (m_bThrustHoming) { + NSSurfacePropEntity projectileOwner = (NSSurfacePropEntity)GetOwner(); + vector ownerPos = projectileOwner.GetEyePos(); + makevectors(projectileOwner.v_angle); + traceline(ownerPos, ownerPos + v_forward * 8096, FALSE, projectileOwner); + SetAngles(vectoangles(trace_endpos - GetOrigin())); + } + + makevectors(GetAngles()); + newVelocity = v_forward * (newSpeed); + + /* prevent thrusting early */ + if ((m_flThrustStart > 0) && GetSpawnAge() < m_flThrustStart) { + return; + } + + /* stop thrusting when we reach the end time */ + if ((m_flThrustEnd > 0) && (GetSpawnAge() > m_flThrustEnd)) { + m_thrustHandler.Destroy(); /* invalidate */ + return; + } + + SetVelocity(newVelocity); +} + +void +NSProjectile::OnRemoveEntity(void) +{ +} + void NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float powerMultiplier, float dmgMultiplier) { @@ -656,6 +710,10 @@ NSProjectile::Launch(vector startPos, vector launchDir, float fuseOffset, float ScheduleThink(_FuseEnded, m_flFuse + fuseOffset); } + if (m_flThrust != 0) { + m_thrustHandler = NSTimer::TemporaryTimer(this, _ThrustThink, 0.0, true); + } + StartSoundDef(m_sndFly, CHAN_BODY, true); SendFlags = (-1); //SendEntity = 0; /* HACK: remove this once Spike fixes CSQC-set traileffectnum etc. */ diff --git a/src/shared/NSTimer.qc b/src/shared/NSTimer.qc index c4e59163..4049b1b8 100644 --- a/src/shared/NSTimer.qc +++ b/src/shared/NSTimer.qc @@ -36,6 +36,11 @@ _NSTimerWrapper(entity receiver, void() func) void NSTimer::_TimerThink(void) { + if (!m_eReceiver) { + Destroy(); + return; + } + _NSTimerWrapper(m_eReceiver, _m_NSTimerFunc); if (m_bRepeats == true)