summaryrefslogtreecommitdiff
path: root/game/shared/econ/attribute_manager.h
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/econ/attribute_manager.h
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/shared/econ/attribute_manager.h')
-rw-r--r--game/shared/econ/attribute_manager.h301
1 files changed, 301 insertions, 0 deletions
diff --git a/game/shared/econ/attribute_manager.h b/game/shared/econ/attribute_manager.h
new file mode 100644
index 0000000..eb83675
--- /dev/null
+++ b/game/shared/econ/attribute_manager.h
@@ -0,0 +1,301 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Attributable entities contain one of these, which handles game specific handling:
+// - Save / Restore
+// - Networking
+// - Attribute providers
+// - Application of attribute effects
+//
+//=============================================================================
+
+#ifndef ATTRIBUTE_MANAGER_H
+#define ATTRIBUTE_MANAGER_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "econ_item_view.h"
+#include "ihasattributes.h"
+#include "tf_gcmessages.h"
+
+// Provider types
+enum attributeprovidertypes_t
+{
+ PROVIDER_GENERIC,
+ PROVIDER_WEAPON,
+};
+
+float CollateAttributeValues( const CEconItemAttributeDefinition *pAttrDef1, const float flAttribValue1, const CEconItemAttributeDefinition *pAttrDef2, const float flAttribValue2 );
+
+// Retrieve the IHasAttributes pointer from a Base Entity. This function checks for NULL entities
+// and asserts the return value is == to dynamic_cast< IHasAttributes * >( pEntity ).
+inline IHasAttributes *GetAttribInterface( CBaseEntity *pEntity )
+{
+ IHasAttributes *pAttribInterface = pEntity ? pEntity->GetHasAttributesInterfacePtr() : NULL;
+ // If this assert hits it most likely means that m_pAttribInterface has not been set
+ // in the leaf class constructor for this object. See CTFPlayer::CTFPlayer() for an
+ // example.
+ Assert( pAttribInterface == dynamic_cast< IHasAttributes *>( pEntity ) );
+ return pAttribInterface;
+}
+
+//-----------------------------------------------------------------------------
+// Macros for hooking the application of attributes
+#define CALL_ATTRIB_HOOK( vartype, retval, hookName, who, itemlist ) \
+ retval = CAttributeManager::AttribHookValue<vartype>( retval, #hookName, static_cast<const CBaseEntity*>( who ), itemlist, true );
+
+#define CALL_ATTRIB_HOOK_INT( retval, hookName ) CALL_ATTRIB_HOOK( int, retval, hookName, this, NULL )
+#define CALL_ATTRIB_HOOK_FLOAT( retval, hookName ) CALL_ATTRIB_HOOK( float, retval, hookName, this, NULL )
+#define CALL_ATTRIB_HOOK_STRING( retval, hookName ) CALL_ATTRIB_HOOK( CAttribute_String, retval, hookName, this, NULL )
+#define CALL_ATTRIB_HOOK_INT_ON_OTHER( other, retval, hookName ) CALL_ATTRIB_HOOK( int, retval, hookName, other, NULL )
+#define CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( other, retval, hookName ) CALL_ATTRIB_HOOK( float, retval, hookName, other, NULL )
+#define CALL_ATTRIB_HOOK_STRING_ON_OTHER( other, retval, hookName ) CALL_ATTRIB_HOOK( CAttribute_String, retval, hookName, other, NULL )
+#define CALL_ATTRIB_HOOK_INT_ON_OTHER_WITH_ITEMS( other, retval, items_array, hookName ) CALL_ATTRIB_HOOK( int, retval, hookName, other, items_array )
+#define CALL_ATTRIB_HOOK_FLOAT_ON_OTHER_WITH_ITEMS( other, retval, items_array, hookName ) CALL_ATTRIB_HOOK( float, retval, hookName, other, items_array )
+#define CALL_ATTRIB_HOOK_STRING_ON_OTHER_WITH_ITEMS( other, retval, items_array, hookName ) CALL_ATTRIB_HOOK( CAttribute_String, retval, hookName, other, items_array )
+
+template< class T > T AttributeConvertFromFloat( float flValue );
+template<> float AttributeConvertFromFloat<float>( float flValue );
+template<> int AttributeConvertFromFloat<int>( float flValue );
+
+//-----------------------------------------------------------------------------
+// Purpose: Base Attribute manager.
+// This class knows how to apply attribute effects that have been
+// provided to its owner by other entities, but doesn't contain attributes itself.
+//-----------------------------------------------------------------------------
+class CAttributeManager
+{
+ DECLARE_CLASS_NOBASE( CAttributeManager );
+public:
+ DECLARE_DATADESC();
+ DECLARE_EMBEDDED_NETWORKVAR();
+
+ CAttributeManager();
+ virtual ~CAttributeManager() {}
+
+ // Call this inside your entity's Spawn()
+ virtual void InitializeAttributes( CBaseEntity *pEntity );
+
+ CBaseEntity *GetOuter( void ) const { return m_hOuter.Get(); }
+
+ //--------------------------------------------------------
+ // Attribute providers.
+ // Other entities that are providing attributes to this entity (i.e. weapons being carried by a player)
+ void ProvideTo( CBaseEntity *pProvider );
+ void StopProvidingTo( CBaseEntity *pProvider );
+
+protected:
+ // Not to be called directly. Use ProvideTo() or StopProvidingTo() above.
+ void AddProvider( CBaseEntity *pProvider );
+ void RemoveProvider( CBaseEntity *pProvider );
+
+public:
+ // Return true if this entity is providing attributes to the specified entity
+ bool IsProvidingTo( CBaseEntity *pEntity ) const;
+
+ // Return true if this entity is being provided attributes by the specified entity
+ bool IsBeingProvidedToBy( CBaseEntity *pEntity ) const;
+
+ // Provider types are used to prevent specified providers supplying to certain initiators
+ void SetProviderType( attributeprovidertypes_t tType ) { m_ProviderType = tType; }
+ attributeprovidertypes_t GetProviderType( void ) const { return m_ProviderType; }
+
+ //--------------------------------------------------------
+ // Attribute hook. Use the CALL_ATTRIB_HOOK macros above.
+ template <class T> static T AttribHookValue( T TValue, const char *pszAttribHook, const CBaseEntity *pEntity, CUtlVector<CBaseEntity*> *pItemList = NULL, bool bIsGlobalConstString = false )
+ {
+ VPROF_BUDGET( "CAttributeManager::AttribHookValue", VPROF_BUDGETGROUP_ATTRIBUTES );
+
+ // Do we have a hook?
+ if ( pszAttribHook == NULL || pszAttribHook[0] == '\0' )
+ return TValue;
+
+ // Verify that we have an entity, at least as "this"
+ if ( pEntity == NULL )
+ return TValue;
+
+ IHasAttributes *pAttribInterface = GetAttribInterface( (CBaseEntity*) pEntity );
+ AssertMsg( pAttribInterface, "If you hit this, you've probably got a hook incorrectly setup, because the entity it's hooking on doesn't know about attributes." );
+ if ( pAttribInterface == NULL )
+ return TValue;
+
+ // Hook base attribute.
+ T Scratch;
+ AttribHookValueInternal( Scratch, TValue, pszAttribHook, pEntity, pAttribInterface, pItemList, bIsGlobalConstString );
+
+ return Scratch;
+ }
+
+private:
+ template <class T> static void TypedAttribHookValueInternal( T& out, T TValue, string_t iszAttribHook, const CBaseEntity *pEntity, IHasAttributes *pAttribInterface, CUtlVector<CBaseEntity*> *pItemList )
+ {
+ float flValue = pAttribInterface->GetAttributeManager()->ApplyAttributeFloatWrapper( static_cast<float>( TValue ), const_cast<CBaseEntity *>( pEntity ), iszAttribHook, pItemList );
+
+ out = AttributeConvertFromFloat<T>( flValue );
+ }
+
+ static void TypedAttribHookValueInternal( CAttribute_String& out, const CAttribute_String& TValue, string_t iszAttribHook, const CBaseEntity *pEntity, IHasAttributes *pAttribInterface, CUtlVector<CBaseEntity*> *pItemList )
+ {
+ string_t iszIn = AllocPooledString( TValue.value().c_str() );
+ string_t iszOut = pAttribInterface->GetAttributeManager()->ApplyAttributeStringWrapper( iszIn, const_cast<CBaseEntity *>( pEntity ), iszAttribHook, pItemList );
+ const char* pszOut = STRING( iszOut );
+ // STRING() returns different value for server and client
+ // server will return "" for NULL_STRING
+ // client will return NULL for NULL_STRING
+ if ( pszOut )
+ {
+ out.set_value( pszOut );
+ }
+ else
+ {
+ out.set_value( "" );
+ }
+ }
+
+ template <class T> static void AttribHookValueInternal( T& out, T TValue, const char *pszAttribHook, const CBaseEntity *pEntity, IHasAttributes *pAttribInterface, CUtlVector<CBaseEntity*> *pItemList, bool bIsGlobalConstString )
+ {
+ Assert( pszAttribHook );
+ Assert( pszAttribHook[0] );
+ Assert( pEntity );
+ Assert( pAttribInterface );
+ Assert( GetAttribInterface( (CBaseEntity*) pEntity ) == pAttribInterface );
+ Assert( pAttribInterface->GetAttributeManager() );
+
+ string_t iszAttribHook = bIsGlobalConstString ? AllocPooledString_StaticConstantStringPointer( pszAttribHook ) : AllocPooledString( pszAttribHook );
+ return TypedAttribHookValueInternal( out, TValue, iszAttribHook, pEntity, pAttribInterface, pItemList );
+ }
+ int m_nCurrentTick;
+ int m_nCalls;
+
+public:
+ virtual float ApplyAttributeFloat( float flValue, CBaseEntity *pInitiator, string_t iszAttribHook = NULL_STRING, CUtlVector<CBaseEntity*> *pItemList = NULL );
+ virtual string_t ApplyAttributeString( string_t iszValue, CBaseEntity *pInitiator, string_t iszAttribHook = NULL_STRING, CUtlVector<CBaseEntity*> *pItemList = NULL );
+
+ //--------------------------------------------------------
+ // Networking
+#ifdef CLIENT_DLL
+ virtual void OnPreDataChanged( DataUpdateType_t updateType );
+ virtual void OnDataChanged( DataUpdateType_t updateType );
+#endif
+
+ //--------------------------------------------------------
+ // memory handling
+ void *operator new( size_t stAllocateBlock );
+ void *operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine );
+
+protected:
+ CUtlVector<EHANDLE> m_Providers; // entities that we receive attribute data *from*
+ CUtlVector<EHANDLE> m_Receivers; // entities that we provide attribute data *to*
+ CNetworkVarForDerived( int, m_iReapplyProvisionParity );
+ CNetworkVarForDerived( EHANDLE, m_hOuter );
+ bool m_bPreventLoopback;
+ CNetworkVarForDerived( attributeprovidertypes_t, m_ProviderType );
+ int m_iCacheVersion; // maps to gamerules counter for global cache flushing
+
+public:
+ virtual void OnAttributeValuesChanged()
+ {
+ ClearCache();
+ }
+
+private:
+ void ClearCache();
+ int GetGlobalCacheVersion() const;
+
+ virtual float ApplyAttributeFloatWrapper( float flValue, CBaseEntity *pInitiator, string_t iszAttribHook, CUtlVector<CBaseEntity*> *pItemList = NULL );
+ virtual string_t ApplyAttributeStringWrapper( string_t iszValue, CBaseEntity *pInitiator, string_t iszAttribHook, CUtlVector<CBaseEntity*> *pItemList = NULL );
+
+ // Cached attribute results
+ // We cache off requests for data, and wipe the cache whenever our providers change.
+ union cached_attribute_types
+ {
+ float fl;
+ string_t isz;
+ };
+
+ struct cached_attribute_t
+ {
+ string_t iAttribHook;
+ cached_attribute_types in;
+ cached_attribute_types out;
+ };
+ CUtlVector<cached_attribute_t> m_CachedResults;
+
+#ifdef CLIENT_DLL
+public:
+ // Data received from the server
+ int m_iOldReapplyProvisionParity;
+#endif
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: This is an attribute manager that also knows how to contain attributes.
+//-----------------------------------------------------------------------------
+class CAttributeContainer : public CAttributeManager
+{
+public:
+ DECLARE_DATADESC();
+ DECLARE_CLASS( CAttributeContainer, CAttributeManager );
+ DECLARE_EMBEDDED_NETWORKVAR();
+
+ virtual void InitializeAttributes( CBaseEntity *pEntity );
+
+ //--------------------------------------------------------
+ // Attribute hook. Use the CALL_ATTRIB_HOOK macros above.
+ virtual float ApplyAttributeFloat( float flValue, CBaseEntity *pInitiator, string_t iszAttribHook = NULL_STRING, CUtlVector<CBaseEntity*> *pItemList = NULL ) OVERRIDE;
+ virtual string_t ApplyAttributeString( string_t iszValue, CBaseEntity *pInitiator, string_t iszAttribHook = NULL_STRING, CUtlVector<CBaseEntity*> *pItemList = NULL ) OVERRIDE;
+
+ CEconItemView *GetItem( void ) { return &m_Item; }
+ const CEconItemView *GetItem( void ) const { return &m_Item; }
+ void SetItem( const CEconItemView *pItem ) { m_Item.CopyFrom( *pItem ); }
+
+ virtual void OnAttributeValuesChanged()
+ {
+ BaseClass::OnAttributeValuesChanged();
+
+ m_Item.OnAttributeValuesChanged();
+ }
+
+private:
+ CNetworkVarEmbedded( CEconItemView, m_Item );
+};
+
+//-----------------------------------------------------------------------------
+// Purpose: An attribute manager that uses a player's shared attributes.
+//-----------------------------------------------------------------------------
+
+#ifndef DOTA_DLL
+class CAttributeContainerPlayer : public CAttributeManager
+{
+public:
+ DECLARE_DATADESC();
+ DECLARE_CLASS( CAttributeContainerPlayer, CAttributeManager );
+ DECLARE_EMBEDDED_NETWORKVAR();
+
+ virtual float ApplyAttributeFloat( float flValue, CBaseEntity *pInitiator, string_t iszAttribHook = NULL_STRING, CUtlVector<CBaseEntity*> *pItemList = NULL ) OVERRIDE;
+ virtual string_t ApplyAttributeString( string_t iszValue, CBaseEntity *pInitiator, string_t iszAttribHook = NULL_STRING, CUtlVector<CBaseEntity*> *pItemList = NULL ) OVERRIDE;
+
+ CBasePlayer* GetPlayer( void ) { return m_hPlayer; }
+ void SetPlayer( CBasePlayer *pPlayer ) { m_hPlayer = pPlayer; }
+
+ virtual void OnAttributeValuesChanged()
+ {
+ BaseClass::OnAttributeValuesChanged();
+
+ m_hPlayer->NetworkStateChanged();
+ }
+
+private:
+ CNetworkHandle( CBasePlayer, m_hPlayer );
+};
+#endif
+
+#ifdef CLIENT_DLL
+EXTERN_RECV_TABLE( DT_AttributeManager );
+EXTERN_RECV_TABLE( DT_AttributeContainer );
+#else
+EXTERN_SEND_TABLE( DT_AttributeManager );
+EXTERN_SEND_TABLE( DT_AttributeContainer );
+#endif
+
+#endif // ATTRIBUTE_MANAGER_H