mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +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
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ protected:
|
|||
public:
|
||||
enum { MaxLifetimeTicks = 4095 };
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
public:
|
||||
// variables set in datablock definition:
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ bool afxSpellBook::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
if (!mDataBlock || !Parent::onNewDataBlock(dptr, reload))
|
||||
return false;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,10 @@ public:
|
|||
|
||||
static void initPersistFields();
|
||||
|
||||
void onChangeTexture() {}
|
||||
void onChangeTexture()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
DECLARE_CONOBJECT(afxBillboardData);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -94,7 +94,10 @@ public:
|
|||
|
||||
static void initPersistFields();
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
void onSequenceChanged() {}
|
||||
|
||||
DECLARE_CONOBJECT(afxModelData);
|
||||
|
|
|
|||
|
|
@ -1064,7 +1064,7 @@ bool afxParticleEmitter::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1108,7 +1108,7 @@ bool afxParticleEmitterVector::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1177,7 +1177,7 @@ bool afxParticleEmitterCone::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1294,7 +1294,7 @@ bool afxParticleEmitterPath::onNewDataBlock(GameBaseData* dptr, bool reload)
|
|||
if (mDataBlock->isTempClone())
|
||||
return true;
|
||||
|
||||
scriptOnNewDataBlock();
|
||||
scriptOnNewDataBlock(reload);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,10 @@ public:
|
|||
|
||||
static void convertGradientRangeFromDegrees(Point2F& gradrange, const Point2F& gradrange_deg);
|
||||
|
||||
void onImageChanged() {}
|
||||
void onImageChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
public:
|
||||
DECLARE_IMAGEASSET(afxZodiacData, Texture, onImageChanged, AFX_GFXZodiacTextureProfile);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,10 @@ public:
|
|||
FACES_BITS = 3
|
||||
};
|
||||
|
||||
void onImageChanged() {}
|
||||
void onImageChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
|
||||
public:
|
||||
DECLARE_IMAGEASSET(afxZodiacPlaneData, Texture, onImageChanged, AFX_GFXZodiacTextureProfile);
|
||||
|
|
|
|||
|
|
@ -162,6 +162,69 @@ namespace PropertyInfo
|
|||
bool hex_print(String & string, const S8 & hex);
|
||||
|
||||
bool default_print(String & result, SimObjectType * const & data);
|
||||
|
||||
template<typename T, size_t count>
|
||||
char* FormatPropertyBuffer(const void* dataPtr, char* buffer, U32 bufSize)
|
||||
{
|
||||
const T* values = reinterpret_cast<const T*>(dataPtr);
|
||||
char* ptr = buffer;
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
S32 written = 0;
|
||||
|
||||
if constexpr (std::is_same_v<T, int> || std::is_same_v<T, S32>)
|
||||
written = dSprintf(ptr, bufSize - (ptr - buffer), "%d", values[i]);
|
||||
else if constexpr (std::is_same_v<T, float> || std::is_same_v<T, F32>)
|
||||
written = dSprintf(ptr, bufSize - (ptr - buffer), "%g", values[i]);
|
||||
else
|
||||
AssertFatal(sizeof(T) == 0, "Unsupported type in FormatProperty");
|
||||
|
||||
ptr += written;
|
||||
if (i < count - 1)
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
|
||||
return ptr; // return end of written string for chaining
|
||||
}
|
||||
|
||||
template<typename T, size_t count>
|
||||
const char* FormatProperty(const void* dataPtr)
|
||||
{
|
||||
static const U32 bufSize = 256;
|
||||
char* buffer = Con::getReturnBuffer(bufSize);
|
||||
FormatPropertyBuffer<T,count>(dataPtr, buffer, bufSize);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template<typename T, size_t count>
|
||||
inline bool ParseProperty(char* str, T(&out)[count])
|
||||
{
|
||||
|
||||
size_t index = 0;
|
||||
char* tok = dStrtok(str, " \t");
|
||||
|
||||
while (tok && index < count)
|
||||
{
|
||||
if constexpr (std::is_same_v<T, int> || std::is_same_v<T, S32>)
|
||||
{
|
||||
out[index++] = mRound(dAtof(tok));
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, float> || std::is_same_v<T, F32>)
|
||||
{
|
||||
out[index++] = dAtof(tok);
|
||||
}
|
||||
else
|
||||
{
|
||||
AssertFatal(sizeof(T) == 0, "Unsupported type in PropertyInfo::ParseProperty");
|
||||
}
|
||||
|
||||
tok = dStrtok(nullptr, " \t");
|
||||
}
|
||||
|
||||
return index == count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Default Scan/print definition
|
||||
|
|
|
|||
|
|
@ -425,39 +425,42 @@ void SimDataBlock::write(Stream &stream, U32 tabStop, U32 flags)
|
|||
// MARK: ---- API ----
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
DefineEngineMethod( SimDataBlock, reloadOnLocalClient, void, (),,
|
||||
"Reload the datablock. This can only be used with a local client configuration." )
|
||||
void SimDataBlock::reloadOnLocalClient()
|
||||
{
|
||||
// Make sure we're running a local client.
|
||||
|
||||
GameConnection* localClient = GameConnection::getLocalClientConnection();
|
||||
if( !localClient )
|
||||
if (!localClient)
|
||||
return;
|
||||
|
||||
// Do an in-place pack/unpack/preload.
|
||||
|
||||
if( !object->preload( true, NetConnection::getErrorBuffer() ) )
|
||||
if (!preload(true, NetConnection::getErrorBuffer()))
|
||||
{
|
||||
Con::errorf( NetConnection::getErrorBuffer() );
|
||||
Con::errorf(NetConnection::getErrorBuffer());
|
||||
return;
|
||||
}
|
||||
|
||||
U8 buffer[ 16384 ];
|
||||
BitStream stream( buffer, 16384 );
|
||||
U8 buffer[16384];
|
||||
BitStream stream(buffer, 16384);
|
||||
|
||||
object->packData( &stream );
|
||||
packData(&stream);
|
||||
stream.setPosition(0);
|
||||
object->unpackData( &stream );
|
||||
unpackData(&stream);
|
||||
|
||||
if( !object->preload( false, NetConnection::getErrorBuffer() ) )
|
||||
if (!preload(false, NetConnection::getErrorBuffer()))
|
||||
{
|
||||
Con::errorf( NetConnection::getErrorBuffer() );
|
||||
Con::errorf(NetConnection::getErrorBuffer());
|
||||
return;
|
||||
}
|
||||
|
||||
// Trigger a post-apply so that change notifications respond.
|
||||
object->inspectPostApply();
|
||||
inspectPostApply();
|
||||
}
|
||||
DefineEngineMethod( SimDataBlock, reloadOnLocalClient, void, (),,
|
||||
"Reload the datablock. This can only be used with a local client configuration." )
|
||||
{
|
||||
object->reloadOnLocalClient();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -176,6 +176,8 @@ public:
|
|||
/// Used by the console system to automatically tell datablock classes apart
|
||||
/// from non-datablock classes.
|
||||
static const bool __smIsDatablock = true;
|
||||
|
||||
void reloadOnLocalClient();
|
||||
protected:
|
||||
struct SubstitutionStatement
|
||||
{
|
||||
|
|
|
|||
|
|
@ -143,7 +143,10 @@ public:
|
|||
return theSignal;
|
||||
}
|
||||
|
||||
void onShapeChanged() {}
|
||||
void onShapeChanged()
|
||||
{
|
||||
reloadOnLocalClient();
|
||||
}
|
||||
};
|
||||
|
||||
typedef Vector<ForestItemData*> ForestItemDataVector;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "console/consoleTypes.h"
|
||||
#include "console/console.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/propertyParsing.h"
|
||||
#include "math/mPoint2.h"
|
||||
#include "math/mPoint3.h"
|
||||
#include "math/mMatrix.h"
|
||||
|
|
@ -169,21 +170,27 @@ ImplementConsoleTypeCasters( TypePoint2I, Point2I )
|
|||
|
||||
ConsoleGetType( TypePoint2I )
|
||||
{
|
||||
Point2I *pt = (Point2I *) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%d %d", pt->x, pt->y);
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<S32, 2>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypePoint2I )
|
||||
{
|
||||
if(argc == 1)
|
||||
dSscanf(argv[0], "%d %d", &((Point2I *) dptr)->x, &((Point2I *) dptr)->y);
|
||||
else if(argc == 2)
|
||||
*((Point2I *) dptr) = Point2I(dAtoi(argv[0]), dAtoi(argv[1]));
|
||||
else
|
||||
Con::printf("Point2I must be set as { x, y } or \"x y\"");
|
||||
if (argc >= 1)
|
||||
{
|
||||
S32 parsed[2];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<S32, 2>(buffer, parsed)) {
|
||||
*((Point2I*)dptr) = Point2I(parsed[0], parsed[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("Point2I must be set as { x, y } or \"x y\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -194,21 +201,27 @@ ImplementConsoleTypeCasters( TypePoint2F, Point2F )
|
|||
|
||||
ConsoleGetType( TypePoint2F )
|
||||
{
|
||||
Point2F *pt = (Point2F *) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%g %g", pt->x, pt->y);
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 2>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypePoint2F )
|
||||
{
|
||||
if(argc == 1)
|
||||
dSscanf(argv[0], "%g %g", &((Point2F *) dptr)->x, &((Point2F *) dptr)->y);
|
||||
else if(argc == 2)
|
||||
*((Point2F *) dptr) = Point2F(dAtof(argv[0]), dAtof(argv[1]));
|
||||
else
|
||||
Con::printf("Point2F must be set as { x, y } or \"x y\"");
|
||||
if (argc >= 1)
|
||||
{
|
||||
F32 parsed[2];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<F32, 2>(buffer, parsed)) {
|
||||
*((Point2F*)dptr) = Point2F(parsed[0], parsed[1]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("Point2F must be set as { x, y } or \"x y\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -219,21 +232,27 @@ ImplementConsoleTypeCasters(TypePoint3I, Point3I)
|
|||
|
||||
ConsoleGetType( TypePoint3I )
|
||||
{
|
||||
Point3I *pt = (Point3I *) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%d %d %d", pt->x, pt->y, pt->z);
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<S32, 3>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypePoint3I )
|
||||
{
|
||||
if(argc == 1)
|
||||
dSscanf(argv[0], "%d %d %d", &((Point3I *) dptr)->x, &((Point3I *) dptr)->y, &((Point3I *) dptr)->z);
|
||||
else if(argc == 3)
|
||||
*((Point3I *) dptr) = Point3I(dAtoi(argv[0]), dAtoi(argv[1]), dAtoi(argv[2]));
|
||||
else
|
||||
Con::printf("Point3I must be set as { x, y, z } or \"x y z\"");
|
||||
if (argc >= 1)
|
||||
{
|
||||
S32 parsed[3];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<S32, 3>(buffer, parsed)) {
|
||||
*((Point3I*)dptr) = Point3I(parsed[0], parsed[1], parsed[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("Point3I must be set as { x, y, z } or \"x y z\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -244,21 +263,27 @@ ImplementConsoleTypeCasters(TypePoint3F, Point3F)
|
|||
|
||||
ConsoleGetType( TypePoint3F )
|
||||
{
|
||||
Point3F *pt = (Point3F *) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g", pt->x, pt->y, pt->z);
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 3>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypePoint3F )
|
||||
{
|
||||
if(argc == 1)
|
||||
dSscanf(argv[0], "%g %g %g", &((Point3F *) dptr)->x, &((Point3F *) dptr)->y, &((Point3F *) dptr)->z);
|
||||
else if(argc == 3)
|
||||
*((Point3F *) dptr) = Point3F(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2]));
|
||||
else
|
||||
Con::printf("Point3F must be set as { x, y, z } or \"x y z\"");
|
||||
if (argc >= 1)
|
||||
{
|
||||
F32 parsed[3];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<F32, 3>(buffer, parsed)) {
|
||||
*((Point3F*)dptr) = Point3F(parsed[0], parsed[1], parsed[2]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("Point3F must be set as { x, y, z } or \"x y z\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -269,21 +294,27 @@ ImplementConsoleTypeCasters( TypePoint4F, Point4F )
|
|||
|
||||
ConsoleGetType( TypePoint4F )
|
||||
{
|
||||
Point4F *pt = (Point4F *) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g %g", pt->x, pt->y, pt->z, pt->w);
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 4>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypePoint4F )
|
||||
{
|
||||
if(argc == 1)
|
||||
dSscanf(argv[0], "%g %g %g %g", &((Point4F *) dptr)->x, &((Point4F *) dptr)->y, &((Point4F *) dptr)->z, &((Point4F *) dptr)->w);
|
||||
else if(argc == 4)
|
||||
*((Point4F *) dptr) = Point4F(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2]), dAtof(argv[3]));
|
||||
else
|
||||
Con::printf("Point4F must be set as { x, y, z, w } or \"x y z w\"");
|
||||
if (argc >= 1)
|
||||
{
|
||||
F32 parsed[4];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<F32, 4>(buffer, parsed)) {
|
||||
*((Point4F*)dptr) = Point4F(parsed[0], parsed[1], parsed[2], parsed[3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("Point4F must be set as { x, y, z, w } or \"x y z w\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -294,23 +325,27 @@ ImplementConsoleTypeCasters( TypeRectI, RectI )
|
|||
|
||||
ConsoleGetType( TypeRectI )
|
||||
{
|
||||
RectI *rect = (RectI *) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%d %d %d %d", rect->point.x, rect->point.y,
|
||||
rect->extent.x, rect->extent.y);
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<S32, 4>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeRectI )
|
||||
{
|
||||
if(argc == 1)
|
||||
dSscanf(argv[0], "%d %d %d %d", &((RectI *) dptr)->point.x, &((RectI *) dptr)->point.y,
|
||||
&((RectI *) dptr)->extent.x, &((RectI *) dptr)->extent.y);
|
||||
else if(argc == 4)
|
||||
*((RectI *) dptr) = RectI(dAtoi(argv[0]), dAtoi(argv[1]), dAtoi(argv[2]), dAtoi(argv[3]));
|
||||
else
|
||||
Con::printf("RectI must be set as { x, y, w, h } or \"x y w h\"");
|
||||
if (argc >= 1)
|
||||
{
|
||||
S32 parsed[4];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<S32, 4>(buffer, parsed)) {
|
||||
*((RectI*)dptr) = RectI(parsed[0], parsed[1], parsed[2], parsed[3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("RectI must be set as { x, y, w, h } or \"x y w h\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -321,23 +356,27 @@ ImplementConsoleTypeCasters( TypeRectF, RectF )
|
|||
|
||||
ConsoleGetType( TypeRectF )
|
||||
{
|
||||
RectF *rect = (RectF *) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g %g", rect->point.x, rect->point.y,
|
||||
rect->extent.x, rect->extent.y);
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 4>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeRectF )
|
||||
{
|
||||
if(argc == 1)
|
||||
dSscanf(argv[0], "%g %g %g %g", &((RectF *) dptr)->point.x, &((RectF *) dptr)->point.y,
|
||||
&((RectF *) dptr)->extent.x, &((RectF *) dptr)->extent.y);
|
||||
else if(argc == 4)
|
||||
*((RectF *) dptr) = RectF(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2]), dAtof(argv[3]));
|
||||
else
|
||||
Con::printf("RectF must be set as { x, y, w, h } or \"x y w h\"");
|
||||
if (argc >= 1)
|
||||
{
|
||||
F32 parsed[4];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<F32, 4>(buffer, parsed)) {
|
||||
*((RectF*)dptr) = RectF(parsed[0], parsed[1], parsed[2], parsed[3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("RectF must be set as { x, y, w, h } or \"x y w h\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -351,36 +390,44 @@ ImplementConsoleTypeCasters( TypeMatrixF, MatrixF )
|
|||
|
||||
ConsoleGetType( TypeMatrixF )
|
||||
{
|
||||
MatrixF* mat = ( MatrixF* ) dptr;
|
||||
MatrixF* mat = (MatrixF*)dptr;
|
||||
|
||||
Point3F col0, col1, col2;
|
||||
mat->getColumn(0, &col0);
|
||||
mat->getColumn(1, &col1);
|
||||
mat->getColumn(2, &col2);
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer,bufSize,"%g %g %g %g %g %g %g %g %g",
|
||||
col0.x, col0.y, col0.z, col1.x, col1.y, col1.z, col2.x, col2.y, col2.z);
|
||||
return returnBuffer;
|
||||
char* buffer = Con::getReturnBuffer(bufSize);
|
||||
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 3>(col0, buffer, bufSize);
|
||||
*buffer++ = ' ';
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 3>(col1, buffer, bufSize);
|
||||
*buffer++ = ' ';
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 3>(col2, buffer, bufSize);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeMatrixF )
|
||||
{
|
||||
if( argc != 1 )
|
||||
if (argc == 1)
|
||||
{
|
||||
Con::errorf( "MatrixF must be set as \"c0x c0y c0z c1x c1y c1z c2x c2y c2z\"" );
|
||||
return;
|
||||
}
|
||||
|
||||
Point3F col0, col1, col2;
|
||||
dSscanf( argv[ 0 ], "%g %g %g %g %g %g %g %g %g",
|
||||
&col0.x, &col0.y, &col0.z, &col1.x, &col1.y, &col1.z, &col2.x, &col2.y, &col2.z );
|
||||
F32 parsed[9];
|
||||
|
||||
MatrixF* mat = ( MatrixF* ) dptr;
|
||||
|
||||
mat->setColumn( 0, col0 );
|
||||
mat->setColumn( 1, col1 );
|
||||
mat->setColumn( 2, col2 );
|
||||
char* buffer = new char[dStrlen(argv[0])];
|
||||
dStrcpy(buffer, argv[0], sizeof(buffer));
|
||||
|
||||
if (PropertyInfo::ParseProperty<F32, 9>(buffer, parsed)) {
|
||||
MatrixF* mat = (MatrixF*)dptr;
|
||||
|
||||
mat->setColumn(0, Point3F(parsed[0], parsed[1], parsed[2]));
|
||||
mat->setColumn(1, Point3F(parsed[3], parsed[4], parsed[5]));
|
||||
mat->setColumn(2, Point3F(parsed[6], parsed[7], parsed[8]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("MatrixF must be set as \"c0x c0y c0z c1x c1y c1z c2x c2y c2z\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -390,32 +437,40 @@ ConsoleMappedType(MatrixPosition, TypeMatrixPosition, Point3F, MatrixF, "")
|
|||
|
||||
ConsoleGetType( TypeMatrixPosition )
|
||||
{
|
||||
F32 *col = (F32 *) dptr + 3;
|
||||
F32* col = (F32*)dptr + 3;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
if(col[12] == 1.f)
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g", col[0], col[4], col[8]);
|
||||
Point4F pos(col[0], col[4], col[8], col[12]);
|
||||
|
||||
if (col[12] == 1.0f)
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 3>(&pos, returnBuffer, bufSize);
|
||||
else
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g %g", col[0], col[4], col[8], col[12]);
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 4>(&pos, returnBuffer, bufSize);
|
||||
|
||||
return returnBuffer;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeMatrixPosition )
|
||||
{
|
||||
F32 *col = ((F32 *) dptr) + 3;
|
||||
if (argc == 1)
|
||||
if (argc >= 1)
|
||||
{
|
||||
col[0] = col[4] = col[8] = 0.f;
|
||||
col[12] = 1.f;
|
||||
dSscanf(argv[0], "%g %g %g %g", &col[0], &col[4], &col[8], &col[12]);
|
||||
F32 parsed[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
// we dont want to hard fail based on the count.
|
||||
// this will allow any number of properties to be set.
|
||||
PropertyInfo::ParseProperty<F32, 4>(buffer, parsed);
|
||||
{
|
||||
Point4F temp(parsed[0], parsed[1], parsed[2], parsed[3]);
|
||||
MatrixF* mat = (MatrixF*)dptr;
|
||||
mat->setColumn(3, temp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (argc <= 4)
|
||||
{
|
||||
for (S32 i = 0; i < argc; i++)
|
||||
col[i << 2] = dAtof(argv[i]);
|
||||
}
|
||||
else
|
||||
Con::printf("Matrix position must be set as { x, y, z, w } or \"x y z w\"");
|
||||
|
||||
Con::warnf("Matrix position must be set as { x, y, z, w } or \"x y z w\"");
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -425,42 +480,38 @@ ConsoleMappedType(MatrixRotation, TypeMatrixRotation, AngAxisF, MatrixF, "")
|
|||
|
||||
ConsoleGetType( TypeMatrixRotation )
|
||||
{
|
||||
AngAxisF aa(*(MatrixF *) dptr);
|
||||
AngAxisF aa(*(MatrixF*)dptr);
|
||||
aa.axis.normalize();
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer,bufSize,"%g %g %g %g",aa.axis.x,aa.axis.y,aa.axis.z,mRadToDeg(aa.angle));
|
||||
return returnBuffer;
|
||||
aa.angle = mRadToDeg(aa.angle);
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 4>(&aa);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeMatrixRotation )
|
||||
{
|
||||
// DMM: Note that this will ONLY SET the ULeft 3x3 submatrix.
|
||||
//
|
||||
AngAxisF aa(Point3F(0,0,0),0);
|
||||
if (argc == 1)
|
||||
if (argc >= 1)
|
||||
{
|
||||
dSscanf(argv[0], "%g %g %g %g", &aa.axis.x, &aa.axis.y, &aa.axis.z, &aa.angle);
|
||||
aa.angle = mDegToRad(aa.angle);
|
||||
}
|
||||
else if (argc == 4)
|
||||
{
|
||||
for (S32 i = 0; i < argc; i++)
|
||||
((F32*)&aa)[i] = dAtof(argv[i]);
|
||||
aa.angle = mDegToRad(aa.angle);
|
||||
}
|
||||
else
|
||||
Con::printf("Matrix rotation must be set as { x, y, z, angle } or \"x y z angle\"");
|
||||
F32 parsed[4];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
//
|
||||
MatrixF temp;
|
||||
aa.setMatrix(&temp);
|
||||
if (PropertyInfo::ParseProperty<F32, 4>(buffer, parsed))
|
||||
{
|
||||
AngAxisF aa(Point3F(parsed[0], parsed[1], parsed[2]), mDegToRad(parsed[3]));
|
||||
MatrixF temp;
|
||||
aa.setMatrix(&temp);
|
||||
|
||||
F32* pDst = *(MatrixF *)dptr;
|
||||
const F32* pSrc = temp;
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
pDst[i*4 + j] = pSrc[i*4 + j];
|
||||
F32* pDst = *(MatrixF*)dptr;
|
||||
const F32* pSrc = temp;
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
for (U32 j = 0; j < 3; j++)
|
||||
pDst[i * 4 + j] = pSrc[i * 4 + j];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("Matrix rotation must be set as { x, y, z, angle } or \"x y z angle\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -472,30 +523,29 @@ ImplementConsoleTypeCasters( TypeAngAxisF, AngAxisF )
|
|||
ConsoleGetType( TypeAngAxisF )
|
||||
{
|
||||
AngAxisF* aa = ( AngAxisF* ) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer,bufSize,"%g %g %g %g",aa->axis.x,aa->axis.y,aa->axis.z,mRadToDeg(aa->angle));
|
||||
return returnBuffer;
|
||||
aa->angle = mRadToDeg(aa->angle);
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 4>(aa);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeAngAxisF )
|
||||
{
|
||||
// DMM: Note that this will ONLY SET the ULeft 3x3 submatrix.
|
||||
//
|
||||
AngAxisF* aa = ( AngAxisF* ) dptr;
|
||||
if (argc == 1)
|
||||
if (argc >= 1)
|
||||
{
|
||||
dSscanf(argv[0], "%g %g %g %g", &aa->axis.x, &aa->axis.y, &aa->axis.z, &aa->angle);
|
||||
aa->angle = mDegToRad(aa->angle);
|
||||
F32 parsed[4];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if(PropertyInfo::ParseProperty<F32, 4>(buffer, parsed))
|
||||
{
|
||||
AngAxisF* aa = (AngAxisF*)dptr;
|
||||
aa->set(Point3F(parsed[0], parsed[1], parsed[2]), mDegToRad(parsed[3]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (argc == 4)
|
||||
{
|
||||
for (S32 i = 0; i < argc; i++)
|
||||
((F32*)&aa)[i] = dAtof(argv[i]);
|
||||
aa->angle = mDegToRad(aa->angle);
|
||||
}
|
||||
else
|
||||
Con::printf("AngAxisF must be set as { x, y, z, angle } or \"x y z angle\"");
|
||||
|
||||
Con::warnf("AngAxisF must be set as { x, y, z, angle } or \"x y z angle\"");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -510,38 +560,35 @@ ImplementConsoleTypeCasters( TypeTransformF, TransformF )
|
|||
|
||||
ConsoleGetType( TypeTransformF )
|
||||
{
|
||||
TransformF* aa = ( TransformF* ) dptr;
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf( returnBuffer, bufSize, "%g %g %g %g %g %g %g",
|
||||
aa->mPosition.x, aa->mPosition.y, aa->mPosition.z,
|
||||
aa->mOrientation.axis.x, aa->mOrientation.axis.y, aa->mOrientation.axis.z, aa->mOrientation.angle );
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 7>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeTransformF )
|
||||
{
|
||||
TransformF* aa = ( TransformF* ) dptr;
|
||||
if( argc == 1 )
|
||||
if(argc >= 1)
|
||||
{
|
||||
U32 count = dSscanf( argv[ 0 ], "%g %g %g %g %g %g %g",
|
||||
&aa->mPosition.x, &aa->mPosition.y, &aa->mPosition.z,
|
||||
&aa->mOrientation.axis.x, &aa->mOrientation.axis.y, &aa->mOrientation.axis.z, &aa->mOrientation.angle );
|
||||
F32 parsed[7];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
aa->mHasRotation = ( count == 7 );
|
||||
if (PropertyInfo::ParseProperty<F32, 7>(buffer, parsed))
|
||||
{
|
||||
TransformF* aa = (TransformF*)dptr;
|
||||
aa->mPosition.x = parsed[0];
|
||||
aa->mPosition.y = parsed[1];
|
||||
aa->mPosition.z = parsed[2];
|
||||
aa->mOrientation.axis.x = parsed[3];
|
||||
aa->mOrientation.axis.y = parsed[4];
|
||||
aa->mOrientation.axis.z = parsed[5];
|
||||
aa->mOrientation.angle = parsed[6];
|
||||
aa->mHasRotation = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( argc == 7 )
|
||||
{
|
||||
aa->mPosition.x = dAtof( argv[ 0 ] );
|
||||
aa->mPosition.y = dAtof( argv[ 1 ] );
|
||||
aa->mPosition.z = dAtof( argv[ 2 ] );
|
||||
aa->mOrientation.axis.x = dAtof( argv[ 3 ] );
|
||||
aa->mOrientation.axis.y = dAtof( argv[ 4 ] );
|
||||
aa->mOrientation.axis.z = dAtof( argv[ 5 ] );
|
||||
aa->mOrientation.angle = dAtof( argv[ 6 ] );
|
||||
}
|
||||
else
|
||||
Con::errorf( "TransformF must be set as { px, py, pz, x, y, z, angle } or \"px py pz x y z angle\"");
|
||||
|
||||
Con::warnf("TransformF must be set as { px, py, pz, x, y, z, angle } or \"px py pz x y z angle\"");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -554,32 +601,33 @@ ImplementConsoleTypeCasters( TypeBox3F, Box3F )
|
|||
|
||||
ConsoleGetType( TypeBox3F )
|
||||
{
|
||||
const Box3F* pBox = (const Box3F*)dptr;
|
||||
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g %g %g %g",
|
||||
pBox->minExtents.x, pBox->minExtents.y, pBox->minExtents.z,
|
||||
pBox->maxExtents.x, pBox->maxExtents.y, pBox->maxExtents.z);
|
||||
|
||||
return returnBuffer;
|
||||
const char* buff = PropertyInfo::FormatProperty<F32, 6>(dptr);
|
||||
return buff;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeBox3F )
|
||||
{
|
||||
Box3F* pDst = (Box3F*)dptr;
|
||||
if (argc >= 1)
|
||||
{
|
||||
F32 parsed[6];
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
U32 args = dSscanf(argv[0], "%g %g %g %g %g %g",
|
||||
&pDst->minExtents.x, &pDst->minExtents.y, &pDst->minExtents.z,
|
||||
&pDst->maxExtents.x, &pDst->maxExtents.y, &pDst->maxExtents.z);
|
||||
AssertWarn(args == 6, "Warning, box probably not read properly");
|
||||
}
|
||||
else
|
||||
{
|
||||
Con::printf("Box3F must be set as \"xMin yMin zMin xMax yMax zMax\"");
|
||||
if (PropertyInfo::ParseProperty<F32, 6>(buffer, parsed))
|
||||
{
|
||||
Box3F* pDst = (Box3F*)dptr;
|
||||
pDst->minExtents.x = parsed[0];
|
||||
pDst->minExtents.y = parsed[1];
|
||||
pDst->minExtents.z = parsed[2];
|
||||
pDst->maxExtents.x = parsed[3];
|
||||
pDst->maxExtents.y = parsed[4];
|
||||
pDst->maxExtents.z = parsed[5];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("Box3F must be set as \"xMin yMin zMin xMax yMax zMax\"");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -591,31 +639,39 @@ ImplementConsoleTypeCasters( TypeEaseF, EaseF )
|
|||
|
||||
ConsoleGetType( TypeEaseF )
|
||||
{
|
||||
const EaseF* pEase = (const EaseF*)dptr;
|
||||
|
||||
static const U32 bufSize = 256;
|
||||
char* returnBuffer = Con::getReturnBuffer(bufSize);
|
||||
dSprintf(returnBuffer, bufSize, "%d %d %g %g",
|
||||
pEase->mDir, pEase->mType, pEase->mParam[0], pEase->mParam[1]);
|
||||
char* buffer = Con::getReturnBuffer(bufSize);
|
||||
|
||||
return returnBuffer;
|
||||
EaseF* pEase = (EaseF*)dptr;
|
||||
PropertyInfo::FormatPropertyBuffer<S32, 2>(pEase + 0, buffer, bufSize);
|
||||
*buffer++ = ' ';
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 2>(pEase + 2, buffer, bufSize);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ConsoleSetType( TypeEaseF )
|
||||
{
|
||||
EaseF* pDst = (EaseF*)dptr;
|
||||
if (argc >= 1)
|
||||
{
|
||||
F32 parsed[4];
|
||||
parsed[2] = -1.0f;
|
||||
parsed[3] = -1.0f;
|
||||
|
||||
// defaults...
|
||||
pDst->mParam[0] = -1.0f;
|
||||
pDst->mParam[1] = -1.0f;
|
||||
if (argc == 1) {
|
||||
U32 args = dSscanf(argv[0], "%d %d %f %f", // the two params are optional and assumed -1 if not present...
|
||||
&pDst->mDir, &pDst->mType, &pDst->mParam[0],&pDst->mParam[1]);
|
||||
if( args < 2 )
|
||||
Con::warnf( "Warning, EaseF probably not read properly" );
|
||||
} else {
|
||||
Con::printf("EaseF must be set as \"dir type [param0 param1]\"");
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
// same as matrix do not hard fail based on count!
|
||||
PropertyInfo::ParseProperty<F32, 4>(buffer, parsed);
|
||||
{
|
||||
((EaseF*)dptr)->set(mRound(parsed[0]), mRound(parsed[1]), parsed[2], parsed[3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Con::warnf("EaseF must be set as \"dir type [param0 param1]\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -633,12 +689,12 @@ ConsoleGetType(TypeRotationF)
|
|||
if (pt->mRotationType == RotationF::Euler)
|
||||
{
|
||||
EulerF out = pt->asEulerF(RotationF::Degrees);
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g", out.x, out.y, out.z);
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 3>(out, returnBuffer, bufSize);
|
||||
}
|
||||
else if (pt->mRotationType == RotationF::AxisAngle)
|
||||
{
|
||||
AngAxisF out = pt->asAxisAngle(RotationF::Degrees);
|
||||
dSprintf(returnBuffer, bufSize, "%g %g %g %g", out.axis.x, out.axis.y, out.axis.z, out.angle);
|
||||
PropertyInfo::FormatPropertyBuffer<F32, 4>(&out, returnBuffer, bufSize);
|
||||
}
|
||||
|
||||
return returnBuffer;
|
||||
|
|
@ -646,34 +702,36 @@ ConsoleGetType(TypeRotationF)
|
|||
|
||||
ConsoleSetType(TypeRotationF)
|
||||
{
|
||||
if (argc == 1)
|
||||
if (argc >= 1)
|
||||
{
|
||||
U32 elements = StringUnit::getUnitCount(argv[0], " \t\n");
|
||||
// Combine argv into a single space-separated string if argc > 1
|
||||
char buffer[256] = { 0 };
|
||||
dStrncpy(buffer, *argv, sizeof(buffer));
|
||||
|
||||
U32 elements = StringUnit::getUnitCount(buffer, " \t\n");
|
||||
if (elements == 3)
|
||||
{
|
||||
EulerF in;
|
||||
dSscanf(argv[0], "%g %g %g", &in.x, &in.y, &in.z);
|
||||
((RotationF *)dptr)->set(in, RotationF::Degrees);
|
||||
F32 parsed[3];
|
||||
if(PropertyInfo::ParseProperty<F32, 3>(buffer, parsed))
|
||||
{
|
||||
EulerF in(parsed[0], parsed[1], parsed[2]);
|
||||
((RotationF*)dptr)->set(in, RotationF::Degrees);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (elements == 4)
|
||||
{
|
||||
AngAxisF in;
|
||||
dSscanf(argv[0], "%g %g %g %g", &in.axis.x, &in.axis.y, &in.axis.z, &in.angle);
|
||||
((RotationF *)dptr)->set(in, RotationF::Degrees);
|
||||
F32 parsed[4];
|
||||
if (PropertyInfo::ParseProperty<F32, 4>(buffer, parsed))
|
||||
{
|
||||
AngAxisF in(Point3F(parsed[0], parsed[1], parsed[2]), parsed[3]);
|
||||
((RotationF*)dptr)->set(in, RotationF::Degrees);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (argc == 3)
|
||||
{
|
||||
EulerF in(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2]));
|
||||
((RotationF *)dptr)->set(in, RotationF::Degrees);
|
||||
}
|
||||
else if (argc == 4)
|
||||
{
|
||||
AngAxisF in(Point3F(dAtof(argv[0]), dAtof(argv[1]), dAtof(argv[2])), dAtof(argv[3]));
|
||||
((RotationF *)dptr)->set(in, RotationF::Degrees);
|
||||
}
|
||||
else
|
||||
Con::printf("RotationF must be set as { x, y, z, w } or \"x y z w\"");
|
||||
|
||||
Con::warnf("RotationF must be set as { x, y, z, w } or \"x y z w\"");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -111,8 +111,12 @@ function handleConnectionErrorMessage(%msgType, %msgString, %msgError)
|
|||
//-----------------------------------------------------------------------------
|
||||
// Disconnect
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function disconnect()
|
||||
{
|
||||
callOnModules("disconnect");
|
||||
}
|
||||
|
||||
function Core_ClientServer::disconnect(%this)
|
||||
{
|
||||
// We need to stop the client side simulation
|
||||
// else physics resources will not cleanup properly.
|
||||
|
|
@ -158,3 +162,16 @@ function disconnectedCleanup()
|
|||
|
||||
moduleExec("onDestroyClientConnection", "Game");
|
||||
}
|
||||
|
||||
function clientCmdsetMoveMap(%movemap)
|
||||
{
|
||||
if (!isObject(%movemap)) return;
|
||||
if(isObject(ServerConnection) && isObject(ServerConnection.curMoveMap))
|
||||
ServerConnection.curMoveMap.pop();
|
||||
|
||||
// clear movement
|
||||
$mvForwardAction = 0;
|
||||
$mvBackwardAction = 0;
|
||||
%movemap.push();
|
||||
ServerConnection.curMoveMap = %movemap;
|
||||
}
|
||||
|
|
@ -275,7 +275,9 @@ function GameConnection::onPostSpawn( %this )
|
|||
if (%this.numModsNeedingLoaded)
|
||||
callOnObjectList("onPostSpawn", %modulesIdList, %this);
|
||||
else
|
||||
%this.listener.onPostSpawnComplete(%this);
|
||||
%this.listener.onPostSpawnComplete(%this);
|
||||
if (isObject(%this.player.getDatablock().controlMap))
|
||||
commandToClient(%this, 'setMoveMap', %this.player.getDatablock().controlMap);
|
||||
}
|
||||
|
||||
function GameConnectionListener::onPostSpawnComplete(%this, %client)
|
||||
|
|
|
|||
|
|
@ -78,17 +78,15 @@ function spawnGameObject(%name, %addToScene)
|
|||
return 0;
|
||||
}
|
||||
|
||||
function GameBaseData::onNewDataBlock(%this, %obj)
|
||||
function GameBaseData::onNewDataBlock(%this, %obj, %reload)
|
||||
{
|
||||
if (%obj.firstDataCheck)
|
||||
if (%reload)
|
||||
{
|
||||
if(%this.isMethod("onRemove"))
|
||||
%this.onRemove(%obj);
|
||||
if(%this.isMethod("onAdd"))
|
||||
%this.onAdd(%obj);
|
||||
}
|
||||
else
|
||||
%obj.firstDataCheck = true;
|
||||
}
|
||||
|
||||
function saveGameObject(%name, %tamlPath, %scriptPath)
|
||||
|
|
|
|||
|
|
@ -23,4 +23,13 @@ function ToolsModule::onCreate(%this)
|
|||
function ToolsModule::onDestroy(%this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function ToolsModule::disconnect(%this)
|
||||
{
|
||||
if ( isObject( Editor ) && Editor.isEditorEnabled() )
|
||||
{
|
||||
EditorGui.saveAs = false; //whatever edits we were doing are irrelevent now
|
||||
Editor.close(MainMenuGui);
|
||||
}
|
||||
}
|
||||
|
|
@ -164,40 +164,3 @@ function toggleEditor(%make)
|
|||
//------------------------------------------------------------------------------
|
||||
// The editor action maps are defined in editor.bind.tscript
|
||||
GlobalActionMap.bind(keyboard, "f11", fastLoadWorldEdit);
|
||||
|
||||
|
||||
// The scenario:
|
||||
// The editor is open and the user closes the level by any way other than
|
||||
// the file menu ( exit level ), eg. typing disconnect() in the console.
|
||||
//
|
||||
// The problem:
|
||||
// Editor::close() is not called in this scenario which means onEditorDisable
|
||||
// is not called on objects which hook into it and also gEditingMission will no
|
||||
// longer be valid.
|
||||
//
|
||||
// The solution:
|
||||
// Override the stock disconnect() function which is in game scripts from here
|
||||
// in tools so we avoid putting our code in there.
|
||||
//
|
||||
// Disclaimer:
|
||||
// If you think of a better way to do this feel free. The thing which could
|
||||
// be dangerous about this is that no one will ever realize this code overriding
|
||||
// a fairly standard and core game script from a somewhat random location.
|
||||
// If it 'did' have unforscene sideeffects who would ever find it?
|
||||
|
||||
package EditorDisconnectOverride
|
||||
{
|
||||
function disconnect()
|
||||
{
|
||||
if ( isObject( Editor ) && Editor.isEditorEnabled() )
|
||||
{
|
||||
EditorGui.saveAs = false; //whatever edits we were doing are irrelevent now
|
||||
%mainMenuGUI = ProjectSettings.value("UI/mainMenuName");
|
||||
if (isObject( %mainMenuGUI ))
|
||||
Editor.close( %mainMenuGUI );
|
||||
}
|
||||
|
||||
Parent::disconnect();
|
||||
}
|
||||
};
|
||||
activatePackage( EditorDisconnectOverride );
|
||||
|
|
|
|||
Loading…
Reference in a new issue