Game Development Community

dev|Pro Game Development Curriculum

fxShapeReplicator: Up to 16 random shapes

by Ben Sparks - Warspawn · 07/03/2006 (11:36 am) · 8 comments

First, some minor changes to fxShapeReplicator.h:

// Field Data.
   class tagFieldData
   {
      public:

      U32                mSeed;
      //BS: changed to array of shapes
      StringTableEntry   mShapeFile[16];
      //END
      U32                mShapeCount;
Then a little further down in the defaults...
tagFieldData()
      {
         // Set Defaults.
         mSeed               = 1376312589;
         //BS: set default for each shape
         for(int i=0;i<16;i++)
        {
             mShapeFile[i]          = NULL;
        }
         //END
         mShapeCount         = 10;

Next, fxShapeReplicator.cc:

...in void fxShapeReplicator::initPersistFields()
addGroup( "Media" );
	addField( "ShapeFile1",          TypeFilename,   Offset( mFieldData.mShapeFile[0],              fxShapeReplicator ) );
	addField( "ShapeFile2",          TypeFilename,   Offset( mFieldData.mShapeFile[1],              fxShapeReplicator ) );
	addField( "ShapeFile3",          TypeFilename,   Offset( mFieldData.mShapeFile[2],              fxShapeReplicator ) );
	addField( "ShapeFile4",          TypeFilename,   Offset( mFieldData.mShapeFile[3],              fxShapeReplicator ) );
	addField( "ShapeFile5",          TypeFilename,   Offset( mFieldData.mShapeFile[4],              fxShapeReplicator ) );
	addField( "ShapeFile6",          TypeFilename,   Offset( mFieldData.mShapeFile[5],              fxShapeReplicator ) );
	addField( "ShapeFile7",          TypeFilename,   Offset( mFieldData.mShapeFile[6],              fxShapeReplicator ) );
	addField( "ShapeFile8",          TypeFilename,   Offset( mFieldData.mShapeFile[7],              fxShapeReplicator ) );
	addField( "ShapeFile9",          TypeFilename,   Offset( mFieldData.mShapeFile[8],              fxShapeReplicator ) );
	addField( "ShapeFile10",          TypeFilename,   Offset( mFieldData.mShapeFile[9],              fxShapeReplicator ) );
	addField( "ShapeFile11",          TypeFilename,   Offset( mFieldData.mShapeFile[10],              fxShapeReplicator ) );
	addField( "ShapeFile12",          TypeFilename,   Offset( mFieldData.mShapeFile[11],              fxShapeReplicator ) );
	addField( "ShapeFile13",          TypeFilename,   Offset( mFieldData.mShapeFile[12],              fxShapeReplicator ) );
	addField( "ShapeFile14",          TypeFilename,   Offset( mFieldData.mShapeFile[13],              fxShapeReplicator ) );
	addField( "ShapeFile15",          TypeFilename,   Offset( mFieldData.mShapeFile[14],              fxShapeReplicator ) );
	addField( "ShapeFile16",          TypeFilename,   Offset( mFieldData.mShapeFile[15],              fxShapeReplicator ) );
    endGroup( "Media" );
further down...
void fxShapeReplicator::CreateShapes(void)
{
    F32             HypX, HypY;
    F32             Angle;
    U32             RelocationRetry;
    Point3F         ShapePosition;
    Point3F         ShapeStart;
    Point3F         ShapeEnd;
    Point3F         ShapeScale;
    EulerF          ShapeRotation;
    QuatF           QRotation;
    bool            CollisionResult;
    RayInfo         RayEvent;
    TSShape*        pShape;
    Container*      pContainer;
    //BS: add variable for random selection
    S32	           pickIndex = 0;
    //END
little further down...
// Cannot continue without shapes!
if (mFieldData.mShapeFile[0] == NULL) return;
down a bit more...
// Check that we have a shape...
if (!mFieldData.mShapeFile[0]) return;
further down in the for loop...
//BS: pick a random shape index
		RandomGen.setSeed(RandomGen.randI(0,mFieldData.mSeed));
		pickIndex = RandomGen.randI(0,15);

        // Set the 'shapeName' field.
        fxStatic->setField("shapeName", mFieldData.mShapeFile[pickIndex]);
        //END

        // Is this Replicator on the Server?
        if (isServerObject())
            // Yes, so stop it from Ghosting. (Hack, Hack, Hack!)
            fxStatic->touchNetFlags(Ghostable, false);
        else
            // No, so flag as ghost object. (Another damn Hack!)
            fxStatic->touchNetFlags(IsGhost, true);

        // Register the Object.
        if (!fxStatic->registerObject())
        {
            // Problem ... BS: changed log output...
            Con::warnf(ConsoleLogEntry::General, "[%s] - Could not load shape file[%d] '%s'!", getName(),pickIndex, mFieldData.mShapeFile[pickIndex]);

            // Destroy Shape.
            delete fxStatic;

            // Destroy existing shapes.
            DestroyShapes();

            // Quit.
            return;
        }
and further down still...
// Set New Position.
            ShapePosition = RayEvent.point;
        }
        else
        {
            // Warning.
            Con::warnf(ConsoleLogEntry::General, "[%s] - Could not find satisfactory position for shape '%s' on %s!", getName(), mFieldData.mShapeFile[pickIndex],isServerObject()?"Server":"Client");

            // Unregister Object.
            fxStatic->unregisterObject();

            // Destroy Shape.
            delete fxStatic;
and down in renewshapes
void fxShapeReplicator::RenewShapes(void)
{
	// Cannot continue without shapes!
	for(int i=0;i<16;i++)
	{
		if(mFieldData.mShapeFile[i] == NULL)
		{
			mFieldData.mShapeFile[i] = mFieldData.mShapeFile[0];
		}
	}
then down in packupdate..
U32 fxShapeReplicator::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
{
    // Pack Parent.
    U32 retMask = Parent::packUpdate(con, mask, stream);
	
    // Write Replication Flag.
    if (stream->writeFlag(mask & ReplicationMask))
    {
        stream->writeAffineTransform(mObjToWorld);                      // Replicator Position.

        stream->writeInt(mFieldData.mSeed, 32);                         // Replicator Seed.
        stream->writeInt(mFieldData.mShapeCount, 32);                   // Shapes Count.
        stream->writeInt(mFieldData.mShapeRetries, 32);                 // Shapes Retries.
		//BS: changed to array
		for(int i=0;i<16;i++)
		{
			stream->writeString(mFieldData.mShapeFile[i]);
		}
		//END
and down in unpack..
void fxShapeReplicator::unpackUpdate(NetConnection * con, BitStream * stream)
{
    // Unpack Parent.
    Parent::unpackUpdate(con, stream);
	
    // Read Replication Details.
    if(stream->readFlag())
    {
        MatrixF     ReplicatorObjectMatrix;

        stream->readAffineTransform(&ReplicatorObjectMatrix);               // Replication Position.

        mFieldData.mSeed                    = stream->readInt(32);          // Replicator Seed.
        mFieldData.mShapeCount              = stream->readInt(32);          // Shapes Count.
        mFieldData.mShapeRetries            = stream->readInt(32);          // Shapes Retries.
		//BS: changed to array
		for(int i=0;i<16;i++)
		{
			mFieldData.mShapeFile[i]               = stream->readSTString();       // Shape File.
		}
		//END

That's it.. compile and now you can have 16 different shapes, trees, rocks, etc...

#1
07/03/2006 (11:59 am)
Awesome! Great Job!
#2
07/03/2006 (8:17 pm)
Nice work. Boy, I wish these resources allowed bigger pictures!
#3
07/08/2006 (6:38 pm)
Totally cool, I had this installed and running in about 30 minutes.
Great Job!!

-Surge
#4
07/08/2006 (6:50 pm)
Im no programmer , and your code works great BTW,but I was wondering

Should
mShapeCount = 10;

Be set to
mShapeCount = 16;

or is that not needed because of the array?
#5
07/21/2006 (10:11 am)
void fxShapeReplicator::RenewShapes(void) is different in TLK 1.4. What line am to replace or do I add this? I have about fourteen error right now.

Fix, I forgot something.
#6
08/21/2006 (1:38 am)
Thanx for sharing
#7
11/10/2006 (10:29 pm)
very nice.
#8
03/26/2007 (2:50 pm)
Any plan from GG to merge this into head?