Skip to content

Commit 9a748c9

Browse files
committed
DumbProjectileBehavior and NeutronMissileUpdate logic decouple working
1 parent b7fcf9f commit 9a748c9

10 files changed

Lines changed: 82 additions & 0 deletions

File tree

GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class GameEngine : public SubsystemInterface
101101

102102
Bool m_quitting; ///< true when we need to quit the game
103103
Bool m_isActive; ///< app has OS focus.
104+
105+
public:
106+
Real getLogicTimeAccumulator() const { return m_logicTimeAccumulator; }
104107
};
105108

106109
inline void GameEngine::setQuitting( Bool quitting ) { m_quitting = quitting; }

GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class DrawModule;
4848
class ClientUpdateModule;
4949
class View;
5050
class Locomotor;
51+
class ProjectileUpdateInterface;
5152
class Anim2D;
5253
class Shadow;
5354
class ModuleInfo;
@@ -652,6 +653,7 @@ class Drawable : public Thing,
652653
private:
653654

654655
const Locomotor* getLocomotor() const;
656+
void applySubFrameExtrapolation(ProjectileUpdateInterface* pui);
655657

656658
// note, these are lazily allocated!
657659
TintEnvelope* m_selectionFlashEnvelope; ///< used for selection flash, works WITH m_colorTintEnvelope
@@ -711,6 +713,7 @@ class Drawable : public Thing,
711713

712714
Matrix3D m_instance; ///< The instance matrix that holds the initial/default position & orientation
713715
Real m_instanceScale; ///< the uniform scale factor applied to the instance matrix before it is sent to W3D.
716+
Matrix3D m_visualExtrapolationMtx; ///< Decoupled visual glide matrix
714717

715718
DrawableInfo m_drawableInfo; ///< structure pointed to by W3D render objects so they know which drawable they belong to.
716719

@@ -730,6 +733,7 @@ class Drawable : public Thing,
730733
Bool m_hiddenByStealth; ///< drawable is hidden due to stealth
731734
Bool m_instanceIsIdentity; ///< If true, instance matrix can be skipped
732735
Bool m_drawableFullyObscuredByShroud; ///<drawable is hidden by shroud/fog
736+
Bool m_useExtrapolation; ///< True if currently gliding
733737
Bool m_ambientSoundEnabled;
734738
Bool m_ambientSoundEnabledFromScript;
735739

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/DumbProjectileBehavior.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class DumbProjectileBehavior : public UpdateModule, public ProjectileUpdateInter
9494
virtual ObjectID projectileGetLauncherID() const override { return m_launcherID; }
9595
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) override {}
9696
virtual void projectileNowJammed() override {}
97+
virtual const Coord3D* getProjectileLogicVelocity() const override { return &m_logicStepVelocity; }
9798

9899
protected:
99100

@@ -109,6 +110,7 @@ class DumbProjectileBehavior : public UpdateModule, public ProjectileUpdateInter
109110
VecCoord3D m_flightPath; ///< The frame by frame flight path in a Bezier curve
110111
Coord3D m_flightPathStart; ///< where flight path started (in case we must regen it)
111112
Coord3D m_flightPathEnd; ///< where flight path ends (in case we must regen it)
113+
Coord3D m_logicStepVelocity; ///< Logic frame velocity vector
112114
Real m_flightPathSpeed; ///< flight path speed (in case we must regen it)
113115
Int m_flightPathSegments; ///< number of segments in the flightpath (in case we must regen it)
114116
Int m_currentFlightPathStep; ///< Our current index in the flight path vector. Quicker than popping off.

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/MissileAIUpdate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ class MissileAIUpdate : public AIUpdateInterface, public ProjectileUpdateInterfa
9696
virtual ObjectID projectileGetLauncherID() const override { return m_launcherID; }
9797
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) override; ///< Number of frames till missile diverts to countermeasures.
9898
virtual void projectileNowJammed() override;///< We lose our Object target and scatter to the ground
99+
virtual const Coord3D* getProjectileLogicVelocity() const override { return &m_logicStepVelocity; }
99100

100101
virtual Bool processCollision(PhysicsBehavior *physics, Object *other) override; ///< Returns true if the physics collide should apply the force. Normally not. jba.
101102

@@ -119,6 +120,7 @@ class MissileAIUpdate : public AIUpdateInterface, public ProjectileUpdateInterfa
119120
Real m_maxAccel;
120121
Coord3D m_originalTargetPos; ///< When firing uphill, we aim high to clear the brow of the hill. jba.
121122
Coord3D m_prevPos;
123+
Coord3D m_logicStepVelocity; ///< Logic frame velocity vector
122124
WeaponBonusConditionFlags m_extraBonusFlags;
123125
const WeaponTemplate* m_detonationWeaponTmpl; ///< weapon to fire at end (or null)
124126
const ParticleSystemTemplate* m_exhaustSysTmpl;

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/NeutronMissileUpdate.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class NeutronMissileUpdate : public UpdateModule,
103103
virtual const Coord3D *getVelocity() const { return &m_vel; } ///< get current velocity
104104
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) override {}
105105
virtual void projectileNowJammed() override {}
106+
virtual const Coord3D* getProjectileLogicVelocity() const override { return &m_logicStepVelocity; }
106107

