mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-12 23:24:41 +00:00
add projectile example changes
These changes are a placeholder because technically we could remove the effects from the projectile class altogether. but for now it fires the effects and uses the projectiles explosion/emitter as a fallback. Also added a specific Ricochet sound effect
This commit is contained in:
parent
e664a2e20c
commit
ca454bfc7a
3 changed files with 82 additions and 6 deletions
|
|
@ -57,6 +57,7 @@
|
||||||
#include "T3D/lightDescription.h"
|
#include "T3D/lightDescription.h"
|
||||||
#include "console/engineAPI.h"
|
#include "console/engineAPI.h"
|
||||||
#include "T3D/rigidShape.h"
|
#include "T3D/rigidShape.h"
|
||||||
|
#include "materials/materialPropertiesManager.h"
|
||||||
|
|
||||||
|
|
||||||
IMPLEMENT_CO_DATABLOCK_V1(ProjectileData);
|
IMPLEMENT_CO_DATABLOCK_V1(ProjectileData);
|
||||||
|
|
@ -1122,8 +1123,14 @@ void Projectile::explode( const Point3F &p, const Point3F &n, const U32 collideT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client (impact) decal.
|
RayInfo matRay;
|
||||||
if ( mDataBlock->decal )
|
BaseMatInstance* hitMat = NULL;
|
||||||
|
if (gClientContainer.castRay(p + n * 0.05f, p - n * 0.01f, csmStaticCollisionMask, &matRay))
|
||||||
|
hitMat = matRay.material;
|
||||||
|
|
||||||
|
// Fallback to datablock decal if no surface effect matched
|
||||||
|
MaterialPropertiesData* fx = MaterialFXManager.resolve(hitMat);
|
||||||
|
if (!fx && mDataBlock->decal)
|
||||||
gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal);
|
gDecalManager->addDecal(p, n, 0.0f, mDataBlock->decal);
|
||||||
|
|
||||||
// Client object
|
// Client object
|
||||||
|
|
@ -1267,10 +1274,62 @@ void Projectile::simulate( F32 dt )
|
||||||
// specific code should be placed inside the function!
|
// specific code should be placed inside the function!
|
||||||
onCollision( rInfo.point, rInfo.normal, rInfo.object );
|
onCollision( rInfo.point, rInfo.normal, rInfo.object );
|
||||||
// Next order of business: do we explode on this hit?
|
// Next order of business: do we explode on this hit?
|
||||||
if ( mCurrTick > mDataBlock->armingDelay || mDataBlock->armingDelay == 0 )
|
if (mCurrTick > mDataBlock->armingDelay || mDataBlock->armingDelay == 0)
|
||||||
{
|
{
|
||||||
mCurrVelocity = Point3F::Zero;
|
MaterialPropertiesResult fx_result = resolveImpact(
|
||||||
explode( rInfo.point, rInfo.normal, objectType );
|
rInfo.material,
|
||||||
|
mCurrVelocity,
|
||||||
|
rInfo.normal,
|
||||||
|
mDataBlock->impactForce,
|
||||||
|
false);
|
||||||
|
|
||||||
|
// Fire visual effects on client only
|
||||||
|
if (isClientObject())
|
||||||
|
{
|
||||||
|
MaterialFXManager.fireEffect(
|
||||||
|
rInfo.material,
|
||||||
|
rInfo.point,
|
||||||
|
rInfo.normal,
|
||||||
|
mCurrVelocity.len(),
|
||||||
|
mDataBlock->impactForce,
|
||||||
|
fx_result.didRicochet,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fx_result.didRicochet)
|
||||||
|
{
|
||||||
|
mCurrVelocity = fx_result.ricochetDirection * fx_result.ricochetSpeed;
|
||||||
|
newPosition = rInfo.point + rInfo.normal * 0.05f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fx_result.didPenetrate)
|
||||||
|
{
|
||||||
|
mCurrVelocity *= fx_result.remainingVelocityFactor;
|
||||||
|
VectorF normVel = mCurrVelocity;
|
||||||
|
normVel.normalizeSafe();
|
||||||
|
newPosition = rInfo.point + normVel * 0.1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fx_result.didPenetrate || fx_result.didRicochet)
|
||||||
|
{
|
||||||
|
if (isServerObject())
|
||||||
|
setMaskBits(BounceMask);
|
||||||
|
|
||||||
|
if (disableSourceObjCollision)
|
||||||
|
mSourceObject->enableCollision();
|
||||||
|
enableCollision();
|
||||||
|
|
||||||
|
mCurrDeltaBase = newPosition;
|
||||||
|
mCurrBackDelta = mCurrPosition - newPosition;
|
||||||
|
mCurrPosition = newPosition;
|
||||||
|
|
||||||
|
xform.setColumn(3, mCurrPosition);
|
||||||
|
setTransform(xform);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mCurrVelocity = Point3F::Zero;
|
||||||
|
explode(rInfo.point, rInfo.normal, objectType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mDataBlock->isBallistic )
|
if ( mDataBlock->isBallistic )
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ MaterialPropertiesData::MaterialPropertiesData()
|
||||||
INIT_ASSET(SoftImpactSound);
|
INIT_ASSET(SoftImpactSound);
|
||||||
INIT_ASSET(MediumImpactSound);
|
INIT_ASSET(MediumImpactSound);
|
||||||
INIT_ASSET(HardImpactSound);
|
INIT_ASSET(HardImpactSound);
|
||||||
|
INIT_ASSET(RicochetSound);
|
||||||
INIT_ASSET(MeleeSoftSound);
|
INIT_ASSET(MeleeSoftSound);
|
||||||
INIT_ASSET(MeleeHardSound);
|
INIT_ASSET(MeleeHardSound);
|
||||||
|
|
||||||
|
|
@ -106,6 +107,8 @@ void MaterialPropertiesData::initPersistFields()
|
||||||
"Sound for medium-velocity impacts.");
|
"Sound for medium-velocity impacts.");
|
||||||
INITPERSISTFIELD_SOUNDASSET(HardImpactSound, MaterialPropertiesData,
|
INITPERSISTFIELD_SOUNDASSET(HardImpactSound, MaterialPropertiesData,
|
||||||
"Sound for high-velocity impacts (bullets, fast projectiles).");
|
"Sound for high-velocity impacts (bullets, fast projectiles).");
|
||||||
|
INITPERSISTFIELD_SOUNDASSET(RicochetSound, MaterialPropertiesData,
|
||||||
|
"Sound for high-velocity ricochets (bullets, fast projectiles).");
|
||||||
INITPERSISTFIELD_SOUNDASSET(MeleeSoftSound, MaterialPropertiesData,
|
INITPERSISTFIELD_SOUNDASSET(MeleeSoftSound, MaterialPropertiesData,
|
||||||
"Melee soft hit sound override. Falls back to SoftImpactSound.");
|
"Melee soft hit sound override. Falls back to SoftImpactSound.");
|
||||||
INITPERSISTFIELD_SOUNDASSET(MeleeHardSound, MaterialPropertiesData,
|
INITPERSISTFIELD_SOUNDASSET(MeleeHardSound, MaterialPropertiesData,
|
||||||
|
|
@ -262,6 +265,11 @@ bool MaterialPropertiesData::preload(bool server, String& errorStr)
|
||||||
getHardImpactSoundProfile();
|
getHardImpactSoundProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isRicochetSoundValid())
|
||||||
|
{
|
||||||
|
getRicochetSoundProfile();
|
||||||
|
}
|
||||||
|
|
||||||
if (isMeleeSoftSoundValid())
|
if (isMeleeSoftSoundValid())
|
||||||
{
|
{
|
||||||
getMeleeSoftSoundProfile();
|
getMeleeSoftSoundProfile();
|
||||||
|
|
@ -287,6 +295,7 @@ void MaterialPropertiesData::packData(BitStream* stream)
|
||||||
PACKDATA_SOUNDASSET(SoftImpactSound);
|
PACKDATA_SOUNDASSET(SoftImpactSound);
|
||||||
PACKDATA_SOUNDASSET(MediumImpactSound);
|
PACKDATA_SOUNDASSET(MediumImpactSound);
|
||||||
PACKDATA_SOUNDASSET(HardImpactSound);
|
PACKDATA_SOUNDASSET(HardImpactSound);
|
||||||
|
PACKDATA_SOUNDASSET(RicochetSound);
|
||||||
PACKDATA_SOUNDASSET(MeleeSoftSound);
|
PACKDATA_SOUNDASSET(MeleeSoftSound);
|
||||||
PACKDATA_SOUNDASSET(MeleeHardSound);
|
PACKDATA_SOUNDASSET(MeleeHardSound);
|
||||||
|
|
||||||
|
|
@ -338,6 +347,7 @@ void MaterialPropertiesData::unpackData(BitStream* stream)
|
||||||
UNPACKDATA_SOUNDASSET(SoftImpactSound);
|
UNPACKDATA_SOUNDASSET(SoftImpactSound);
|
||||||
UNPACKDATA_SOUNDASSET(MediumImpactSound);
|
UNPACKDATA_SOUNDASSET(MediumImpactSound);
|
||||||
UNPACKDATA_SOUNDASSET(HardImpactSound);
|
UNPACKDATA_SOUNDASSET(HardImpactSound);
|
||||||
|
UNPACKDATA_SOUNDASSET(RicochetSound);
|
||||||
UNPACKDATA_SOUNDASSET(MeleeSoftSound);
|
UNPACKDATA_SOUNDASSET(MeleeSoftSound);
|
||||||
UNPACKDATA_SOUNDASSET(MeleeHardSound);
|
UNPACKDATA_SOUNDASSET(MeleeHardSound);
|
||||||
|
|
||||||
|
|
@ -462,6 +472,7 @@ void MaterialPropertiesManager::fireEffect(BaseMatInstance* mat,
|
||||||
F32 impactVelocity,
|
F32 impactVelocity,
|
||||||
F32 impactForce,
|
F32 impactForce,
|
||||||
bool isMelee,
|
bool isMelee,
|
||||||
|
bool isRicochet,
|
||||||
bool clientOnly)
|
bool clientOnly)
|
||||||
{
|
{
|
||||||
MaterialPropertiesData* fx = resolve(mat);
|
MaterialPropertiesData* fx = resolve(mat);
|
||||||
|
|
@ -491,6 +502,9 @@ void MaterialPropertiesManager::fireEffect(BaseMatInstance* mat,
|
||||||
snd = fx->getHardImpactSoundProfile();
|
snd = fx->getHardImpactSoundProfile();
|
||||||
else
|
else
|
||||||
snd = fx->getMediumImpactSoundProfile();
|
snd = fx->getMediumImpactSoundProfile();
|
||||||
|
|
||||||
|
if (isRicochet && fx->isRicochetSoundValid())
|
||||||
|
snd = fx->getRicochetSoundProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snd)
|
if (snd)
|
||||||
|
|
@ -579,7 +593,7 @@ MaterialPropertiesResult resolveImpact( BaseMatInstance* mat,
|
||||||
F32 glanceDeg = mRadToDeg(mAcos(mClampF(cosGlance, 0.0f, 1.0f)));
|
F32 glanceDeg = mRadToDeg(mAcos(mClampF(cosGlance, 0.0f, 1.0f)));
|
||||||
|
|
||||||
|
|
||||||
bool angleOk = (90.0f - glanceDeg) >= fx->ricochetMinAngle;
|
bool angleOk = glanceDeg >= fx->ricochetMinAngle;
|
||||||
|
|
||||||
if (angleOk && gRandGen.randF() < fx->ricochetChance)
|
if (angleOk && gRandGen.randF() < fx->ricochetChance)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ public:
|
||||||
DECLARE_ASSET_SETGET(MaterialPropertiesData, MediumImpactSound)
|
DECLARE_ASSET_SETGET(MaterialPropertiesData, MediumImpactSound)
|
||||||
DECLARE_SOUNDASSET(MaterialPropertiesData, HardImpactSound)
|
DECLARE_SOUNDASSET(MaterialPropertiesData, HardImpactSound)
|
||||||
DECLARE_ASSET_SETGET(MaterialPropertiesData, HardImpactSound)
|
DECLARE_ASSET_SETGET(MaterialPropertiesData, HardImpactSound)
|
||||||
|
DECLARE_SOUNDASSET(MaterialPropertiesData, RicochetSound)
|
||||||
|
DECLARE_ASSET_SETGET(MaterialPropertiesData, RicochetSound)
|
||||||
|
|
||||||
// Optional: separate sounds for melee (crowbar clink vs bullet ping
|
// Optional: separate sounds for melee (crowbar clink vs bullet ping
|
||||||
// on the same metal surface feel very different)
|
// on the same metal surface feel very different)
|
||||||
|
|
@ -180,6 +182,7 @@ public:
|
||||||
F32 impactVelocity,
|
F32 impactVelocity,
|
||||||
F32 impactForce,
|
F32 impactForce,
|
||||||
bool isMelee,
|
bool isMelee,
|
||||||
|
bool isRicochet,
|
||||||
bool clientOnly = true);
|
bool clientOnly = true);
|
||||||
|
|
||||||
void setDefaultEffect(MaterialPropertiesData* data);
|
void setDefaultEffect(MaterialPropertiesData* data);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue