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.
758 lines
20 KiB
758 lines
20 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/>. |
|
|
|
Additional permissions under GNU GPL version 3 section 7 |
|
|
|
If you modify this Program, or any covered work, by linking or |
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, |
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent |
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK |
|
(or a modified version of those libraries), |
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, |
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG |
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the |
|
licensors of this Program grant you additional |
|
permission to convey the resulting work. Corresponding Source for a |
|
non-source form of such a combination shall include the source code for |
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered |
|
work. |
|
|
|
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==*/ |
|
|
|
#include "hsTypes.h" |
|
#include "hsTimer.h" |
|
#include "plLayerAnimation.h" |
|
#include "../pnKeyedObject/plKey.h" |
|
|
|
#include "../plInterp/plController.h" |
|
#include "../plMessage/plAnimCmdMsg.h" |
|
#include "../plMessage/plLinkToAgeMsg.h" |
|
#include "../pnMessage/plSDLModifierMsg.h" |
|
#include "../plModifier/plLayerSDLModifier.h" |
|
#include "../pnMessage/plCameraMsg.h" |
|
#include "../plNetClient/plLinkEffectsMgr.h" |
|
#include "plgDispatch.h" |
|
#include "hsResMgr.h" |
|
#include "../plModifier/plSDLModifier.h" |
|
#include "../plSDL/plSDL.h" |
|
#include "../pnMessage/plSDLNotificationMsg.h" |
|
#include "../plMessage/plAvatarMsg.h" |
|
|
|
plLayerAnimationBase::plLayerAnimationBase() |
|
: |
|
fPreshadeColorCtl(nil), |
|
fRuntimeColorCtl(nil), |
|
fAmbientColorCtl(nil), |
|
fSpecularColorCtl(nil), |
|
fOpacityCtl(nil), |
|
fTransformCtl(nil), |
|
fEvalTime(-1.0), |
|
fCurrentTime(-1.f), |
|
fSegmentID(nil) |
|
{ |
|
} |
|
|
|
plLayerAnimationBase::~plLayerAnimationBase() |
|
{ |
|
delete fPreshadeColorCtl; |
|
delete fRuntimeColorCtl; |
|
delete fAmbientColorCtl; |
|
delete fSpecularColorCtl; |
|
delete fOpacityCtl; |
|
delete fTransformCtl; |
|
delete [] fSegmentID; |
|
} |
|
|
|
void plLayerAnimationBase::Read(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerInterface::Read(s, mgr); |
|
|
|
fPreshadeColorCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); |
|
fRuntimeColorCtl = plController::ConvertNoRef( mgr->ReadCreatable( s ) ); |
|
fAmbientColorCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); |
|
fSpecularColorCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); |
|
fOpacityCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); |
|
fTransformCtl = plController::ConvertNoRef(mgr->ReadCreatable(s)); |
|
|
|
if( fOpacityCtl ) |
|
{ |
|
fOwnedChannels |= kOpacity; |
|
fOpacity = TRACKED_NEW hsScalar; |
|
} |
|
if( fPreshadeColorCtl ) |
|
{ |
|
fOwnedChannels |= kPreshadeColor; |
|
fPreshadeColor = TRACKED_NEW hsColorRGBA; |
|
} |
|
if( fRuntimeColorCtl ) |
|
{ |
|
fOwnedChannels |= kRuntimeColor; |
|
fRuntimeColor = TRACKED_NEW hsColorRGBA; |
|
} |
|
if( fAmbientColorCtl ) |
|
{ |
|
fOwnedChannels |= kAmbientColor; |
|
fAmbientColor = TRACKED_NEW hsColorRGBA; |
|
} |
|
if( fSpecularColorCtl ) |
|
{ |
|
fOwnedChannels |= kSpecularColor; |
|
fSpecularColor = TRACKED_NEW hsColorRGBA; |
|
} |
|
if( fTransformCtl ) |
|
{ |
|
fOwnedChannels |= kTransform; |
|
fTransform = TRACKED_NEW hsMatrix44; |
|
} |
|
fLength = IMakeUniformLength(); |
|
} |
|
|
|
void plLayerAnimationBase::Write(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerInterface::Write(s, mgr); |
|
|
|
mgr->WriteCreatable(s, fPreshadeColorCtl); |
|
mgr->WriteCreatable(s, fRuntimeColorCtl); |
|
mgr->WriteCreatable(s, fAmbientColorCtl); |
|
mgr->WriteCreatable(s, fSpecularColorCtl); |
|
mgr->WriteCreatable(s, fOpacityCtl); |
|
mgr->WriteCreatable(s, fTransformCtl); |
|
} |
|
|
|
plLayerInterface* plLayerAnimationBase::Attach(plLayerInterface* prev) |
|
{ |
|
return plLayerInterface::Attach(prev); |
|
} |
|
|
|
void plLayerAnimationBase::IEvalConvertedTime(hsScalar secs, UInt32 passChans, UInt32 evalChans, UInt32 &dirty) |
|
{ |
|
if( evalChans & kPreshadeColor ) |
|
{ |
|
fPreshadeColorCtl->Interp(fCurrentTime, fPreshadeColor); |
|
dirty |= kPreshadeColor; |
|
} |
|
else if( passChans & kPreshadeColor ) |
|
{ |
|
*fPreshadeColor = fUnderLay->GetPreshadeColor(); |
|
} |
|
|
|
if( evalChans & kRuntimeColor ) |
|
{ |
|
fRuntimeColorCtl->Interp( fCurrentTime, fRuntimeColor ); |
|
dirty |= kRuntimeColor; |
|
} |
|
else if( passChans & kRuntimeColor ) |
|
{ |
|
*fRuntimeColor = fUnderLay->GetRuntimeColor(); |
|
} |
|
|
|
if( evalChans & kAmbientColor ) |
|
{ |
|
fAmbientColorCtl->Interp(fCurrentTime, fAmbientColor); |
|
dirty |= kAmbientColor; |
|
} |
|
else if( passChans & kAmbientColor ) |
|
{ |
|
*fAmbientColor = fUnderLay->GetAmbientColor(); |
|
} |
|
|
|
if( evalChans & kSpecularColor ) |
|
{ |
|
fSpecularColorCtl->Interp( fCurrentTime, fSpecularColor ); |
|
dirty |= kSpecularColor; |
|
} |
|
else if( passChans & kSpecularColor ) |
|
{ |
|
*fSpecularColor = fUnderLay->GetSpecularColor(); |
|
} |
|
|
|
if( evalChans & kOpacity ) |
|
{ |
|
fOpacityCtl->Interp(fCurrentTime, fOpacity); |
|
*fOpacity *= 1.e-2f; |
|
dirty |= kOpacity; |
|
} |
|
else if( passChans & kOpacity ) |
|
{ |
|
*fOpacity = fUnderLay->GetOpacity(); |
|
} |
|
|
|
if( evalChans & kTransform ) |
|
{ |
|
fTransformCtl->Interp(fCurrentTime, fTransform); |
|
dirty |= kTransform; |
|
} |
|
else if( passChans & kTransform ) |
|
{ |
|
*fTransform = fUnderLay->GetTransform(); |
|
} |
|
fPassThruChannels = 0; // already handled, don't need to keep passing them through. |
|
} |
|
|
|
hsBool plLayerAnimationBase::MsgReceive(plMessage* msg) |
|
{ |
|
return plLayerInterface::MsgReceive(msg); |
|
} |
|
|
|
void plLayerAnimationBase::SetPreshadeColorCtl(plController* colCtl) |
|
{ |
|
if( fPreshadeColorCtl ) |
|
delete fPreshadeColorCtl; |
|
else |
|
fPreshadeColor = TRACKED_NEW hsColorRGBA; |
|
|
|
fOwnedChannels |= kPreshadeColor; |
|
fPreshadeColorCtl = colCtl; |
|
} |
|
|
|
void plLayerAnimationBase::SetRuntimeColorCtl(plController* colCtl) |
|
{ |
|
if( fRuntimeColorCtl ) |
|
delete fRuntimeColorCtl; |
|
else |
|
fRuntimeColor = TRACKED_NEW hsColorRGBA; |
|
|
|
fOwnedChannels |= kRuntimeColor; |
|
fRuntimeColorCtl = colCtl; |
|
} |
|
|
|
void plLayerAnimationBase::SetAmbientColorCtl(plController* ambCtl) |
|
{ |
|
if( fAmbientColorCtl ) |
|
delete fAmbientColorCtl; |
|
else |
|
fAmbientColor = TRACKED_NEW hsColorRGBA; |
|
|
|
fOwnedChannels |= kAmbientColor; |
|
fAmbientColorCtl = ambCtl; |
|
} |
|
|
|
void plLayerAnimationBase::SetSpecularColorCtl(plController* ambCtl) |
|
{ |
|
if( fSpecularColorCtl ) |
|
delete fSpecularColorCtl; |
|
else |
|
fSpecularColor = TRACKED_NEW hsColorRGBA; |
|
|
|
fOwnedChannels |= kSpecularColor; |
|
fSpecularColorCtl = ambCtl; |
|
} |
|
|
|
void plLayerAnimationBase::SetOpacityCtl(plController* opaCtl) |
|
{ |
|
if( fOpacityCtl ) |
|
delete fOpacityCtl; |
|
else |
|
fOpacity = TRACKED_NEW hsScalar; |
|
|
|
fOwnedChannels |= kOpacity; |
|
fOpacityCtl = opaCtl; |
|
} |
|
|
|
void plLayerAnimationBase::SetTransformCtl(plController* xfmCtl) |
|
{ |
|
if( fTransformCtl ) |
|
delete fTransformCtl; |
|
else |
|
fTransform = TRACKED_NEW hsMatrix44; |
|
|
|
fOwnedChannels |= kTransform; |
|
fTransformCtl = xfmCtl; |
|
} |
|
|
|
hsScalar plLayerAnimationBase::IMakeUniformLength() |
|
{ |
|
fLength = 0; |
|
if( fPreshadeColorCtl && (fPreshadeColorCtl->GetLength() > fLength) ) |
|
fLength = fPreshadeColorCtl->GetLength(); |
|
if( fRuntimeColorCtl && (fRuntimeColorCtl->GetLength() > fLength) ) |
|
fLength = fRuntimeColorCtl->GetLength(); |
|
if( fAmbientColorCtl && (fAmbientColorCtl->GetLength() > fLength) ) |
|
fLength = fAmbientColorCtl->GetLength(); |
|
if( fSpecularColorCtl && (fSpecularColorCtl->GetLength() > fLength) ) |
|
fLength = fSpecularColorCtl->GetLength(); |
|
if( fOpacityCtl && (fOpacityCtl->GetLength() > fLength) ) |
|
fLength = fOpacityCtl->GetLength(); |
|
if( fTransformCtl && (fTransformCtl->GetLength() > fLength) ) |
|
fLength = fTransformCtl->GetLength(); |
|
|
|
return fLength; |
|
} |
|
|
|
///////////////////////////////////////////////////////////////////////////////// |
|
|
|
plLayerAnimation::plLayerAnimation() |
|
: |
|
plLayerAnimationBase(), |
|
fLayerSDLMod(nil) |
|
{ |
|
fTimeConvert.SetOwner(this); |
|
} |
|
|
|
plLayerAnimation::~plLayerAnimation() |
|
{ |
|
delete fLayerSDLMod; |
|
} |
|
|
|
void plLayerAnimation::Read(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerAnimationBase::Read(s, mgr); |
|
|
|
fTimeConvert.Read(s, mgr); |
|
if (!(fTimeConvert.IsStopped())) |
|
{ |
|
plSynchEnabler ps(true); // enable dirty tracking so that we send state about |
|
// the anim resetting to start now. |
|
fTimeConvert.SetCurrentAnimTime(0, true); |
|
} |
|
Eval(hsTimer::GetSysSeconds(),0,0); |
|
|
|
// add sdl modifier |
|
delete fLayerSDLMod; |
|
fLayerSDLMod = TRACKED_NEW plLayerSDLModifier; |
|
fLayerSDLMod->SetLayerAnimation(this); |
|
} |
|
|
|
|
|
void plLayerAnimation::Write(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerAnimationBase::Write(s, mgr); |
|
|
|
fTimeConvert.Write(s, mgr); |
|
} |
|
|
|
plLayerInterface* plLayerAnimation::Attach(plLayerInterface* prev) |
|
{ |
|
fCurrentTime = fTimeConvert.CurrentAnimTime()-1.f; |
|
|
|
return plLayerAnimationBase::Attach(prev); |
|
} |
|
|
|
UInt32 plLayerAnimation::Eval(double wSecs, UInt32 frame, UInt32 ignore) |
|
{ |
|
UInt32 dirty = plLayerInterface::Eval(wSecs, frame, ignore); |
|
if( wSecs != fEvalTime ) |
|
{ |
|
UInt32 evalChans = 0; |
|
UInt32 passChans = dirty | fPassThruChannels; |
|
hsScalar secs = fTimeConvert.WorldToAnimTime(wSecs); |
|
if( secs != fCurrentTime ) |
|
{ |
|
evalChans = fOwnedChannels & ~ignore & ~fPassThruChannels; |
|
fCurrentTime = secs; |
|
} |
|
|
|
IEvalConvertedTime(secs, passChans, evalChans, dirty); |
|
} |
|
fEvalTime = wSecs; |
|
return dirty; |
|
} |
|
|
|
hsBool plLayerAnimation::MsgReceive(plMessage* msg) |
|
{ |
|
// pass sdl msg to sdlMod |
|
plSDLModifierMsg* sdlMsg = plSDLModifierMsg::ConvertNoRef(msg); |
|
if (sdlMsg && fLayerSDLMod) |
|
{ |
|
if (fLayerSDLMod->MsgReceive(sdlMsg)) |
|
return true; // msg handled |
|
} |
|
|
|
hsBool retVal = false; |
|
plAnimCmdMsg* cmdMsg = plAnimCmdMsg::ConvertNoRef(msg); |
|
if( cmdMsg ) |
|
{ |
|
// Evaluate first, so we'll be transitioning from our |
|
// real current state, whether we've been evaluated (in view) |
|
// lately or not. |
|
TopOfStack()->Eval(hsTimer::GetSysSeconds(), 0, 0); |
|
retVal = fTimeConvert.HandleCmd(cmdMsg); |
|
DirtySynchState(kSDLLayer, 0); |
|
} |
|
|
|
if( retVal ) |
|
{ |
|
if( !fTimeConvert.IsStopped() || fTimeConvert.GetFlag(plAnimTimeConvert::kForcedMove) ) |
|
{ |
|
ClaimChannels(fOwnedChannels); |
|
fCurrentTime = -1.f; // force an eval |
|
} |
|
} |
|
else |
|
{ |
|
retVal = plLayerAnimationBase::MsgReceive(msg); |
|
} |
|
|
|
return retVal; |
|
} |
|
|
|
void plLayerAnimation::DefaultAnimation() |
|
{ |
|
IMakeUniformLength(); |
|
fTimeConvert.SetBegin(0); |
|
fTimeConvert.SetEnd(fLength); |
|
fTimeConvert.SetLoopPoints(0,fLength); |
|
fTimeConvert.Loop(); |
|
fTimeConvert.Start(); |
|
} |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
plLayerLinkAnimation::plLayerLinkAnimation() : |
|
fLinkKey(nil), |
|
fLeavingAge(true), |
|
fEnabled(true), |
|
fFadeFlags(0), |
|
fLastFadeFlag(0), |
|
fFadeFlagsDirty(false) |
|
{ |
|
fIFaceCallback = TRACKED_NEW plEventCallbackMsg(); |
|
fIFaceCallback->fEvent = kTime; |
|
fIFaceCallback->fRepeats = 0; |
|
} |
|
|
|
plLayerLinkAnimation::~plLayerLinkAnimation() |
|
{ |
|
hsRefCnt_SafeUnRef(fIFaceCallback); |
|
} |
|
|
|
|
|
void plLayerLinkAnimation::Read(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerAnimation::Read(s, mgr); |
|
|
|
fLinkKey = mgr->ReadKey(s); |
|
fLeavingAge = s->ReadBool(); |
|
plgDispatch::Dispatch()->RegisterForExactType(plLinkEffectBCMsg::Index(), GetKey()); |
|
plgDispatch::Dispatch()->RegisterForExactType(plLinkEffectPrepBCMsg::Index(), GetKey()); |
|
plgDispatch::Dispatch()->RegisterForExactType(plCameraTargetFadeMsg::Index(), GetKey()); |
|
plgDispatch::Dispatch()->RegisterForExactType(plAvatarStealthModeMsg::Index(), GetKey()); |
|
plgDispatch::Dispatch()->RegisterForExactType(plIfaceFadeAvatarMsg::Index(), GetKey()); |
|
plgDispatch::Dispatch()->RegisterForExactType(plPseudoLinkAnimTriggerMsg::Index(), GetKey()); |
|
|
|
fIFaceCallback->AddReceiver(GetKey()); |
|
} |
|
|
|
|
|
void plLayerLinkAnimation::Write(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerAnimation::Write(s, mgr); |
|
|
|
mgr->WriteKey(s, fLinkKey); |
|
s->WriteBool(fLeavingAge); |
|
} |
|
|
|
UInt32 plLayerLinkAnimation::Eval(double wSecs, UInt32 frame, UInt32 ignore) |
|
{ |
|
UInt32 dirty = plLayerInterface::Eval(wSecs, frame, ignore); |
|
if (wSecs != fEvalTime) |
|
{ |
|
UInt32 evalChans = 0; |
|
UInt32 passChans = dirty | fPassThruChannels; |
|
hsScalar oldAnimTime = fTimeConvert.CurrentAnimTime(); |
|
hsScalar secs = oldAnimTime; |
|
|
|
if (fFadeFlagsDirty) |
|
{ |
|
hsScalar goal = 0.f; |
|
|
|
if (fFadeFlags & kFadeLinkPrep) |
|
secs = goal = fLength; |
|
else |
|
{ |
|
hsScalar rate = 0.f; |
|
hsScalar delta = (hsScalar)(wSecs - fEvalTime); |
|
|
|
if (fFadeFlags & kFadeLinking) |
|
{ |
|
goal = fLength; |
|
rate = 1.f; |
|
} |
|
else if (fFadeFlags & kFadeCamera) |
|
{ |
|
goal = fLength; |
|
rate = 10.f; |
|
} |
|
else if (fFadeFlags & (kFadeIFace | kFadeCCR)) |
|
{ |
|
goal = fLength * 0.4f; |
|
rate = 10.f; |
|
} |
|
else if (fFadeFlags == 0) |
|
{ |
|
goal = 0.f; |
|
if (fLastFadeFlag == kFadeLinking) |
|
rate = 1.f; |
|
else |
|
rate = 10.f; |
|
} |
|
|
|
if (fabs(oldAnimTime - goal) < delta * rate || rate == 0) |
|
secs = goal; |
|
else if (goal > oldAnimTime) |
|
secs = oldAnimTime + delta * rate; |
|
else |
|
secs = oldAnimTime - delta * rate; |
|
} |
|
|
|
if (secs == goal) |
|
fFadeFlagsDirty = false; |
|
} |
|
|
|
if( secs != fCurrentTime ) |
|
{ |
|
fTimeConvert.SetCurrentAnimTime(secs); |
|
if (secs == 0.f || oldAnimTime == 0.f) |
|
{ |
|
// Either we're going opaque, or we were opaque and now we're fading. |
|
// Tell the armature to re-eval its opacity settings. |
|
plAvatarOpacityCallbackMsg *opacityMsg = TRACKED_NEW plAvatarOpacityCallbackMsg(fLinkKey, kStop); |
|
opacityMsg->SetBCastFlag(plMessage::kPropagateToModifiers); |
|
opacityMsg->Send(); |
|
} |
|
evalChans = fOwnedChannels & ~ignore & ~fPassThruChannels; |
|
fCurrentTime = secs; |
|
} |
|
IEvalConvertedTime(secs, passChans, evalChans, dirty); |
|
} |
|
fEvalTime = wSecs; |
|
return dirty; |
|
} |
|
|
|
void plLayerLinkAnimation::SetFadeFlag(UInt8 flag, hsBool val) |
|
{ |
|
if (val) |
|
fFadeFlags |= flag; |
|
else |
|
fFadeFlags &= ~flag; |
|
|
|
if (fFadeFlags == 0) |
|
fLastFadeFlag = flag; |
|
|
|
TopOfStack()->Eval(hsTimer::GetSysSeconds(), 0, 0); |
|
ClaimChannels(fOwnedChannels); |
|
fCurrentTime = -1; // force eval |
|
fFadeFlagsDirty = true; |
|
} |
|
|
|
hsBool plLayerLinkAnimation::MsgReceive( plMessage* pMsg ) |
|
{ |
|
plLinkEffectPrepBCMsg *bcpMsg = plLinkEffectPrepBCMsg::ConvertNoRef(pMsg); |
|
if (bcpMsg != nil) |
|
{ |
|
if (bcpMsg->fLinkKey != fLinkKey || bcpMsg->fLeavingAge) |
|
return true; |
|
|
|
SetFadeFlag(kFadeLinkPrep, true); |
|
return true; |
|
} |
|
|
|
|
|
plLinkEffectBCMsg *msg = plLinkEffectBCMsg::ConvertNoRef(pMsg); |
|
if (msg != nil) |
|
{ |
|
if (msg->fLinkKey == fLinkKey) |
|
{ |
|
SetFadeFlag(kFadeLinkPrep, false); |
|
if (msg->HasLinkFlag(plLinkEffectBCMsg::kLeavingAge)) |
|
SetFadeFlag(kFadeLinking, true); |
|
else |
|
SetFadeFlag(kFadeLinking, false); |
|
|
|
if (msg->HasLinkFlag(plLinkEffectBCMsg::kSendCallback)) |
|
{ |
|
plLinkEffectsMgr *mgr; |
|
if (mgr = plLinkEffectsMgr::ConvertNoRef(msg->GetSender()->ObjectIsLoaded())) |
|
mgr->WaitForEffect(msg->fLinkKey, fTimeConvert.GetEnd() - fTimeConvert.GetBegin()); |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
plPseudoLinkAnimTriggerMsg* pSeudoMsg = plPseudoLinkAnimTriggerMsg::ConvertNoRef(pMsg); |
|
if (pSeudoMsg) |
|
{ |
|
if (fLinkKey != pSeudoMsg->fAvatarKey) |
|
return true; |
|
|
|
if (pSeudoMsg->fForward) |
|
SetFadeFlag(kFadeLinking, true); |
|
else |
|
SetFadeFlag(kFadeLinking, false); |
|
|
|
// add a callback for when it's done if it's in forward |
|
plLinkEffectsMgr *mgr; |
|
if (mgr = plLinkEffectsMgr::ConvertNoRef(pMsg->GetSender()->ObjectIsLoaded())) |
|
if (pSeudoMsg->fForward) |
|
mgr->WaitForPseudoEffect(fLinkKey, fTimeConvert.GetEnd() - fTimeConvert.GetBegin()); |
|
|
|
return true; |
|
} |
|
// used to fade the player in or out when entering / exiting first person mode |
|
// or when distance between camera and player is too small... |
|
plCameraTargetFadeMsg* fMsg = plCameraTargetFadeMsg::ConvertNoRef(pMsg); |
|
if (fMsg) |
|
{ |
|
if (fLinkKey != fMsg->GetSubjectKey()) |
|
return true; |
|
|
|
if (fMsg->FadeOut()) |
|
SetFadeFlag(kFadeCamera, true); |
|
else |
|
SetFadeFlag(kFadeCamera, false); |
|
|
|
return true; |
|
} |
|
plIfaceFadeAvatarMsg* iMsg = plIfaceFadeAvatarMsg::ConvertNoRef(pMsg); |
|
if (iMsg) |
|
{ |
|
if (fLinkKey != iMsg->GetSubjectKey()) |
|
return true; |
|
|
|
if (iMsg->GetEnable()) |
|
{ |
|
Enable(true); |
|
} |
|
else if (iMsg->GetDisable()) |
|
{ |
|
Enable(false); // disable and un-fade |
|
SetFadeFlag(kFadeIFace, false); |
|
} |
|
else |
|
if (fEnabled) |
|
{ |
|
if (iMsg->FadeOut()) |
|
SetFadeFlag(kFadeIFace, true); |
|
else |
|
SetFadeFlag(kFadeIFace, false); |
|
} |
|
return true; |
|
} |
|
|
|
plAvatarStealthModeMsg *sMsg = plAvatarStealthModeMsg::ConvertNoRef(pMsg); |
|
if (sMsg) |
|
{ |
|
if (sMsg->GetSender() == fLinkKey) |
|
{ |
|
if (sMsg->fMode == plAvatarStealthModeMsg::kStealthCloakedButSeen) |
|
{ |
|
SetFadeFlag(kFadeCCR, true); |
|
} |
|
else if (sMsg->fMode == plAvatarStealthModeMsg::kStealthVisible) |
|
{ |
|
SetFadeFlag(kFadeCCR, false); |
|
} |
|
// Don't need to set opacity if we're fully cloaked, since we won't |
|
// even be drawing the spans (due to plEnableMsg() on the sceneObject) |
|
} |
|
return true; |
|
} |
|
|
|
return plLayerAnimation::MsgReceive( pMsg ); |
|
} |
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
plLayerSDLAnimation::plLayerSDLAnimation() : plLayerAnimationBase(), fVar(nil), fVarName(nil) {} |
|
|
|
plLayerSDLAnimation::~plLayerSDLAnimation() |
|
{ |
|
delete [] fVarName; |
|
} |
|
|
|
UInt32 plLayerSDLAnimation::Eval(double wSecs, UInt32 frame, UInt32 ignore) |
|
{ |
|
UInt32 dirty = plLayerInterface::Eval(wSecs, frame, ignore); |
|
if( wSecs != fEvalTime ) |
|
{ |
|
UInt32 evalChans = 0; |
|
UInt32 passChans = dirty | fPassThruChannels; |
|
|
|
if (fEvalTime < 0) |
|
{ |
|
if (fVarName != nil) |
|
{ |
|
extern const plSDLModifier *ExternFindAgeSDL(); |
|
const plSDLModifier *sdlMod = ExternFindAgeSDL(); |
|
if (sdlMod) |
|
{ |
|
fVar = sdlMod->GetStateCache()->FindVar(fVarName); |
|
if (fVar) |
|
sdlMod->AddNotifyForVar(GetKey(), fVarName, 0); |
|
} |
|
} |
|
} |
|
hsScalar secs; |
|
if (fVar) |
|
fVar->Get(&secs); |
|
else |
|
secs = 0.f; |
|
|
|
// We're guaranteed a 0-1 time. Scale that to our animation length. |
|
secs *= GetLength(); |
|
|
|
if( secs != fCurrentTime ) |
|
{ |
|
evalChans = fOwnedChannels & ~ignore & ~fPassThruChannels; |
|
fCurrentTime = secs; |
|
} |
|
|
|
IEvalConvertedTime(secs, passChans, evalChans, dirty); |
|
} |
|
fEvalTime = wSecs; |
|
return dirty; |
|
} |
|
|
|
hsBool plLayerSDLAnimation::MsgReceive(plMessage* msg) |
|
{ |
|
plSDLNotificationMsg* nMsg = plSDLNotificationMsg::ConvertNoRef(msg); |
|
if (nMsg) |
|
{ |
|
TopOfStack()->Eval(hsTimer::GetSysSeconds(), 0, 0); |
|
ClaimChannels(fOwnedChannels); |
|
return true; |
|
} |
|
|
|
return plLayerAnimationBase::MsgReceive(msg); |
|
} |
|
|
|
void plLayerSDLAnimation::Read(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerAnimationBase::Read(s, mgr); |
|
|
|
fVarName = s->ReadSafeString(); |
|
} |
|
|
|
void plLayerSDLAnimation::Write(hsStream* s, hsResMgr* mgr) |
|
{ |
|
plLayerAnimationBase::Write(s, mgr); |
|
|
|
s->WriteSafeString(fVarName); |
|
} |
|
|
|
void plLayerSDLAnimation::SetVarName(char *name) |
|
{ |
|
delete [] fVarName; |
|
fVarName = hsStrcpy(name); |
|
}
|
|
|