/*==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);
}