107108
virtual UpdateSleepTime update() override;
108109
virtual void onDelete() override;
@@ -119,6 +120,7 @@ class NeutronMissileUpdate : public UpdateModule,
119120

120121
Coord3D m_accel;
121122
Coord3D m_vel;
123+
Coord3D m_logicStepVelocity; ///< Logic frame velocity vector
122124

123125
UnsignedInt m_stateTimestamp; ///< time of state change
124126
Bool m_isLaunched;

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/UpdateModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ class ProjectileUpdateInterface
266266
virtual Bool projectileHandleCollision(Object *other) = 0;
267267
virtual void setFramesTillCountermeasureDiversionOccurs( UnsignedInt frames ) = 0; ///< Number of frames till missile diverts to countermeasures.
268268
virtual void projectileNowJammed() = 0;
269+
virtual const Coord3D* getProjectileLogicVelocity() const { return nullptr; }
269270
};
270271

271272
//-------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Source/GameClient/Drawable.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "Common/DrawModule.h"
3939
#include "Common/FramePacer.h"
4040
#include "Common/GameAudio.h"
41+
#include "Common/GameEngine.h"
4142
#include "Common/GameLOD.h"
4243
#include "Common/GameState.h"
4344
#include "Common/GameUtility.h"
@@ -61,6 +62,7 @@
6162
#include "GameLogic/Module/StealthUpdate.h"
6263
#include "GameLogic/Module/StickyBombUpdate.h"
6364
#include "GameLogic/Module/BattlePlanUpdate.h"
65+
#include "GameLogic/Module/UpdateModule.h"
6466
#include "GameLogic/ScriptEngine.h"
6567
#include "GameLogic/Weapon.h"
6668

