mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +00:00
Merge branch 'development' of https://github.com/TorqueGameEngines/Torque3D into alpha41/DamageModel
# Conflicts: # Engine/source/T3D/vehicles/vehicle.cpp
This commit is contained in:
commit
be35c27411
64 changed files with 619 additions and 371 deletions
|
|
@ -370,7 +370,7 @@ public: \
|
|||
|
||||
#pragma region Arrayed Asset Macros
|
||||
|
||||
#define DECLARE_SHAPEASSET_ARRAY(className,name,max) public: \
|
||||
#define DECLARE_SHAPEASSET_ARRAY(className,name,max,changeFunc) public: \
|
||||
static const U32 sm##name##Count = max;\
|
||||
Resource<TSShape>m##name[max];\
|
||||
StringTableEntry m##name##Name[max]; \
|
||||
|
|
@ -384,6 +384,10 @@ public: \
|
|||
\
|
||||
bool _set##name(StringTableEntry _in, const U32& index)\
|
||||
{\
|
||||
if (m##name##Asset[index].notNull())\
|
||||
{\
|
||||
m##name##Asset[index]->getChangedSignal().remove(this, &className::changeFunc);\
|
||||
}\
|
||||
if(m##name##AssetId[index] != _in || m##name##Name[index] != _in)\
|
||||
{\
|
||||
if(index >= sm##name##Count || index < 0)\
|
||||
|
|
@ -430,6 +434,8 @@ public: \
|
|||
if (get##name(index) != StringTable->EmptyString() && m##name##Asset[index].notNull())\
|
||||
{\
|
||||
m##name[index] = m##name##Asset[index]->getShapeResource();\
|
||||
\
|
||||
m##name##Asset[index]->getChangedSignal().notify(this, &className::changeFunc);\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ bool Camera::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ bool Debris::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
|
||||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,10 @@ public:
|
|||
void onPerformSubstitutions() override;
|
||||
bool allowSubstitutions() const override { return true; }
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
};
|
||||
|
||||
//**************************************************************************
|
||||
|
|
|
|||
|
|
@ -147,6 +147,11 @@ void GuiHealthBarHud::onRender(Point2I offset, const RectI &updateRect)
|
|||
if (!conn)
|
||||
return;
|
||||
ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject());
|
||||
|
||||
//cover the case of a connection controling an object in turn controlling another
|
||||
if (control && control->getControlObject())
|
||||
control = control->getControlObject();
|
||||
|
||||
if (!control || !(control->getTypeMask() & (PlayerObjectType | VehicleObjectType)))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,12 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
|
|||
GameConnection* conn = GameConnection::getConnectionToServer();
|
||||
if (!conn)
|
||||
return;
|
||||
ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject());
|
||||
ShapeBase* control = dynamic_cast<ShapeBase*>(conn->getControlObject());
|
||||
|
||||
//cover the case of a connection controling an object in turn controlling another
|
||||
if (control && control->getControlObject())
|
||||
control = control->getControlObject();
|
||||
|
||||
if (!control || !(control->getTypeMask() & (PlayerObjectType | VehicleObjectType)))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1127,7 +1127,7 @@ bool Explosion::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
|
||||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,10 @@ public:
|
|||
ExplosionData* cloneAndPerformSubstitutions(const SimObject*, S32 index=0);
|
||||
bool allowSubstitutions() const override { return true; }
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -852,8 +852,11 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
|||
// It's sloppy, but it works for now.
|
||||
_freeCells();
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
if (isProperlyAdded())
|
||||
{
|
||||
_initMaterial();
|
||||
_initShapes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ protected:
|
|||
RectF mBillboardRects[MAX_COVERTYPES];
|
||||
|
||||
/// The cover shape filenames.
|
||||
DECLARE_SHAPEASSET_ARRAY(GroundCover, Shape, MAX_COVERTYPES);
|
||||
DECLARE_SHAPEASSET_ARRAY(GroundCover, Shape, MAX_COVERTYPES, onShapeChanged);
|
||||
DECLARE_ASSET_ARRAY_NET_SETGET(GroundCover, Shape, -1);
|
||||
|
||||
/// The cover shape instances.
|
||||
|
|
@ -409,6 +409,12 @@ protected:
|
|||
S32 randSeed );
|
||||
|
||||
void _debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
||||
|
||||
void onShapeChanged()
|
||||
{
|
||||
_initShapes();
|
||||
setMaskBits(U32(-1));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _GROUNDCOVER_H_
|
||||
|
|
|
|||
|
|
@ -474,7 +474,7 @@ bool Lightning::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,10 @@ class ParticleData : public SimDataBlock
|
|||
static bool protectedSetSizes(void* object, const char* index, const char* data);
|
||||
static bool protectedSetTimes(void* object, const char* index, const char* data);
|
||||
|
||||
void onImageChanged() {}
|
||||
void onImageChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
public:
|
||||
ParticleData();
|
||||
|
|
|
|||
|
|
@ -1131,7 +1131,7 @@ bool ParticleEmitter::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
return true;
|
||||
}
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ bool ParticleEmitterNode::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
return false;
|
||||
|
||||
// Todo: Uncomment if this is a "leaf" class
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -614,7 +614,7 @@ bool Precipitation::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
initMaterials();
|
||||
}
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,14 @@ class PrecipitationData : public GameBaseData
|
|||
void packData(BitStream* stream) override;
|
||||
void unpackData(BitStream* stream) override;
|
||||
|
||||
void onDropChanged() {}
|
||||
void onSplashChanged() {}
|
||||
void onDropChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
void onSplashChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
};
|
||||
|
||||
struct Raindrop
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ bool RibbonNode::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
return false;
|
||||
|
||||
// Todo: Uncomment if this is a "leaf" class
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@ bool Splash::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,10 @@ public:
|
|||
|
||||
DECLARE_IMAGEASSET_ARRAY(SplashData, Texture, NUM_TEX, onTextureChanged);
|
||||
DECLARE_IMAGEASSET_ARRAY_SETGET(SplashData, Texture)
|
||||
void onTextureChanged() {}
|
||||
void onTextureChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
ExplosionData* explosion;
|
||||
S32 explosionId;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ IMPLEMENT_CALLBACK( GameBaseData, onAdd, void, ( GameBase* obj ), ( obj ),
|
|||
"}\n\n"
|
||||
"@endtsexample\n" );
|
||||
|
||||
IMPLEMENT_CALLBACK( GameBaseData, onNewDataBlock, void, ( GameBase* obj ), ( obj ),
|
||||
IMPLEMENT_CALLBACK( GameBaseData, onNewDataBlock, void, ( GameBase* obj, bool reload), ( obj, reload),
|
||||
"@brief Called when the object has a new datablock assigned.\n\n"
|
||||
"@param obj the GameBase object\n\n"
|
||||
"@see onAdd for an example\n" );
|
||||
|
|
@ -512,12 +512,12 @@ void GameBase::scriptOnAdd()
|
|||
mDataBlock->onAdd_callback( this );
|
||||
}
|
||||
|
||||
void GameBase::scriptOnNewDataBlock()
|
||||
void GameBase::scriptOnNewDataBlock(bool reload)
|
||||
{
|
||||
// Script onNewDataBlock() must be called by the leaf class
|
||||
// after everything is loaded.
|
||||
if (mDataBlock && !isGhost())
|
||||
mDataBlock->onNewDataBlock_callback( this );
|
||||
mDataBlock->onNewDataBlock_callback( this, reload);
|
||||
}
|
||||
|
||||
void GameBase::scriptOnRemove()
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ public:
|
|||
/// @{
|
||||
DECLARE_CALLBACK( void, onAdd, ( GameBase* obj ) );
|
||||
DECLARE_CALLBACK( void, onRemove, ( GameBase* obj ) );
|
||||
DECLARE_CALLBACK( void, onNewDataBlock, ( GameBase* obj ) );
|
||||
DECLARE_CALLBACK( void, onNewDataBlock, ( GameBase* obj, bool reload) );
|
||||
DECLARE_CALLBACK( void, onMount, ( SceneObject* obj, SceneObject* mountObj, S32 node ) );
|
||||
DECLARE_CALLBACK( void, onUnmount, ( SceneObject* obj, SceneObject* mountObj, S32 node ) );
|
||||
/// @}
|
||||
|
|
@ -299,7 +299,7 @@ public:
|
|||
/// Executes the 'onNewDataBlock' script function for this object.
|
||||
///
|
||||
/// @note This must be called after everything is loaded.
|
||||
void scriptOnNewDataBlock();
|
||||
void scriptOnNewDataBlock(bool reload = false);
|
||||
|
||||
/// Executes the 'onRemove' script function for this object.
|
||||
/// @note This must be called while the object is still valid
|
||||
|
|
|
|||
|
|
@ -422,7 +422,7 @@ bool Item::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
return false;
|
||||
|
||||
if (!mSubclassItemHandlesScene)
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
|
||||
if ( isProperlyAdded() )
|
||||
_updatePhysics();
|
||||
|
|
|
|||
|
|
@ -106,7 +106,10 @@ protected:
|
|||
void _makePrimBuffer( GFXPrimitiveBufferHandle *pb, U32 count );
|
||||
void _renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
||||
|
||||
void onImageChanged() {}
|
||||
void onImageChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ bool MissionMarker::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
mDataBlock = dynamic_cast<MissionMarkerData*>( dptr );
|
||||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return(false);
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ bool PathCamera::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ bool PathShape::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ public:
|
|||
void packData( BitStream *stream ) override;
|
||||
void unpackData( BitStream *stream ) override;
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
DECLARE_CONOBJECT( PhysicsDebrisData );
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,10 @@ public:
|
|||
SimObjectRef< ExplosionData > explosion;
|
||||
SimObjectRef< PhysicsShapeData > destroyedShape;
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
};
|
||||
|
||||
typedef PhysicsShapeData::SimType PhysicsSimType;
|
||||
|
|
|
|||
|
|
@ -460,6 +460,7 @@ PlayerData::PlayerData()
|
|||
jumpTowardsNormal = true;
|
||||
|
||||
physicsPlayerType = StringTable->EmptyString();
|
||||
mControlMap = StringTable->EmptyString();
|
||||
|
||||
dMemset( actionList, 0, sizeof(actionList) );
|
||||
}
|
||||
|
|
@ -739,7 +740,9 @@ void PlayerData::initPersistFields()
|
|||
endGroup( "Camera" );
|
||||
|
||||
addGroup( "Movement" );
|
||||
|
||||
addField("controlMap", TypeString, Offset(mControlMap, PlayerData),
|
||||
"@brief movemap used by these types of objects.\n\n");
|
||||
|
||||
addFieldV( "maxStepHeight", TypeRangedF32, Offset(maxStepHeight, PlayerData), &CommonValidators::PositiveFloat,
|
||||
"@brief Maximum height the player can step up.\n\n"
|
||||
"The player will automatically step onto changes in ground height less "
|
||||
|
|
@ -1923,7 +1926,7 @@ bool Player::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
onScaleChanged();
|
||||
resetWorldBox();
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ struct PlayerData: public ShapeBaseData {
|
|||
/// that we don't create a TSThread on the player if we don't
|
||||
/// need to.
|
||||
|
||||
DECLARE_SHAPEASSET_ARRAY(PlayerData, ShapeFP, ShapeBase::MaxMountedImages); ///< Used to render with mounted images in first person [optional]
|
||||
DECLARE_SHAPEASSET_ARRAY(PlayerData, ShapeFP, ShapeBase::MaxMountedImages, onShapeChanged); ///< Used to render with mounted images in first person [optional]
|
||||
DECLARE_ASSET_ARRAY_SETGET(PlayerData, ShapeFP);
|
||||
|
||||
StringTableEntry imageAnimPrefixFP; ///< Passed along to mounted images to modify
|
||||
|
|
@ -346,7 +346,7 @@ struct PlayerData: public ShapeBaseData {
|
|||
|
||||
// Jump off surfaces at their normal rather than straight up
|
||||
bool jumpTowardsNormal;
|
||||
|
||||
StringTableEntry mControlMap;
|
||||
// For use if/when mPhysicsPlayer is created
|
||||
StringTableEntry physicsPlayerType;
|
||||
|
||||
|
|
@ -366,6 +366,11 @@ struct PlayerData: public ShapeBaseData {
|
|||
void packData(BitStream* stream) override;
|
||||
void unpackData(BitStream* stream) override;
|
||||
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
/// @name Callbacks
|
||||
/// @{
|
||||
DECLARE_CALLBACK( void, onPoseChange, ( Player* obj, const char* oldPose, const char* newPose ) );
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@
|
|||
#include "T3D/decal/decalData.h"
|
||||
#include "T3D/lightDescription.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "T3D/rigidShape.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(ProjectileData);
|
||||
|
|
@ -163,6 +164,7 @@ ProjectileData::ProjectileData()
|
|||
scale.set( 1.0f, 1.0f, 1.0f );
|
||||
|
||||
isBallistic = false;
|
||||
mExplodeOnTmeout = false;
|
||||
|
||||
velInheritFactor = 1.0f;
|
||||
muzzleVelocity = 50;
|
||||
|
|
@ -203,6 +205,7 @@ ProjectileData::ProjectileData(const ProjectileData& other, bool temp_clone) : G
|
|||
muzzleVelocity = other.muzzleVelocity;
|
||||
impactForce = other.impactForce;
|
||||
isBallistic = other.isBallistic;
|
||||
mExplodeOnTmeout = other.mExplodeOnTmeout;
|
||||
bounceElasticity = other.bounceElasticity;
|
||||
bounceFriction = other.bounceFriction;
|
||||
gravityMod = other.gravityMod;
|
||||
|
|
@ -285,6 +288,8 @@ void ProjectileData::initPersistFields()
|
|||
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"
|
||||
"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),
|
||||
"@brief Detetmines if the projectile should be affected by gravity and whether or not "
|
||||
"it bounces before exploding.\n\n");
|
||||
|
|
@ -455,13 +460,14 @@ void ProjectileData::packData(BitStream* stream)
|
|||
stream->write(armingDelay);
|
||||
stream->write(fadeDelay);
|
||||
|
||||
stream->writeFlag(mExplodeOnTmeout);
|
||||
if(stream->writeFlag(isBallistic))
|
||||
{
|
||||
stream->write(gravityMod);
|
||||
stream->write(bounceElasticity);
|
||||
stream->write(bounceFriction);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ProjectileData::unpackData(BitStream* stream)
|
||||
|
|
@ -514,6 +520,7 @@ void ProjectileData::unpackData(BitStream* stream)
|
|||
stream->read(&armingDelay);
|
||||
stream->read(&fadeDelay);
|
||||
|
||||
mExplodeOnTmeout = stream->readFlag();
|
||||
isBallistic = stream->readFlag();
|
||||
if(isBallistic)
|
||||
{
|
||||
|
|
@ -611,6 +618,7 @@ Projectile::Projectile()
|
|||
mProjectileShape( NULL ),
|
||||
mActivateThread( NULL ),
|
||||
mMaintainThread( NULL ),
|
||||
mHasHit(false),
|
||||
mHasExploded( false ),
|
||||
mFadeValue( 1.0f )
|
||||
{
|
||||
|
|
@ -1128,10 +1136,18 @@ void Projectile::processTick( const Move *move )
|
|||
|
||||
void Projectile::simulate( F32 dt )
|
||||
{
|
||||
if ( isServerObject() && mCurrTick >= mDataBlock->lifetime )
|
||||
if ( isServerObject() )
|
||||
{
|
||||
deleteObject();
|
||||
return;
|
||||
if (mCurrTick >= (mDataBlock->lifetime - TickMs))
|
||||
{
|
||||
if (mDataBlock->mExplodeOnTmeout)
|
||||
explode(mCurrPosition, Point3F::UnitZ, VehicleObjectType);
|
||||
}
|
||||
if (mCurrTick >= mDataBlock->lifetime || (mHasHit && mCurrTick < mDataBlock->armingDelay))
|
||||
{
|
||||
deleteObject();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mHasExploded )
|
||||
|
|
@ -1167,9 +1183,16 @@ void Projectile::simulate( F32 dt )
|
|||
|
||||
if ( mPhysicsWorld )
|
||||
hit = mPhysicsWorld->castRay( oldPosition, newPosition, &rInfo, Point3F( newPosition - oldPosition) * mDataBlock->impactForce );
|
||||
else
|
||||
else
|
||||
{
|
||||
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 )
|
||||
{
|
||||
// make sure the client knows to bounce
|
||||
|
|
@ -1237,6 +1260,8 @@ void Projectile::simulate( F32 dt )
|
|||
else
|
||||
{
|
||||
mCurrVelocity = Point3F::Zero;
|
||||
newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f;
|
||||
mHasHit = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,9 +87,9 @@ public:
|
|||
/// Force imparted on a hit object.
|
||||
F32 impactForce;
|
||||
|
||||
bool mExplodeOnTmeout;
|
||||
/// Should it arc?
|
||||
bool isBallistic;
|
||||
|
||||
/// How HIGH should it bounce (parallel to normal), [0,1]
|
||||
F32 bounceElasticity;
|
||||
/// How much momentum should be lost when it bounces (perpendicular to normal), [0,1]
|
||||
|
|
@ -154,7 +154,10 @@ public:
|
|||
ProjectileData(const ProjectileData&, bool = false);
|
||||
bool allowSubstitutions() const override { return true; }
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -274,7 +277,7 @@ protected:
|
|||
|
||||
LightInfo *mLight;
|
||||
LightState mLightState;
|
||||
|
||||
bool mHasHit;
|
||||
bool mHasExploded; ///< Prevent rendering, lighting, and duplicate explosions.
|
||||
F32 mFadeValue; ///< set in processTick, interpolation between fadeDelay and lifetime
|
||||
///< in data block
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ bool ProximityMine::onNewDataBlock( GameBaseData* dptr, bool reload )
|
|||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -906,7 +906,7 @@ bool RigidShape::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
else
|
||||
mRigid.setObjectInertia(mObjBox.maxExtents - mObjBox.minExtents);
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ bool ShapeBaseData::preload(bool server, String &errorStr)
|
|||
|
||||
S32 i;
|
||||
U32 assetStatus = ShapeAsset::getAssetErrCode(mShapeAsset);
|
||||
if (assetStatus == AssetBase::Ok|| assetStatus == AssetBase::UsingFallback)
|
||||
if (assetStatus == AssetBase::Ok || assetStatus == AssetBase::UsingFallback)
|
||||
{
|
||||
if (!server && !mShape->preloadMaterialList(mShape.getPath()) && NetConnection::filesWereDownloaded())
|
||||
shapeError = true;
|
||||
|
|
@ -912,7 +912,17 @@ void ShapeBaseData::unpackData(BitStream* stream)
|
|||
silent_bbox_check = stream->readFlag();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
void ShapeBaseData::onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
void ShapeBaseData::onDebrisChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ struct ShapeBaseImageData: public GameBaseData {
|
|||
F32 scriptAnimTransitionTime; ///< The amount of time to transition between the previous sequence and new sequence
|
||||
///< when the script prefix has changed.
|
||||
|
||||
DECLARE_SHAPEASSET_ARRAY(ShapeBaseImageData, Shape, MaxShapes); ///< Name of shape to render.
|
||||
DECLARE_SHAPEASSET_ARRAY(ShapeBaseImageData, Shape, MaxShapes, onShapeChanged); ///< Name of shape to render.
|
||||
DECLARE_ASSET_ARRAY_SETGET(ShapeBaseImageData, Shape);
|
||||
|
||||
//DECLARE_SHAPEASSET(ShapeBaseImageData, ShapeFP); ///< Name of shape to render in first person (optional).
|
||||
|
|
@ -505,6 +505,11 @@ struct ShapeBaseImageData: public GameBaseData {
|
|||
|
||||
void handleStateSoundTrack(const U32& stateId);
|
||||
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Callbacks
|
||||
|
|
@ -683,8 +688,8 @@ public:
|
|||
Vector<TextureTagRemapping> txr_tag_remappings;
|
||||
bool silent_bbox_check;
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onDebrisChanged() {}
|
||||
void onShapeChanged();
|
||||
void onDebrisChanged();
|
||||
public:
|
||||
ShapeBaseData(const ShapeBaseData&, bool = false);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ bool StaticShape::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -465,7 +465,7 @@ bool Trigger::onNewDataBlock( GameBaseData *dptr, bool reload )
|
|||
if ( !mDataBlock || !Parent::onNewDataBlock( dptr, reload ) )
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -545,7 +545,7 @@ bool AITurretShape::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
mShapeInstance->setTimeScale(mStateAnimThread,0);
|
||||
}
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ TurretShapeData::TurretShapeData()
|
|||
recoilSequence[i] = -1;
|
||||
pitchSequence = -1;
|
||||
headingSequence = -1;
|
||||
mControlMap = StringTable->EmptyString();
|
||||
}
|
||||
|
||||
void TurretShapeData::initPersistFields()
|
||||
|
|
@ -134,6 +135,8 @@ void TurretShapeData::initPersistFields()
|
|||
docsURL;
|
||||
Parent::initPersistFields();
|
||||
addGroup("Steering");
|
||||
addField("controlMap", TypeString, Offset(mControlMap, TurretShapeData),
|
||||
"@brief movemap used by these types of objects.\n\n");
|
||||
addField("zRotOnly", TypeBool, Offset(zRotOnly, TurretShapeData),
|
||||
"@brief Should the turret allow only z rotations.\n\n"
|
||||
"True indicates that the turret may only be rotated on its z axis, just like the Item class. "
|
||||
|
|
@ -440,7 +443,7 @@ bool TurretShape::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
|
||||
if (!mSubclassTurretShapeHandlesScene)
|
||||
{
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ public:
|
|||
bool startLoaded; ///< Should the turret's mounted weapon(s) start in a loaded state?
|
||||
|
||||
bool zRotOnly; ///< Should the turret allow only z rotations (like an item)?
|
||||
StringTableEntry mControlMap;
|
||||
|
||||
public:
|
||||
TurretShapeData();
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ bool FlyingVehicle::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
mJetThread[i] = 0;
|
||||
}
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -549,7 +549,7 @@ bool HoverVehicle::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
}
|
||||
|
||||
// Todo: Uncomment if this is a "leaf" class
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ VehicleData::VehicleData()
|
|||
dMemset( damageEmitterOffset, 0, sizeof( damageEmitterOffset ) );
|
||||
dMemset( damageEmitterIDList, 0, sizeof( damageEmitterIDList ) );
|
||||
dMemset( damageLevelTolerance, 0, sizeof( damageLevelTolerance ) );
|
||||
mControlMap = StringTable->EmptyString();
|
||||
|
||||
numDmgEmitterAreas = 0;
|
||||
|
||||
|
|
@ -321,6 +322,8 @@ void VehicleData::initPersistFields()
|
|||
endGroup("Collision");
|
||||
|
||||
addGroup("Steering");
|
||||
addField("controlMap", TypeString, Offset(mControlMap, VehicleData),
|
||||
"@brief movemap used by these types of objects.\n\n");
|
||||
addFieldV( "jetForce", TypeRangedF32, Offset(jetForce, VehicleData), &CommonValidators::PositiveFloat,
|
||||
"@brief Additional force applied to the vehicle when it is jetting.\n\n"
|
||||
"For WheeledVehicles, the force is applied in the forward direction. For "
|
||||
|
|
@ -726,6 +729,7 @@ void Vehicle::updateMove(const Move* move)
|
|||
if (mDamageState == Enabled) {
|
||||
setImageTriggerState(0,move->trigger[0]);
|
||||
setImageTriggerState(1,move->trigger[1]);
|
||||
//legacy code has trigger 2 and 3 reserved
|
||||
setImageTriggerState(2, move->trigger[4]);
|
||||
setImageTriggerState(3, move->trigger[5]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ struct VehicleData : public RigidShapeData
|
|||
F32 damageLevelTolerance[ VC_NUM_DAMAGE_LEVELS ];
|
||||
F32 numDmgEmitterAreas;
|
||||
|
||||
StringTableEntry mControlMap;
|
||||
bool enablePhysicsRep;
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -711,7 +711,7 @@ bool WheeledVehicle::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
mJetSound = SFX->createSource( mDataBlock->getWheeledVehicleSoundsProfile(WheeledVehicleData::JetSound), &getTransform() );
|
||||
}
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,10 @@ struct WheeledVehicleTire: public SimDataBlock
|
|||
void packData(BitStream* stream) override;
|
||||
void unpackData(BitStream* stream) override;
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue