projectile augs

use impactforce to applyimpulse for stock physics too
add an optional explodeOnTmeout
for nonballistic projectiles, track if they hit something before their armingdelay is up, and delete them next simulation cycle
This commit is contained in:
AzaezelX 2025-04-16 13:08:39 -05:00
parent 75e23e85ea
commit f0c0f3c42c
2 changed files with 33 additions and 8 deletions

View file

@ -56,6 +56,7 @@
#include "T3D/decal/decalData.h" #include "T3D/decal/decalData.h"
#include "T3D/lightDescription.h" #include "T3D/lightDescription.h"
#include "console/engineAPI.h" #include "console/engineAPI.h"
#include "T3D/rigidShape.h"
IMPLEMENT_CO_DATABLOCK_V1(ProjectileData); IMPLEMENT_CO_DATABLOCK_V1(ProjectileData);
@ -163,6 +164,7 @@ ProjectileData::ProjectileData()
scale.set( 1.0f, 1.0f, 1.0f ); scale.set( 1.0f, 1.0f, 1.0f );
isBallistic = false; isBallistic = false;
mExplodeOnTmeout = false;
velInheritFactor = 1.0f; velInheritFactor = 1.0f;
muzzleVelocity = 50; muzzleVelocity = 50;
@ -203,6 +205,7 @@ ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : G
muzzleVelocity = other.muzzleVelocity; muzzleVelocity = other.muzzleVelocity;
impactForce = other.impactForce; impactForce = other.impactForce;
isBallistic = other.isBallistic; isBallistic = other.isBallistic;
mExplodeOnTmeout = other.mExplodeOnTmeout;
bounceElasticity = other.bounceElasticity; bounceElasticity = other.bounceElasticity;
bounceFriction = other.bounceFriction; bounceFriction = other.bounceFriction;
gravityMod = other.gravityMod; gravityMod = other.gravityMod;
@ -285,6 +288,8 @@ void ProjectileData::initPersistFields()
addProtectedFieldV("fadeDelay", TypeRangedS32, Offset(fadeDelay, ProjectileData), &setFadeDelay, &getScaledValue, &CommonValidators::NaturalNumber, addProtectedFieldV("fadeDelay", TypeRangedS32, Offset(fadeDelay, ProjectileData), &setFadeDelay, &getScaledValue, &CommonValidators::NaturalNumber,
"@brief Amount of time, in milliseconds, before the projectile begins to fade out.\n\n" "@brief Amount of time, in milliseconds, before the projectile begins to fade out.\n\n"
"This value must be smaller than the projectile's lifetime to have an affect."); "This value must be smaller than the projectile's lifetime to have an affect.");
addField("explodeOnTmeout", TypeBool, Offset(mExplodeOnTmeout, ProjectileData),
"@brief Detetmines if the projectile should explode on timeout");
addField("isBallistic", TypeBool, Offset(isBallistic, ProjectileData), addField("isBallistic", TypeBool, Offset(isBallistic, ProjectileData),
"@brief Detetmines if the projectile should be affected by gravity and whether or not " "@brief Detetmines if the projectile should be affected by gravity and whether or not "
"it bounces before exploding.\n\n"); "it bounces before exploding.\n\n");
@ -455,6 +460,7 @@ void ProjectileData::packData(BitStream* stream)
stream->write(armingDelay); stream->write(armingDelay);
stream->write(fadeDelay); stream->write(fadeDelay);
stream->writeFlag(mExplodeOnTmeout);
if(stream->writeFlag(isBallistic)) if(stream->writeFlag(isBallistic))
{ {
stream->write(gravityMod); stream->write(gravityMod);
@ -514,6 +520,7 @@ void ProjectileData::unpackData(BitStream* stream)
stream->read(&armingDelay); stream->read(&armingDelay);
stream->read(&fadeDelay); stream->read(&fadeDelay);
mExplodeOnTmeout = stream->readFlag();
isBallistic = stream->readFlag(); isBallistic = stream->readFlag();
if(isBallistic) if(isBallistic)
{ {
@ -611,6 +618,7 @@ Projectile::Projectile()
mProjectileShape( NULL ), mProjectileShape( NULL ),
mActivateThread( NULL ), mActivateThread( NULL ),
mMaintainThread( NULL ), mMaintainThread( NULL ),
mHasHit(false),
mHasExploded( false ), mHasExploded( false ),
mFadeValue( 1.0f ) mFadeValue( 1.0f )
{ {
@ -1128,11 +1136,19 @@ void Projectile::processTick( const Move *move )
void Projectile::simulate( F32 dt ) void Projectile::simulate( F32 dt )
{ {
if ( isServerObject() && mCurrTick >= mDataBlock->lifetime ) if ( isServerObject() )
{
if (mCurrTick >= (mDataBlock->lifetime - TickMs))
{
if (mDataBlock->mExplodeOnTmeout)
explode(mCurrPosition, Point3F::UnitZ, VehicleObjectType);
}
if (mCurrTick >= mDataBlock->lifetime || (mHasHit && mCurrTick < mDataBlock->armingDelay))
{ {
deleteObject(); deleteObject();
return; return;
} }
}
if ( mHasExploded ) if ( mHasExploded )
return; return;
@ -1168,8 +1184,15 @@ void Projectile::simulate( F32 dt )
if ( mPhysicsWorld ) if ( mPhysicsWorld )
hit = mPhysicsWorld->castRay( oldPosition, newPosition, &rInfo, Point3F( newPosition - oldPosition) * mDataBlock->impactForce ); hit = mPhysicsWorld->castRay( oldPosition, newPosition, &rInfo, Point3F( newPosition - oldPosition) * mDataBlock->impactForce );
else else
{
hit = getContainer()->castRay(oldPosition, newPosition, dynamicCollisionMask | staticCollisionMask, &rInfo); hit = getContainer()->castRay(oldPosition, newPosition, dynamicCollisionMask | staticCollisionMask, &rInfo);
if (hit && rInfo.object->getTypeMask() & VehicleObjectType)
{
RigidShape* aRigid = dynamic_cast<RigidShape*>(rInfo.object);
if (aRigid)
aRigid->applyImpulse(rInfo.point, Point3F(newPosition - oldPosition) * mDataBlock->impactForce);
}
}
if ( hit ) if ( hit )
{ {
// make sure the client knows to bounce // make sure the client knows to bounce
@ -1237,6 +1260,8 @@ void Projectile::simulate( F32 dt )
else else
{ {
mCurrVelocity = Point3F::Zero; mCurrVelocity = Point3F::Zero;
newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f;
mHasHit = true;
} }
} }

View file

@ -87,9 +87,9 @@ public:
/// Force imparted on a hit object. /// Force imparted on a hit object.
F32 impactForce; F32 impactForce;
bool mExplodeOnTmeout;
/// Should it arc? /// Should it arc?
bool isBallistic; bool isBallistic;
/// How HIGH should it bounce (parallel to normal), [0,1] /// How HIGH should it bounce (parallel to normal), [0,1]
F32 bounceElasticity; F32 bounceElasticity;
/// How much momentum should be lost when it bounces (perpendicular to normal), [0,1] /// How much momentum should be lost when it bounces (perpendicular to normal), [0,1]
@ -274,7 +274,7 @@ protected:
LightInfo *mLight; LightInfo *mLight;
LightState mLightState; LightState mLightState;
bool mHasHit;
bool mHasExploded; ///< Prevent rendering, lighting, and duplicate explosions. bool mHasExploded; ///< Prevent rendering, lighting, and duplicate explosions.
F32 mFadeValue; ///< set in processTick, interpolation between fadeDelay and lifetime F32 mFadeValue; ///< set in processTick, interpolation between fadeDelay and lifetime
///< in data block ///< in data block