@@ -412,6 +414,8 @@ Drawable::Drawable( const ThingTemplate *thingTemplate, DrawableStatusBits statu
412414
//Real scaleFuzziness = thingTemplate->getInstanceScaleFuzziness();
413415
//Real fuzzyScale = ( 1.0f + GameClientRandomValueReal( -scaleFuzziness, scaleFuzziness ));
414416
m_instanceScale = thingTemplate->getAssetScale();// * fuzzyScale;
417+
m_useExtrapolation = FALSE;
418+
m_visualExtrapolationMtx.Make_Identity();
415419

416420
// initially not bound to an object
417421
m_object = nullptr;
@@ -1149,6 +1153,18 @@ void Drawable::updateDrawable()
11491153
UnsignedInt now = TheGameLogic->getFrame();
11501154
Object *obj = getObject();
11511155

1156+
if (obj)
1157+
{
1158+
for (BehaviorModule** m = obj->getBehaviorModules(); m && *m; ++m)
1159+
{
1160+
if (ProjectileUpdateInterface* pui = (*m)->getProjectileUpdateInterface())
1161+
{
1162+
applySubFrameExtrapolation(pui);
1163+
break;
1164+
}
1165+
}
1166+
}
1167+
11521168
{
11531169
for (ClientUpdateModule** cu = getClientUpdateModules(); cu && *cu; ++cu)
11541170
{
@@ -4248,6 +4264,11 @@ void Drawable::setInstanceMatrix( const Matrix3D *instance )
42484264
//-------------------------------------------------------------------------------------------------
42494265
const Matrix3D *Drawable::getTransformMatrix() const
42504266
{
4267+
if (m_useExtrapolation)
4268+
{
4269+
return &m_visualExtrapolationMtx;
4270+
}
4271+
42514272
const Object *obj = getObject();
42524273

42534274
if (obj)
@@ -5643,3 +5664,20 @@ void TintEnvelope::loadPostProcess()
56435664

56445665
}
56455666

5667+
5668+
void Drawable::applySubFrameExtrapolation(ProjectileUpdateInterface* pui)
5669+
{
5670+
const Coord3D* v = pui->getProjectileLogicVelocity();
5671+
Real alpha = TheGameEngine->getLogicTimeAccumulator() * TheFramePacer->getActualLogicTimeScaleFps();
5672+
5673+
if (v && alpha > 0.0f && m_object)
5674+
{
5675+
m_visualExtrapolationMtx = *m_object->getTransformMatrix();
5676+
m_visualExtrapolationMtx.Adjust_Translation(*(Vector3*)v * (alpha > 1.0f ? 1.0f : alpha));
5677+
m_useExtrapolation = TRUE;
5678+
}
5679+
else
5680+
{
5681+
m_useExtrapolation = FALSE;
5682+
}
5683+
}

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/DumbProjectileBehavior.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ DumbProjectileBehavior::DumbProjectileBehavior( Thing *thing, const ModuleData*
121121
m_extraBonusFlags = 0;
122122

123123
m_hasDetonated = FALSE;
124+
m_logicStepVelocity.zero();
124125
}
125126

126127
//-------------------------------------------------------------------------------------------------
@@ -579,6 +580,8 @@ void DumbProjectileBehavior::detonate()
579580
UpdateSleepTime DumbProjectileBehavior::update()
580581
{
581582
const DumbProjectileBehaviorModuleData* d = getDumbProjectileBehaviorModuleData();
583+
m_logicStepVelocity.zero();
584+
Coord3D oldPos = *getObject()->getPosition();
582585

583586
if (m_lifespanFrame != 0 && TheGameLogic->getFrame() >= m_lifespanFrame)
584587
{
@@ -714,6 +717,16 @@ UpdateSleepTime DumbProjectileBehavior::update()
714717

715718
++m_currentFlightPathStep;
716719

720+
if (m_currentFlightPathStep < (Int)m_flightPath.size())
721+
{
722+
m_logicStepVelocity = m_flightPath[m_currentFlightPathStep];
723+
m_logicStepVelocity.sub( &flightStep ); // flightStep is currentPos
724+
}
725+
else
726+
{
727+
m_logicStepVelocity.zero();
728+
}
729+
717730
return UPDATE_SLEEP_NONE;//This no longer flys with physics, so it needs to not sleep
718731
}
719732

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/MissileAIUpdate.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ MissileAIUpdate::MissileAIUpdate( Thing *thing, const ModuleData* moduleData ) :
136136
m_framesTillDecoyed = 0;
137137
m_noDamage = FALSE;
138138
m_isJammed = FALSE;
139+
m_logicStepVelocity.zero();
139140
}
140141

141142
//-------------------------------------------------------------------------------------------------
@@ -731,6 +732,9 @@ UpdateSleepTime MissileAIUpdate::update()
731732

732733
/*UpdateSleepTime ret =*/ AIUpdateInterface::update();
733734

735+
m_logicStepVelocity = *getObject()->getPosition();
736+
m_logicStepVelocity.sub( &newPos );
737+
734738
#if 1
735739
// srj sez: doh, why was this never in place? I guess 'cuz so few "smart" missiles ever go in
736740
// a downward-towards-ground attitude. however, comanche rocket pod missiles do, so this fix

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/NeutronMissileUpdate.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ NeutronMissileUpdate::NeutronMissileUpdate( Thing *thing, const ModuleData* modu
125125
m_frameAtLaunch = 0;
126126

127127
m_exhaustSysTmpl = nullptr;
128+
m_logicStepVelocity.zero();
128129

129130
}
130131

@@ -255,13 +256,16 @@ void NeutronMissileUpdate::doLaunch()
255256

256257
// fall
257258
Coord3D pos = *getObject()->getPosition();
259+
Coord3D oldPos = pos;
258260

259261
pos.x += m_vel.x;
260262
pos.y += m_vel.y;
261263
pos.z += m_vel.z;
262264

263265
getObject()->setPosition( &pos );
264266

267+
m_logicStepVelocity = m_vel;
268+
265269
FXList::doFXObj(getNeutronMissileUpdateModuleData()->m_ignitionFX, getObject());
266270

267271
if (m_exhaustSysTmpl != nullptr)
@@ -335,6 +339,7 @@ void NeutronMissileUpdate::doAttack()
335339
{
336340
Matrix3D mx;
337341
Real speed = getNeutronMissileUpdateModuleData()->m_relativeSpeed;
342+
Coord3D oldPos = *getObject()->getPosition();
338343

339344
if (getNeutronMissileUpdateModuleData()->m_targetFromDirectlyAbove && m_reachedIntermediatePos)
340345
speed *= STRAIGHT_DOWN_SLOW_FACTOR;
@@ -423,6 +428,8 @@ void NeutronMissileUpdate::doAttack()
423428
getObject()->setTransformMatrix( &mx );
424429
getObject()->setPosition( &pos );
425430

431+
m_logicStepVelocity = m_vel;
432+
m_logicStepVelocity.add( &m_accel );
426433
}
427434

428435
//-------------------------------------------------------------------------------------------------
@@ -526,6 +533,12 @@ UpdateSleepTime NeutronMissileUpdate::update()
526533
normal.z = -1.0f;
527534
getObject()->onCollide(nullptr, getObject()->getPosition(), &normal);
528535
}
536+
537+
if (m_state == DEAD)
538+
{
539+
m_logicStepVelocity.zero();
540+
}
541+
529542
return UPDATE_SLEEP_NONE;
530543
}
531544

0 commit comments

Comments
 (0)