/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ ///////////////////////////////////////////////////////////////////////////// // // NAME: cyAnimation // // PURPOSE: Class wrapper to map animation functions to plasma2 message // #include "plgDispatch.h" #include "../plMessage/plAnimCmdMsg.h" #include "../pnMessage/plEventCallbackMsg.h" #include "cyAnimation.h" cyAnimation::cyAnimation() { fSender = nil; fAnimName = nil; fNetForce = false; } cyAnimation::cyAnimation(pyKey& sender) { SetSender(sender); fAnimName = nil; fNetForce = false; } // copy constructor cyAnimation::cyAnimation(const cyAnimation& anim) { fSender = anim.fSender; fRecvr = anim.fRecvr; // here is why we needed the copy constructor fAnimName = hsStrcpy(anim.fAnimName); // make our own copy of this string fNetForce = anim.fNetForce; } // clean up on the way out cyAnimation::~cyAnimation() { if (fAnimName != nil ) { delete [] fAnimName; fAnimName = nil; } } // setters void cyAnimation::SetSender(pyKey& sender) { fSender = sender.getKey(); } void cyAnimation::AddRecvr(pyKey& recvr) { fRecvr.Append(recvr.getKey()); } PyObject* cyAnimation::GetFirstRecvr() { if ( fRecvr.Count() > 0 ) return pyKey::New(fRecvr[0]); return nil; } void cyAnimation::SetAnimName(const char* name) { if ( fAnimName != nil ) delete [] fAnimName; fAnimName = hsStrcpy(name); } void cyAnimation::SetNetForce(hsBool state) { // set our flag fNetForce = state; } ///////////////////////////////////////////////////////////////////////////// // // Function : Play // PARAMETERS : // // PURPOSE : Play animation from start to end (whatever is already set) // void cyAnimation::Play() { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); // NOTE: The animation modifier will set the animation back to the starting point automatically // then continue from there pMsg->SetCmd(plAnimCmdMsg::kGoToBegin); pMsg->SetCmd(plAnimCmdMsg::kContinue); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : Stop // PARAMETERS : // // PURPOSE : Stop an animation // void cyAnimation::Stop() { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kStop); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : Resume // PARAMETERS : // // PURPOSE : Continue playing animation from wherever it last stopped // void cyAnimation::Resume() { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kContinue); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : PlayRange // PARAMETERS : start - start time for the range // : end - end time of the range // // PURPOSE : Play an animation only from specific time start to end // void cyAnimation::PlayRange(hsScalar start, hsScalar end) { SkipToTime(start); PlayToTime(end); } ///////////////////////////////////////////////////////////////////////////// // // Function : PlayToTime // PARAMETERS : time - where to stop playing animation // // PURPOSE : Play (continue) an animation until the specified time is reached // void cyAnimation::PlayToTime(hsScalar time) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kPlayToTime); pMsg->fTime = time; plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : PlayToPercentage // PARAMETERS : zeroToOne - How far (scale of 0 to 1) to play into the anim // // PURPOSE : Play (continue) an animation until the specified point is reached // void cyAnimation::PlayToPercentage(hsScalar zeroToOne) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kPlayToPercentage); pMsg->fTime = zeroToOne; plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : SkipToTime // PARAMETERS : // // PURPOSE : Jump the animation to the specified time // : Doesn't start or stop playing of animation // void cyAnimation::SkipToTime(hsScalar time) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kGoToTime); pMsg->fTime = time; plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : Looped // PARAMETERS : looped - state to change to // // PURPOSE : Set whether the animation is to be looped or not // void cyAnimation::Looped(hsBool looped) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); if ( looped ) pMsg->SetCmd(plAnimCmdMsg::kSetLooping); else pMsg->SetCmd(plAnimCmdMsg::kUnSetLooping); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : Backwards // PARAMETERS : backwards - state of the backwards flag // // PURPOSE : Sets the backwards state for the animation // void cyAnimation::Backwards(hsBool backwards) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); if ( backwards ) pMsg->SetCmd(plAnimCmdMsg::kSetBackwards); else pMsg->SetCmd(plAnimCmdMsg::kSetForewards); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : SetLoopStart and SetLoopEnd // PARAMETERS : value - sets the start or the end of the animation // void cyAnimation::SetLoopStart(hsScalar start) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kSetLoopBegin); pMsg->fLoopBegin = start; plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } void cyAnimation::SetLoopEnd(hsScalar end) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kSetLoopEnd); pMsg->fLoopEnd = end; plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } ///////////////////////////////////////////////////////////////////////////// // // Function : Speed // PARAMETERS : speed - speed to set the animation to // // PURPOSE : Sets the speed of the animation // : Doesn't start or stop playing animation // void cyAnimation::Speed(hsScalar speed) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(plAnimCmdMsg::kSetSpeed); pMsg->fSpeed = speed; plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } void cyAnimation::IRunOneCmd(int cmd) { // must have a receiver! if ( fRecvr.Count() > 0 ) { // create message plAnimCmdMsg* pMsg = TRACKED_NEW plAnimCmdMsg; // check if this needs to be network forced to all clients if (fNetForce ) { // set the network propagate flag to make sure it gets to the other clients pMsg->SetBCastFlag(plMessage::kNetPropagate); pMsg->SetBCastFlag(plMessage::kNetForce); } if ( fSender ) pMsg->SetSender(fSender); // add all our receivers to the message receiver list int i; for ( i=0; iAddReceiver(fRecvr[i]); } // set the notetrack name (if there is one) if ( fAnimName != nil ) pMsg->SetAnimName(fAnimName); pMsg->SetCmd(cmd); plgDispatch::MsgSend( pMsg ); // whoosh... off it goes } } void cyAnimation::SkipToBegin() { IRunOneCmd(plAnimCmdMsg::kGoToBegin); } void cyAnimation::SkipToEnd() { IRunOneCmd(plAnimCmdMsg::kGoToEnd); } void cyAnimation::SkipToLoopBegin() { IRunOneCmd(plAnimCmdMsg::kGoToLoopBegin); } void cyAnimation::SkipToLoopEnd() { IRunOneCmd(plAnimCmdMsg::kGoToLoopEnd); } // Bump the animation ahead one frame (whatever deltime is) // void cyAnimation::IncrementForward() { IRunOneCmd(plAnimCmdMsg::kIncrementForward); } // Bump the animation back one frame (whatever deltime is) // void cyAnimation::IncrementBackward() { IRunOneCmd(plAnimCmdMsg::kIncrementBackward); }