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.
302 lines
10 KiB
302 lines
10 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#ifndef BASEFLEX_H |
|
#define BASEFLEX_H |
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
|
|
#include "BaseAnimatingOverlay.h" |
|
#include "utlvector.h" |
|
#include "utlrbtree.h" |
|
#include "sceneentity_shared.h" |
|
|
|
struct flexsettinghdr_t; |
|
struct flexsetting_t; |
|
class AI_Response; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: A .vfe referenced by a scene during .vcd playback |
|
//----------------------------------------------------------------------------- |
|
class CFlexSceneFile |
|
{ |
|
public: |
|
enum |
|
{ |
|
MAX_FLEX_FILENAME = 128, |
|
}; |
|
|
|
char filename[ MAX_FLEX_FILENAME ]; |
|
void *buffer; |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Animated characters who have vertex flex capability (e.g., facial expressions) |
|
//----------------------------------------------------------------------------- |
|
class CBaseFlex : public CBaseAnimatingOverlay |
|
{ |
|
DECLARE_CLASS( CBaseFlex, CBaseAnimatingOverlay ); |
|
public: |
|
DECLARE_SERVERCLASS(); |
|
DECLARE_DATADESC(); |
|
DECLARE_PREDICTABLE(); |
|
|
|
// Construction |
|
CBaseFlex( void ); |
|
~CBaseFlex( void ); |
|
|
|
virtual void SetModel( const char *szModelName ); |
|
|
|
void Blink( ); |
|
|
|
virtual void SetViewtarget( const Vector &viewtarget ); |
|
const Vector &GetViewtarget( void ) const; |
|
|
|
void SetFlexWeight( char *szName, float value ); |
|
void SetFlexWeight( LocalFlexController_t index, float value ); |
|
float GetFlexWeight( char *szName ); |
|
float GetFlexWeight( LocalFlexController_t index ); |
|
|
|
// Look up flex controller index by global name |
|
LocalFlexController_t FindFlexController( const char *szName ); |
|
void EnsureTranslations( const flexsettinghdr_t *pSettinghdr ); |
|
|
|
// Keep track of what scenes are being played |
|
void StartChoreoScene( CChoreoScene *scene ); |
|
void RemoveChoreoScene( CChoreoScene *scene, bool canceled = false ); |
|
|
|
// Start the specifics of an scene event |
|
virtual bool StartSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); |
|
|
|
// Manipulation of events for the object |
|
// Should be called by think function to process all scene events |
|
// The default implementation resets m_flexWeight array and calls |
|
// AddSceneEvents |
|
virtual void ProcessSceneEvents( void ); |
|
|
|
// Assumes m_flexWeight array has been set up, this adds the actual currently playing |
|
// expressions to the flex weights and adds other scene events as needed |
|
virtual bool ProcessSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
|
|
// Remove all playing events |
|
void ClearSceneEvents( CChoreoScene *scene, bool canceled ); |
|
|
|
// Stop specifics of event |
|
virtual bool ClearSceneEvent( CSceneEventInfo *info, bool fastKill, bool canceled ); |
|
|
|
// Add the event to the queue for this actor |
|
void AddSceneEvent( CChoreoScene *scene, CChoreoEvent *event, CBaseEntity *pTarget = NULL ); |
|
|
|
// Remove the event from the queue for this actor |
|
void RemoveSceneEvent( CChoreoScene *scene, CChoreoEvent *event, bool fastKill ); |
|
|
|
// Checks to see if the event should be considered "completed" |
|
bool CheckSceneEvent( float currenttime, CChoreoScene *scene, CChoreoEvent *event ); |
|
|
|
// Checks to see if a event should be considered "completed" |
|
virtual bool CheckSceneEventCompletion( CSceneEventInfo *info, float currenttime, CChoreoScene *scene, CChoreoEvent *event ); |
|
|
|
// Finds the layer priority of the current scene |
|
int GetScenePriority( CChoreoScene *scene ); |
|
|
|
// Returns true if the actor is not currently in a scene OR if the actor |
|
// is in a scene, but a PERMIT_RESPONSES event is active and the permit time |
|
// period has enough time remaining to handle the response in full. |
|
bool PermitResponse( float response_length ); |
|
|
|
// Set response end time (0 to clear response blocking) |
|
void SetPermitResponse( float endtime ); |
|
|
|
void SentenceStop( void ) { EmitSound( "AI_BaseNPC.SentenceStop" ); } |
|
|
|
virtual float PlayScene( const char *pszScene, float flDelay = 0.0f, AI_Response *response = NULL, IRecipientFilter *filter = NULL ); |
|
virtual float PlayAutoGeneratedSoundScene( const char *soundname ); |
|
|
|
virtual int GetSpecialDSP( void ) { return 0; } |
|
|
|
protected: |
|
// For handling .vfe files |
|
// Search list, or add if not in list |
|
const void *FindSceneFile( const char *filename ); |
|
|
|
// Find setting by name |
|
const flexsetting_t *FindNamedSetting( const flexsettinghdr_t *pSettinghdr, const char *expr ); |
|
|
|
// Called at the lowest level to actually apply an expression |
|
void AddFlexSetting( const char *expr, float scale, const flexsettinghdr_t *pSettinghdr, bool newexpression ); |
|
|
|
// Called at the lowest level to actually apply a flex animation |
|
void AddFlexAnimation( CSceneEventInfo *info ); |
|
|
|
bool HasSceneEvents() const; |
|
bool IsRunningSceneMoveToEvent(); |
|
|
|
LocalFlexController_t FlexControllerLocalToGlobal( const flexsettinghdr_t *pSettinghdr, int key ); |
|
|
|
private: |
|
// Starting various expression types |
|
|
|
bool RequestStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); |
|
bool RequestStartGestureSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); |
|
|
|
bool HandleStartSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor ); |
|
bool HandleStartGestureSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor ); |
|
bool StartFacingSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); |
|
bool StartMoveToSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event, CChoreoActor *actor, CBaseEntity *pTarget ); |
|
|
|
// Processing various expression types |
|
bool ProcessFlexAnimationSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
bool ProcessFlexSettingSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
bool ProcessSequenceSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
bool ProcessGestureSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
bool ProcessFacingSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
bool ProcessMoveToSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
bool ProcessLookAtSceneEvent( CSceneEventInfo *info, CChoreoScene *scene, CChoreoEvent *event ); |
|
|
|
// Set playing the scene sequence |
|
public: |
|
bool EnterSceneSequence( CChoreoScene *scene, CChoreoEvent *event, bool bRestart = false ); |
|
private: |
|
bool ExitSceneSequence( void ); |
|
|
|
private: |
|
CNetworkArray( float, m_flexWeight, MAXSTUDIOFLEXCTRL ); // indexed by model local flexcontroller |
|
|
|
// Vector from actor to eye target |
|
CNetworkVector( m_viewtarget ); |
|
|
|
// Blink state |
|
CNetworkVar( int, m_blinktoggle ); |
|
|
|
// Array of active SceneEvents, in order oldest to newest |
|
CUtlVector < CSceneEventInfo > m_SceneEvents; |
|
|
|
// Mapping for each loaded scene file used by this actor |
|
struct FS_LocalToGlobal_t |
|
{ |
|
explicit FS_LocalToGlobal_t() : |
|
m_Key( 0 ), |
|
m_nCount( 0 ), |
|
m_Mapping( 0 ) |
|
{ |
|
} |
|
|
|
explicit FS_LocalToGlobal_t( const flexsettinghdr_t *key ) : |
|
m_Key( key ), |
|
m_nCount( 0 ), |
|
m_Mapping( 0 ) |
|
{ |
|
} |
|
|
|
void SetCount( int count ) |
|
{ |
|
Assert( !m_Mapping ); |
|
Assert( count > 0 ); |
|
m_nCount = count; |
|
m_Mapping = new LocalFlexController_t[ m_nCount ]; |
|
Q_memset( m_Mapping, 0, m_nCount * sizeof( int ) ); |
|
} |
|
|
|
FS_LocalToGlobal_t( const FS_LocalToGlobal_t& src ) |
|
{ |
|
m_Key = src.m_Key; |
|
delete m_Mapping; |
|
m_Mapping = new LocalFlexController_t[ src.m_nCount ]; |
|
Q_memcpy( m_Mapping, src.m_Mapping, src.m_nCount * sizeof( int ) ); |
|
|
|
m_nCount = src.m_nCount; |
|
} |
|
|
|
~FS_LocalToGlobal_t() |
|
{ |
|
delete m_Mapping; |
|
m_nCount = 0; |
|
m_Mapping = 0; |
|
} |
|
|
|
const flexsettinghdr_t *m_Key; |
|
int m_nCount; |
|
LocalFlexController_t *m_Mapping; |
|
}; |
|
|
|
static bool FlexSettingLessFunc( const FS_LocalToGlobal_t& lhs, const FS_LocalToGlobal_t& rhs ); |
|
|
|
CUtlRBTree< FS_LocalToGlobal_t, unsigned short > m_LocalToGlobal; |
|
|
|
// The NPC is in a scene, but another .vcd (such as a short wave to say in response to the player doing something ) |
|
// can be layered on top of this actor (assuming duration matches, etc. |
|
float m_flAllowResponsesEndTime; |
|
|
|
// List of actively playing scenes |
|
CUtlVector < CChoreoScene * > m_ActiveChoreoScenes; |
|
bool m_bUpdateLayerPriorities; |
|
|
|
public: |
|
bool IsSuppressedFlexAnimation( CSceneEventInfo *info ); |
|
|
|
private: |
|
// last time a foreground flex animation was played |
|
float m_flLastFlexAnimationTime; |
|
|
|
|
|
public: |
|
void DoBodyLean( void ); |
|
|
|
virtual void Teleport( const Vector *newPosition, const QAngle *newAngles, const Vector *newVelocity ); |
|
|
|
|
|
#ifdef HL2_DLL |
|
Vector m_vecPrevOrigin; |
|
Vector m_vecPrevVelocity; |
|
CNetworkVector( m_vecLean ); |
|
CNetworkVector( m_vecShift ); |
|
#endif |
|
}; |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// For toggling blinking |
|
//----------------------------------------------------------------------------- |
|
inline void CBaseFlex::Blink() |
|
{ |
|
m_blinktoggle = !m_blinktoggle; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Do we have active expressions? |
|
//----------------------------------------------------------------------------- |
|
inline bool CBaseFlex::HasSceneEvents() const |
|
{ |
|
return m_SceneEvents.Count() != 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Other inlines |
|
//----------------------------------------------------------------------------- |
|
inline const Vector &CBaseFlex::GetViewtarget( ) const |
|
{ |
|
return m_viewtarget.Get(); // bah |
|
} |
|
|
|
inline void CBaseFlex::SetFlexWeight( char *szName, float value ) |
|
{ |
|
SetFlexWeight( FindFlexController( szName ), value ); |
|
} |
|
|
|
inline float CBaseFlex::GetFlexWeight( char *szName ) |
|
{ |
|
return GetFlexWeight( FindFlexController( szName ) ); |
|
} |
|
|
|
|
|
EXTERN_SEND_TABLE(DT_BaseFlex); |
|
|
|
|
|
#endif // BASEFLEX_H
|
|
|