Game Development Community

setActionThread() does not play certain sequences (+fix)

by Ivan Mandzhukov · in Torque 3D Professional · 08/31/2010 (9:50 am) · 0 replies

When working with the main action thread in the C++ side,all works fine.However if you try to call setActionThread() on the script side,then several problems will appear - sometimes the sequence is set,sometimes not.
When working with AIs it is good to have a scripted control over animation.

There are several problems:
- the forceSet flag is not extended to TS. When working with multiple sequences it is good in most cases to have an option to forceset a new animation,because you'll get an active control immediately and will keep this control from a second forceSet call (if there is!).

In player.h:
bool setActionThread(const char* sequence,bool hold,bool wait,bool fsp = false,bool forceSet = true);

Player.cpp
ConsoleMethod( Player, setActionThread, bool, 4, 6, "(string sequenceName, bool hold, bool fsp)")
{
   bool hold = (argc > 3)? dAtob(argv[3]): false;
   bool fsp  = (argc > 4)? dAtob(argv[4]): true;
   return object->setActionThread(argv[2],hold,false,fsp,true);
}

This is the new version of setActionThread():
bool Player::setActionThread(const char* sequence,bool hold,bool wait,bool fsp,bool forceSet)
{
   for (U32 i = 1; i < mDataBlock->actionCount; i++)
   {
      PlayerData::ActionAnimation &anim = mDataBlock->actionList[i];
      if (!dStricmp(anim.name,sequence))
      {
         setActionThread(i,true,hold,wait,fsp,forceSet);
         setMaskBits(ActionMask);
         return true;
      }
   }
   return false;
}

There is a small bug which prevents the action parameters from being updated correctly.

U32 Player::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
{
   U32 retMask = Parent::packUpdate(con, mask, stream);

   if (stream->writeFlag((mask & ImpactMask) && !(mask & InitialUpdateMask)))
      stream->writeInt(mImpactSound, PlayerData::ImpactBits);

   if (stream->writeFlag(mask & ActionMask &&
         mActionAnimation.action != PlayerData::NullAnimation &&
         mActionAnimation.action <= PlayerData::NumTableActionAnims)) {// !!!
      stream->writeInt(mActionAnimation.action,PlayerData::ActionAnimBits);
      stream->writeFlag(mActionAnimation.holdAtEnd);
      stream->writeFlag(mActionAnimation.atEnd);
      stream->writeFlag(mActionAnimation.firstPerson);
      if (!mActionAnimation.atEnd) {
         // If somewhere in middle on initial update, must send position-
         F32   where = mShapeInstance->getPos(mActionAnimation.thread);
         if (stream->writeFlag((mask & InitialUpdateMask) != 0 && where > 0))
            stream->writeSignedFloat(where, 6);
      }
   }
   .....

Now in TorqueScript this call will always work for all sequences:

%AI.setActionThread("attack", false, false, true);