You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

255 lines
7.8 KiB

/*==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 <http://www.gnu.org/licenses/>.
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==*/
//////////////////////////////////////////////////////////////////////////////
// //
// pfGUIProgressCtrl Definition //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "pfGUIProgressCtrl.h"
#include "pfGameGUIMgr.h"
#include "pfGUIDialogMod.h"
#include "plInputCore/plInputInterface.h"
#include "pnMessage/plRefMsg.h"
#include "pfMessage/pfGameGUIMsg.h"
#include "plMessage/plAnimCmdMsg.h"
#include "plMessage/plTimerCallbackMsg.h"
// #include "plAvatar/plAGModifier.h"
#include "plAvatar/plAGMasterMod.h"
#include "plAvatar/plAGAnimInstance.h"
#include "plSurface/plLayerAnimation.h"
#include "pnSceneObject/plSceneObject.h"
#include "pnSceneObject/plCoordinateInterface.h"
#include "pnTimer/plTimerCallbackManager.h"
#include "plgDispatch.h"
#include "hsResMgr.h"
//// Constructor/Destructor //////////////////////////////////////////////////
pfGUIProgressCtrl::pfGUIProgressCtrl() : fStopSoundTimer(99)
{
fAnimTimesCalced = false;
fAnimName = nil;
fPlaySound = true;
}
pfGUIProgressCtrl::~pfGUIProgressCtrl()
{
delete [] fAnimName;
}
//// IEval ///////////////////////////////////////////////////////////////////
hsBool pfGUIProgressCtrl::IEval( double secs, hsScalar del, UInt32 dirty )
{
return pfGUIValueCtrl::IEval( secs, del, dirty );
}
//// MsgReceive //////////////////////////////////////////////////////////////
hsBool pfGUIProgressCtrl::MsgReceive( plMessage *msg )
{
plTimerCallbackMsg *timerMsg = plTimerCallbackMsg::ConvertNoRef(msg);
if (timerMsg)
{
if (timerMsg->fID == fStopSoundTimer)
{
// we've finished animating, stop the sound that's playing
StopSound(kAnimateSound);
}
}
return pfGUIValueCtrl::MsgReceive( msg );
}
//// Read/Write //////////////////////////////////////////////////////////////
void pfGUIProgressCtrl::Read( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Read(s, mgr);
fAnimationKeys.Reset();
UInt32 i, count = s->ReadSwap32();
for( i = 0; i < count; i++ )
fAnimationKeys.Append( mgr->ReadKey( s ) );
fAnimName = s->ReadSafeString();
fAnimTimesCalced = false;
}
void pfGUIProgressCtrl::Write( hsStream *s, hsResMgr *mgr )
{
pfGUIValueCtrl::Write( s, mgr );
UInt32 i, count = fAnimationKeys.GetCount();
s->WriteSwap32( count );
for( i = 0; i < count; i++ )
mgr->WriteKey( s, fAnimationKeys[ i ] );
s->WriteSafeString( fAnimName );
}
//// UpdateBounds ////////////////////////////////////////////////////////////
void pfGUIProgressCtrl::UpdateBounds( hsMatrix44 *invXformMatrix, hsBool force )
{
pfGUIValueCtrl::UpdateBounds( invXformMatrix, force );
if( fAnimationKeys.GetCount() > 0 )
fBoundsValid = false;
}
//// SetAnimationKeys ////////////////////////////////////////////////////////
void pfGUIProgressCtrl::SetAnimationKeys( hsTArray<plKey> &keys, const char *name )
{
fAnimationKeys = keys;
delete [] fAnimName;
if( name != nil )
{
fAnimName = TRACKED_NEW char[ strlen( name ) + 1 ];
strcpy( fAnimName, name );
}
else
fAnimName = nil;
}
//// ICalcAnimTimes //////////////////////////////////////////////////////////
// Loops through and computes the max begin and end for our animations. If
// none of them are loaded and we're not already calced, returns false.
hsBool pfGUIProgressCtrl::ICalcAnimTimes( void )
{
if( fAnimTimesCalced )
return true;
hsScalar tBegin = 1e30, tEnd = -1e30;
bool foundOne = false;
for( int i = 0; i < fAnimationKeys.GetCount(); i++ )
{
// Handle AGMasterMods
plAGMasterMod *mod = plAGMasterMod::ConvertNoRef( fAnimationKeys[ i ]->ObjectIsLoaded() );
if( mod != nil )
{
for( int j = 0; j < mod->GetNumAnimations(); j++ )
{
hsScalar begin = mod->GetAnimInstance( j )->GetTimeConvert()->GetBegin();
hsScalar end = mod->GetAnimInstance( j )->GetTimeConvert()->GetEnd();
if( begin < tBegin )
tBegin = begin;
if( end > tEnd )
tEnd = end;
}
foundOne = true;
}
// Handle layer animations
plLayerAnimation *layer = plLayerAnimation::ConvertNoRef( fAnimationKeys[ i ]->ObjectIsLoaded() );
if( layer != nil )
{
hsScalar begin = layer->GetTimeConvert().GetBegin();
hsScalar end = layer->GetTimeConvert().GetEnd();
if( begin < tBegin )
tBegin = begin;
if( end > tEnd )
tEnd = end;
foundOne = true;
}
}
if( foundOne )
{
fAnimBegin = tBegin;
fAnimEnd = tEnd;
fAnimTimesCalced = true;
}
return fAnimTimesCalced;
}
//// SetCurrValue ////////////////////////////////////////////////////////////
void pfGUIProgressCtrl::SetCurrValue( hsScalar v )
{
int old = (int)fValue;
pfGUIValueCtrl::SetCurrValue( v );
// if( old == (int)fValue )
// return;
if( fAnimationKeys.GetCount() > 0 )
{
ICalcAnimTimes();
hsScalar tLength = fAnimEnd - fAnimBegin;
hsScalar newTime;
if( HasFlag( kReverseValues ) )
newTime = ( ( fMax - fValue ) / ( fMax - fMin ) ) * tLength + fAnimBegin;
else
newTime = ( ( fValue - fMin ) / ( fMax - fMin ) ) * tLength + fAnimBegin;
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kGoToTime );
msg->SetAnimName( fAnimName );
msg->fTime = newTime;
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
}
}
void pfGUIProgressCtrl::AnimateToPercentage( hsScalar percent )
{
// percent should be a value in range 0.0 to 1.0
if (percent >= 0.0f && percent <= 1.0f)
{
pfGUIValueCtrl::SetCurrValue( (fMax - fMin) * percent + fMin );
if( fAnimationKeys.GetCount() > 0 )
{
plAnimCmdMsg *msg = TRACKED_NEW plAnimCmdMsg();
msg->SetCmd( plAnimCmdMsg::kPlayToPercentage );
msg->SetAnimName( fAnimName );
msg->fTime = percent;
msg->AddReceivers( fAnimationKeys );
plgDispatch::MsgSend( msg );
if (fPlaySound)
{
// play the sound, looping
PlaySound(kAnimateSound, true);
// setup a timer to call back when we finish animating
hsScalar elapsedTime = (fAnimEnd - fAnimBegin) * percent;
plTimerCallbackMsg *timerMsg = TRACKED_NEW plTimerCallbackMsg(GetKey(), fStopSoundTimer);
plgTimerCallbackMgr::NewTimer(elapsedTime, timerMsg);
}
}
}
}