/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : // AnimAction that can handle a typical three-fragment Intro/Middle (sometimes looping)/Outro sequence. #ifndef CRYINCLUDE_CRYACTION_MANNEQUIN_ANIMACTIONTRISTATE_H #define CRYINCLUDE_CRYACTION_MANNEQUIN_ANIMACTIONTRISTATE_H #pragma once //--------------------------------------------------------------------------------------------------- struct IAnimActionTriStateListener { virtual ~IAnimActionTriStateListener() {} // Called when the action is entered (called before Intro) virtual void OnAnimActionTriStateEnter(class CAnimActionTriState* pAction) {} // Called when the Intro substate starts (also when there is no animation for it) virtual void OnAnimActionTriStateIntro(class CAnimActionTriState* pAction) {} // Called when the Middle substate starts (also when there is no animation for // it or when a call to Abort() will cause the middle part to be skipped) // Will NOT get called when the action gets trumped by a higher prio action // during the Intro substate, or when it gets a call to ForceFinsh() virtual void OnAnimActionTriStateMiddle(class CAnimActionTriState* pAction) {} // Called when the Outro substate starts (also when there is no animation for it) // Will NOT get called when the action gets trumped by a higher prio action // during the Middle substate, or when it gets a call to ForceFinsh() virtual void OnAnimActionTriStateOutro(class CAnimActionTriState* pAction) {} // Called when the Outro substate ends (also when there is no animation for it) // Will NOT get called when the action gets trumped by a higher prio action // during the Outro substate, or when it gets a call to ForceFinsh() virtual void OnAnimActionTriStateOutroEnd(class CAnimActionTriState* pAction) {} // Called when the action is exited (guaranteed to be called when Enter was // called before -- except in error cases) virtual void OnAnimActionTriStateExit(class CAnimActionTriState* pAction) {} }; //--------------------------------------------------------------------------------------------------- class CAnimActionTriState : public TAction< SAnimationContext > { public: typedef TAction< SAnimationContext > TBase; DEFINE_ACTION("TriState"); enum ESubState { eSS_None, eSS_Intro, eSS_Middle, eSS_Outro, eSS_Exit, }; // -------------------------------------------------------------------------- CAnimActionTriState(int priority, FragmentID fragmentID, IAnimatedCharacter& animChar, bool oneShot, float maxMiddleDuration = -1, bool skipIntro = false, IAnimActionTriStateListener* pListener = NULL); // -------------------------------------------------------------------------- // *Must* be called when the action's lifetime can be bigger than the listener's void UnregisterListener(); // Initialize the location that is passed as parameter "TargetPos" to CryMannequin void InitTargetLocation(const QuatT& targetLocation); // Clear the location that is passed as parameter "TargetPos" to CryMannequin void ClearTargetLocation(); // Initialize the MovementControlMethods that will be set when this action enters // Note: This only happens when the fragment runs on layer 0, otherwise this // setting is ignored void InitMovementControlMethods(EMovementControlMethod mcmHorizontal, EMovementControlMethod mcmVertical); // Stop the action gracefully. Intro & Outro will still play, but the middle // part will be skipped or stopped. When the Middle part is already playing, // it will still play fully when the action is marked as OneShot. // Note: When in an Intro, the Middle event will still be sent and immediately // followed by the Outro event. // Contrast this behavior to calling ForceFinish() or when this action is // pushed away by another, higher priority action. In that case only the Exit // event will be sent. void Stop(); inline ESubState GetSubState() const { return m_subState; } inline bool IsOneShot() const { return (m_triStateFlags & eTSF_OneShot) != 0; } protected: // -------------------------------------------------------------------------- // Called when the action is entered (called before Intro) virtual void OnEnter() {} // Called when the Intro substate starts (also when there is no animation for it) virtual void OnIntro() {} // Called when the Middle substate starts (also when there is no animation for // it or when a call to Abort() will cause the middle part to be skipped) // Will NOT get called when the action gets trumped by a higher prio action // during the Intro substate, or when it gets a call to ForceFinsh() virtual void OnMiddle() {} // Called when the Outro substate starts (also when there is no animation for it) // Will NOT get called when the action gets trumped by a higher prio action // during the Middle substate, or when it gets a call to ForceFinsh() virtual void OnOutro() {} // Called when the Outro substate ends (also when there is no animation for it) // Will NOT get called when the action gets trumped by a higher prio action // during the Outro substate, or when it gets a call to ForceFinsh() virtual void OnOutroEnd() {} // Called when the action is exited (guaranteed to be called when Enter was // called before -- except in error cases) virtual void OnExit() {} // -------------------------------------------------------------------------- // overrides ---------------------------------------------------------------- virtual void OnAnimationEvent(ICharacterInstance* pCharacter, const AnimEventInstance& event) override; virtual void OnSequenceFinished(int layer, uint32 scopeID) override; virtual EStatus Update(float timePassed) override; virtual void Enter() override; virtual void Exit() override; virtual void Install() override; virtual void OnRequestBlendOut(EPriorityComparison priorityComp) override; virtual void OnInitialise() override; // ~overrides ---------------------------------------------------------------- protected: IAnimatedCharacter& m_animChar; IAnimActionTriStateListener* m_pListener; ESubState m_subState; #ifndef _RELEASE bool m_entered; #endif private: bool TrySetTransitionFragment(uint32 fragTagCRC); void TransitionToNextSubState(); enum ETriStateFlag { eTSF_TargetLocation = BIT(1), // has target location eTSF_SkippedIntro = BIT(2), eTSF_SkipMiddle = BIT(3), eTSF_OneShot = BIT(4), }; uint32 m_triStateFlags; EMovementControlMethod m_mcmHorizontal; EMovementControlMethod m_mcmVertical; EMovementControlMethod m_mcmHorizontalOld; EMovementControlMethod m_mcmVerticalOld; QuatT m_targetLocation; float m_maxMiddleDuration; CTimeValue m_middleEndTime; }; #endif // CRYINCLUDE_CRYACTION_MANNEQUIN_ANIMACTIONTRISTATE_H